我正在使用 LWJGL 3,我的三角形不渲染。这是我的代码:
package com.xicreations.infinimob;
import org.lwjgl.glfw.GLFWVidMode;
import org.lwjgl.opengl.GL;
import org.lwjgl.system.MemoryStack;
import java.nio.IntBuffer;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL15.*;
import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.opengl.GL30.*;
import static org.lwjgl.system.MemoryStack.stackPush;
import static org.lwjgl.system.MemoryUtil.NULL;
public class Infinimob
{
private final int WIDTH = 800, HEIGHT = 800;
private final String TITLE = "Infinimob 0.0.1a";
private static String vs = "#version 330 core\n" +
"layout (location = 0) in vec3 aPos;\n" +
"void main()\n" +
"{\n" +
" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n" +
"}\0";
private static String fs = "#version 330 core\n" +
"out vec4 fragColor;\n" +
"void main()\n" +
"{\n" +
" fragColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);\n" +
"}\0";
private long window;
private int vao, vbo;
private int vertexCount = 3;
private void init()
{
if (!glfwInit())
{
throw new IllegalStateException("Unable to initialize GLFW");
}
glfwDefaultWindowHints();
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
window = glfwCreateWindow(WIDTH, HEIGHT, TITLE, NULL, NULL);
if (window == NULL)
{
throw new RuntimeException("Failed to create the GLFW window");
}
try (MemoryStack stack = stackPush())
{
IntBuffer pWidth = stack.mallocInt(1);
IntBuffer pHeight = stack.mallocInt(1);
glfwGetWindowSize(window, pWidth, pHeight);
GLFWVidMode vidMode = glfwGetVideoMode(glfwGetPrimaryMonitor());
glfwSetWindowPos(
window,
(vidMode.width() - pWidth.get(0)) / 2,
(vidMode.height() - pHeight.get(0)) / 2
);
}
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
glfwShowWindow(window);
}
private int loadShader(String shaderSource, int shaderType)
{
int shader = glCreateShader(shaderType);
glShaderSource(shader, shaderSource);
glCompileShader(shader);
if (glGetShaderi(shader, GL_COMPILE_STATUS) == GL_FALSE) {
throw new RuntimeException("Failed to compile shader: " + glGetShaderInfoLog(shader));
}
return shader;
}
private void initShaders()
{
int vertexShader = loadShader(vs, GL_VERTEX_SHADER);
int fragmentShader = loadShader(fs, GL_FRAGMENT_SHADER);
int shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, fragmentShader);
glAttachShader(shaderProgram, vertexShader);
glLinkProgram(shaderProgram);
if (glGetProgrami(shaderProgram, GL_LINK_STATUS) == GL_FALSE) {
throw new RuntimeException("Failed to link shader program: " + glGetProgramInfoLog(shaderProgram));
}
glUseProgram(shaderProgram);
}
private void loop()
{
GL.createCapabilities();
initShaders();
float[] vertices =
{
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};
vao = glGenVertexArrays();
vbo = glGenBuffers();
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 3 * Float.BYTES, 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glViewport(0, 0, WIDTH, HEIGHT);
while (!glfwWindowShouldClose(window))
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(0);
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, vertexCount);
glBindVertexArray(0);
glfwSwapBuffers(window);
glfwPollEvents();
}
}
private void cleanup()
{
glDeleteBuffers(vbo);
glDeleteVertexArrays(vao);
glfwTerminate();
}
public static void main(String[] args)
{
Infinimob app = new Infinimob();
app.init();
app.loop();
app.cleanup();
}
}
我认为它应该有效,但事实并非如此。
更多信息:
我正在使用 OpenGL 3.3,更奇怪的是,如果我使顶点着色器和片段着色器完全相同,并删除对链接错误的检查,则三角形渲染为白色。如果没有效果,我可能会重写整个代码。
在此代码中-
while (!glfwWindowShouldClose(window))
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(0);
glBindVertexArray(vao);
您不应该将“0”传递给 glUseProgram。它将取消绑定您在 initShaders 函数中创建并绑定的着色器程序。您应该传递 glCreateProgram 返回的着色器程序的句柄/id。
但是,在 initShaders 函数中,您没有将句柄/id 值存储在类的成员变量中。所以你能做的就是简单地删除“glUseProgram(0);”行,因为程序已经绑定并且应该可以工作,即使我还没有测试代码。
更理想的解决方案是将“int ShaderProgram”声明为成员变量而不是 local-
private void initShaders()
{
int vertexShader = loadShader(vs, GL_VERTEX_SHADER);
int fragmentShader = loadShader(fs, GL_FRAGMENT_SHADER);
shaderProgram = glCreateProgram();
...
然后在绘制三角形之前将其传递给 glUseProgram -
while (!glfwWindowShouldClose(window))
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(shaderProgram);
glBindVertexArray(vao);