【问题标题】:Exception at glDrawElementsglDrawElements 的异常
【发布时间】:2014-04-10 03:26:36
【问题描述】:

我正在尝试将模型加载到我的项目中,但在 glDrawElements 处出现异常。 我读取模型文件 (.nfg),并将顶点和索引保留到向量中,并使用 Vertex Buffer Object 绑定我的模型。

我试过this: 我从(GLvoid*)(sizeof(Vector3) * x)修改了第四个参数 到(GLvoid*)(offset(Vertex, attribute)),但什么也没做(在链接中,问题是他在第四个参数中发送内存地址,我想也许我将错误的参数发送到错误的属性,但仍然是实际显示模型时出现问题)。

我正在使用 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";
}

我忘了提到项目/解决方案构建成功(在清理之后,或通过重建)。

【问题讨论】:

  • 哪个 ES 2.0 实现?
  • 我不知道。我正在研究教职员工的框架。我怎样才能找到它?
  • glGetString() on GL_VENDORGL_RENDERERGL_VERSION
  • GL_VENDOR:Imagination Technologies(主机 GL:“英特尔”); GL_RENDERER:PowerVR PVRVFrame 4.2SGX 530(主机'Intel(R) HD Graphics 400'); GL_VERSION:OpenGL ES 2.0(SDK 版本:2.04.24.0809)
  • OpenGL 不会抛出 C++ 异常,在 try/catch 块中围绕 GL 调用不会改变任何东西。构建 GL 实现的底层标准库可能会抛出 C++ 异常,但我真诚地怀疑它——它们通常是用 C 编写的。你必须明白那里是语言级异常和硬件/操作系统级异常之间的区别……它们具有相同的通用名称,但工作方式却大不相同。

标签: c++ opengl-es opengl-es-2.0


【解决方案1】:

在了解到 OpenGL 不会引发异常后,我开始研究它如何处理错误。我发现它“返回”错误代码(如果成功则返回 0),可以通过 glGetError() 找到。

通过代码去glGetError(),发现错误是由glUseProgram(myShaders.program);引起的。

知道了之后,我查看了使用myShaders变量的函数,发现调用loadModelNfg("../../ResourcesPacket/Models/Bila.nfg", vbo, ibo, num, myShaders);后,变量发生了变化。

记得我不再使用它,我只是将其删除,一切都很好。

奇怪的是我没有在该函数的任何地方修改myShaders 变量(问题中的代码是最后一个)。我认为问题在于我没有声明参数const Shaders shaders

所以,结论: 在代码中使用glGetError() 和断点来找到真正的问题。它可能不是它破裂的地方!

PS:我希望我把这个作为答案是可以的。如果不是,我会更新问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-21
    • 1970-01-01
    相关资源
    最近更新 更多