Problems with rendering a skybox

Hello,
so I have spent countless hours trying to figure out why my skybox doesnt want to render, so far with no luck. Most of my code is inspired by learnopengl.com, however, I have also followed many tutorials on how to do this, but I wasn’t able to fix the problem. I would like to kindly ask for your help.

here is the problematic code from main class:


public class Scene {
    private static final int CAMERA_BUFFER_BINDING = 0;
    private int skyboxProgram;
    private int skyboxBuffer;
    private int skyboxArray;
    private int skyboxUniformLoc;
    private int skyboxTexture;
    private static final int SIZEOF_SKYBOX_VERTEX = 3 * Float.BYTES;
    private static final float S_SIZE = 200.0f; //skybox dimensions
    private static final float SKYBOX[] = {
            // Positions
            -S_SIZE, S_SIZE, -S_SIZE,
            -S_SIZE, -S_SIZE, -S_SIZE,
            S_SIZE, -S_SIZE, -S_SIZE,
            S_SIZE, -S_SIZE, -S_SIZE,
            S_SIZE, S_SIZE, -S_SIZE,
            -S_SIZE, S_SIZE, -S_SIZE,

            -S_SIZE, -S_SIZE, S_SIZE,
            -S_SIZE, -S_SIZE, -S_SIZE,
            -S_SIZE, S_SIZE, -S_SIZE,
            -S_SIZE, S_SIZE, -S_SIZE,
            -S_SIZE, S_SIZE, S_SIZE,
            -S_SIZE, -S_SIZE, S_SIZE,

            S_SIZE, -S_SIZE, -S_SIZE,
            S_SIZE, -S_SIZE, S_SIZE,
            S_SIZE, S_SIZE, S_SIZE,
            S_SIZE, S_SIZE, S_SIZE,
            S_SIZE, S_SIZE, -S_SIZE,
            S_SIZE, -S_SIZE, -S_SIZE,

            -S_SIZE, -S_SIZE, S_SIZE,
            -S_SIZE, S_SIZE, S_SIZE,
            S_SIZE, S_SIZE, S_SIZE,
            S_SIZE, S_SIZE, S_SIZE,
            S_SIZE, -S_SIZE, S_SIZE,
            -S_SIZE, -S_SIZE, S_SIZE,

            -S_SIZE, S_SIZE, -S_SIZE,
            S_SIZE, S_SIZE, -S_SIZE,
            S_SIZE, S_SIZE, S_SIZE,
            S_SIZE, S_SIZE, S_SIZE,
            -S_SIZE, S_SIZE, S_SIZE,
            -S_SIZE, S_SIZE, -S_SIZE,

            -S_SIZE, -S_SIZE, -S_SIZE,
            -S_SIZE, -S_SIZE, S_SIZE,
            S_SIZE, -S_SIZE, -S_SIZE,
            S_SIZE, -S_SIZE, -S_SIZE,
            -S_SIZE, -S_SIZE, S_SIZE,
            S_SIZE, -S_SIZE, S_SIZE
    };


    private ByteBuffer getTextureData(String filename) throws IOException {
        BufferedImage image = ImageIO.read(Cv5.class.getResourceAsStream(filename));
        byte[] pixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();

        ByteBuffer textureData = BufferUtils.createByteBuffer(pixels.length);
        textureData.put(pixels);
        textureData.rewind();
        return textureData;
    }

    private int loadCubeMap() {
        glUseProgram(skyboxProgram);
        int width = 1024;
        int height = 1024;
        int textureID = glGenTextures();
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);

        for (int i = 0; i < 6; i++) {
            String path;
            switch (i) {
                case 0:
                    path = "/resources/textures/posx.jpg"; break;
                case 1:
                    path = "/resources/textures/negx.jpg"; break;
                case 2:
                    path = "/resources/textures/posy.jpg"; break;
                case 3:
                    path = "/resources/textures/negy.jpg"; break;
                case 4:
                    path = "/resources/textures/posz.jpg"; break;
                default:
                    path = "/resources/textures/negz.jpg";
            }
            try {
                ByteBuffer data = getTextureData(path);
                glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB,
                        width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
            } catch (IOException ex) {
                System.out.println("Could not find file " + path);
            }
        }

        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

        return textureID;
    }

    private void drawSkybox() {
        glUseProgram(skyboxProgram);
        glDisable(GL_DEPTH_TEST);
        glBindVertexArray(skyboxArray);

        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_CUBE_MAP, skyboxTexture);
        glUniform1i(skyboxUniformLoc, 0);
        glDrawArrays(GL_TRIANGLES, 0, 36);

        glUseProgram(0);
        glEnable(GL_DEPTH_TEST);
    }

    private void init() {
        // code loadProgram is not provided but it definitely works
        try {
            skyboxProgram = loadProgram("/resources/shaders/skybox.vs.glsl",
                    "/resources/shaders/skybox.fs.glsl");
        } catch (IOException ex) {
            System.exit(1);
        }

        skyboxUniformLoc = glGetUniformLocation(skyboxProgram, "skybox");
        int cameraIdx = glGetUniformBlockIndex(skyboxProgram, "Camera");
        glUniformBlockBinding(skyboxProgram, cameraIdx, CAMERA_BUFFER_BINDING);

        // create buffers with geometry
        int[] buffers = new int[4];
        glGenBuffers(buffers);
        skyboxBuffer = buffers[3];

        // create a vertex array object for the geometry
        int[] arrays = new int[4];
        glGenVertexArrays(arrays);
        skyboxArray = arrays[3];

        // fill skybox buffer with geometry
        glBindBuffer(GL_ARRAY_BUFFER, skyboxBuffer);
        glBufferData(GL_ARRAY_BUFFER, SKYBOX, GL_STATIC_DRAW);
        // clear buffer binding
        glBindBuffer(GL_ARRAY_BUFFER, 0);

        // get skybox program attributes
        int positionAttribLoc = glGetAttribLocation(skyboxProgram, "position");
        // bind skybox buffer
        glBindVertexArray(skyboxArray);
        glBindBuffer(GL_ARRAY_BUFFER, skyboxBuffer);
        glEnableVertexAttribArray(positionAttribLoc);
        glVertexAttribPointer(positionAttribLoc, 3, GL_FLOAT, false, SIZEOF_SKYBOX_VERTEX, 0);
        glBindBuffer(GL_ARRAY_BUFFER, 0);

        // load SkyBox
        skyboxTexture = loadCubeMap();

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

    // called every frame
    private void render() {
        // some code
        drawSkybox();
        // some code
    }
}

this is the skybox vertex shader code:


#version 330

in vec3 position;
out vec3 TexCoords;

uniform mat4 projection;
uniform mat4 view;

void main()
{
    gl_Position = projection * view * vec4(position, 1.0);
    TexCoords = position;
}

and here is fragment shader:


#version 330

in vec3 TexCoords;
out vec4 out_Color;

uniform samplerCube skybox;

layout (std140) uniform Camera {
    mat4 view;
    mat4 projection;
} camera;

void main()
{
    out_Color = texture(skybox, TexCoords);
}

Sorry to bother you with this mess. I’ll be glad for any suggestions and ideas. Thank you

Hi
I have been following the learnopengl tutorials also. I haven’t reached the point you have as yet, but my experience with those tutorials, is that although the are good imo, they sometimes don’t include some vital detail.
So what I do when I get a problem, is open the corresponding source code, and look to see what’s out of sync. Usually there is code that has been left out, or placed before.
Cheers

what problem?

@john_connor the problem was that the skybox didnt render at all

@AiJai1 thanks for the suggestion! After I have closely inspected source code, I found out, that I wasn’t feeding viewMatrix and projectionMatrix to skybox vertex shader. Adding following piece of code to function drawSkybox solved the problem. It’s working now, thanks a lot :).


Matrix4f viewNoTranslation = new Matrix4f(new Matrix3f(view));
FloatBuffer projectionData = BufferUtils.createFloatBuffer(16);
FloatBuffer viewData = BufferUtils.createFloatBuffer(16);
projection.get(projectionData);
viewNoTranslation.get(viewData);
glUniformMatrix4fv(skyboxViewLoc, false, viewData);
glUniformMatrix4fv(skyboxProjectionLoc, false, projectionData);

The fragment shader and application code are using a named uniform block for the transformation matrices, while the vertex shader is using default-block uniforms (which aren’t assigned by the application code). Use one or the other; or if you must use both, assign the default-block uniforms with glUniformMatrix4fv().

Cool. :cool: Keep following that procedure and you should be smooth sailing. :wink: Cheers