1

As far as I can tell, my first attempt to draw a texture on a triangle is being setup correctly, but it shows up as all black.

I am sending the image to OpenGL as such:

   GLuint gridTexture;
    glGenTextures(1, &gridTexture);
    glBindTexture(GL_TEXTURE_2D, gridTexture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);


glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.x,
                 size.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);

While I'm not sure how to test that "pixels" holds what I'd expect, I do know that the size.x and size.y variables are logging correctly for the PNG I'm using so I assume the pixels is working well also since they are both extracted together in my resource loader

My shaders are simple:

attribute vec4 Position;
attribute vec4 SourceColor;
attribute vec2 TextureCoordinate;

varying vec4 DestinationColor;
varying vec2 TextureCoordOut;

uniform mat4 Projection;
uniform mat4 Modelview;

void main(void)
{
    DestinationColor = SourceColor;

    gl_Position=Projection*Modelview*Position;
    TextureCoordOut = TextureCoordinate;
}

fragment:

varying lowp vec4 DestinationColor;
varying mediump vec2 TextureCoordOut;

uniform sampler2D Sampler;

void main(void)
{
    gl_FragColor = texture2D(Sampler, TextureCoordOut) * DestinationColor;
//        gl_FragColor = DestinationColor; //this works and I see varied colors fine
}

I send texture coordinates from client memory like this:

glEnableVertexAttribArray(textCoordAttribute));    
glVertexAttribPointer(textCoordAttribute, 2, GL_FLOAT, GL_FALSE, sizeof(vec2),&texs[0]);

The triangle and its vertices with texture coordinates are like this; I know the coordinates aren't polished, I just want to see something on the screen:

//omitting structures that I use to hold my vertex data, but you can at least see the vertices and the coordinates I am associating with them. The triangle draws fine, and if I disable the texture2D() function in the frag shader I can see the colors of the vertices so everything appears to be working except the texture itself.

    top.Color=vec4(1,0,0,1);
    top.Position=vec3(0,300,0);
    texs.push_back(vec2(0,1));

    right.Color=vec4(0,1,0,1);
    right.Position=vec3(300,0,0);
    texs.push_back(vec2(1,0));

    left.Color=vec4(0,0,1,1);
    left.Position=vec3(-300,0,0);
    texs.push_back(vec2(0,0));

    verts.push_back(top);
    verts.push_back(right);
    verts.push_back(left);

For good measure I tried binding the texture again with glBindTexture before drawing to make it was "active" but that made no difference.

I think there is probably a very simple step I am not doing somewhere but I can't find it anywhere.

Christian Rau
  • 45,360
  • 10
  • 108
  • 185
johnbakers
  • 24,158
  • 24
  • 130
  • 258

3 Answers3

6

For people suffering from textures showing up black, another reason I found was if you don't set up these simple parameters when creating the texture (before glTexImage2D), the texture shows up black

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
Archon 808
  • 180
  • 1
  • 8
0

The issue is resolved by making my texture dimensions a power of 2 in length and width.

johnbakers
  • 24,158
  • 24
  • 130
  • 258
  • 1
    Please check your OpenGL version then! The Power of 2 constraint has been lifted with OpenGL-2, so it's likely you're running on OpenGL-1.x – which indicates your drivers are not installed properly. See the reference http://www.opengl.org/sdk/docs/man2/xhtml/glGetString.xml you're interested in GL_VERSION and GL_RENDERER – datenwolf Apr 18 '13 at 09:28
  • 1
    Well, you're using shaders, so you're running on a modern OpenGL version, on second thought. But I don't think it's an alignment issue, because you'd see something (a distorted image) if your alignment wasn't correct... – datenwolf Apr 18 '13 at 09:34
  • 1
    And bingo! *datenwolf*'s comment shows a clear example why the `opengl` tag was completely misplaced. Because since *datenwolf* says if using shaders in desktop GL the version needs to be high enough to support NPOT textures anyway. But in OpenGL ES 2.0 this doesn't need to be the case. – Christian Rau Apr 18 '13 at 10:44
-3

you must have a bound data to the texture before setting the filter. You must call glTexImage2D first

GLuint gridTexture;
glGenTextures(1, &gridTexture);
glBindTexture(GL_TEXTURE_2D, gridTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.x,
                 size.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);  
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
DanP
  • 187
  • 3
  • 10
  • 2
    Setting glTexParameter can be done before uploading the texture data just fine. Some drivers are buggy in that regard, but a conforming OpenGL implementation must not put constraints in which order image and parameters are set. – datenwolf Apr 18 '13 at 09:27
  • Oh sorry, I just remembered something. I've had problems like these before, the first time I saw your code, I noticed the order (different from mine), I did a lot of things and I thought the order was important.. – DanP Apr 18 '13 at 09:29
  • `gl_FragColor = texture2D(Sampler, TextureCoordOut);` is black too? – DanP Apr 18 '13 at 09:30