PDA

View Full Version : GLSL texture2D() always returning black



jbates
08-16-2012, 02:35 PM
I'm having a heck of a time getting GLSL texture sampling to work. The two most common reasons I've come across in Google searches are not setting minification/magnification filters and mixing up GL_TEXTURE0-based indices with 0-based indices. But I'm not making either of those mistakes.


#include <string.h>

#include <OpenGLES/ES2/gl.h>

#define SHADER_SOURCE(text) "#version 100\n" #text


GLubyte textureData[4][320][460];

const char* vertexShaderSource = SHADER_SOURCE(
attribute vec2 vertexPosition;
void main() {
gl_Position = vec4(vertexPosition, 0, 1);
}
);

const char* fragmentShaderSource = SHADER_SOURCE(
precision highp float;

uniform vec2 screenSize;
uniform sampler2D sampler;

void main() {
vec2 texCoord = gl_FragCoord.xy / screenSize;
gl_FragColor = texture2D(sampler, texCoord);
}
);

const float screenCorners[] = {
-1.0f, -1.0f,
1.0f, -1.0f,
1.0f, 1.0f,
-1.0f, 1.0f,
};


void drawScene(int screenWidth, int screenHeight) {
GLuint texture;
glGenTextures(1, &texture);

glBindTexture(GL_TEXTURE_2D, texture);
memset(textureData, 0xFF, 4*320*460);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, screenWidth, screenHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, 0);

//

glEnableVertexAttribArray(0);

GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
int sourceLength = strlen(vertexShaderSource);
glShaderSource(vertexShader, 1, &vertexShaderSource, &sourceLength);
glCompileShader(vertexShader);

GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
sourceLength = strlen(fragmentShaderSource);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, &sourceLength);
glCompileShader(fragmentShader);

GLuint program = glCreateProgram();
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
glBindAttribLocation(program, 0, "vertexPosition");
glLinkProgram(program);

GLuint screenSizeUniformLocation = glGetUniformLocation(program, "screenSize");
GLuint samplersUniformLocation = glGetUniformLocation(program, "sampler");

//

glUseProgram(program);
glViewport(0, 0, screenWidth, screenHeight);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);

glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, screenCorners);
glUniform2f(screenSizeUniformLocation, screenWidth, screenHeight);
glUniform1i(samplersUniformLocation, 0);

glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}

I'd expect this code to fill the screen with white pixels, but it's filling the screen with black. If I replace the fragment shader's texture2D() call with a constant color, the screen fills with that color as expected. What am I missing?

Aumnayan
08-16-2012, 02:49 PM
Try adding the following:

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

Change GL_CLAMP_TO_EDGE to whatever behavior you want. I had the same problem a while back and specifying the desired behaviour in this regard seamed to fix it.

jbates
08-16-2012, 03:11 PM
GL_CLAMP_TO_EDGE seems to make ti work but GL_REPEAT and GL_MIRRORED_REPEAT don't. I wonder why those don't work?

jbates
08-16-2012, 03:16 PM
GL_REPEAT and GL_MIRRORED_REPEAT only work on power-of-two textures.

Wow, I spent way too much time on this problem. Thanks.

Alfonse Reinheart
08-16-2012, 07:44 PM
GL_REPEAT and GL_MIRRORED_REPEAT only work on power-of-two textures.

That's not true at all. They don't work on rectangle textures, but there's no problem with using them on 2D NPOTs.

V-man
08-17-2012, 04:52 AM
My guess is that he isn't using opengl at all. He is using opengl es.