Here is an example (using glut but it should be quite simple to adapt to 
pyglet).

The texture to be colorized is "texture" within the shader
The lookup color table is "lut".

You can also have a look at glumpy where I use this "trick" a lot.
Hope that helps.


Nicolas




On Aug 13, 2013, at 12:43 AM, Fred <[email protected]> wrote:

> Hello,
> 
> on a previous thread, I mentionned my unsuccessful attempts at making a 
> cycling palette effect at a decent framerate (by generating all images at 
> every steps in the palette shifting and using sprites). 
> 
> I've looked at some OpenGL discussions on the subject and the most seen 
> answer is to use a Fragment Shader that takes 2 Textures, one containing 
> the palette (let's say my_palette) and the other containing the indexed map 
> (in 'One Byte Per Pixel' format, for example GL_RED ; let's call it 
> my_indexed_image), to compute the resulting output color (see 
> http://www.opengl.org/wiki/Common_Mistakes#Paletted_textures).
> 
> I've looked for examples of use of shaders with pyglet and managed to use 
> simple ones, passing parameters through "uniform vecx".
> 
> But, if I understood correctely (which may not be the case, it's my first 
> insights in OpenGL, and documentation available on the net is often 
> contradictory since it doesn't always concern the same versions of OpenGL), 
> I must first create a texture with the indexed image in GL_RED format.
> 
> I've tried something like that :
> 
> image, palette = load_bmp('bridge.bmp')
> 
> indexed_image = pyglet.image.ImageData(512, 512, 'R', image.flatten())
> indexed_texture = indexed_image.get_texture()
> 
> load_bmp is a custom fonction, reading an indexed bmp file and returning 
> both image (a numpy.array with shape (512, 512), dtype = uint8) and palette 
> (a numpy.array with shape (256, 4), dtype = uint8).
> 
> But it does not work :
> 
> Traceback (most recent call last):
>  File 
> "C:\Users\Tryphon\Documents\workspace\pyglet-shaders\demo\cycling.py", line 
> 39, in <module>
>    indexed_texture = indexed_image.get_texture()
>  File "C:\Python27\lib\site-packages\pyglet\image\__init__.py", line 801, 
> in get_texture
>    force_rectangle)
>  File "C:\Python27\lib\site-packages\pyglet\image\__init__.py", line 792, 
> in create_texture
>    self.anchor_x, self.anchor_y, 0, None)
>  File "C:\Python27\lib\site-packages\pyglet\image\__init__.py", line 972, 
> in blit_to_texture
>    data)
> ctypes.ArgumentError: argument 9: <type 'exceptions.TypeError'>: wrong type
> 
> Can someone point me what the problem is ?
> 
> Thanks in advance !
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "pyglet-users" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at http://groups.google.com/group/pyglet-users.
> For more options, visit https://groups.google.com/groups/opt_out.
> 
> 

import os, sys, ctypes
import numpy as np
import OpenGL.GL as gl
import OpenGL.GLUT as glut


class ShaderException(Exception):
    pass

class Shader:
    def __init__(self, vertex_code = None, fragment_code = None):
        self.uniforms = {}
        self.handle = gl.glCreateProgram()
        self.linked = False
        self._build_shader(vertex_code, gl.GL_VERTEX_SHADER)
        self._build_shader(fragment_code, gl.GL_FRAGMENT_SHADER)
        self._link()

    def _build_shader(self, strings, shader_type):
        count = len(strings)
        if count < 1: 
            return
        shader = gl.glCreateShader(shader_type)
        gl.glShaderSource(shader, strings)
        gl.glCompileShader(shader)
        status = gl.glGetShaderiv(shader, gl.GL_COMPILE_STATUS)
        if not status:
            if shader_type == gl.GL_VERTEX_SHADER:
                raise (ShaderException, 
                       'Vertex compilation: ' + gl.glGetShaderInfoLog(shader))
            elif shader_type == gl.GL_FRAGMENT_SHADER:
                raise (ShaderException,
                       'Fragment compilation:' + gl.glGetShaderInfoLog(shader))
            else:
                raise (ShaderException,
                           gl.glGetShaderInfoLog(shader))
        else:
            gl.glAttachShader(self.handle, shader)

    def _link(self):
        gl.glLinkProgram(self.handle)
        temp = ctypes.c_int(0)
        gl.glGetProgramiv(self.handle, gl.GL_LINK_STATUS, ctypes.byref(temp))
        if not temp:
            gl.glGetProgramiv(self.handle,
                              gl.GL_INFO_LOG_LENGTH, ctypes.byref(temp))
            log = gl.glGetProgramInfoLog(self.handle)
            raise(ShaderException, 'Linking: '+ log)
        else:
            self.linked = True

    def bind(self):
        gl.glUseProgram(self.handle)

    def unbind(self):
        gl.glUseProgram(0)

    def uniformf(self, name, *vals):
        loc = self.uniforms.get(name, gl.glGetUniformLocation(self.handle,name))
        self.uniforms[name] = loc
        if len(vals) in range(1, 5):
            { 1 : gl.glUniform1f,
              2 : gl.glUniform2f,
              3 : gl.glUniform3f,
              4 : gl.glUniform4f
            }[len(vals)](loc, *vals)

    def uniformi(self, name, *vals):
        loc = self.uniforms.get(name, gl.glGetUniformLocation(self.handle,name))
        self.uniforms[name] = loc
        if len(vals) in range(1, 5):
            { 1 : gl.glUniform1i,
              2 : gl.glUniform2i,
              3 : gl.glUniform3i,
              4 : gl.glUniform4i
            }[len(vals)](loc, *vals)

    def uniform_matrixf(self, name, mat):
        loc = self.uniforms.get(name, gl.glGetUniformLocation(self.handle,name))
        self.uniforms[name] = loc
        gl.glUniformMatrix4fv(loc, 1, False, (ctypes.c_float * 16)(*mat))



def display():
    gl.glClearColor(1,1,1,1)
    gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)

    gl.glEnable(gl.GL_BLEND)
    gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
    gl.glColor(1,1,1,1)

    gl.glEnable( gl.GL_TEXTURE_1D )
    gl.glActiveTexture( gl.GL_TEXTURE1 )
    gl.glBindTexture( gl.GL_TEXTURE_1D, lut_id)

    gl.glEnable( gl.GL_TEXTURE_2D )
    gl.glActiveTexture( gl.GL_TEXTURE0 )
    gl.glBindTexture( gl.GL_TEXTURE_2D, image_id)

    # gl.glTexSubImage2D (gl.GL_TEXTURE_2D, 0, 0, 0,
    #                     512, 512, gl.GL_ALPHA, gl.GL_FLOAT, image)

    shader.bind()
    shader.uniformi('texture', 0)
    shader.uniformi('lut', 1)
    gl.glBegin(gl.GL_QUADS)
    gl.glTexCoord2f(0, 1), gl.glVertex2i(0,   0)
    gl.glTexCoord2f(0, 0), gl.glVertex2i(0,   512)
    gl.glTexCoord2f(1, 0), gl.glVertex2i(512, 512)
    gl.glTexCoord2f(1, 1), gl.glVertex2i(512, 0)
    gl.glEnd()
    shader.unbind()

    glut.glutSwapBuffers()

def reshape(width,height):
    gl.glViewport(0, 0, width, height)
    gl.glMatrixMode(gl.GL_PROJECTION)
    gl.glLoadIdentity()
    gl.glOrtho(0, width, 0, height, -1, 1)
    gl.glMatrixMode(gl.GL_MODELVIEW)

def keyboard( key, x, y ):
    if key == '\033':
        sys.exit( )


if __name__ == '__main__':
    glut.glutInit(sys.argv)
    glut.glutInitDisplayMode(glut.GLUT_DOUBLE | glut.GLUT_RGBA | glut.GLUT_DEPTH)
    glut.glutCreateWindow('glut-colorizer')
    glut.glutReshapeWindow(512,512)
    glut.glutDisplayFunc(display)
    glut.glutReshapeFunc(reshape)
    glut.glutKeyboardFunc(keyboard )

    fragment = """
        uniform sampler2D texture; 
        uniform sampler1D lut; 
        void main() 
        { 
            vec2 uv = gl_TexCoord[0].xy; 
            vec4 color = texture2D(texture, uv); 
            gl_FragColor = texture1D(lut,color.a); 
        }"""
    vertex = """
        void main()
        {
            gl_FrontColor = gl_Color;
            gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;
            gl_Position = gl_ModelViewProjectionMatrix*gl_Vertex;
        }"""

    shader = Shader(vertex,fragment)

    # Image to be displayed
    image = np.random.uniform(0,1,(64,64)).astype(np.float32)

    image_id = gl.glGenTextures(1)
    gl.glEnable(gl.GL_TEXTURE_2D)
    gl.glBindTexture(gl.GL_TEXTURE_2D, image_id)
    gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_ALPHA, 64, 64, 0,
                    gl.GL_ALPHA, gl.GL_FLOAT, image)
    gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST)
    gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_NEAREST)

    # Color lookup table (R,G,B)
    lut = np.zeros((512,3)).astype(np.float32)
    lut[:,0] = np.linspace(0,1,512)
    lut[:,1] = np.linspace(1,0,512)
    lut[:,2] = .5
    lut_id = gl.glGenTextures(1)
    gl.glEnable(gl.GL_TEXTURE_1D)
    gl.glBindTexture(gl.GL_TEXTURE_1D, lut_id)
    gl.glTexImage1D(gl.GL_TEXTURE_1D, 0, gl.GL_RGB, 512, 0,
                    gl.GL_RGB, gl.GL_FLOAT, lut)
    gl.glTexParameterf(gl.GL_TEXTURE_1D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST)
    gl.glTexParameterf(gl.GL_TEXTURE_1D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_NEAREST)

    glut.glutMainLoop()
-- 
You received this message because you are subscribed to the Google Groups 
"pyglet-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/pyglet-users.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to