Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenGL, Shader Model 3.3 Texturing: Black Textures?

I've been banging my head against this for hours now, I'm sure it's something simple, but I just can't get a result. I've had to edit this code down a bit because I've built a little library to encapsulate the OpenGL calls, but the following is an accurate description of the state of affairs.

I'm using the following vertex shader:

#version 330
in vec4 position;
in vec2 uv;
out vec2 varying_uv;
void main(void)
{
    gl_Position = position;
    varying_uv = uv;
}

And the following fragment shader:

#version 330
in vec2 varying_uv;
uniform sampler2D base_texture;
out vec4 fragment_colour;
void main(void)
{
    fragment_colour = texture2D(base_texture, varying_uv);
}

Both shaders compile and the program links without issue.

In my init section, I load a single texture like so:

// Check for errors.
kt::kits::open_gl::Core<QString>::throw_on_error();

// Load an image.
QImage image("G:/test_image.png");
image = image.convertToFormat(QImage::Format_RGB888);

if(!image.isNull())
{
    // Load up a single texture.
    glGenTextures(1, &Texture);
    glBindTexture(GL_TEXTURE_2D, Texture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, image.width(), image.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, image.constBits());
    glBindTexture(GL_TEXTURE_2D, 0);
}

// Check for errors.
kt::kits::open_gl::Core<QString>::throw_on_error();

You'll observe that I'm using Qt to load the texture. The calls to ::throw_on_error() check for errors in OpenGL (by calling Error()), and throw an exception if one occurs. No OpenGL errors occur in this code, and the image loaded using Qt is valid.

Drawing is performed as follows:

// Clear previous.
glClear(GL_COLOR_BUFFER_BIT |
    GL_DEPTH_BUFFER_BIT |
    GL_STENCIL_BUFFER_BIT);

// Use our program.
glUseProgram(GLProgram);

// Bind the vertex array.
glBindVertexArray(GLVertexArray);

/* ------------------ Setting active texture here ------------------- */

// Tell the shader which textures are which.
kt::kits::open_gl::gl_int tAddr = glGetUniformLocation(GLProgram, "base_texture");
glUniform1i(tAddr, 0);

// Activate the texture Texture(0) as texture 0.
glActiveTexture(GL_TEXTURE0 + 0);
glBindTexture(GL_TEXTURE_2D, Texture);

/* ------------------------------------------------------------------ */

// Draw vertex array as triangles.
glDrawArrays(GL_TRIANGLES, 0, 4);
glBindVertexArray(0);
glUseProgram(0);

// Detect errors.
kt::kits::open_gl::Core<QString>::throw_on_error();

Similarly, no OpenGL errors occur, and a triangle is drawn to screeen. However, it looks like this:

Texturing, not as expected.

It occurred to me the problem may be related to my texture coordinates. So, I rendered the following image using s as the 'red' component, and t as the 'green' component:

Coloring using st coordinates.

The texture coordinates appear correct, yet I'm still receiving the black triangle of doom. What am I doing wrong?

like image 308
Liam M Avatar asked Jan 11 '12 11:01

Liam M


2 Answers

I think it could be depending on an incomplete init of your texture object.

Try to init the texture MIN and MAG filter

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

Moreover, I would suggest to check the size of the texture. If it is not power of 2, then you have to set the wrapping mode to CLAMP_TO_EDGE

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);

Black textures are often due to this issue, very common problem around.

Ciao

like image 70
Maurizio Benedetti Avatar answered Nov 03 '22 07:11

Maurizio Benedetti


In your fragment shader you're writing to a self defined target

   fragment_colour = texture2D(base_texture, varying_uv);

If that's not to be gl_FragColor or gl_FragData[…], did you properly set the designated fragment data location?

like image 2
datenwolf Avatar answered Nov 03 '22 06:11

datenwolf