Pregunta

Im new to the most recent versions of OpenGL and im trying to learn it by following this tutorial: http://open.gl/drawing

Yet, I am using the latest version of LWJGL and trying my best to use its OpenGL equally to the tutorial. Still, the white triangle that is supposed to be drawn just isnt.

This is my code:

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

My shaders are identical to the tutorial's but ill post them anyway for easier reading:

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

The code runs but all is black. Any ideas?

¿Fue útil?

Solución

I found the problem:

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

This code is wrong. The right way to do it is:

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

Here is the whole code in case its useful for anyone, i tried to make it as readable as possible :)

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

Otros consejos

You are checking shader compile logs already, so the shaders should be fine. A good way to start debugging these is to start inserting glGetError() calls in a lot of places. If you get a non-zero return value (0 == GL_NO_ERROR), you'll know something's wrong with an earlier gl* call. Currently, for example, you are calling glValidateProgram which will generate an error if the program was not linked successfully, but you must check for the error yourself with glGetError().

EDIT: Since you're using LWJGL, you can also use the error check methods in lwjgl.opengl.Util.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top