управление vao для модели с несколькими сетками

У меня есть модель .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]);
}

}
}

0

Решение

Вы назначаете newEd массивы для локальных переменных. После возврата функции эта память теряется.

Это должно быть что-то вроде:

bool load_mesh(const char* file_name, GLuint** _vao, int** _point_count,int* num_mesh)

(нота ** по двум параметрам, и _ ради примера)

А потом,:

GLuint *vao = new GLuint[scene->mNumMeshes];
*_vao = vao;

И то же самое для второго парам.

num_mesh является указателем, но вы присваиваете ему целое число (и оно является локальным, поэтому значение снова теряется). Так должно быть *num_mesh = scene->mNumMeshes;,

Другое дело, что вы используете glGenVertexArrays в цикле — его следует использовать только один раз; на каждой итерации вы теряете предыдущие данные.

Неясно, как вы собираетесь удалять свои вершинные массивы, когда они вам больше не нужны, поскольку вызывающая сторона понятия не имеет, что это за значения.

0

Другие решения


По вопросам рекламы [email protected]