簡體   English   中英

glDrawElements異常

[英]Exception at glDrawElements

我正在嘗試將模型加載到我的項目中,並且glDrawElements出現異常。 我讀取了模型文件(.nfg),並將頂點和索引保留為向量,然后使用“頂點緩沖對象”綁定我的模型。

我嘗試了這一點 :我將第四個參數從(GLvoid*)(sizeof(Vector3) * x)(GLvoid*)(offset(Vertex, attribute)) ,但沒有做任何事情(在鏈接中,問題是他在第4個參數中發送內存地址,我想可能是我將錯誤的參數發送給了錯誤的屬性,但在實際顯示模型時仍然會出現問題)。

我正在使用OpenGL ES 2.0,並且沒有針對Android或iOS進行此項目; 當前在Windows 8.1上的Visual Studio 2013中工作

模型加載器:

void loadModelNfg(const std::string &filename, 
                    GLuint &vbo, GLuint &ibo, GLuint &num, Shaders shaders){

    // put here the verteces and indices from the file
    std::vector<Vertex> vertices;
    std::vector<GLushort> indices;

    _loadModelNfg(filename, vertices, indices);
    std::cout << "Mesh Loader: loaded file: " << filename << "\n";

    // creates OpenGL objects necessary for drawing
    GLuint gl_vertex_buffer_object, gl_index_buffer_object;

    // vertex buffer object -> object in which to keep the vertices
    glGenBuffers(1, &gl_vertex_buffer_object);
    glBindBuffer(GL_ARRAY_BUFFER, gl_vertex_buffer_object);

    glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), 
                    &vertices[0], GL_STATIC_DRAW);

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    // index buffer object -> object in which to keep the indices
    glGenBuffers(1, &gl_index_buffer_object);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gl_index_buffer_object);

    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLushort), 
                    &indices[0], GL_STATIC_DRAW);

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    vbo = gl_vertex_buffer_object;
    ibo = gl_index_buffer_object;
    num = indices.size();
}

調用上一個函數:

// for now, global variables:
GLuint vbo, ibo, num;
Shader myShaders;

int Init ( ESContext* esContext ) {
    glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f );

    // this one works: tried with a triangle
    int ret = myShaders.Init("../Resources/Shaders/TriangleShaderVS.vs", 
                    "../Resources/Shaders/TriangleShaderFS.fs");
    if (ret == 0)
        loadModelNfg("../../ResourcesPacket/Models/Bila.nfg", vbo, ibo, num, myShaders);

    return ret;
}

繪制模型:

void Draw(ESContext* esContext) {
    Matrix world;
    world.SetIdentity();
    Matrix view = c.getView();
    Matrix persp = c.getPerspective();
    Matrix trans = world * view *persp;

    glClear(GL_COLOR_BUFFER_BIT);
    glUseProgram(myShaders.program);

    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);

    if (myShaders.positionAttribute != -1) {
            glEnableVertexAttribArray(myShaders.positionAttribute);
            glVertexAttribPointer(myShaders.positionAttribute, 3, GL_FLOAT, 
                    GL_FALSE, sizeof(Vertex), (GLvoid*)(offsetof(Vertex, pos)));
    }
    if (myShaders.normalAttribute != -1) {
            glEnableVertexAttribArray(myShaders.normalAttribute);
            glVertexAttribPointer(myShaders.normalAttribute, 3, GL_FLOAT, 
                    GL_FALSE, sizeof(Vertex), (GLvoid*)(offsetof(Vertex, norm)));
    }
    if (myShaders.binormalAttribute != -1) {
            glEnableVertexAttribArray(myShaders.binormalAttribute);
            glVertexAttribPointer(myShaders.binormalAttribute, 3, GL_FLOAT, 
                    GL_FALSE, sizeof(Vertex), (GLvoid*)(offsetof(Vertex, binorm)));
    }
    if (myShaders.tangentAttribute != -1) {
            glEnableVertexAttribArray(myShaders.tangentAttribute);
            glVertexAttribPointer(myShaders.tangentAttribute, 3, GL_FLOAT, 
                    GL_FALSE, sizeof(Vertex), (GLvoid*)(offsetof(Vertex, tgt)));
    }
    if (myShaders.texcoordAttribute != -1) {
            glEnableVertexAttribArray(myShaders.texcoordAttribute);
            glVertexAttribPointer(myShaders.texcoordAttribute, 2, GL_FLOAT, 
                    GL_FALSE, sizeof(Vertex), (GLvoid*)(offsetof(Vertex, uv)));
    }
    if (myShaders.colorAttribute != -1) {
            glEnableVertexAttribArray(myShaders.colorAttribute);
            glVertexAttribPointer(myShaders.colorAttribute, 3, GL_FLOAT, 
                    GL_FALSE, sizeof(Vertex), (GLvoid*)(offsetof(Vertex, col)));
    }
    if (myShaders.MVPuniform != -1) {
            glUniformMatrix4fv(myShaders.MVPuniform, 1, GL_FALSE, (GLfloat*) trans.m);
    }

    // HERE GETS EXCEPTION
    glDrawElements(GL_TRIANGLES, num, GL_UNSIGNED_SHORT, (GLvoid*) 0);

    eglSwapBuffers (esContext->eglDisplay, esContext->eglSurface);
}

我不確定我是否正確綁定了loadModelNfg()函數中的緩沖區。

這個問題從何而來?如何解決?

編輯:

GL_VENDOR:   Imagination Technologies (Host GL: 'Intel'); 
GL_RENDERER: PowerVR PVRVFrame 4.2SGX 530 (Host 'Intel(R) HD Graphics 400'); 
GL_VERSION:  OpenGL ES 2.0 (SDK build: 2.04.24.0809)

編輯:

我用try-catch語句包圍了該函數,但是在調用它時仍會中斷:

try {
    glDrawElements(GL_TRIANGLES, num, GL_UNSIGNED_SHORT, (GLvoid*)0);
}
catch (const std::exception& e) {
    std::cout << e.what() << "\n";
}

我忘了提到項目/解決方案的構建成功(在清理后或通過重建)。

在得知OpenGL不會引發異常之后,我開始研究它如何處理錯誤。 我發現它“返回”錯誤代碼(如果成功,則返回0),可以通過glGetError()找到該錯誤代碼。

通過代碼中的glGetError() ,我發現錯誤是由glUseProgram(myShaders.program);引起的glUseProgram(myShaders.program);

知道這一點之后,我遍歷了使用myShaders變量的函數, myShaders現在調用loadModelNfg("../../ResourcesPacket/Models/Bila.nfg", vbo, ibo, num, myShaders); ,該變量已更改。

記住我不再使用它了,我只是刪除了它,一切都很好。

奇怪的是,我沒有在該函數的任何地方修改myShaders變量(問題中的代碼是最后一個)。 我認為問題是我沒有聲明參數const Shaders shaders

因此,得出的結論是:在代碼中使用glGetError()和斷點來查找真正的問題。 它可能不是它破裂的地方!

PS:我希望這可以作為答案。 如果不是,我將更新問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM