为什么这段代码在 LWJGL 3 中没有显示三角形?



我正尝试着创造一个游戏引擎,但我却停留在三角形步骤上。由于我当前的代码有多个类,我试图将其简化为一个类。

public class MainGame {
public static void main(String[] args) {
GLFW.glfwInit();

GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MAJOR, 4);
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MINOR, 0);
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_PROFILE, GLFW.GLFW_OPENGL_CORE_PROFILE);

long window = GLFW.glfwCreateWindow(900, 900, "Test Window", NULL, NULL);

GLFWVidMode vid = GLFW.glfwGetVideoMode(GLFW.glfwGetPrimaryMonitor());
GLFW.glfwSetWindowPos(window, (vid.width() - 900)/2, 
(vid.height() - 900)/2);

GLFW.glfwMakeContextCurrent(window);

GL.createCapabilities();

GLFW.glfwSwapInterval(1);
GLFW.glfwShowWindow(window);

int programId = 0;
try {
programId = loadProgram("triangle.vert.glsl", "triangle.frag.glsl");
} catch (IOException e) {
e.printStackTrace();
}
int vaoId = loadTriangle();
while (!GLFW.glfwWindowShouldClose(window)) {
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
GL11.glClearColor(1, 0, 0, 1);
GLFW.glfwSwapBuffers(window); 
GLFW.glfwPollEvents();

GL30.glUseProgram(programId);
GL30.glBindVertexArray(vaoId);
GL20.glEnableVertexAttribArray(0);
GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, 3);
GL20.glDisableVertexAttribArray(0);
GL30.glBindVertexArray(0);
GL30.glUseProgram(0);
}

GL30.glDeleteVertexArrays(vaoId);
GL30.glDeleteProgram(programId);
GLFW.glfwDestroyWindow(window);
GLFW.glfwTerminate();

}

private static int loadTriangle() {
float[] positions = new float[] {
+0f, +1f,
-1f, -1f,
+1f, -1f
};

FloatBuffer buffer = BufferUtils.createFloatBuffer(positions.length);
buffer.put(positions);
buffer.flip();
int vaoId = GL30.glGenVertexArrays();
GL30.glBindVertexArray(vaoId);

int bufferId = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, bufferId);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
GL20.glVertexAttribPointer(0, 2, GL11.GL_FLOAT, false, 0, 0);

GL30.glBindVertexArray(0);

return vaoId;
} 

private static int loadProgram(String vertex, String fragment) throws IOException {
int vertexShader = GL30.glCreateShader(GL30.GL_VERTEX_SHADER);
int fragmentShader = GL30.glCreateShader(GL30.GL_FRAGMENT_SHADER);
String vertexCode = Files.lines(Paths.get(vertex))
.collect(Collectors.joining("n"));
String fragmentCode = Files.lines(Paths.get(fragment))
.collect(Collectors.joining("n"));

GL30.glShaderSource(vertexShader, vertexCode);
GL30.glCompileShader(vertexShader);
String slog = GL30.glGetShaderInfoLog(vertexShader);
System.out.println(slog);

GL30.glShaderSource(fragmentShader, fragmentCode);
GL30.glCompileShader(fragmentShader);
slog = GL30.glGetShaderInfoLog(fragmentShader);
System.out.println(slog);
int program = GL30.glCreateProgram();
GL30.glAttachShader(program, vertexShader);
GL30.glAttachShader(program, fragmentShader);
GL30.glLinkProgram(program);
GL30.glDetachShader(program, vertexShader);
GL30.glDetachShader(program, fragmentShader);
GL30.glDeleteShader(vertexShader);
GL30.glDeleteShader(fragmentShader);

return program;
}
}

这是triangle.vert.glsl:

#version 400 core
layout(location = 0) in vec2 position;
void main() {
gl_Position = vec4(position, 0.0, 1.0);
}

This is triangle. lang .glsl:

#version 400 core
out vec4 color;
void main() {
color = vec4(0.0, 0.0, 1.0, 1.0);
}

当我运行程序时,没有OpenGL或GLSL错误。我尝试使用glGetError(),但一切都是0。

我希望看到一个红色背景的蓝色三角形,但我只有一个红色的窗口。我很确定问题不在于GLFW代码(窗口确实显示),或着色器代码(着色器编译,当我在着色器代码中犯错误时,程序将其列出)。但是三角形代码似乎也没问题。

有什么我错过或错了吗?

注意:我只在一台电脑上测试过,所以这可能是一个特定于电脑的错误。

你的循环中每帧的操作顺序是错误的。

如果我们看看在一个帧内发生了什么(从swapbuffers到swapbuffers间隔),那么本质上,你首先做绘制调用来渲染你的三角形,然后你再次清除颜色缓冲区(这将覆盖你的三角形与明确的颜色)和然后你交换缓冲区。

所以,现在,每帧的操作顺序总是:
  1. 清除缓冲区
  2. 交换缓冲区

为了解决这个问题,你应该把交换缓冲区调用glfwSwapBuffers(window)放在循环的末尾,这将改变每帧操作的顺序:

  1. 清除缓冲区
  2. 交换缓冲区

然后你会看到蓝色的三角形。

最新更新