PDA

View Full Version : Problems with rendering a skybox



Wanderer901
05-28-2018, 08:33 PM
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(filenam e));
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

AiJai1
05-28-2018, 11:10 PM
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

john_connor
05-29-2018, 03:32 AM
... to fix the problem

what problem?

Wanderer901
05-29-2018, 05:41 AM
@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);

GClements
05-29-2018, 06:28 AM
here is the problematic code from main class:


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





this is the skybox vertex shader code:


uniform mat4 projection;
uniform mat4 view;





and here is fragment shader:


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



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().

AiJai1
05-29-2018, 10:47 AM
Cool. :cool: Keep following that procedure and you should be smooth sailing. ;) Cheers