[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] GLSL Texturing example ? (and ctypes...?)



JoN wrote:

Sorry I should have clarified.

I got that demo working fine, but then tried to modify it to do texturing and
didn't get very far.
What I am having problems with is the operations to set the active texture.
I've been using some NeHe demo code to bind 2D textures just fine and have been
happily texturing quads using python opengl.

However, I am new to ctypes, which does really look like the way to go.


Here's a modification to the first GLSL (coloured teapot, GL 1.5/2.0) example.

To load the texture data (nothing GLSLy or ctypesy here): (make sure your texture dimensions are powers of 2)

   import pygame.image
   image = pygame.image.load('kitten.png')
   glEnable(GL_TEXTURE_2D)
   texture = glGenTextures(1)
   glBindTexture(GL_TEXTURE_2D, texture)
   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
                image.get_width(), image.get_height(),
                0, GL_RGBA, GL_UNSIGNED_BYTE,
                pygame.image.tostring(image,'RGBA', True))
   glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
   glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)

Get two more functions out of libGL using ctypes:

   glGetUniformLocation = gl.glGetUniformLocation
   glUniform1i = gl.glUniform1i

Add a uniform sampler2D to the fragment shader, and make it modulate the colour with the texture:
// Fragment program
varying vec3 pos;
uniform sampler2D texture;
void main() {
gl_FragColor.rgb = pos.xyz * tex2D(texture, gl_TexCoord[0].xy).rgb;
}


The vertex program needs to pass the texture coordinates through: (should multiply by the texture matrix here, but we don't care about that)
// Vertex program
varying vec3 pos;
void main() {
pos = gl_Vertex.xyz;
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}


Get the location of the uniform sampler2D in Python (if it's -1, you've done something wrong).
texture_param = glGetUniformLocation(program, "texture");


Set the sampler to use the first texture unit (0):
   glUseProgram(program)
   glUniform1i(texture_param, 0);
   glutSolidTeapot(1.0)

One kittened teapot.

Alex.