LWJGL Forum

Programming => OpenGL => Topic started by: pilif0 on July 05, 2016, 21:39:48

Title: [Solved] [newb] Nothing renders in the window
Post by: pilif0 on July 05, 2016, 21:39:48
I am trying to learn how to use LWJGL3 and I just got to a state where I want to render something (a test quad for now). I have a class that represents a mesh where I set up the VAO with vertex, colour and element buffers and another object later takes the mesh instance, retrieves its VAO ID and attempts to render it.

The problem I have is that no matter what I try, nothing renders in the window. I can change the background colour through the glClearColor() method but the quad never shows up. I also tried to run some of the demos and they ran fine, so the problem is in this project. But I can't find it.

The VAO set up:
vertexCount = indices.length;

vaoID = glGenVertexArrays();
glBindVertexArray(vaoID);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);

//Vertices
FloatBuffer verticesBuffer = BufferUtils.createFloatBuffer(positions.length);
verticesBuffer.put(positions).flip();

vboID = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glBufferData(GL_ARRAY_BUFFER, verticesBuffer, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 3 * 4, 0);

//Colours
FloatBuffer colorsBuffer = BufferUtils.createFloatBuffer(colors.length);
colorsBuffer.put(colors).flip();

colVboID = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, colVboID);
glBufferData(GL_ARRAY_BUFFER, colorsBuffer, GL_STATIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, false, 3 * 4, 0);

//Indices
IntBuffer indicesBuffer = BufferUtils.createIntBuffer(indices.length);
indicesBuffer.put(indices).flip();

idxVboID = glGenBuffers();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, idxVboID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer, GL_STATIC_DRAW);

//Unbind
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);


The rendering code:
//Bind the shader
shaderProgram.bind();

//Bind the VAO
glBindVertexArray(mesh.getVaoID());

//Draw
glDrawElements(GL_TRIANGLES, mesh.getVertexCount(), GL_UNSIGNED_INT, 0);

//Restore
glBindVertexArray(0);
shaderProgram.unbind();


Vertex shader:
#version 330

layout (location=0) in vec3 pos;
layout (location=1) in vec3 inColor;

out vec3 exColor;

void main()
{
    gl_Position = vec4(pos, 1.0);
    exColor = inColor;
}


Fragment shader:
#version 330

in vec3 exColor;
out vec4 fragColor;


void main()
{
    fragColor = vec4(exColor, 1.0);
}


Test data being fed into it:

/** The vertices */
float[] vertices = new float[]{
    -0.5f,  0.5f, 0.0f,
    -0.5f, -0.5f, 0.0f,
     0.5f, -0.5f, 0.0f,
     0.5f,  0.5f, 0.0f
};
/** The indices */
int[] indices = new int[]{0, 1, 3, 3, 1, 2};
/** The colours */
float[] colors = new float[]{
    1.0f, 1.0f, 1.0f,
    1.0f, 1.0f, 1.0f,
    1.0f, 1.0f, 1.0f,
    1.0f, 1.0f, 1.0f
};


Could you please tell me what I'm doing wrong? If you need any other parts of code, I'll be happy to provide them.
Title: Re: [newb] Nothing renders in the window
Post by: quew8 on July 08, 2016, 10:52:41
Nothing immediately jumps out but have you called glGetError()? Should always be calling it in the render loop when you're debugging.
Title: Re: [newb] Nothing renders in the window
Post by: pilif0 on July 08, 2016, 13:43:45
Quote from: quew8 on July 08, 2016, 10:52:41
Nothing immediately jumps out but have you called glGetError()? Should always be calling it in the render loop when you're debugging.

I added a the error check as suggested, but it didn't trigger.

This is the check I wrote:
int error = glGetError();
if(error != GL_NO_ERROR){
    Log.log(Log.Severity.ERROR, "OpenGL", "OpenGL error: " + error);
}


It is second-last part of the main loop (the last is delta time calculation). The Log class is my custom logger that formats the message and writes it to both System.out and a file.
Title: Re: [newb] Nothing renders in the window
Post by: Kai on July 08, 2016, 17:04:20
The shown code in your first post works for me. I added a little scaffolding to load the shader and to setup a GLFW window and I see the quad.
Your vertex colors are all white, though. Did you probably set the clearColor to all 1.0f and don't see the quad because of this? :)

Self-contained LWJGL3 program I used:

import static org.lwjgl.glfw.GLFW.*;
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 static org.lwjgl.system.MemoryUtil.NULL;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.glfw.GLFWKeyCallback;
import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GLUtil;
import org.lwjgl.system.Callback;

public class ShaderTest {
    private long window;
    private int program;
    private int vertexCount, vaoID, vboID, idxVboID, colVboID;
    private GLFWKeyCallback keyCallback;
    private Callback debugProc;

    private void init() {
        if (!glfwInit())
            throw new IllegalStateException("Unable to initialize GLFW");
        glfwDefaultWindowHints();
        glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
        glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
        window = glfwCreateWindow(800, 600, "", NULL, NULL);
        if (window == NULL) {
            throw new AssertionError("Failed to create the GLFW window");
        }
        glfwSetKeyCallback(window, keyCallback = new GLFWKeyCallback() {
            @Override
            public void invoke(long window, int key, int scancode, int action, int mods) {
                if (action != GLFW_RELEASE)
                    return;

                if (key == GLFW_KEY_ESCAPE) {
                    glfwSetWindowShouldClose(window, true);
                }
            }
        });
        glfwMakeContextCurrent(window);
        glfwShowWindow(window);
        GL.createCapabilities();
        debugProc = GLUtil.setupDebugMessageCallback();

        createProgram();
        createVbo();
    }
    private void createVbo() {
        // See: http://forum.lwjgl.org/index.php?topic=6271.msg33478#msg33478
        /** The vertices */
        float[] positions = new float[]{
            -0.5f,  0.5f, 0.0f,
            -0.5f, -0.5f, 0.0f,
             0.5f, -0.5f, 0.0f,
             0.5f,  0.5f, 0.0f
        };
        /** The indices */
        int[] indices = new int[]{0, 1, 3, 3, 1, 2};
        /** The colours */
        float[] colors = new float[]{
            0.0f, 1.0f, 1.0f,
            1.0f, 0.0f, 1.0f,
            1.0f, 1.0f, 0.0f,
            0.0f, 0.0f, 1.0f
        };

        vertexCount = indices.length;
        vaoID = glGenVertexArrays();
        glBindVertexArray(vaoID);
        glEnableVertexAttribArray(0);
        glEnableVertexAttribArray(1);

        //Vertices
        FloatBuffer verticesBuffer = BufferUtils.createFloatBuffer(positions.length);
        verticesBuffer.put(positions).flip();

        vboID = glGenBuffers();
        glBindBuffer(GL_ARRAY_BUFFER, vboID);
        glBufferData(GL_ARRAY_BUFFER, verticesBuffer, GL_STATIC_DRAW);
        glVertexAttribPointer(0, 3, GL_FLOAT, false, 3 * 4, 0);

        //Colours
        FloatBuffer colorsBuffer = BufferUtils.createFloatBuffer(colors.length);
        colorsBuffer.put(colors).flip();

        colVboID = glGenBuffers();
        glBindBuffer(GL_ARRAY_BUFFER, colVboID);
        glBufferData(GL_ARRAY_BUFFER, colorsBuffer, GL_STATIC_DRAW);
        glVertexAttribPointer(1, 3, GL_FLOAT, false, 3 * 4, 0);

        //Indices
        IntBuffer indicesBuffer = BufferUtils.createIntBuffer(indices.length);
        indicesBuffer.put(indices).flip();

        idxVboID = glGenBuffers();
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, idxVboID);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer, GL_STATIC_DRAW);

        //Unbind
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glBindVertexArray(0);
    }
    private static int createShader(String source, int type) {
        int shader = glCreateShader(type);
        glShaderSource(shader, source);
        glCompileShader(shader);
        int compiled = glGetShaderi(shader, GL_COMPILE_STATUS);
        String shaderLog = glGetShaderInfoLog(shader);
        if (shaderLog.trim().length() > 0)
            System.err.println(shaderLog);
        if (compiled == 0)
            throw new AssertionError("Could not compile shader");
        return shader;
    }
    private void createProgram() {
        int program = glCreateProgram();
        int vshader = createShader(
"#version 330\n" +
"layout (location=0) in vec3 pos;" +
"layout (location=1) in vec3 inColor;" +
"out vec3 exColor;" +
"void main()" +
"{" +
"    gl_Position = vec4(pos, 1.0);" +
"    exColor = inColor;" +
"}"
, GL_VERTEX_SHADER);
        int fshader = createShader(
"#version 330\n" +
"in vec3 exColor;" +
"out vec4 fragColor;" +
"void main()" +
"{" +
"    fragColor = vec4(exColor, 1.0);" +
"}"
,GL_FRAGMENT_SHADER);
        glAttachShader(program, vshader);
        glAttachShader(program, fshader);
        glLinkProgram(program);
        int linked = glGetProgrami(program, GL_LINK_STATUS);
        String programLog = glGetProgramInfoLog(program);
        if (programLog.trim().length() > 0)
            System.err.println(programLog);
        if (linked == 0)
            throw new AssertionError("Could not link program");
        this.program = program;
        glUseProgram(program);
        glUseProgram(0);
    }
    private void render() {
        glClear(GL_COLOR_BUFFER_BIT);
        // See: http://forum.lwjgl.org/index.php?topic=6271.msg33478#msg33478
        glUseProgram(program);
        glBindVertexArray(vaoID);
        glDrawElements(GL_TRIANGLES, vertexCount, GL_UNSIGNED_INT, 0);
        glBindVertexArray(0);
        glUseProgram(0);
    }
    private void loop() {
        while (!glfwWindowShouldClose(window)) {
            glfwPollEvents();
            render();
            glfwSwapBuffers(window);
        }
    }
    private void run() {
        try {
            init();
            loop();
            if (debugProc != null) {
                debugProc.free();
            }
            keyCallback.free();
            glfwDestroyWindow(window);
        } catch (Throwable t) {
            t.printStackTrace();
        } finally {
            glfwTerminate();
        }
    }
    public static void main(String[] args) {
        new ShaderTest().run();
    }
}
Title: Re: [newb] Nothing renders in the window
Post by: pilif0 on July 08, 2016, 20:15:02
I ran your program Kai and it worked. That showed me that the problem must be somewhere else in the code and I believe that I have found it now. After about an hour of comparing your code to my project I noticed a different order of function calls. In the main loop, I called the buffer swap at the start, you at the end. And right after that I noticed something that made me red wit emberrassment. I was clearing the color and depth buffer right before it. I was clearing the buffer right before showing it the whole time.  :-[

Lesson learned: don't just copy from a book, think thoroughly about what you're doing

I moved the buffer swap to the end of the loop right before the delta time calculation and it's now showing a nice white quad. I want to thank you both for your help with this. If I manage to bring this project to successfull completion, it will be a small game and you are both guaranteed a copy. If you want to take a look at the rest of the code, it is up on https://github.com/pilif0/Runner (https://github.com/pilif0/Runner). I will clean up the code and commit the rendering there withing the next two days.