当前位置: 首页 > 知识库问答 >
问题:

我在使用OpenGL和glfw(LWJGL)将模型渲染到窗口时遇到问题

申屠宗清
2023-03-14

我正在努力熟悉Java的LWJGL库,我一直在线学习一些教程,我似乎无法渲染模型。

我使用的是OpenGL 2.1(这似乎非常过时,但我不知道如何更新它,我知道它与你的硬件捆绑在一起,如果有人对我的规格感兴趣,我使用的是MacBook Pro 2017型号)

如果有人能看看我的代码,告诉我哪里做错了,我会非常感激!(现在呈现的只是一个红色窗口)

从我研究过的来源来看,这段代码应该会产生一个由两个三角形组成的正方形,使用顶点和片段着色器以渐变方式着色,但没有渲染任何内容。

public class Main {

private long window;
    private int width = 1280, height = 720;

    public void run() {
    System.out.println("LWJGL " + Version.getVersion() + "!");

    init();
    loop();

    glfwFreeCallbacks(window);
    glfwDestroyWindow(window);

    glfwTerminate();
    glfwSetErrorCallback(null).free();
    }

    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); 

    window = glfwCreateWindow(width, height, "TESTING", NULL, NULL);
    if (window == NULL) throw new RuntimeException("Failed to create the GLFW window");

    glfwSetKeyCallback(window, (window, key, scancode, action, mods) -> {
        if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE) glfwSetWindowShouldClose(window, true); /
    });

    try (MemoryStack stack = stackPush()) {
        IntBuffer pWidth = stack.mallocInt(1); // int*
        IntBuffer pHeight = stack.mallocInt(1); // int*

        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 void loop() {
    GL.createCapabilities();

      GL11.glClearColor(1.0f, 0.0f, 0.0f, 0.0f);

    Renderer renderer = new Renderer();
    Loader loader = new Loader();
        StaticShader shader = new StaticShader();


    float[] vertices = {
            -0.5f, 0.5f, 0f,
            -0.5f, -0.5f, 0f,
            0.5f, -0.5f, 0f,
            0.5f, 0.5f, 0f,
          };

    int[] indicies = {
        0,1,3,
        3,1,2
    };

    RawModel model = loader.loadToVAO(vertices, indicies);

    while (!glfwWindowShouldClose(window)) {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glfwSwapBuffers(window);

        renderer.prepare();
        shader.start();
        renderer.render(model);
        shader.stop();

        glfwPollEvents();
    }
     loader.cleanUp();
     shader.cleanUp();
    }

    public static void main(String[] args) {
    new Main().run();
    }

}

public class RawModel {

    private int vaoID;
    private int vertexCount;

    public RawModel(int vaoID, int vertexCount) {
    this.vaoID = vaoID;
    this.vertexCount = vertexCount;
    }

    public int getVaoID() {
    return vaoID;
    }

    public int getVertexCount() {
    return vertexCount;
    }

}

public class Renderer {

    public void prepare() {
        GL11.glClearColor(1, 0, 0, 1);
        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
    }

    public void render(RawModel model){
            GL30.glBindVertexArray(model.getVaoID());
            GL20.glEnableVertexAttribArray(0);
            //System.out.println(model.getVertexCount());
            GL11.glDrawElements(GL11.GL_TRIANGLES, model.getVertexCount(), GL11.GL_UNSIGNED_INT, 0);
            GL20.glDisableVertexAttribArray(0);
            GL30.glBindVertexArray(0);
        }
}

public class Loader {

    private List<Integer> vaos = new ArrayList<Integer>();
    private List<Integer> vbos = new ArrayList<Integer>();

    public RawModel loadToVAO(float[] positions,int[] indicies) {
        int vaoID = createVAO();
        bindIndecesBuffer(indicies); 
        storeDataInAttributeList(0, positions);
        unbindVAO();
        return new RawModel(vaoID, indicies.length);
    }

    private void bindIndecesBuffer(int[] indices) {
        int vboID = GL15.glGenBuffers();
        vbos.add(vboID);
        GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboID);
        IntBuffer buffer = storeDatainIntBuffer(indices);
        GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
    }

    private IntBuffer storeDatainIntBuffer(int[] data) {
        IntBuffer buffer = BufferUtils.createIntBuffer(data.length);
        buffer.put(data);
        buffer.flip();
        return buffer;
    }

    public void cleanUp() {
        for (int vao : vaos) {
            GL30.glDeleteVertexArrays(vao);
        }
        for (int vbo : vbos) {
            GL15.glDeleteBuffers(vbo);
        }
    }


    private int createVAO() {
        int vaoID = GL30.glGenVertexArrays();
        vaos.add(vaoID);
        GL30.glBindVertexArray(vaoID);
        return vaoID;
    }


    private void storeDataInAttributeList(int attributeNumber, float[] data) {
        int vboID = GL15.glGenBuffers();
        vbos.add(vboID);
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboID);
        FloatBuffer buffer = storeDataInFloatBuffer(data);
        GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
        GL20.glVertexAttribPointer(attributeNumber, 3, GL11.GL_FLOAT, false, 0, 0);
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
    }

    private void unbindVAO() {
        GL30.glBindVertexArray(0);
    }

    private FloatBuffer storeDataInFloatBuffer(float[] data) {
        FloatBuffer buffer = BufferUtils.createFloatBuffer(data.length);
        buffer.put(data);
        buffer.flip();
        return buffer;
    }

}

public abstract class ShaderProgram {

    private int programID;
    private int vertexShaderID;
    private int fragmentShaderID;

    public ShaderProgram(String vertexFile,String fragmentFile){
        vertexShaderID = loadShader(vertexFile,GL20.GL_VERTEX_SHADER);
        fragmentShaderID = loadShader(fragmentFile,GL20.GL_FRAGMENT_SHADER);
        programID = GL20.glCreateProgram();
        GL20.glAttachShader(programID, vertexShaderID);
        GL20.glAttachShader(programID, fragmentShaderID);
        bindAttributes();
        GL20.glLinkProgram(programID);
        GL20.glValidateProgram(programID);
    }

    public void start(){
        GL20.glUseProgram(programID);
    }

    public void stop(){
        GL20.glUseProgram(0);
    }

    public void cleanUp(){
        stop();
        GL20.glDetachShader(programID, vertexShaderID);
        GL20.glDetachShader(programID, fragmentShaderID);
        GL20.glDeleteShader(vertexShaderID);
        GL20.glDeleteShader(fragmentShaderID);
        GL20.glDeleteProgram(programID);
    }

    protected abstract void bindAttributes();

    protected void bindAttribute(int attribute, String variableName){
        GL20.glBindAttribLocation(programID, attribute, variableName);
    }

    private static int loadShader(String file, int type){
        StringBuilder shaderSource = new StringBuilder();
        try{
            BufferedReader reader = new BufferedReader(new FileReader(file));
            String line;
            while((line = reader.readLine())!=null){
                shaderSource.append(line).append("//\n");
            }
            reader.close();
        }catch(IOException e){
            e.printStackTrace();
            System.exit(-1);
        }
        int shaderID = GL20.glCreateShader(type);
        GL20.glShaderSource(shaderID, shaderSource);
        GL20.glCompileShader(shaderID);
        if(GL20.glGetShaderi(shaderID, GL20.GL_COMPILE_STATUS )== GL11.GL_FALSE){
            System.out.println(GL20.glGetShaderInfoLog(shaderID, 500));
            System.err.println("Could not compile shader!");
            System.exit(-1);
        }
        return shaderID;
    }

}

public class StaticShader extends ShaderProgram {

    private static final String VERTEX_FILE = "src/shaderEngine/vertexShader.txt";
    private static final String FRAGMENT_FILE = "src/shaderEngine/fragmentShader.txt";

    public StaticShader() {
        super(VERTEX_FILE, FRAGMENT_FILE);
    }

    @Override
    protected void bindAttributes() {
        super.bindAttribute(0, "position");
    }

}

//VERTEX SHADER

#version 120

attribute vec3 position;

varying vec3 colour;

void main(void){

    gl_Position = vec4(position,1.0);
    colour = vec3(position.x+0.5,0.0,position.y+0.5);
}

//FRAGMENT SHADER

#version 120

varying vec3 colour;

void main(void){

    gl_FragColor = vec4(colour,1.0);

}

共有1个答案

国兴贤
2023-03-14

代码使用顶点阵列对象(VAO)进行渲染。正如lwjgl的<code>GL30</code>语法已经表明的,这是OpenGL 3.0的一个特性。仅当您的实现碰巧实现了GL_ARB_vertex_array_objectOpenGL扩展时,才可以在GL 2.1上下文中运行此代码。

我使用的是OpenGL 2.1(这似乎非常过时,但我不知道如何更新它,我知道它与你的硬件捆绑在一起,如果有人对我的规格感兴趣,我使用的是MacBook Pro 2017型号)

您仅限于OpenGL 2.1,因为您使用的是遗留的GL上下文。如果您想要在OSX上使用有点现代的OpenGL,您必须在上下文创建时请求GL 3.2核心配置文件上下文。另请注意,Apple将支持的最新GL版本是GL 4.1,Apple实际上宣布OpenGL已弃用,并且可能会将其从未来版本的OSX中完全删除。

 类似资料:
  • 我有一个常规的Win32窗口,我想使用OpenGL渲染该窗口的一部分,我发现了这个问题: 在常规窗口中使用打开GL (Win32) 但我真的不知道他们是如何在一个窗口内创建一个面板,并获得了它的DC。。 基本上,我想要一个使用win32绘制按钮、列表等的窗口,并在同一窗口的某个指定部分渲染opengl内容。 我试着使用glScissor和清除缓冲区,但这只是用黑色填充整个屏幕,而我指定的部分是透明

  • 我正在尝试使用GLFW创建一个窗口。窗口已创建,但经过几次尝试,创建窗口需要很长时间。 https://drive.google.com/file/d/1zq4IEjcSIJxy5wnXWLrGe46ptHMbKM5R/view?usp=sharing 我找不到任何解决办法,也不知道这是由什么引起的。 这是我正在使用的代码: 程序输出为 所以看起来初始化glfw需要很长时间,但我不知道如何修复它。

  • 下面的LWJGL代码将在屏幕中心呈现一个蓝色正方形。相反,我得到了一个空白的白色屏幕。就像渲染根本不工作,或者我在屏幕外渲染。 我是OpenGL和LWJGL的新手,所以我力不从心。我浏览了所有内容,但似乎找不到任何可能与代码有关的问题。 OpenGLTest.scala VertexArray.scala

  • 我试图使用opengl在lwjgl显示器上显示自定义字体的文本。目前,我正在使用自定义位图字体类从png文件加载字体,并以与tileset相同的方式显示它们。它工作正常,但当我将文本绘制到屏幕上时,字符之间的间距完全不同,因为字母M比字母i宽得多,并且所有字符的宽度都不同。有没有办法检测每个字符的宽度?或者是否有任何特定于lwjgl字体的库?有一种方法可以使用slick2d来实现,但加载整个库只是

  • 我写了一个< code>OpenGL代码用于在屏幕上渲染图像。我使用< code>GLUT来创建一个窗口和回调,但是我想在< code>win32窗口中而不是在< code>GLUT中呈现图像,基本上我们有一个< code > CreateWindowEx() API来在< code>win32中创建窗口,并且我们有一个< code>HWND(句柄),以便我们可以将此句柄传递给< code>HDC

  • 我有两个VBO,我试图渲染,它们在屏幕上应该有两个不同的位置。当我试图修改其中一个VBO的位置时,它会被转移到另一个VBOs。 示例-我更改了对象2的y位置,对象1和对象2现在都存在于该y位置。 我用于转换VBO的代码: 请注意位置,旋转,缩放都是Vector3fs,modelMatrix是well,模型矩阵。 此外,这是一个工具包。degToRad类似于数学。toRadians()类型的方法。