LWJGL3 和 OpenGL 是否需要着色器来渲染?
Does LWJGL3 and OpenGL need a shader to render?
我的代码不起作用。我认为有一种方法可以在没有着色器的情况下在屏幕上渲染某些东西,但是怎么做呢?我听说过有关现代 OpenGL 渲染的一些信息,以及 OpenGL 如何需要着色器来渲染。帮帮我。
这是我的代码:
import static org.lwjgl.glfw.GLFW.glfwDestroyWindow;
import static org.lwjgl.glfw.GLFW.glfwTerminate;
import java.nio.FloatBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWVidMode;
import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GL30;
import org.lwjgl.system.MemoryUtil;
public class Main {
public static long window;
public static boolean running = true;
public static void createWindow() {
GLFW.glfwInit();
GLFW.glfwDefaultWindowHints();
GLFW.glfwWindowHint(GLFW.GLFW_VISIBLE, GL30.GL_FALSE);
GLFW.glfwWindowHint(GLFW.GLFW_VISIBLE, GL30.GL_TRUE);
window = GLFW.glfwCreateWindow(600, 600, "RenderQuad", 0, 0);
GLFW.glfwMakeContextCurrent(window);
GLFWVidMode vidmode = GLFW.glfwGetVideoMode(GLFW.glfwGetPrimaryMonitor());
GLFW.glfwSetWindowPos(window, (vidmode.width() - 600) / 2, (vidmode.height() - 600) / 2);
GLFW.glfwShowWindow(window);
GL.createCapabilities();
GL30.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
}
public static int vaoID;
public static int vboID;
public static void render() {
float[] vertices = {
-0.5f, 0.5f, 0f,
-0.5f, -0.5f, 0f,
0.5f, -0.5f, 0f,
0.5f, -0.5f, 0f,
0.5f, 0.5f, 0f,
-0.5f, 0.5f, 0f
};
vaoID = GL30.glGenVertexArrays();
GL30.glBindVertexArray(vaoID);
FloatBuffer buffer = MemoryUtil.memAllocFloat(vertices.length);
buffer.put(vertices);
buffer.flip();
vboID = GL30.glGenBuffers();
GL30.glBindBuffer(GL30.GL_ARRAY_BUFFER, vboID);
GL30.glBufferData(GL30.GL_ARRAY_BUFFER, buffer, GL30.GL_STATIC_DRAW);
MemoryUtil.memFree(buffer);
GL30.glVertexAttribPointer(0, 3, GL30.GL_FLOAT, false, 0, 0);
GL30.glBindBuffer(GL30.GL_ARRAY_BUFFER, 0);
GL30.glBindVertexArray(0);
}
public static void loopCycle() {
GL30.glClear(GL30.GL_COLOR_BUFFER_BIT);
GL30.glEnableVertexAttribArray(0);
GL30.glBindVertexArray(vaoID);
GL30.glDrawArrays(GL30.GL_TRIANGLES, 0, 6);
GL30.glDisableVertexAttribArray(0);
GL30.glBindVertexArray(0);
}
public static void clean() {
GL30.glDisableVertexAttribArray(0);
GL30.glBindBuffer(GL30.GL_ARRAY_BUFFER, 0);
GL30.glBindVertexArray(0);
GL30.glDeleteBuffers(vboID);
GL30.glDeleteVertexArrays(vaoID);
glfwDestroyWindow(window);
glfwTerminate();
}
public static void loop() {
GLFW.glfwSwapBuffers(window);
GLFW.glfwPollEvents();
//GL30.glClear(GL30.GL_COLOR_BUFFER_BIT | GL30.GL_DEPTH_BUFFER_BIT);
}
public static void main(String[] args) {
createWindow();
render();
while(running) {
if(GLFW.glfwWindowShouldClose(window)) {running = false; break;}
loopCycle();
loop();
}
clean();
}
}
您在绘制时没有启用顶点属性 0 的数组。每个顶点属性的数组启用状态是VAO的一部分,当你调用glEnableVertexAttribArray
时它会影响当前绑定的VAO .
我不知道这是从哪里来的,但是很多人(似乎还有教程)使用这样的方案:
Setup() {
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// ... [set up some VBOs and maybe EBO]
glVertexAttribPointer(...);
glBindVertexArray(vao);
}
Draw()
{
glBindVertexArray(vao);
glEnableVertexAttribArray(...);
glDraw...(...);
glDisableVertexAttribArray(...);
glBindVertexArray(0);
}
现在这个方案原则上是可行的,你只是在 VAO 0 仍然绑定时错误地启用了数组,然后切换到 vao
根本没有启用数组.
但是这个方案是完全低效的,VAO 确实存储了这个信息是有原因的:这样你就不必在每次要使用它时都重新指定它。因此,glEnableVertexAttribArray()
属于 Setup
函数,只有当特定 VAO 的实际顶点属性集发生变化时才应再次调用(即 never 在那些例子中)。
I heard something about modern OpenGL rendering and how OpenGL needs shaders to render.
是的。请注意,着色器是在 2004 年的 2.0 版中引入 OpenGL 的,因此当涉及到 GPU 开发时,这与术语 modern 相当相近。您真的应该考虑切换到 3.2 核心配置文件 上下文,其中删除了 90 年代遗留下来的所有遗留弃用内容。
我的代码不起作用。我认为有一种方法可以在没有着色器的情况下在屏幕上渲染某些东西,但是怎么做呢?我听说过有关现代 OpenGL 渲染的一些信息,以及 OpenGL 如何需要着色器来渲染。帮帮我。
这是我的代码:
import static org.lwjgl.glfw.GLFW.glfwDestroyWindow;
import static org.lwjgl.glfw.GLFW.glfwTerminate;
import java.nio.FloatBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWVidMode;
import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GL30;
import org.lwjgl.system.MemoryUtil;
public class Main {
public static long window;
public static boolean running = true;
public static void createWindow() {
GLFW.glfwInit();
GLFW.glfwDefaultWindowHints();
GLFW.glfwWindowHint(GLFW.GLFW_VISIBLE, GL30.GL_FALSE);
GLFW.glfwWindowHint(GLFW.GLFW_VISIBLE, GL30.GL_TRUE);
window = GLFW.glfwCreateWindow(600, 600, "RenderQuad", 0, 0);
GLFW.glfwMakeContextCurrent(window);
GLFWVidMode vidmode = GLFW.glfwGetVideoMode(GLFW.glfwGetPrimaryMonitor());
GLFW.glfwSetWindowPos(window, (vidmode.width() - 600) / 2, (vidmode.height() - 600) / 2);
GLFW.glfwShowWindow(window);
GL.createCapabilities();
GL30.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
}
public static int vaoID;
public static int vboID;
public static void render() {
float[] vertices = {
-0.5f, 0.5f, 0f,
-0.5f, -0.5f, 0f,
0.5f, -0.5f, 0f,
0.5f, -0.5f, 0f,
0.5f, 0.5f, 0f,
-0.5f, 0.5f, 0f
};
vaoID = GL30.glGenVertexArrays();
GL30.glBindVertexArray(vaoID);
FloatBuffer buffer = MemoryUtil.memAllocFloat(vertices.length);
buffer.put(vertices);
buffer.flip();
vboID = GL30.glGenBuffers();
GL30.glBindBuffer(GL30.GL_ARRAY_BUFFER, vboID);
GL30.glBufferData(GL30.GL_ARRAY_BUFFER, buffer, GL30.GL_STATIC_DRAW);
MemoryUtil.memFree(buffer);
GL30.glVertexAttribPointer(0, 3, GL30.GL_FLOAT, false, 0, 0);
GL30.glBindBuffer(GL30.GL_ARRAY_BUFFER, 0);
GL30.glBindVertexArray(0);
}
public static void loopCycle() {
GL30.glClear(GL30.GL_COLOR_BUFFER_BIT);
GL30.glEnableVertexAttribArray(0);
GL30.glBindVertexArray(vaoID);
GL30.glDrawArrays(GL30.GL_TRIANGLES, 0, 6);
GL30.glDisableVertexAttribArray(0);
GL30.glBindVertexArray(0);
}
public static void clean() {
GL30.glDisableVertexAttribArray(0);
GL30.glBindBuffer(GL30.GL_ARRAY_BUFFER, 0);
GL30.glBindVertexArray(0);
GL30.glDeleteBuffers(vboID);
GL30.glDeleteVertexArrays(vaoID);
glfwDestroyWindow(window);
glfwTerminate();
}
public static void loop() {
GLFW.glfwSwapBuffers(window);
GLFW.glfwPollEvents();
//GL30.glClear(GL30.GL_COLOR_BUFFER_BIT | GL30.GL_DEPTH_BUFFER_BIT);
}
public static void main(String[] args) {
createWindow();
render();
while(running) {
if(GLFW.glfwWindowShouldClose(window)) {running = false; break;}
loopCycle();
loop();
}
clean();
}
}
您在绘制时没有启用顶点属性 0 的数组。每个顶点属性的数组启用状态是VAO的一部分,当你调用glEnableVertexAttribArray
时它会影响当前绑定的VAO .
我不知道这是从哪里来的,但是很多人(似乎还有教程)使用这样的方案:
Setup() {
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// ... [set up some VBOs and maybe EBO]
glVertexAttribPointer(...);
glBindVertexArray(vao);
}
Draw()
{
glBindVertexArray(vao);
glEnableVertexAttribArray(...);
glDraw...(...);
glDisableVertexAttribArray(...);
glBindVertexArray(0);
}
现在这个方案原则上是可行的,你只是在 VAO 0 仍然绑定时错误地启用了数组,然后切换到 vao
根本没有启用数组.
但是这个方案是完全低效的,VAO 确实存储了这个信息是有原因的:这样你就不必在每次要使用它时都重新指定它。因此,glEnableVertexAttribArray()
属于 Setup
函数,只有当特定 VAO 的实际顶点属性集发生变化时才应再次调用(即 never 在那些例子中)。
I heard something about modern OpenGL rendering and how OpenGL needs shaders to render.
是的。请注意,着色器是在 2004 年的 2.0 版中引入 OpenGL 的,因此当涉及到 GPU 开发时,这与术语 modern 相当相近。您真的应该考虑切换到 3.2 核心配置文件 上下文,其中删除了 90 年代遗留下来的所有遗留弃用内容。