PDA

View Full Version : OpenGL 3.3 textures only black



toyowski
11-02-2015, 09:00 AM
Hi everyone,

I'm trying to learn OpenGL. I am able to render a triangle with fixed colors, but when I tried adding textures I only get black colors:

Main App:


//TEXTURE
glEnable(GL_TEXTURE_2D);
glGenBuffers(1, &tbo);
glBindBuffer(GL_ARRAY_BUFFER, tbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coords), tex_coords, GL_STATIC_DRAW);
//Attributes
int tex_coords_index = glGetAttribLocation(program, "texCoords");
glEnableVertexAttribArray(tex_coords_index);
glVertexAttribPointer(tex_coords_index, 2, GL_FLOAT, GL_FALSE, 0, 0);
//Image
int width, height;
unsigned char *image = SOIL_load_image("c:/image.png", &width, &height, 0, GL_RGB);
glGenTextures(1, &tex);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
//Uniform
int sampler2D = glGetUniformLocation(program, "tex");
glUniform1i(sampler2D, 0);


Shaders:


char *vertex_shader_source = {

"#version 330 core\n"
"in vec3 vertices;"
"in vec2 texCoords;"
"out vec2 ftexCoords;"
"void main(){"
" gl_Position = vec4(vertices, 1.0f);"
" ftexCoords = texCoords;"
"}"

};

char *fragment_shader_source = {

"#version 330 core\n"
"in vec2 ftexCoords;"
"out vec4 out_color;"
"uniform sampler2D tex;"
"void main(){"
" out_color = texture(tex, ftexCoords);"
//" out_color = vec4(0.0, 1.0, 0.0, 1.0);"
"}"

};


Any feedbacks and suggestions will be greatly appreciated.

Thanks.

GClements
11-02-2015, 03:13 PM
A few things stand out:





glEnable(GL_TEXTURE_2D);


This is only meaningful for the fixed-function pipeline. It isn't relevant when using shaders, and isn't valid in the core profile.





unsigned char *image = SOIL_load_image("c:/image.png", &width, &height, 0, GL_RGB);


GL_RGB isn't valid as the force_channels parameter to SOIL_load_image? Did you mean to use SOIL_LOAD_RGB instead? Or SOIL_LOAD_RGBA (see below)?

Also, you aren't checking the return value. Passing NULL to glTexImage2D() is valid; it creates the texture with the specified format and dimensions but the contents will be undefined.




glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);


Above, you appear to be trying to load the image as RGB, but you're then telling glTexImage2D() that the data is RGBA.

toyowski
11-02-2015, 07:41 PM
Hi GClements,

Thanks for the reply. I tried updating my code, but still getting the black textures. See my updated code below:



//TEXTURE
glGenBuffers(1, &tbo);
glBindBuffer(GL_ARRAY_BUFFER, tbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coords), tex_coords, GL_STATIC_DRAW);
//Attributes
int tex_coords_index = glGetAttribLocation(program, "texCoords");
glEnableVertexAttribArray(tex_coords_index);
glVertexAttribPointer(tex_coords_index, 2, GL_FLOAT, GL_FALSE, 0, 0);
//Image
int width, height;
unsigned char *image = SOIL_load_image("c:/toyo.png", &width, &height, 0, SOIL_LOAD_RGB);
glGenTextures(1, &tex);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
//Uniform
int sampler2D = glGetUniformLocation(program, "tex");
glUniform1i(sampler2D, 0);


Also I did not find any return value for glTexImage2D.

Thanks again for the reply.

GClements
11-02-2015, 07:48 PM
Also I did not find any return value for glTexImage2D.
glTexImage2D() doesn't have a return value. OpenGL errors are only reported by calling glGetError().

It's the return value of SOIL_load_image() you should be checking.

toyowski
11-03-2015, 12:34 AM
Hi GClements,

I was able to make the texture appear. What happened was I did not include texture parameters:



glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);


I mistakenly assumed that OpenGL have default values for these parameters. I got it working now. The only thing weird is the image is upside down. I remedied it by flipping the y-coordinates for my texture coordinates.

GClements
11-03-2015, 01:37 AM
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

I mistakenly assumed that OpenGL have default values for these parameters.

It does have default values. But the default value for GL_TEXTURE_MIN_FILTER is GL_NEAREST_MIPMAP_LINEAR, which requires all mipmap levels to be defined (either by uploading them explicitly or using glGenerateMipmap() to generate them from the base level).


The only thing weird is the image is upside down.
The first pixel on the first row of the texture data is at the corner with texture coordinates (0,0). If the texture data is stored with the top row first, texture coordinates (0,0) will be the top-left corner of the texture. Window coordinates have (0,0) at the bottom-left corner, normalised device coordinates have (-1,-1) at the bottom-left corner of the viewport, so if texture coordinates have the same orientation as window coordinates and normalised device coordinates, top-row-first textures will be upside-down.