PDA

View Full Version : I get a black cube



wenhaug
04-27-2018, 04:16 PM
Hello. The programs renders a cube. If I set the color in the fragment shader manually, it works, but when I use a texture color, the cube becomes black. I wonder how to fix this?

The cube is rendered using glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 0);

The texture is set up as follows:

GLsizei width = 2;
GLsizei height = 2;
GLsizei layerCount = 1;
GLsizei mipLevelCount = 1;
float * data_test = new float[width * height * 4];
for (int i = 0; i < width*height*4; i+=4)
{
data_test[i + 0] = 0.25f;
data_test[i + 1] = 0.45f;
data_test[i + 2] = 0.95f;
data_test[i + 3] = 1.00f;
}

glGenTextures(1, &game_graphics_admin.texture);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D_ARRAY, game_graphics_admin.texture);
glTexStorage3D(GL_TEXTURE_2D_ARRAY, mipLevelCount, GL_RGBA, width, height, layerCount);
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, width, height, layerCount, GL_RGBA, GL_FLOAT, data_test);
delete[] data_test;

glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glGenerateMipmap(GL_TEXTURE_2D_ARRAY);


Vertex shader fetch:
12 triangles x 3 vertices = 36 vertices that are indexed.
36 x 2 uv texture coordinates

Vertex shader code:

#version 430 core
layout(location = 0) in vec4 position;
layout(location = 5) in vec2 texCoord;
uniform mat4 mv_matrix;
uniform mat4 proj_matrix;
out vec2 TexCoords;
void main(void)
{
gl_Position = proj_matrix * mv_matrix * position;
TexCoords = texCoord;
}


Fragment shader code:

#version 430 core
in vec2 TexCoords;
layout (binding=0) uniform sampler2DArray textureArray;
//layout (location=1) uniform int layer;
out vec4 color;

void main(void)
{
color = vec4(texture2DArray(textureArray, vec3(TexCoords.xy, 0)));
}


Texture UV coordinate attribute is taken from a uv-buffer, and for simplicity is made of repeating the 3 coordinate pairs (0.0f,0.0f),(0.0f,1.0f),(1.0f,1.0f), ... . It total, 36 uv-pairs.

BenSwolo
04-27-2018, 04:52 PM
is

glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 2*sizeof(GL_FLOAT), NULL);
glEnableVertexAttribArray(2);

suppose to be...

glVertexAttribPointer(5, 2, GL_FLOAT, GL_FALSE, 2*sizeof(GL_FLOAT), NULL);
glEnableVertexAttribArray(5);

You specify the location in the vertex shader for tex coords to be: layout(location = 5) in vec2 texCoord;

wenhaug
04-28-2018, 04:44 AM
is

glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 2*sizeof(GL_FLOAT), NULL);
glEnableVertexAttribArray(2);

suppose to be...

glVertexAttribPointer(5, 2, GL_FLOAT, GL_FALSE, 2*sizeof(GL_FLOAT), NULL);
glEnableVertexAttribArray(5);

You specify the location in the vertex shader for tex coords to be: layout(location = 5) in vec2 texCoord;

Thank you for your answer. I tried your advise, currently it doesn't work.
Take a look at uv-buffer code:

glGenBuffers(1, &game_graphics_admin.uv_buffer);
glBindBuffer(GL_ARRAY_BUFFER, game_graphics_admin.uv_buffer);
GLfloat uv_data[72];
for (int i = 0; i < 72; i += 6)
{
uv_data[i + 0] = 0.0f;
uv_data[i + 1] = 0.0f;
uv_data[i + 2] = 0.0f;
uv_data[i + 3] = 1.0f;
uv_data[i + 4] = 1.0f;
uv_data[i + 5] = 1.0f;
}
glBufferData(GL_ARRAY_BUFFER,
sizeof(uv_data),
&uv_data[0],
GL_STATIC_DRAW);
glVertexAttribPointer(5, 2, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(5);

Here, The uv-coordinates are inputted to the vertex shader via Attribute 5.


But, the texture array is inputted straight to the fragment shader via attribute 2.
Still don't understand how to fix this error.

GClements
04-28-2018, 07:33 AM
But, the texture array is inputted straight to the fragment shader via attribute 2.
Still don't understand how to fix this error.

The texture array is specified by a uniform (attributes can't be samplers):



layout (binding=2) uniform sampler2DArray textureArray;


The binding qualifier initialises the uniform to refer to texture unit 2, but your code binds the texture to texture unit 0:


glActiveTexture(GL_TEXTURE0);

wenhaug
04-28-2018, 07:56 AM
Thank you for your answer. I have applied your corrections, and updated my first post's code to take account for all the replies.
But the cube is unfortunately still black.

In my opinion, the error is about textures, because I checked uv-coordinate correctness by adding the following condition to the fragment shader, and got an expected pattern.

if((TexCoords.x >= 0.1f) && (TexCoords.x <= 0.9f))
{
if((TexCoords.y >= 0.1f) && (TexCoords.y <= 0.9f))
{
color = vec4(1.0f,1.0f,1.0f,1.0f);
}
}


Still don't know how to fix it.

Dark Photon
04-28-2018, 03:16 PM
Are you checking for GL errors and shader compile/link errors?


OpenGL Error (https://www.khronos.org/opengl/wiki/OpenGL_Error)
Example/GLSL Shader Compile Error Testing (https://www.khronos.org/opengl/wiki/Example/GLSL_Shader_Compile_Error_Testing)
Example/GLSL Program Link Error Testing (https://www.khronos.org/opengl/wiki/Example/GLSL_Program_Link_Error_Testing)

The texture2DArray() function reference in a #version 430 core shader w/o any #extension present caught my eye. See arekkusu's post here: LINK (https://www.opengl.org/discussion_boards/showthread.php/183166-Function-texture2DArray-always-requires-to-enable-GL_EXT_texture_array), and also EXT_texture_array. (https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_texture_array.txt)

GClements
04-28-2018, 06:01 PM
See arekkusu's post here: LINK (https://www.opengl.org/disc ussion_boards/showthread.php/183166-Function-texture2DArray-always-requires-to-enable-GL_EXT_texture_array)

That link is broken due to an extraneous space in the URL ("disc ussion"); should be: LINK (https://www.opengl.org/discussion_boards/showthread.php/183166-Function-texture2DArray-always-requires-to-enable-GL_EXT_texture_array).

wenhaug
04-29-2018, 07:04 AM
Gentlemen, I have applied error checking. The results are:
-the shaders compiled ok.
-the shaders linked in a program ok.

But, in this line, the GL_INVALID_ENUM error appears.

glTexStorage3D(GL_TEXTURE_2D_ARRAY, mipLevelCount, GL_RGBA, width, height, layerCount);

arekkusu
04-29-2018, 08:16 AM
See previous answer (http://www.opengl.org/discussion_boards/showthread.php/183754-Array-Texture-confusion?p=1258273#post1258273).

GClements
04-29-2018, 08:25 AM
But, in this line, the GL_INVALID_ENUM error appears.

glTexStorage3D(GL_TEXTURE_2D_ARRAY, mipLevelCount, GL_RGBA, width, height, layerCount);

Unsized internal formats are invalid for glTexStorage*. Use e.g. GL_RGBA8.

wenhaug
04-29-2018, 11:31 AM
Now it finally works. Thank you all.