【问题标题】:Triangle not being drawn in LWJGL OpenGL with VBO and VBA没有在 LWJGL OpenGL 中使用 VBO 和 VBA 绘制三角形
【发布时间】:2014-03-16 05:31:24
【问题描述】:

我是 OpenGL 最新版本的新手,我正在尝试按照本教程学习它:http://open.gl/drawing

然而,我正在使用最新版本的 LWJGL,并尽我所能将其 OpenGL 与本教程一样使用。尽管如此,应该绘制的白色三角形还没有。

这是我的代码:

package experiments;

import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL15.*;
import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.opengl.GL30.*;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;

import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;


public class Exp1 {

    //Shader
    private int shaderProgram;
    private int vertShader;
    private int fragShader;

    //Vertex Buffer Object
    private int vbo;

    //Vertex Array Object
    private int vao;

    //Triangle
    private float vertices[] = {
             0.0f,  0.5f, // Vertex 1 (X, Y)
             0.5f, -0.5f, // Vertex 2 (X, Y)
            -0.5f, -0.5f  // Vertex 3 (X, Y)
    };

    public Exp1() throws IOException {
        setUpDisplay();
    }

    private void createShader() throws IOException
    {
        this.shaderProgram = glCreateProgram();
        this.vertShader = glCreateShader(GL_VERTEX_SHADER);
        this.fragShader = glCreateShader(GL_FRAGMENT_SHADER);

        //set source and compile
        glShaderSource(vertShader, fileToString("src/experiments/shader.vert"));
        glCompileShader(vertShader);
        if(glGetShaderi(vertShader, GL_COMPILE_STATUS) == GL_FALSE) System.err.print("Vertex Shader wasn't able to be compiled correctly");

        glShaderSource(fragShader, fileToString("src/experiments/shader.frag"));
        glCompileShader(fragShader);
        if(glGetShaderi(fragShader, GL_COMPILE_STATUS) == GL_FALSE) System.err.print("Fragment Shader wasn't able to be compiled correctly");

        //attach shaders to shader program
        glAttachShader(shaderProgram, vertShader);
        glAttachShader(shaderProgram, fragShader);
        glLinkProgram(shaderProgram);
        glValidateProgram(shaderProgram);
    }

    private void start() throws IOException
    {   
        this.vao = glGenVertexArrays();
        glBindVertexArray(vao);

        this.vbo = glGenBuffers();
        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        FloatBuffer fBuffer= ByteBuffer.allocateDirect(vertices.length * 4).asFloatBuffer();
        fBuffer.put(vertices);
        glBufferData(GL_ARRAY_BUFFER, fBuffer, GL_STATIC_DRAW);

        createShader();
        glUseProgram(shaderProgram);

        int posAttrib = glGetAttribLocation(shaderProgram, "position");
        glVertexAttribPointer(posAttrib, 2, GL_FLOAT, false, 0, 0);
        glEnableVertexAttribArray(posAttrib);

        while(!Display.isCloseRequested())
        {
            render();
            Display.update();
            Display.sync(60);
        }
        glDeleteProgram(shaderProgram);
        glDeleteShader(vertShader);
        glDeleteShader(fragShader);
        Display.destroy();
        System.exit(0);

    }

    private void render()
    {
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        glDrawArrays(GL_TRIANGLES, 0, 3);
    }

    private String fileToString(String path) throws IOException
    {
        StringBuilder builder = new StringBuilder();
        BufferedReader reader = new BufferedReader(new FileReader(path));

        String line;
        while((line = reader.readLine()) != null)
            builder.append(line).append('\n');

        reader.close();

        return builder.toString();
    }

    private void setUpDisplay()
    {
        try
        {
            Display.setDisplayMode(new DisplayMode(640, 480));
            Display.setTitle("Shader Demo");
            Display.create();
        }
        catch (LWJGLException e) {
            System.out.println("Display Fail");
            e.printStackTrace();
            Display.destroy();
            System.exit(1);
        }
    }

    public static void main(String[] args) throws IOException {
        Exp1 demo = new Exp1();
        demo.start();
    }
}

我的着色器与教程的相同,但为了便于阅读,我还是把它们贴出来:

.frag

#version 150

out vec4 outColor;

void main()
{
    outColor = vec4(1.0, 1.0, 1.0, 1.0);
}

.vert

#version 150

in vec2 position;

void main()
{
    gl_Position = vec4(position, 0.0, 1.0);
}

代码运行,但一切都是黑色的。有什么想法吗?

【问题讨论】:

    标签: opengl glsl shader lwjgl vbo


    【解决方案1】:

    我发现了问题:

        FloatBuffer fBuffer= ByteBuffer.allocateDirect(vertices.length * 4).asFloatBuffer();
        fBuffer.put(vertices);
        glBufferData(GL_ARRAY_BUFFER, fBuffer, GL_STATIC_DRAW);
    

    此代码错误。正确的做法是:

        //Create vertice buffer
        FloatBuffer verticeBuffer= BufferUtils.createFloatBuffer(vertices.length);
        verticeBuffer.put(vertices).flip();
    
        //Send vertice buffer to VBO
        glBufferData(GL_ARRAY_BUFFER, verticeBuffer, GL_STATIC_DRAW);
    

    这是整个代码,以防它对任何人有用,我试图使其尽可能可读:)

    package experiments;
    
    import static org.lwjgl.opengl.GL11.*;
    import static org.lwjgl.opengl.GL15.*;
    import static org.lwjgl.opengl.GL20.*;
    import static org.lwjgl.opengl.GL30.*;
    
    import java.io.BufferedReader;
    import java.io.FileReader;
    import java.io.IOException;
    import java.nio.FloatBuffer;
    
    import org.lwjgl.BufferUtils;
    import org.lwjgl.LWJGLException;
    import org.lwjgl.opengl.Display;
    import org.lwjgl.opengl.DisplayMode;
    
    
    public class Exp1 {
    
        //Shader
        private int shaderProgram;
        private int vertShader;
        private int fragShader;
    
        //Vertex Buffer Object
        private int vbo;
    
        //Vertex Array Object
        private int vao;
    
        //Triangle
        private float vertices[] = {
             0.0f,  0.5f, // Vertex 1 (X, Y)
             0.5f, -0.5f, // Vertex 2 (X, Y)
            -0.5f, -0.5f  // Vertex 3 (X, Y)
        };
        private int posAttrib;
    
        public Exp1() throws IOException {
            setUpDisplay();
        }
    
        private void start() throws IOException
        {   
            setUpDraw();
    
            while(!Display.isCloseRequested())
            {
                render();
                Display.update();
                Display.sync(60);
            }
    
            glDeleteProgram(shaderProgram);
            glDeleteShader(vertShader);
            glDeleteShader(fragShader);
    
            glDeleteBuffers(vbo);
            glDeleteVertexArrays(vao);
    
            Display.destroy();
            System.exit(0);
        }
    
        private void setUpDraw() throws IOException{
            // Create a new VAO in memory and bind it (A VAO can have up to 16 attributes (VBO's) assigned to it by default)
            this.vao = glGenVertexArrays();
            glBindVertexArray(vao);
    
            //Create a new VBO in memory and bind it (A VBO is a collection of Vectors which in this case resemble the location of each vertex)
            this.vbo = glGenBuffers();
            glBindBuffer(GL_ARRAY_BUFFER, vbo);
    
            //Create new shader and use it
            createShader();
            glUseProgram(shaderProgram);
    
            //Create vertice buffer
            FloatBuffer verticeBuffer= BufferUtils.createFloatBuffer(vertices.length);
            verticeBuffer.put(vertices).flip();
    
            //Send vertice buffer to VBO
            glBufferData(GL_ARRAY_BUFFER, verticeBuffer, GL_STATIC_DRAW);
    
            //Put the VBO in the attributes list at index posAttrib
            posAttrib = glGetAttribLocation(shaderProgram, "position");
            glVertexAttribPointer(posAttrib, 2, GL_FLOAT, false, 0, 0);
    
            //Unbind VBO and VAO
            glBindBuffer(GL_ARRAY_BUFFER, 0);
            glBindVertexArray(0);
        }
    
        private void createShader() throws IOException
        {
            //create
            this.shaderProgram = glCreateProgram();
            this.vertShader = glCreateShader(GL_VERTEX_SHADER);
            this.fragShader = glCreateShader(GL_FRAGMENT_SHADER);
    
            //set source and compile
            glShaderSource(vertShader, fileToString("src/experiments/shader.vert"));
            glCompileShader(vertShader);
            if(glGetShaderi(vertShader, GL_COMPILE_STATUS) == GL_FALSE) System.err.print("Vertex Shader wasn't able to be compiled correctly");
    
            glShaderSource(fragShader, fileToString("src/experiments/shader.frag"));
            glCompileShader(fragShader);
            if(glGetShaderi(fragShader, GL_COMPILE_STATUS) == GL_FALSE) System.err.print("Fragment Shader wasn't able to be compiled correctly");
    
            //attach shaders to shader program
            glAttachShader(shaderProgram, vertShader);
            glAttachShader(shaderProgram, fragShader);
            glLinkProgram(shaderProgram);
            glValidateProgram(shaderProgram);
        }
    
        private void render()
        {
            //Clear screen
            glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
            glClear(GL_COLOR_BUFFER_BIT);
    
            //Bind our VAO which already has the quad info and enable attribute list in posAttrib index
            glBindVertexArray(vao);
            glEnableVertexAttribArray(posAttrib);
    
            //Draw the vertices
            glDrawArrays(GL_TRIANGLES, 0, 3);
    
            //Unbind back to defaults
            glDisableVertexAttribArray(posAttrib);
            glBindVertexArray(0);
        }
    
        private String fileToString(String path) throws IOException
        {
            StringBuilder builder = new StringBuilder();
            BufferedReader reader = new BufferedReader(new FileReader(path));
    
            String line;
            while((line = reader.readLine()) != null)
                builder.append(line).append('\n');
    
            reader.close();
    
            return builder.toString();
        }
    
        private void setUpDisplay()
        {
            try
            {
                Display.setDisplayMode(new DisplayMode(640, 480));
                Display.setTitle("Shader Demo");
                Display.create();
            }
            catch (LWJGLException e) {
                System.out.println("Display Fail");
                e.printStackTrace();
                Display.destroy();
                System.exit(1);
            }
        }
    
        public static void main(String[] args) throws IOException {
            Exp1 demo = new Exp1();
            demo.start();
        }
    }
    

    【讨论】:

      【解决方案2】:

      您已经在检查着色器编译日志,所以着色器应该没问题。开始调试这些的一个好方法是开始在很多地方插入glGetError() 调用。如果你得到一个非零的返回值 (0 == GL_NO_ERROR),你就会知道之前的 gl* 调用有问题。当前,例如,您正在调用glValidateProgram,如果程序未成功链接,则会产生错误,但您必须自己检查错误glGetError()

      编辑:由于您使用的是 LWJGL,因此您还可以使用lwjgl.opengl.Util 中的错误检查方法。

      【讨论】:

      • 我试过了,但显然没有抛出异常:/
      猜你喜欢
      • 2020-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-12
      相关资源
      最近更新 更多