LWJGL3和OpenGL是否需要着色器进行渲染?

时间:2020-03-25 19:40:26

标签: opengl shader lwjgl

我的代码不起作用。我认为有一种方法可以在不使用着色器的情况下在屏幕上呈现某些内容,但是又如何呢?我听到了一些有关现代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();
    }
}

1 个答案:

答案 0 :(得分:3)

在绘制时,没有启用顶点属性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 这些例子)。

我听说了一些有关现代OpenGL渲染的信息,以及OpenGL如何需要着色器进行渲染。

是的。请注意,着色器是在2004年随2.0版引入OpenGL的,因此,在GPU开发方面,这是 modern 术语的精妙之处。您确实应该考虑切换到3.2 核心配置文件上下文,在该上下文中,将删除90年代遗留下来的所有旧版已弃用的东西。