Cubemapping - render only black cube

code.cpp


    unsigned int cubeVAO, cubeVBO;
    glGenVertexArrays(1, &cubeVAO);
    glGenBuffers(1, &cubeVBO);
    glBindVertexArray(cubeVAO);
    glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), &cubeVertices, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
    glEnableVertexAttribArray(1);

    glGenTextures(1, &cubeTextureId);

        int Cwidth,Cheight;
        png_byte* Cimage_data;

        Cimage_data = png_texture_load("bg.png", &Cwidth, &Cheight);

        if(Cimage_data)
        {
            glBindTexture(GL_TEXTURE_2D, cubeTextureId);
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Cwidth, Cheight, 0, GL_RGB, GL_UNSIGNED_BYTE, Cimage_data);
            glGenerateMipmap(GL_TEXTURE_2D);

            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
            free(Cimage_data);
        }

        else
        {
            std::cout << "Cubemap texture failed to load at path: " << "kitten.png" << std::endl;

        }

        // cubes
        glBindVertexArray(cubeVAO);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, cubeTextureId);
        glDrawArrays(GL_TRIANGLES, 0, 36);
        glBindVertexArray(0);



        glDepthFunc(GL_LEQUAL);  // change depth function so depth test passes when values are equal to depth buffer's content

    glLinkProgram(sky_program);
    glUseProgram(sky_program);


    GLuint skybox_loc = glGetUniformLocation(sky_program,"skybox");
    glUniform1i(skybox_loc, 0);

        GLuint Sview_loc = glGetUniformLocation(sky_program,"view");
        GLuint Sproj_loc = glGetUniformLocation(sky_program,"projection");

        glUniformMatrix4fv(Sview_loc, 1, GL_FALSE, glm::value_ptr(cam_view_mat));
        glUniformMatrix4fv(Sproj_loc, 1, GL_FALSE, glm::value_ptr(proj_mat));

    unsigned int skyboxVAO, skyboxVBO;
    glGenVertexArrays(1, &skyboxVAO);
    glGenBuffers(1, &skyboxVBO);
    glBindVertexArray(skyboxVAO);
    glBindBuffer(GL_ARRAY_BUFFER, skyboxVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), &skyboxVertices, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    GLenum  cube[6] = {  GL_TEXTURE_CUBE_MAP_POSITIVE_X,
                     GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
                     GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
                     GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
                     GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
                     GL_TEXTURE_CUBE_MAP_NEGATIVE_Z };

    const char *cubeimage[6] = { "right.png", "left.png", "top.png", "bottom.png", "front.png", "back.png" };

    glGenTextures(1, &cubeMaptextureID);

    for(int i=0;i<6;i++)
    {
        int width,height;
        png_byte* image_data;

        image_data = png_texture_load(cubeimage[i], &width, &height);

        if(image_data)
        {

            glBindTexture(GL_TEXTURE_CUBE_MAP, cubeMaptextureID);
            glTexImage2D(cube[i], 0, GL_RGBA, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image_data);

            glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_REPEAT);
            glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_REPEAT);
            glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_REPEAT);

            glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
            glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

            free(image_data);

        }

        else
        {
            std::cout << "Cubemap texture failed to load at path: " << cubeimage[i] << std::endl;

        }

    }

    glBindVertexArray(skyboxVAO);


        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_CUBE_MAP, cubeMaptextureID);
        glDrawArrays(GL_TRIANGLES, 0, 36);

        glDepthFunc(GL_LESS); 

Shader code

skybox.vs


#version 300 es
layout (location = 0) in vec3 aPos;

out vec3 TexCoords;

uniform mat4 projection;
uniform mat4 view;

void main()
{
    TexCoords = aPos;
    vec4 pos = projection * view * vec4(aPos, 1.0);
    gl_Position = pos.xyww;
}  

skybox.fs


#version 300 es
precision mediump float;

out vec4 FragColor;

in vec3 TexCoords;

uniform samplerCube skybox;

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

The above code renders the Background 2D texture fine. But it renders the cubemap as black. What may be the issue?

One problem I see is you’ve got trilinear filtering on both textures, but you’ve only generated MIPmaps for your 2D texture.

Try flipping the MIN_FILTER on your cube map to LINEAR.

Thanks for your reply. I have tried but it is still a black cube.

Anyone have idea about this issue?

try breaking the problem down. replace texture file data with a simple rgba color like:

GLubyte rgba_data = { 0x00, 0xFF, 0xFF, 0xFF, };

check the number of channels of your textures, according to your code they should have only 3 (rgb)

those glTexParameteri(…) calls you need to do only once, not 6 times.

most importantly: ask opengl if somethings going wrong, either:
by using a gl debug context with a callback function that shows you occuring errors
(here an example)

or:
by simply checking if glGetError() returns anything other than GL_NO_ERROR
(here an example)

Thanks for your reply. I have tried as per your suggestion. But it is still a black cube. glGetError returns GL_INVALID_VALUE.

https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glGetError.xhtml

GL_INVALID_VALUE

A numeric argument is out of range. The offending command is ignored and has no other side effect than to set the error flag.

now find out which function causes this error by adding several …

CHECK_GL_ERROR; // take a look at the linked example above

… in your code at different places. once the error happens, the code stops (because of cin.get()) and make a warning sound (because of cout << (char)7; ) and shows you the line at which the error has been detected (meaning the error happend in the gl lines before) in the console window.

once you know what function throws that error, take a look at its API description page and read its error section. there you find all possible errors, (at least) one of those is your error.