Pythonstuff GLSL in English Pythonstuff GLSL auf Deutsch Pythonstuff GLSL Pythonstuff
PythonStuff Home
 

 

Example 3 - adding GLSL Texture Maps

Based on the previous example we add GLSL Texture Maps.

The result looks like this:

Texture Mapped Torus Texture Mapped Torus - moved the light Texture Mapped Sphere

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 description

To 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 !


Deutschsprachige Version, Start
Impressum & Disclaimer