1
\$\begingroup\$

So I made a program to draw a simple cube with colors at each vertex. The program worked fine until I added shaders. It was using vbos and indicies and it did draw a colored cube like it should. So then I went on to add shaders and it all broke. Now all it shows me is a blue screen. When I looked at the lwjglx debug output it didn't show any errors.

I tried making the cube large, so if it was behind the camera, it would still be visible. I also turned off backface culling and made sure the znear and zfar was set correctly. They are. Other than that I can't seem to figure out what the problem is.

Anyway, my question is how can the shader code be fixed to show a cube? I've searched for days trying to find the answer, so any help would be appreciated.

Main.java

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.*;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import org.lwjgl.glfw.GLFWVidMode;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.*;
import org.joml.Matrix4f;

public class Main {
    private Thread thread;
    public boolean running = true;

    private long window;

    private int width = 1200, height = 800;
    float angle = 0.0f;

    Matrix4f viewProjMatrix = new Matrix4f();
    FloatBuffer fb = BufferUtils.createFloatBuffer(16);

    int program;
    int viewProjMatrixLocation;
    int colorLocation;

    int indexVBO;
    int cubeVAO;

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

    void buildShader() {
        program = glCreateProgram();
        int vs = glCreateShader(GL_VERTEX_SHADER);
        glShaderSource(vs,
          "#version 420\n" +
          "layout(location=0) in vec3 position;\n" +
          "uniform mat4 viewProjMatrix;\n" +
          "void main() {\n" +
          "    gl_Position = viewProjMatrix * vec4(position, 1.0);\n" +
          "}"
        );
        glCompileShader(vs);
        glAttachShader(program, vs);
        int fs = glCreateShader(GL_FRAGMENT_SHADER);
        glShaderSource(fs,
          "#version 420\n" +
          "layout(location=1) in vec3 color;\n" +
          "out vec4 fragColor;\n" +
          "void main() {\n" +
          "    fragColor = vec4(1.0, 0.5, 1.0, 0.5);\n" +
          "}"
        );
        glCompileShader(fs);
        glAttachShader(program, fs);
        glLinkProgram(program);
        glUseProgram(program);

        viewProjMatrixLocation = glGetUniformLocation(program, "viewProjMatrix");
        colorLocation = glGetUniformLocation(program, "color");
        glUseProgram(0);
    }

    void buildCube() {
        float[] colorArray = new float[] {
            1.0f, 0.0f, 0.0f,
            0.0f, 1.0f, 0.0f,
            0.0f, 0.0f, 1.0f,
            1.0f, 1.0f, 0.0f,
            0.0f, 1.0f, 1.0f,
            1.0f, 0.0f, 1.0f,
            0.0f, 0.0f, 0.0f,
            1.0f, 1.0f, 1.0f
        };
        float[] vertexArray = new float[] {
            10.0f, 10.0f, 10.0f,    // 0
            -10.0f, 10.0f, 10.0f,   // 1
            -10.0f, -10.0f, 10.0f,  // 2
            10.0f, -10.0f, 10.0f,   // 3
            10.0f, 10.0f, -10.0f,   // 4
            -10.0f, 10.0f, -10.0f,  // 5
            -10.0f, -10.0f, -10.0f, // 6
            10.0f, -10.0f, -10.0f   // 7
        };
        int[] elementArray = new int[] {
            0, 1, 2,
            1, 2, 3,

            4, 5, 6,
            5, 6, 7,

            0, 1, 5,
            1, 5, 4,

            2, 3, 7,
            3, 7, 6,

            0, 4, 7,
            4, 7, 3,

            1, 5, 6,
            5, 6, 2
        };

        FloatBuffer cb = BufferUtils.createFloatBuffer(colorArray.length);
        FloatBuffer vb = BufferUtils.createFloatBuffer(vertexArray.length);

        cb.put(colorArray);
        vb.put(vertexArray);
        vb.flip();
        cb.flip();

        IntBuffer eb = BufferUtils.createIntBuffer(elementArray.length);
        eb.put(elementArray);
        eb.flip();

        // vao
        cubeVAO = glGenVertexArrays();
        glBindVertexArray(cubeVAO);

        // vbo
        int cubeVbo = glGenBuffers();
        glBindBuffer(GL_ARRAY_BUFFER, cubeVbo);
        glBufferData(GL_ARRAY_BUFFER, cb, GL_STATIC_DRAW);

        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 3, GL_FLOAT, false, 6 * (Float.SIZE / Byte.SIZE) * 3, 0);

        // color
        glEnableVertexAttribArray(1);
        glVertexAttribPointer(1, 3, GL_FLOAT, false, 6 * (Float.SIZE / Byte.SIZE) * 3, 3 * (Float.SIZE / Byte.SIZE));

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

        // indicies
        indexVBO = glGenBuffers();
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVBO);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, eb, GL_STATIC_DRAW);

        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    }

    public void init() {
        if(!glfwInit()) {
            System.err.println("Could not initialize GLFW");
        }

        glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
        glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

        window = glfwCreateWindow(width, height, "Game", NULL, NULL);

        if(window == NULL) {
            System.err.println("Could not create window");
        }

        glfwSetWindowPos(window, 100, 100);

        glfwMakeContextCurrent(window);

        glfwShowWindow(window);

        GL.createCapabilities();

        glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
        glEnable(GL_DEPTH_TEST);
        //glEnable(GL_CULL_FACE);
        glDepthFunc(GL11.GL_LEQUAL);
        //glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
        glDisable(GL_CULL_FACE); // just to test drawing

        buildShader();
        buildCube();
    }

    public void update(int tick) {
        glfwPollEvents();

        angle += 0.01f;
    }

    public void render() {
        glViewport(0, 0, width, height);
        glUseProgram(program);

        viewProjMatrix.setPerspective((float)Math.toRadians(45.0f), (float)width / height, 0.01f, 100.0f).setLookAt(0.0f, 2.0f, 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
        glUniformMatrix4fv(viewProjMatrixLocation, false, viewProjMatrix.get(fb));

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glBindVertexArray(cubeVAO);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVBO);
        glDrawElements(GL_TRIANGLES, 12, GL_UNSIGNED_INT, 0);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
        glBindVertexArray(0);

        glUseProgram(0);
        glfwSwapBuffers(window);

        int error = glGetError();
        if(error != GL_NO_ERROR) {
            System.out.println("GL ERROR: " + error);
        }
    }

    public Main() {
        init();
        long lastTime = System.nanoTime();
        double delta = 0.0;
        double ns = 1000000000.0 / 6.0;
        long timer = System.currentTimeMillis();
        int updates = 0;
        int frames = 0;

        running = true;
        while(running) {
            long now = System.nanoTime();
            delta += (now - lastTime) / ns;
            lastTime = now;
            if (delta >= 1.0) {
                update(updates);
                updates++;
                delta--;
            }
            render();
            frames++;
            if(System.currentTimeMillis() - timer > 5000) {
                timer += 5000;
                updates = 0;
                frames = 0;
            }
            if(glfwWindowShouldClose(window)) {
                running = false;
            }
        }
    }
}
\$\endgroup\$
  • \$\begingroup\$ Did you check for compile/link errors from your shader? \$\endgroup\$ – user253751 May 7 at 3:25
  • \$\begingroup\$ @immibis Yes I did. lwjglx debug shows all compile errors. Unfortunately it didn't show anything this time \$\endgroup\$ – mooncat39 May 7 at 17:17
  • \$\begingroup\$ Ill answer in 30min \$\endgroup\$ – mackycheese21 May 7 at 21:27
  • \$\begingroup\$ Your vertex data setup is all wrong. You never actually use/upload the data in FloatBuffer vb. You use an interleaved vertex specification whereas in reality you have two different memory regions (ByteBuffers) holding the position and color information separately. \$\endgroup\$ – httpdigest May 15 at 21:55
0
\$\begingroup\$

Your shaders are wrong. Honestly, I'm suprised that it didn't error earlier.

This is your vertex shader:

#version 420
layout(location=0) in vec3 position;
uniform mat4 viewProjMatrix;
void main() {
    gl_Position = viewProjMatrix * vec4(position, 1.0);
}

The vertex shader is run once per vertex, or once per (position, color) tuple. So it follows that the vertex shader should have as its input position and color, not only position. And then, the vertex shader passes the color to the fragment shader, and the fragment shader gets run once per pixel. This means your vertex shader should look like this:

#version 420
layout(location=0) in vec3 position;
layout (location=1) in vec3 inColor;

out vec3 color;
uniform mat4 viewProjMatrix;
void main() {
    gl_Position = viewProjMatrix * vec4(position, 1.0);
    color = inColor;
}

And your fragment shader, which can't take layout (per-vertex) inputs, should look like this:

#version 420
in vec3 color;
out vec4 fragColor;
void main(){
    fragColor=vec4(color,1.0);
}

This is all a bit confusing, so I recommend you read https://learnopengl.com/Getting-started/Hello-Triangle. Pipeline description

I'm not entirely sure if your buffer code is correct, but it looks like its fine to me. So fix your shaders, read the article and let me know if it works!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.