OpenGL, Shader Model 3.3 Texturing: Black Textures?
Asked Answered
S

2

6

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?

Sibilant answered 11/1, 2012 at 11:1 Comment(0)
A
11

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

Aphrodisiac answered 11/1, 2012 at 11:22 Comment(6)
I don't think this is relevant. If they are not set, then default values would be usedAlleviator
You sir, are a god among men! @VJovic I thought exactly the same thing :).Sibilant
Wow this fixed the issue for me as well. It seems that GL_TEXTURE_MIN_FILTER specifically doesn't have a proper default value.Zincograph
Works for me on #version 330. I took it for granted that every TexParameter has a proper default value. No!Valerievalerio
This solved a similar problem for me, too! I wasted way too much time on this - Is there an easy way to debug issues like this? AFAIK, the only symptom of this issue is a black texture. Everything looked normal in RenderDocQuart
Spent countless hours checking all my shader programs, bindings, textures in renderdoc... only to stumble on this and it fixed everything. Very infuriating, why are these things not on some default value!?Gowen
L
2

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?

Lucullus answered 11/1, 2012 at 11:29 Comment(2)
Well, gl_FragColor is deprecated, so is gl_FragData. Post 1.2 (I think) you need to use out and bind to buffers. Given that I can draw everything else fine, I don't think is the issue.Sibilant
@LiamM: Indeed, but I was wondering if maybe you accidently missed that.Lucullus

© 2022 - 2024 — McMap. All rights reserved.