我正在尝试将模型加载到我的项目中,并在glDrawElements
处获得异常。
我读取了模型文件(.nfg),并将顶点和索引保留在矢量中,并使用Vertex Buffer Object来绑定我的模型。
我试过this:
我从(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";
}
我忘了提及项目/解决方案构建成功(清理后或通过重建)。
答案 0 :(得分:2)
在得知OpenGL没有抛出异常后,我开始研究它如何处理错误。我发现它&#34;返回&#34;错误代码(如果成功,则为0),可以使用glGetError()
找到。
通过代码glGetError()
,我发现错误是由glUseProgram(myShaders.program);
引起的。
知道了,我查看了使用myShaders
变量的函数,我发现在调用loadModelNfg("../../ResourcesPacket/Models/Bila.nfg", vbo, ibo, num, myShaders);
之后,变量发生了变化。
记住我不再使用它,我只是删除它,一切都很好。
奇怪的是,我没有在该函数的任何地方修改myShaders
变量(问题中的代码是最后一个)。我认为问题在于我没有声明参数const Shaders shaders
。
所以,结论是:
在代码中使用glGetError()
和断点来查找真正的问题。它可能不是它破碎的地方!