LWJGL3+OpenGL 3.2三角形Demo窗口空白无报错求助
问题:LWJGL3 + OpenGL 3.2+ 三角形Demo空白无渲染(无OpenGL错误)
我正在学习LWJGL3与OpenGL 3.2+,编写了一个三角形Demo程序。程序运行正常且未出现任何OpenGL错误,但窗口始终显示空白,三角形无法渲染出来。
已排查常见问题:VAO已创建绑定并配置顶点属性,三角形坐标有效,着色器编译链接均正常,仍找不到原因。
完整代码
package net.part1kl; import com.hackoeur.jglm.Mat4; import com.hackoeur.jglm.Matrices; import org.lwjgl.Version; import org.lwjgl.glfw.*; import static org.lwjgl.glfw.GLFW.*; import org.lwjgl.opengl.GL; import java.nio.FloatBuffer; import java.nio.IntBuffer; import static org.lwjgl.opengl.GL30C.*; import static org.lwjgl.system.MemoryUtil.*; public class Demo { public static void main(String[] args) { init(); loop(); dispose(); } private static long window; private static void init(){ /* Initialize GLFW */ System.out.println(Version.getVersion()); glfwSetErrorCallback(GLFWErrorCallback.createPrint(System.err)); if (!glfwInit()) throw new IllegalStateException("GLFW Init Failed"); /* Set window hints and create window */ glfwDefaultWindowHints(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE); glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); window = glfwCreateWindow(600, 600, "Demo", NULL, NULL); if ( window == NULL) { glfwTerminate(); throw new RuntimeException("Window Creation Failed"); } /* Other window setup */ glfwSetWindowPos(window, 200, 200); glfwMakeContextCurrent(window); GL.createCapabilities(); glfwSwapInterval(1); glfwSetKeyCallback(window, (window, key, scancode, action, mods) -> { if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) glfwSetWindowShouldClose(window, true); }); glfwShowWindow(window); /* Create and bind VAO */ vao = glGenVertexArrays(); glBindVertexArray(vao); /* Create, bind, and populate VBO */ vbo = glGenBuffers(); glBindBuffer(GL_ARRAY_BUFFER, vbo); FloatBuffer verts = memAllocFloat(vertices.length); for (float val : vertices) verts.put(val); verts.flip(); glBufferData(GL_ARRAY_BUFFER, verts, GL_STATIC_DRAW); memFree(verts); /* Create Vertex Shader */ vShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vShader, vertexSource); glCompileShader(vShader); if (glGetShaderi(vShader, GL_COMPILE_STATUS) != GL_TRUE) throw new RuntimeException(glGetShaderInfoLog(vShader)); /* Create Fragment Shader */ fShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fShader, fragmentSource); glCompileShader(fShader); if (glGetShaderi(fShader, GL_COMPILE_STATUS) != GL_TRUE) throw new RuntimeException(glGetShaderInfoLog(fShader)); /* Create Shader Program */ program = glCreateProgram(); glAttachShader(program, vShader); glAttachShader(program, fShader); glBindFragDataLocation(program, 0, "fragColor"); glLinkProgram(program); if (glGetProgrami(program, GL_LINK_STATUS) != GL_TRUE) throw new RuntimeException(glGetProgramInfoLog(program)); glUseProgram(program); /* Set pointer for vertex position information */ int pAttr = glGetAttribLocation(program, "position"); glEnableVertexAttribArray(pAttr); glVertexAttribPointer(pAttr, 3, GL_FLOAT, false, 6 * Float.BYTES, 0); /* Set pointer for vertex color information */ int cAttr = glGetAttribLocation(program, "color"); glEnableVertexAttribArray(cAttr); glVertexAttribPointer(cAttr, 3, GL_FLOAT, false, 6 * Float.BYTES, 3 * Float.BYTES); /* Create and set model uniform. Using com.hackoeur.jglm v1.0.0 for matrices. */ Mat4 model = new Mat4(); int uModel = glGetUniformLocation(program, "model"); glUniformMatrix4fv(uModel, false, (FloatBuffer)model.getBuffer().flip()); /* Create and set view uniform */ Mat4 view = new Mat4(); int uView = glGetUniformLocation(program, "view"); glUniformMatrix4fv(uView, false, (FloatBuffer)view.getBuffer().flip()); /* Get window size ratio for projection */ IntBuffer width = memAllocInt(1); IntBuffer height = memAllocInt(1); GLFW.glfwGetFramebufferSize(window, width, height); float ratio = width.get() / (float) height.get(); memFree(width); memFree(height); /* Create and set projection uniform */ Mat4 projection = Matrices.ortho(-ratio, ratio, -1f, 1f, -1f, 1f); int uProjection = glGetUniformLocation(program, "projection"); glUniformMatrix4fv(uProjection, false, (FloatBuffer)projection.getBuffer().flip()); } private static void loop(){ double lastTime = glfwGetTime(); double time = lastTime; while(!glfwWindowShouldClose(window)){ double delta = (float) (time - lastTime); glClear(GL_COLOR_BUFFER_BIT); glBindVertexArray(vao); glBindBuffer(GL_ARRAY_BUFFER, vbo); glUseProgram(program); glDrawArrays(GL_TRIANGLES, 0, 3); glfwSwapBuffers(window); glfwPollEvents(); glCheck(); lastTime = time; time = glfwGetTime(); } } private static void dispose(){ glDeleteVertexArrays(vao); glDeleteBuffers(vbo); glDeleteShader(vShader); glDeleteShader(fShader); glDeleteProgram(program); glfwDestroyWindow(window); } private static void print(String message) { System.out.println(message); } private static void err(String message) { System.err.println(message); } private static int glCheckCounter = 0; private static void glCheck() { int val = glGetError(); if (val==0) print("GL Error Check "+glCheckCounter+" no error."); else err("GL Error Check "+glCheckCounter+" returned error "+val); glCheckCounter++; } private static int vao, vbo, vShader, fShader, program; private static final float[] vertices = { -0.6f, -0.4f, 0f, 1f, 0f, 0f, 0.6f, -0.4f, 0f, 0f, 1f, 0f, 0f, 0.6f, 0f, 0f, 0f, 1f }; private static final CharSequence vertexSource = "#version 150 core\n" + "\n" + "in vec3 position;\n" + "in vec3 color;\n" + "\n" + "out vec3 vertexColor;\n" + "\n" + "uniform mat4 model;\n" + "uniform mat4 view;\n" + "uniform mat4 projection;\n" + "\n" + "void main() {\n" + " vertexColor = color;\n" + " mat4 mvp = projection * view * model;\n" + " gl_Position = mvp * vec4(position, 1.0);\n" + "}"; private static final CharSequence fragmentSource = "#version 150 core\n" + "\n" + "in vec3 vertexColor;\n" + "\n" + "out vec4 fragColor;\n" + "\n" + "void main() {\n" + " fragColor = vec4(vertexColor, 1.0);\n" + "}"; }
程序运行输出
3.3.1 build 7 GL Error Check 0 no error. GL Error Check 1 no error. GL Error Check 2 no error. GL Error Check 3 no error. GL Error Check 4 no error. GL Error Check 5 no error. GL Error Check 6 no error. GL Error Check 7 no error.
问题原因与解决方法
问题出在未设置OpenGL视口。
OpenGL默认视口尺寸为(0, 0, 1, 1),仅占窗口的1x1像素,导致渲染的三角形无法在窗口中显示。需要在初始化OpenGL上下文后,添加视口设置代码,将视口尺寸与窗口帧缓冲尺寸匹配。
修改步骤:
在init()函数中,GL.createCapabilities();之后,添加以下代码:
// 获取窗口帧缓冲尺寸 IntBuffer width = memAllocInt(1); IntBuffer height = memAllocInt(1); glfwGetFramebufferSize(window, width, height); // 设置视口 glViewport(0, 0, width.get(), height.get()); memFree(width); memFree(height);
另外,建议添加清屏颜色设置,让三角形与背景更易区分,可在视口设置后添加:
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
修改后重新运行程序,即可看到彩色三角形正常渲染。
内容的提问来源于stack exchange,提问作者part1kl
相关产品推荐
相关产品推荐

