提问人:part1kl 提问时间:3/19/2023 最后编辑:Rabbid76part1kl 更新时间:3/19/2023 访问量:72
OpenGL Triange 演示显示空白窗口
OpenGL Triange demo shows blank window
问:
我通过三角形演示开始学习 LWJGL3 和 OpenGL 3.2+。该程序似乎运行良好,我没有收到任何 OpenGL 错误,但三角形没有显示在屏幕上。
我在这里查看了一些类似的问题,其中许多问题的确定问题是缺少 VAO 或三角形坐标或着色器错误,但我已经在我的代码中检查了这些问题。创建 VAO,分配绑定和顶点属性。三角形坐标实际上应该构成一个三角形,我的着色器说它们已经正确编译和链接。我对我在这里错过的东西感到茫然。
这是我的代码。所有内容都在这个文件中(三角形顶点数据、OpenGL 对象 ID 和底部的着色器源代码),除了 LWJGL 本身和我用于矩阵的 com.hackoeur.jglm 库:
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.
只要程序运行,“GL Error Check # no error.” 就会一直运行,我已经在 8 个循环中切断了它。它从未出现过 OpenGL 错误。
答:
new Mat4()
不构造单位矩阵。可以使用单个参数 1.0f 构造单位矩阵:
Mat4 model = new Mat4();
Mat4 model = new Mat4(1.0f);
Mat4 view = new Mat4();
Mat4 view = new Mat4(1.0f);
评论
问题似乎出在 Mat4 对象创建缓冲区的方式上。这是我的IDE为com.hackoeur.jglm.Mat4.getBuffer()反编译的源代码:
public FloatBuffer getBuffer() {
FloatBuffer buffer = this.allocateFloatBuffer();
int startPos = buffer.position();
buffer.put(this.m00).put(this.m01).put(this.m02).put(this.m03);
buffer.put(this.m10).put(this.m11).put(this.m12).put(this.m13);
buffer.put(this.m20).put(this.m21).put(this.m22).put(this.m23);
buffer.put(this.m30).put(this.m31).put(this.m32).put(this.m33);
buffer.position(startPos);
return buffer;
}
我不是 100% 确定它的问题是什么,或者我是否只是用错了,但是当我回到我最初由 SilverTiger 遵循的教程的源代码并在那里使用 Matrix4f 对象时,三角形出现了。silvertiger.tutorial.lwjgl.math.Matrix4f.toBuffer() 的源代码:
public void toBuffer(FloatBuffer buffer) {
buffer.put(m00).put(m10).put(m20).put(m30);
buffer.put(m01).put(m11).put(m21).put(m31);
buffer.put(m02).put(m12).put(m22).put(m32);
buffer.put(m03).put(m13).put(m23).put(m33);
buffer.flip();
}
评论
new Mat4()