Нужны ли шейдерам для рендеринга LWJGL3 и OpenGL? - PullRequest
1 голос
/ 25 марта 2020

Мой код не работает. Я думаю, что есть способ сделать что-то на экране без шейдеров, но как? Я слышал кое-что о современном рендеринге 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 Ответ

3 голосов
/ 25 марта 2020

Вы не включили массив для атрибута вершины 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 изменяется (который в этих примерах никогда никогда не меняется).

Я что-то слышал о современном рендеринге OpenGL и о том, как OpenGL нужны шейдеры для рендеринга.

Да. Обратите внимание, что шейдеры были введены в OpenGL с версией 2.0 в 2004 году, так что это вполне уместно для термина modern , когда речь идет о разработке графических процессоров. Вы действительно должны подумать о переходе к контексту основного профиля 3.2 , где удаляются все устаревшие устаревшие вещи из 90-х.

...