为什么我的OpenGL对象相对于最后绘制的对象进行绘制?

Ale*_*ohr 0 c++ opengl matrix glfw

我很确定这是因为我对GL_MODELVIEW矩阵的工作方式缺乏了解.这是一个屏幕录制正在发生的事情:http://youtu.be/3F7FLkVI7kA

如您所见,最底部的三角形是第一个绘制的三角形,并且随着我预期其他两个三角形移动而移动.第二个三角形相对于第一个三角形移动和旋转,第三个三角形相对于该组合​​移动和旋转.

我想要的是所有三个三角形在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();
}
Run Code Online (Sandbox Code Playgroud)

rat*_*eak 5

首先使用矩阵堆栈已弃用.管理自己的矩阵要好得多

其次,您应该在转换之前和绘制之后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();

}
Run Code Online (Sandbox Code Playgroud)

这将保存并恢复最顶层的矩阵,因此删除了2个调用之间的任何更改.

  • @AlexMohr:否.推送和弹出矩阵使用旧的,不推荐使用的OpenGL固定函数矩阵堆栈.没有严肃的程序曾经使用过该功能; 与它合作很麻烦,并且没有任何好处.所以它从现代OpenGL中删除 - 很好的解决.无论如何,你应该得到一个真正的矩阵数学库(最好是一个旨在用于图形的,如GLM或linmath.h)并管理你自己的一组转换矩阵.您仍然可以进行分层转换,但您更灵活. (2认同)