为啥我的 OpenGL 对象绘制相对于最后绘制的对象?
Posted
技术标签:
【中文标题】为啥我的 OpenGL 对象绘制相对于最后绘制的对象?【英文标题】:Why are my OpenGL objects drawing relative to the last object drawn?为什么我的 OpenGL 对象绘制相对于最后绘制的对象? 【发布时间】:2015-01-18 01:35:38 【问题描述】:我很确定这是由于我对 GL_MODELVIEW
矩阵的工作原理缺乏了解。这是正在发生的事情的屏幕记录:http://youtu.be/3F7FLkVI7kA
如您所见,最底部的三角形是第一个绘制的三角形,并且按照我预期的方式移动其他 2 个三角形。第二个三角形相对于第一个三角形移动和旋转,第三个三角形相对于该组合移动和旋转。
我想要的是所有三个三角形在 3D 空间中都是静止的,但在旋转(就像第一个三角形一样)。
来源:
// Main loop
do
// Clear Screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Update camera
glfwGetCursorPos(window, &cursorX, &cursorY);
cam.update(0.001f, (int)cursorX, (int)cursorY);
// Reset Matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// move camera
glRotatef(cam.rotation.x, 1.0f, 0.0f, 0.0f);
glRotatef(cam.rotation.y, 0.0f, 1.0f, 0.0f);
// translate modelview matrix to position of the camera - everything should now draw relative to camera position
glTranslatef(-cam.position.x, cam.position.y, -cam.position.z);
// Draw ground
drawGroundGrid(-25.0f);
drawSpinningTriangle(0.0f, 0.0f, -5.0f);
drawSpinningTriangle(3.14f, 3.0f, -6.0f);
drawSpinningTriangle(-6.0f, 12.0f, -5.0f);
// Swap buffers - back buffer is now front buffer to be rendered to next frame
glfwSwapBuffers(window);
glfwPollEvents();
calcFPS();
while (!glfwGetKey(window, GLFW_KEY_ESCAPE) && !glfwWindowShouldClose(window));// Main Loop End
[...]
void drawSpinningTriangle(float x, float y, float z)
glMatrixMode(GL_MODELVIEW);
glTranslatef(x, y, z);
glRotatef(glfwGetTime() * 50.0f, 0.0f, 1.0f, 0.0f);
glBegin(GL_TRIANGLES);
// Red vertex
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 1.0f, 0.0f);
// Yellow vertex
glColor3f(1.0f, 1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 0.0f);
// White vertex
glColor3f(1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 0.0f);
glEnd();
【问题讨论】:
确保您的深度缓冲区已设置并启用。 已经完成了,但那不会只影响 z 剔除吗? 【参考方案1】:首先使用矩阵堆栈已被弃用。管理自己的矩阵要好得多
其次,你应该在转换之前和绘制之后 pushMatrix 和 popMatrix:
void drawSpinningTriangle(float x, float y, float z)
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glTranslatef(x, y, z);
glRotatef(glfwGetTime() * 50.0f, 0.0f, 1.0f, 0.0f);
glBegin(GL_TRIANGLES);
// Red vertex
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 1.0f, 0.0f);
// Yellow vertex
glColor3f(1.0f, 1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 0.0f);
// White vertex
glColor3f(1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 0.0f);
glEnd();
glPopMatrix();
这将保存和恢复最顶部的矩阵,因此两次调用之间的任何更改都将被删除。
【讨论】:
管理自己的矩阵是什么意思?那是推送和弹出矩阵吗? @AlexMohr:不。推送和弹出矩阵使用旧的、已弃用的 OpenGL 固定函数矩阵堆栈。没有一个严肃的程序曾经使用过这个功能;使用起来很麻烦,并且提供零收益。所以它从现代 OpenGL 中被删除了——很好摆脱。无论如何,你应该得到一个真正的矩阵数学库(最好是一个用于图形的库,如 GLM 或 linmath.h)并管理你自己的一组转换矩阵。您仍然可以进行分层转换,但要灵活得多。以上是关于为啥我的 OpenGL 对象绘制相对于最后绘制的对象?的主要内容,如果未能解决你的问题,请参考以下文章