Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 6 of 6

Thread: GLSL texture2D() always returning black

  1. #1
    Junior Member Newbie
    Join Date
    Jul 2012
    Posts
    5

    GLSL texture2D() always returning black

    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.

    Code :
    #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?

  2. #2
    Junior Member Newbie
    Join Date
    Mar 2011
    Posts
    14
    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.

  3. #3
    Junior Member Newbie
    Join Date
    Jul 2012
    Posts
    5
    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?

  4. #4
    Junior Member Newbie
    Join Date
    Jul 2012
    Posts
    5
    GL_REPEAT and GL_MIRRORED_REPEAT only work on power-of-two textures.

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

  5. #5
    Senior Member OpenGL Guru
    Join Date
    May 2009
    Posts
    4,948
    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.

  6. #6
    Super Moderator OpenGL Guru
    Join Date
    Feb 2000
    Location
    Montreal, Canada
    Posts
    4,264
    My guess is that he isn't using opengl at all. He is using opengl es.
    ------------------------------
    Sig: http://glhlib.sourceforge.net
    an open source GLU replacement library. Much more modern than GLU.
    float matrix[16], inverse_matrix[16];
    glhLoadIdentityf2(matrix);
    glhTranslatef2(matrix, 0.0, 0.0, 5.0);
    glhRotateAboutXf2(matrix, angleInRadians);
    glhScalef2(matrix, 1.0, 1.0, -1.0);
    glhQuickInvertMatrixf2(matrix, inverse_matrix);
    glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
    glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •