PDA

View Full Version : All textures are black



neon29
11-18-2016, 08:17 AM
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.

Grognard
11-18-2016, 09:30 AM
Usually means the textures could not be found basically. So you have sent in zeroed out mem which turns out to be black.

GClements
11-18-2016, 10:09 AM
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)



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.



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


Maybe from




ivec2 uv = ivec2(value % 0x100, value / 0x100);



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

neon29
11-18-2016, 01:38 PM
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.