Reputation: 1758
I am working on an application using OpenGL ES 2.0 for an embedded device.
This is my fragment shader:
varying vec2 v_texCoord;
uniform sampler2D s_texture;
void main() {
gl_FragColor = texture2D(s_texture, v_texCoord);
}
I set up the textures properly. For some reason, calling glTexImage2D
is not producing the result I'm looking for. The texture is entirely black, rather than being filled with the data I provide it.
This is how I create the texture:
GLuint textureId;
// 2x2 Image, 3 bytes per pixel (R, G, B)
GLubyte pixels[6 * 3] =
{
255, 0, 0, // Red
0, 255, 0, // Green
0, 0, 255, // Blue
255, 255, 0, // Yellow
0, 255, 255,
255, 0, 255
};
// Use tightly packed data
glPixelStorei ( GL_UNPACK_ALIGNMENT, 1 );
// Generate a texture object
glGenTextures ( 1, &textureId );
// Bind the texture object
glBindTexture ( GL_TEXTURE_2D, textureId );
// Load the texture
glTexImage2D ( GL_TEXTURE_2D, 0, GL_RGB, 3, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels );
// Set the filtering mode
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
Afterward, I bind the texture like so:
samplerLoc = glGetUniformLocation ( userData->programObject, "s_texture" );
glActiveTexture ( GL_TEXTURE0 );
glBindTexture ( GL_TEXTURE_2D, textureId );
// Set the sampler texture unit to 0
glUniform1i ( samplerLoc, 0 );
I confirmed that the vertex and texture coordinates are bound and passed to the shaders when debugging. So, it has to be an issue with s_texture
or the glTexImage2D
function itself.
Upvotes: 2
Views: 5158
Reputation: 1681
You need to set the clamp modes to CLAMP_TO_EDGE
for both U and V dimensions, otherwise the texture is incomplete and will sample as black.
Upvotes: 9
Reputation: 812
Perhaps I'm missing something obvious but if you are storing only 2 x 2 pixels with 3 bytes per color (= 4 x 3 bytes = 12 bytes) as a texture; then where does the 6 in "GLubyte pixels[6 * 3]" come from?
6*3 equals 18 and != power of 2
// Load the texture glTexImage2D ( GL_TEXTURE_2D, 0, GL_RGB, 3, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels );
From the spec: glTexImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid * data);
Bolded vars are best a ^2...
So, try this:
// Load the texture glTexImage2D ( GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels );
Delete the last 2 rows from your pixels array, then change all values to "255"; if you get a white texture, that means it's working.
Another example:
GLubyte pixels[4 * 3] = {
255, 0, 0, //Red //Green //Blue // pixel 0
255, 0, 0, //Red //Green //Blue // pixel 1
255, 0, 0, //Red //Green //Blue // pixel 2
255, 0, 0 //Red //Green //Blue // pixel 3
};
And everything shows up red.
If that doesnt do it, perhaps my code will help :
void CMesh::renderMesh(GLuint program, glm::mat4 *mvp){
glUseProgram(program);
int mvpLocation = glGetUniformLocation(program, "matViewProjection");
int texLocation = glGetUniformLocation(program, "baseMap");
glUniformMatrix4fv( mvpLocation, 1, GL_FALSE, glm::value_ptr(*mvp));
int vertexAttribLocation = glGetAttribLocation(program, "vertex");
int uvAttribLocation = glGetAttribLocation(program, "texturecoordinate");
// Bind our texture in Texture Unit 0
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureIndex);
glUniform1i(texLocation, 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexAttribPointer(
vertexAttribLocation,
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, uvBuffer);
glVertexAttribPointer(
uvAttribLocation,
2, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// Draw the triangles !
glDrawArrays(GL_TRIANGLES, 0, vertices.size() );
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
};
Upvotes: 3