1
votes

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.

3
Why was the OpenGL tag removed from this? There is not ES-specific code or techniques here; they apply to desktop OpenGL also. - johnbakers
Yes there is, as datenwolf's comment to your answer shows. - Christian Rau

3 Answers

1
votes

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);
0
votes

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

-3
votes

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);