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

Why are my OpenGL objects drawing relative to the last object drawn?

我很确定这是因为我不了解 GL_MODELVIEW 矩阵的工作原理。这是正在发生的事情的屏幕录像:http://youtu.be/3F7FLkVI7kA

如您所见,最底部的三角形是第一个绘制的三角形,它的移动方式与我预期的其他 2 个三角形的移动方式相同。第二个三角形相对于第一个三角形移动和旋转,第三个三角形相对于该组合​​移动和旋转。

我想要的是所有三个三角形在 3D 中都是静止的 space,但旋转(就像第一个三角形)。

来源:

// 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();
}

首先不推荐使用矩阵堆栈。管理自己的矩阵要好得多

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

}

这将保存并恢复最顶层的矩阵,以便删除两次调用之间的任何更改。