OpenGL 绘制网格不正确
Posted
技术标签:
【中文标题】OpenGL 绘制网格不正确【英文标题】:OpenGL drawing meshes incorrectly 【发布时间】:2014-04-05 15:46:15 【问题描述】:我正在尝试用 C++ 制作 OpenGL 引擎,但无法正确渲染网格。网格在渲染时创建的面连接网格上的两个随机点,或者网格上的一个随机点与 0,0,0。
问题可以看这里:
(我做了一个线框图,以便更清楚地看到问题)
代码:
// Render all meshes (Graphics.cpp)
for( int curMesh = 0; curMesh < numMesh; curMesh++ )
// Save pointer of buffer
meshes[curMesh]->updatebuf();
Buffer buffer = meshes[curMesh]->buffer;
// Update model matrix
glm::mat4 mvp = Proj*View*(meshes[curMesh]->model);
// Initialize vertex array
glBindBuffer( GL_ARRAY_BUFFER, vertbuffer );
glBufferData( GL_ARRAY_BUFFER, sizeof(GLfloat)*buffer.numcoords*3, meshes[curMesh]->verts, GL_STATIC_DRAW );
// Pass information to shader
GLuint posID = glGetAttribLocation( shader, "s_vPosition" );
glVertexAttribPointer( posID, 3, GL_FLOAT, GL_FALSE, 0, (void*)0 );
glEnableVertexAttribArray( posID );
// Check if texture applicable
if( meshes[curMesh]->texID != NULL && meshes[curMesh]->uvs != NULL )
// Initialize uv array
glBindBuffer( GL_ARRAY_BUFFER, uvbuffer );
glBufferData( GL_ARRAY_BUFFER, sizeof(GLfloat)*buffer.numcoords*2, meshes[curMesh]->uvs, GL_STATIC_DRAW );
// Pass information to shader
GLuint uvID = glGetAttribLocation( shader, "s_vUV" );
glVertexAttribPointer( uvID, 2, GL_FLOAT, GL_FALSE, 0, (void*)(0) );
glEnableVertexAttribArray( uvID );
// Set mesh texture
glActiveTexture( GL_TEXTURE0 );
glBindTexture( GL_TEXTURE_2D, meshes[curMesh]->texID );
GLuint texID = glGetUniformLocation( shader, "Sampler" );
glUniform1i( texID, 0 );
// Actiavte shader
glUseProgram( shader );
// Set MVP matrix
GLuint mvpID = glGetUniformLocation( shader, "MVP" );
glUniformMatrix4fv( mvpID, 1, GL_FALSE, &mvp[0][0] );
// Draw verticies on screen
bool wireframe = true;
if( wireframe )
for(int i = 0; i < buffer.numcoords; i += 3)
glDrawArrays(GL_LINE_LOOP, i, 3);
else
glDrawArrays( GL_TRIANGLES, 0, buffer.numcoords );
// Mesh Class (Graphics.h)
class mesh
public:
mesh();
void updatebuf();
Buffer buffer;
GLuint texID;
bool updated;
GLfloat* verts;
GLfloat* uvs;
glm::mat4 model;
;
我的 Obj 加载代码在这里:https://www.dropbox.com/s/tdcpg4vok11lf9d/ObjReader.txt(它很粗糙,没有组织,但应该仍然可以工作)
【问题讨论】:
你能发布你的示例文件吗?你在加载器中做了一堆假设,这些假设可能会或可能不会被数据尊重,但如果没有数据就很难判断。 @DirkR 也许这可能是问题所在,这是我正在使用的 teapot.obj 文件:dropbox.com/s/z8fy46x3zeadg0s/teapot.obj.txt 嗯,好的,这应该是可行的。所以我的建议是放弃你自己的加载器,改用 assimp (assimp.sourceforge.net),它支持更多的格式并且被广泛使用。 编写自己的有效加载程序并非不可能。我会仔细检查数据,看看缓冲区内容是否符合您的预期。这很乏味,但你肯定会以这种方式找到根本原因。经常犯的一个常见错误是没有将索引移动 1(OpenGL 从 0 开始计数,OBJ 从 1 开始计数)。我会尝试从目标文件中手动删除一些面,只留下有问题的顶点,然后首先确认 VBO 实际上具有正确的数据。 【参考方案1】:对我来说,这看起来像是一个原始的重启问题。如果没有看到一些代码,很难说出究竟是什么问题。看看上面和下面的大约 20 行,包括绘制调用渲染茶壶,这将有很大帮助。 IE。对应的 glDrawArrays、glDrawElements 或 glBegin 调用之前的 20 行和之后的 20 行。
【讨论】:
我认为这与重新启动三角形有关,但 OBJ 文件中没有任何内容表示顶点断点,所以我怎么知道新三角形列表何时开始? (顺便说一句,我发布了代码)【参考方案2】:这是因为您的三角形没有连接到线框看起来很完美。 如果三角形未连接,则应构建索引缓冲区。
【讨论】:
以上是关于OpenGL 绘制网格不正确的主要内容,如果未能解决你的问题,请参考以下文章
为啥绘制我的 OpenGL-ES VBO 网格会阻止其他三角形显示?