相同的 openGL 调用在 LWJGL 中产生不同的结果

Same openGL calls yield different results in LWJGL

我们应该使用 LWJGL 2.9.3 创建一个显示线框对象的简单应用程序。我根据 http://www.glprogramming.com/red/chapter01.html 中的第一个示例代码创建了一个测试 class 我最终得到的是一个程序,该程序会短暂闪烁白色方块然后消失。我不确定我做错了什么。

测试代码如下:

package Test.LWJGL;

import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;

import static CS355.LWJGL.LWJGLSandbox.DISPLAY_HEIGHT;
import static CS355.LWJGL.LWJGLSandbox.DISPLAY_WIDTH;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL11.glFlush;


public class LWJGLTest {
    public static void render() {
        glClear(GL_COLOR_BUFFER_BIT);
        glColor3f(1.0f, 1.0f, 1.0f);
        glOrtho(0, 1.0, 0.0, 1.0, -1.0, 1.0);
        glBegin(GL_POLYGON);
            glVertex3f(0.25f, 0.25f, 0.0f);
            glVertex3f(0.75f, 0.25f, 0.0f);
            glVertex3f(0.75f, 0.75f, 0.0f);
            glVertex3f(0.25f, 0.75f, 0.0f);
        glEnd();
        glFlush();
    }

    public static void main(String[] args)  {
        try {
            Display.setDisplayMode(new DisplayMode(DISPLAY_WIDTH,DISPLAY_HEIGHT));
            Display.setFullscreen(false);
            Display.create();

            glClearColor(0.0f,0.0f,0.0f,0.0f);

            while(!Display.isCloseRequested() && !Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) {
                if(Display.isVisible()) {
                    render();
                }
                else {
                    if(Display.isDirty()) {
                        render();
                    }
                    try {
                        Thread.sleep(100);
                    }
                    catch(InterruptedException ex) {}
                }
                Display.update();
                Display.sync(60);
            }
        }
        catch(Exception ex) {
            ex.printStackTrace();
        }
        finally {
            Mouse.destroy();
            Keyboard.destroy();
            Display.destroy();
        }
    }
}

OpenGL 是一个状态机。这意味着,您可以设置许多状态,这些状态将以某种明确定义的方式影响最终渲染结果。这些状态 永远不会 自动重置,它们只会保持您设置的状态,直到您更改它们。没有 "frames" 或 "scene objects" 这样的东西,只有状态设置或绘图命令流。

OpenGL的矩阵栈也只是一种状态。函数 glOrtho 将当前所选矩阵堆栈的当前顶部元素与该邻接矩阵相乘 ,并将用该结果替换顶部元素。

假设正交矩阵被称为O。最初,GL 的所有矩阵都是相同的。因此,当您第一次调用 render 时,您将得到:M = M * O = I * O = O。然而,第二次,你会得到M = M * O = O * O。等等。

您必须在帧开始时明确地将您的矩阵重置为恒等式:

glLoadIdentity();
glOrtho(...);

您应该知道您使用的代码不是很好。它使用 MODELVIEW 堆栈作为投影矩阵,这意味着去 GL_PROJECTION。但在您尝试了解该员工之前,请注意所有这些在 GL 中已经完全弃用十年了。现代核心版本的 OpenGL 根本不支持这些功能。