0

複数のメッシュを持つ .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]);
        }

    }
}
4

1 に答える 1

0

newed 配列をローカル変数に割り当てています。関数が戻った後、このメモリは失われます。

次のようになります。

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

**( 2つのパラメータに注意してください、そして_例のために)

その後、:

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

2番目のパラメーターについても同じです。

num_meshはポインタですが、それに整数を代入しています (ローカルなので、値が再び失われます)。である必要があります*num_mesh = scene->mNumMeshes;

もう 1 つのことはglGenVertexArrays、ループ内で使用していることです。一度だけ使用する必要があります。反復ごとに、以前のデータが失われます。

呼び出し側にはこの値が何であるかがわからないため、頂点配列が不要になったときに頂点配列を削除する方法は不明です。

于 2014-07-07T10:52:40.977 に答える