Example 3 - adding GLSL Texture MapsBased on the previous example we add GLSL Texture Maps. The result looks like this:
The texture is in the Texture Pack. To run this demo, you need Pyglet and Tristam Macdonald's Library Shader.py. You find everything on the installation page. Program descriptionTo display a texture on the object surface, we have to load a picture into the graphics card memory. To ease picture management, we use Pyglet-Ressources: resource.path.append('textures') resource.reindex() texturecnt = 1 We make the directory “textures” known, so it can be accessed by textureSurface = pyglet.resource.texture(texturefile) We will need more than one picture in the next example, so we use the variable “texturecnt” for loading them to main memory (a variable number of textures named “Texturemap<x>.jpg”), and to bind them to the shader program: ... texture = [] for i in range (texturecnt): texturefile = 'Texturemap' + str(i) + '.jpg' print "Loading Texture", texturefile textureSurface = pyglet.resource.texture(texturefile) texture.append( textureSurface.get_texture() ) glBindTexture(texture[i].target, texture[i].id) ... for i in range(texturecnt): glActiveTexture(GL_TEXTURE0+i) glEnable(GL_TEXTURE_2D) glBindTexture(GL_TEXTURE_2D, texture[i].id) shader.uniformi('my_color_texture[' + str(i) + ']',i ) ... The declaration in the shader program looks like this: uniform sampler2D my_color_texture['''+str(texturecnt)+''']; // 0 = ColorMap uniform int toggletexture; // false/true We have defined the shader program as a Python triple quote string, so we “interrupt” the string and insert the (static) value of “texturecnt”. In the fragment shader we can now access the color in a certain position of the image by vec4 texColor = texture2D(my_color_texture[0], gl_TexCoord[0].st); This color replaces the constant value used in the previous example - the only thing missing is now the texture coordinate to select the correct position in the picture. For this we extend the vertex data by the texture coordinate running from 0..1 for u and v: textureuvw.extend([u / (2 * pi), v / (2 * pi), 0.0]) (u and v are running from 0..2*pi for the figure generation, hence the division). This array is submitted to the vertex list generation by ... ('t3f/static', textureuvw), ... and is assigned to the standard “varying” variable “gl_TexCoord[0]” in the vertex shader: gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0 So you see why the following access gives you the texture color: vec4 texColor = texture2D(my_color_texture[0], gl_TexCoord[0].st); Switching the texture on and off is controlled by the “T”-key we have used for switching between wireframe and filled polygons in the previous example: ... elif symbol == key.T: toggletexture = not toggletexture print 'Toggle Texture ', toggletexture ... This variable is handed over to the fragment shader - if it has a value of “False”, we replace the texture color by a constant value (as in the previous example): if ( toggletexture == 0 ) texColor = gl_FrontMaterial.ambient; Now let us add Bump Mapping ! |