All textures are black

Today, I have tried to launch an OpenGL code which worked pretty well few months ago. However, now, all my textures appear in black while I am (almost) sure it worked well when I left it (I hope I am wrong!).

There is no problem for the vertices, just the textures.

Here are my vertex and fragment shaders:


VERTEX_SHADER = """
#version 440 core

uniform mat4 Model;
uniform mat4 View;
uniform mat4 Projection;

in vec2 position;
in vec2 texcoord;

out vec2 Texcoord;


void main()
{
    gl_Position =  Projection*View*Model*vec4(position, 0.0, 1.0);
    Texcoord = texcoord;

}
 """

FRAGMENT_SHADER_WATERFALL = """
#version 440 core

in vec2 Texcoord;
uniform usampler2D texSonar;
uniform sampler2D transcodMap;
out vec4 fragColor;

void main()
{
    // retrieve 16-bits value
    
    uint value = texture(texSonar, Texcoord).x;
    // find out the corresponding uv coordinates in the colormap
    ivec2 uv = ivec2(value % 0x100, value / 0x100);
    // apply it
    vec4 tmp = texelFetch(transcodMap, uv, 0);
    fragColor = vec4(tmp.rgb, 1);

} """


transcodMap is a 256*256 image where each of the 65535 pixels the (R, G, B) color to assign to a given pixel.

My PaintGL method which call the renderWaterfall one:


 def paintGL(self):

        # Every time the paintGL (or updateGL which call the paintGL one) method is called,
        # we need to reload the View matrix to ensure that the right one is taken into
        # into account, as the two GL widgets share the same context.
        # loc = glGetUniformLocation(self.shaderProgram, 'View')
        # glUniformMatrix4fv(loc, 1, False, np.ascontiguousarray(self.matView.T))
        # loc = glGetUniformLocation(self.shaderProgram, 'Projection')
        # glUniformMatrix4fv(loc, 1, False, np.ascontiguousarray(self.matProj.T))

        # print('paintGL CALL from %s'%str(type(self)))

        self.viewport = fn.viewport(0, 0, self.width(), self.height())
        glUseProgram(self.program.programId())
        glClearColor(0, 0, 1, 1)
        
        # to ensure vertices are OK
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
        glEnable(GL_DEPTH_TEST)

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        glEnable(GL_BLEND)
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

        if np.array(self.objects).size:

            #print('there are %i objects' % (len(self.objects)))
            # active shader program
            self.objects[0].renderWaterfall(self.program.programId())

            glBindBuffer(GL_ARRAY_BUFFER, 0)
            glBindTexture(GL_TEXTURE_2D, 0)
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)
            glUseProgram(0)

            if self.boolCursor:
                self.updateCursor()



        else:
            if self.boolCursor:
                self.updateCursor()


The renderWaterfall() method consists in iterating over all the tiles to display them:


def renderWaterfall(self, programID):
        
        glActiveTexture(GL_TEXTURE1)
        glBindTexture(GL_TEXTURE_2D, self.colormapBuffer)
        glUniform1i(glGetUniformLocation(programID, 'transcodMap'), 0)

        # only display the first tile for debugging purpose
        for i, tile in enumerate(self.tileList[0:1]):
#            print('Buffer info: Position: %i | Texcoord: %i | '
#                  'Texture: %i | Indices: %i' %(tile.VBO[0], tile.VBO[1], tile.TBO, tile.EBO))
            #print(obj.indices)
            loc_pos = glGetAttribLocation(programID, "position")
            glEnableVertexAttribArray(loc_pos)
            glBindBuffer(GL_ARRAY_BUFFER, tile.VBO[0])
            glVertexAttribPointer(loc_pos, 2, GL_DOUBLE, False, 0, ctypes.c_void_p(0))

            loc_uv = glGetAttribLocation(programID, "texcoord")
            glEnableVertexAttribArray(loc_uv)
            glBindBuffer(GL_ARRAY_BUFFER, tile.VBO[1])
            glVertexAttribPointer(loc_uv, 2, GL_DOUBLE, False, 0, ctypes.c_void_p(0))

            glActiveTexture(GL_TEXTURE0)
            glBindTexture(GL_TEXTURE_2D, tile.TBO)
            glUniform1i(glGetUniformLocation(programID, 'texSonar'), 0)

            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tile.EBO)
            
            glDrawElements(GL_TRIANGLES, tile.indices.size, GL_UNSIGNED_INT, ctypes.c_void_p(0))
            
            glDisableVertexAttribArray(loc_pos)
            glDisableVertexAttribArray(loc_uv)



Before requesting displaying, I (of course) fill my Tile objects. An example is given below, where vertices, uv_coordinates, indices and the texture tile are already computed:


glBindBuffer(GL_ARRAY_BUFFER, tileObj.VBO[0])
                glBufferData(GL_ARRAY_BUFFER, vertices.nbytes, vertices, GL_DYNAMIC_DRAW)

                glBindBuffer(GL_ARRAY_BUFFER, tileObj.VBO[1])
                glBufferData(GL_ARRAY_BUFFER, uv_coordinates.nbytes, uv_coordinates, GL_DYNAMIC_DRAW)

                glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tileObj.EBO)
                glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.nbytes, indices, GL_DYNAMIC_DRAW)

                glBindTexture(GL_TEXTURE_2D, tileObj.TBO)
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)

                img_data = np.ascontiguousarray(tile.flatten(), dtype=np.uint16)
                glTexImage2D(GL_TEXTURE_2D, 0, GL_R16UI, tile.shape[0], tile.shape[1], 0, GL_RED_INTEGER,
                             GL_UNSIGNED_SHORT, img_data)                             
                      

                # unbind buffers
                glBindBuffer(GL_ARRAY_BUFFER, 0)
                glBindTexture(GL_TEXTURE_2D, 0)
                glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)


I do not manage to see what could explain the fact that I am unable to display textures.

EDIT:

I’ve just noticed that removing the following line (which fills the texture buffer):


glTexImage2D(GL_TEXTURE_2D, 0, GL_R16UI, tile.shape[0], tile.shape[1], 0, GL_RED_INTEGER,
                             GL_UNSIGNED_SHORT, img_data)

has no effect i.e. no error which seems strange…

Moreover, I got an “implicit cast from int to uint” in the fragment shader but I can’t see where.

Usually means the textures could not be found basically. So you have sent in zeroed out mem which turns out to be black.

It makes no sense to enable linear filtering for an integer texture. Set both filters to GL_NEAREST. I’m not sure if that’s related to your problem though.

Maybe from

Try 0x100U instead. But that won’t be related to your problem.

I have tried replacing GL_LINEAR by GL_NEAREST and 0x100 by 0x100U but I still get no textures. I have also displayed the textures with Matplotlib with no problem.

You can refer to this post: https://www.opengl.org/discussion_boards/showthread.php/198213-Apply-my-own-colormap-in-the-fragment-shader, to understand the goal of my fragment shader.