java - 为什么我在 OpenGL (3) 中的三角形不使用 lwjgl 渲染?

标签 java c++ opengl glsl lwjgl

所以我最近开始学习 lwjgl,并很快意识到我需要改进 OpenGL 才能继续。我按照教程 here并尝试使用 java 和 lwjgl 实现相同的代码(教程中的代码使用 C++)。我成功地使用 lwjgl api 从教程中复制了 OpenGL 调用,但是当我启动我的程序时,我只看到黑屏,没有其他任何东西 =(没有三角形,什么都没有。控制台以太没有错误。

我的 Window.java 类,我在其中执行 OpenGL 渲染(别管 Spring 注释,我只是使用 IoC 容器来管理对象,方法 run( ) 在 Spring 上下文创建后调用):

import com.gitlab.cvazer.dnd.map.desktop.ashlesy.Orchestrator;
import com.gitlab.cvazer.dnd.map.desktop.render.Camera;
import com.gitlab.cvazer.dnd.map.desktop.util.Shaders;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.lwjgl.Version;
import org.lwjgl.glfw.GLFWErrorCallback;
import org.lwjgl.opengl.GL;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Objects;

import static org.lwjgl.glfw.Callbacks.glfwFreeCallbacks;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL30.*;
import static org.lwjgl.system.MemoryUtil.NULL;

@Slf4j
@Component
public class Window {
    private @Autowired Shaders shaders;
    private @Getter long window;

    //START HERE!
    public void run() {
        new Thread(() -> {
            log.info("Hello LWJGL " + Version.getVersion() + "!");
            init();
            try {
                loop();
            } catch (IOException e) {
                e.printStackTrace();
            }
            glfwFreeCallbacks(window);
            glfwDestroyWindow(window);
            glfwTerminate();
            Objects.requireNonNull(glfwSetErrorCallback(null)).free();
        }).start();
    }

    private void init() {
        GLFWErrorCallback.createPrint(System.err).set();
        if ( !glfwInit() ) throw new IllegalStateException("Unable to initialize GLFW");
        glfwDefaultWindowHints();
        glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
        glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
        glfwWindowHint(GLFW_SAMPLES, 8);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
        glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
        window = glfwCreateWindow(800, 600, "Hello World!", NULL, NULL);
        if ( window == NULL ) throw new RuntimeException("Failed to create the GLFW window");
        callbacks();
        glfwMakeContextCurrent(window);
        glfwSwapInterval(1);
        glfwShowWindow(window);
    }

    private void loop() throws IOException {
        GL.createCapabilities();

        int vertexArray = glGenVertexArrays();
        glBindVertexArray(vertexArray);

        int vertexBuffer = glGenBuffers();
        glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);

        float[] data = {-1.0f, -1.0f, 0.0f,
                1.0f, -1.0f, 0.0f,
                0.0f,  1.0f, 0.0f};

        glBufferData(GL_ARRAY_BUFFER, data, GL_STATIC_DRAW);

        int program = shaders.loadShaders("vertex.glsl", "fragment.glsl");

        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

        long lastTime = System.currentTimeMillis();
        while ( !glfwWindowShouldClose(window) ) {
            long delta = System.currentTimeMillis() - lastTime;
            lastTime = System.currentTimeMillis();

            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
            glUseProgram(program);

            glEnableVertexAttribArray(0);
            glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
            glVertexAttribPointer(0,3,GL_FLOAT, false, 0, vertexBuffer);
            glDrawArrays(GL_TRIANGLES, 0, 3);
            glDisableVertexAttribArray(0);

            glfwSwapBuffers(window); // swap the color buffers
            glfwPollEvents();
        }
    }
}

Shaders.java类:

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

import static org.lwjgl.opengl.GL30.*;

@Slf4j
@Service
public class Shaders {
    public int loadShaders(String vertexFilePath, String fragmentFilePath) throws IOException {
        int vertexShader = glCreateShader(GL_VERTEX_SHADER);
        int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);

        String vertexCode = Files.lines(Paths.get(vertexFilePath))
                .collect(Collectors.joining("\n"));

        String fragmentCode = Files.lines(Paths.get(fragmentFilePath))
                .collect(Collectors.joining("\n"));

        compileShader(vertexShader, vertexCode);
        compileShader(fragmentShader, fragmentCode);

        int program = glCreateProgram();
        glAttachShader(program, vertexShader);
        glAttachShader(program, fragmentShader);
        glLinkProgram(program);

        glDetachShader(program, vertexShader);
        glDetachShader(program, fragmentShader);

        glDeleteShader(vertexShader);
        glDeleteShader(fragmentShader);

        return program;
    }

    private void compileShader(int shader, String code){
        glShaderSource(shader, code);
        glCompileShader(shader);
        String slog = glGetShaderInfoLog(shader);
        if (slog.contentEquals("")) return;
        log.info(slog);
    }
}

vertex.glsl 文件:

#version 330 core
layout(location = 0) in vec3 vertexPosition_modelspace;
void main(){
  gl_Position.xyz = vertexPosition_modelspace;
  gl_Position.w = 1.0;
}

fragment.glsl 文件:

#version 330 core
out vec3 color;
void main(){
  color = vec3(1,0,0);
}

我遵循了本教程的第 1 部分(编码 OpenGL 调用)和第 2 部分(编码 GLSL 着色器,加载它们),但是添加着色器并没有解决我的问题

我不认为进一步谷歌搜索可以给我答案,因为几乎所有关于 lwjgl 主题的在线教程都使用 OpenGL 1 进行渲染。

我怎样才能让它工作?

最佳答案

问题是线路

glVertexAttribPointer(0,3,GL_FLOAT, false, 0, vertexBuffer);

如果绑定(bind)了命名缓冲区对象,则 glVertexAttribPointer 的最后一个参数被视为缓冲区对象数据存储中的字节偏移量。

当您使用 glVertexAttribPointer 时,您不必通过参数指定顶点缓冲区。该函数将顶点属性与当前绑定(bind)到目标 GL_ARRAY_BUFFER 的缓冲区对象相关联。

它必须是:

glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);

另见 Java Code Examples for org.lwjgl.opengl.GL20.glVertexAttribPointer()

关于java - 为什么我在 OpenGL (3) 中的三角形不使用 lwjgl 渲染?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58889068/

相关文章:

java - 运行时动态绑定(bind)和类继承的区别

opengl - 3D投影映射

opengl - 如何避免彩色条纹

opengl - 现代 GLSL 中的每像素光照?

java - 当值在范围内时返回键

Java - 复制构造函数 - java.lang.NullPointerException

java - 如何在 Hibernate Envers 中查询客户 RevisionEntity?

python - C++ 和 Python 实现之间的不同伪随机数

C++键盘输入到2个数组

c++ - 读取结构时 VS2015 C++ 调试器出现奇怪的结果