我有一个带有多个网格的 .obj 模型。我想为每个网格创建一个 vao。然后渲染所有的东西。
为此,我想创建一个 vao 指针,根据模型中的网格数量更改其大小。
我使用 assimp 为模型充电。
没有编译问题,但执行此程序时程序崩溃。
glBindVertexArray(modele_multvao[z]);
glDrawArrays(GL_TRIANGLES, 0, modele_multcount[z]);
知道我的程序出了什么问题?(我对openGL有点陌生)
我的代码:
GLuint *modele_vao;
int *point_count;
int number_of_mesh;
bool load_mesh(const char* file_name, GLuint* vao, int* point_count,int* num_mesh) {
/* load file with assimp and print some stats */
const aiScene* scene = aiImportFile(file_name, aiProcess_Triangulate);
if (!scene) {
std::wcout <<"ERROR: reading mesh: "<< file_name << std::endl;
std::wcout << aiGetErrorString() << std::endl;
return false;
}
std::wcout << "mesh import succeeded" << std::endl;
std::wcout << scene->mNumAnimations << " animations" << std::endl;
std::wcout << scene->mNumCameras << " cameras" << std::endl;
std::wcout << scene->mNumLights << " lights" << std::endl;
std::wcout << scene->mNumMaterials << " materials" << std::endl;
std::wcout << scene->mNumMeshes << " meshes" << std::endl;
std::wcout << scene->mNumTextures << " textures" << std::endl;
num_mesh=scene->mNumMeshes;
vao = new GLuint[scene->mNumMeshes];
point_count=new int[scene->mNumMeshes];
int i=0;
for(i=1;i<=(scene->mNumMeshes);i++)
{
/* get mesh n°i in file */
const aiMesh* mesh = scene->mMeshes[i-1];
std::wcout << "vertices in mesh :" << mesh->mNumVertices<< std::endl;
/* pass back number of vertex points in mesh */
*point_count = mesh->mNumVertices;
/* generate a VAO, using the pass-by-reference parameter that we give to the
function */
glGenVertexArrays(scene->mNumMeshes, vao);
glBindVertexArray(vao[i-1]);
/* we really need to copy out all the data from AssImp's funny little data
structures into pure contiguous arrays before we copy it into data buffers
because assimp's texture coordinates are not really contiguous in memory.
i allocate some dynamic memory to do this. */
GLfloat* points = NULL; // array of vertex points
GLfloat* normals = NULL; // array of vertex normals
GLfloat* texcoords = NULL; // array of texture coordinates
if (mesh->HasPositions()) {
points = (GLfloat*)malloc(*point_count * 3 * sizeof (GLfloat));
for (int i = 0; i < *point_count; i++) {
const aiVector3D* vp = &(mesh->mVertices[i]);
points[i * 3] = (GLfloat)vp->x;
points[i * 3 + 1] = (GLfloat)vp->y;
points[i * 3 + 2] = (GLfloat)vp->z;
}
}
if (mesh->HasNormals()) {
normals = (GLfloat*)malloc(*point_count * 3 * sizeof (GLfloat));
for (int i = 0; i < *point_count; i++) {
const aiVector3D* vn = &(mesh->mNormals[i]);
normals[i * 3] = (GLfloat)vn->x;
normals[i * 3 + 1] = (GLfloat)vn->y;
normals[i * 3 + 2] = (GLfloat)vn->z;
}
}
if (mesh->HasTextureCoords(0)) {
texcoords = (GLfloat*)malloc(*point_count * 2 * sizeof (GLfloat));
for (int i = 0; i < *point_count; i++) {
const aiVector3D* vt = &(mesh->mTextureCoords[0][i]);
texcoords[i * 2] = (GLfloat)vt->x;
texcoords[i * 2 + 1] = (GLfloat)vt->y;
}
}
/* copy mesh data into VBOs */
if (mesh->HasPositions()) {
GLuint vbo_pos;
glGenBuffers(1, &vbo_pos);
glBindBuffer(GL_ARRAY_BUFFER, vbo_pos);
glBufferData(
GL_ARRAY_BUFFER,
3 * *point_count * sizeof (GLfloat),
points,
GL_DYNAMIC_DRAW
);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(0);
free(points); // free our temporary memory
}
if (mesh->HasNormals()) {
GLuint vbo_norm;
glGenBuffers(1, &vbo_norm);
glBindBuffer(GL_ARRAY_BUFFER, vbo_norm);
glBufferData(
GL_ARRAY_BUFFER,
3 * *point_count * sizeof (GLfloat),
normals,
GL_DYNAMIC_DRAW
);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(2);
free(normals); // free our temporary memory
}
if (mesh->HasTextureCoords(0)) {
GLuint vbo_tex;
glGenBuffers(1, &vbo_tex);
glBindBuffer(GL_ARRAY_BUFFER, vbo_tex);
glBufferData(
GL_ARRAY_BUFFER,
2 * *point_count * sizeof (GLfloat),
texcoords,
GL_DYNAMIC_DRAW
);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(1);
free(texcoords); // free our temporary memory
}
if (mesh->HasTangentsAndBitangents()) {
// NB: could store/print tangents here
}
}
/* free assimp's copy of memory */
aiReleaseImport(scene);
std::wcout << "mesh loaded" << std::endl;
return true;
}
int main()
{
load_mesh("somewhere", modele_vao, point_count, &num_of_mesh)
[...]
while(1){
[...]
for(z=0;z<num_of_mesh;z++){
glBindVertexArray(modele_vao[z]);
glDrawArrays(GL_TRIANGLES, 0, modele_count[z]);
}
}
}