gpt4 book ai didi

c++ - glDrawElements 异常

转载 作者:行者123 更新时间:2023-11-30 04:06:21 26 4
gpt4 key购买 nike

我正在尝试将模型加载到我的项目中,但在 glDrawElements 处出现异常。我读取模型文件 (.nfg),并将顶点和索引保留到 vector 中,然后使用顶点缓冲区对象来绑定(bind)我的模型。

我试过了 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);
}

我不确定我是否正确绑定(bind)了 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);引起的。

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

记得我不用它了,我就把它去掉了,一切都很好。

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

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

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

关于c++ - glDrawElements 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22940388/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com