コード例 #1
0
 def __init__( self, dimensions ):
     super( GOL_Renderable, self ).__init__( "GOL_Renderable" )
     
     self.dt = 0.0
     self.shader = Shader(
         vert = GOL_Renderable.vertex_shader,
         frag = GOL_Renderable.fragment_shader
         )
     
     # create an FBO texture
     # convert our image to a texture
     self.texture = ShaderGeneratedTexture(
         self.shader,
         dimensions,
         texture1 = self.create_initial_texture( dimensions ).get_texture()
         )
コード例 #2
0
class GOL_Renderable( RenderNode ):
    vertex_shader = """
void main()
{
    gl_Position    = gl_ModelViewProjectionMatrix * gl_Vertex;
    gl_FrontColor  = gl_Color;
    gl_TexCoord[0] = gl_MultiTexCoord0;
}
"""
    
    fragment_shader = """
#version 120

// inputs
uniform sampler2D tex0;
uniform vec2 dimensions;

void main()
{
    // retrieve the texture coordinate
    vec2 tc = gl_TexCoord[0].xy;
    
    // convert from 0.0 -> 1.0 to texel
    vec2 texel_frac = tc * dimensions;
    
    // ignore the fractional part
    // convert back to texture coord
    float x = floor( texel_frac.x ) / dimensions.x;
    float y = floor( texel_frac.y ) / dimensions.y;
    
    vec2 texel = vec2( x, y );
    float cell_width = 1.0 / dimensions.x;
    float cell_height = 1.0 / dimensions.y;

    // get the current texel
    float current = texture2D(tex0, vec2( x, y ) ).r;
    
    //gl_FragColor = vec4( texture2D(tex0, vec2( x, y ) ).rgb, 1.0 );
    //return;

    // count the neightbouring pixels with a value greater than zero
    float neighbours = 0.0;
    neighbours += texture2D(tex0, texel + vec2( 0.0,       -cell_height ) ).r;
    neighbours += texture2D(tex0, texel + vec2( cell_width,-cell_height ) ).r;
    neighbours += texture2D(tex0, texel + vec2( cell_width, 0.0 ) ).r;
    neighbours += texture2D(tex0, texel + vec2( cell_width, cell_height ) ).r;
    neighbours += texture2D(tex0, texel + vec2( 0.0,        cell_height ) ).r;
    neighbours += texture2D(tex0, texel + vec2(-cell_width, cell_height ) ).r;
    neighbours += texture2D(tex0, texel + vec2(-cell_width, 0.0 ) ).r;
    neighbours += texture2D(tex0, texel + vec2(-cell_width, -cell_height ) ).r;
    
    // apply the rules    
    
    // 1. Any live cell with fewer than two live neighbours dies, as if caused by under-population.
    if ( neighbours < 2.0 )
    {
        gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );
        return;
    }
    
    // 2. Any live cell with two or three live neighbours lives on to the next generation.
    if ( neighbours >= 2.0 && neighbours <= 3.0 && current == 1.0 )
    {
        gl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );
        return;
    }
    
    // 3. Any live cell with more than three live neighbours dies, as if by overcrowding.
    if ( neighbours > 3.0 )
    {
        gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );
        return;
    }
    
    // 4. Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.
    if ( neighbours == 3.0 && current == 0.0 )
    {
        gl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );
        return;
    }
    
    gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );
}
"""

    def __init__( self, dimensions ):
        super( GOL_Renderable, self ).__init__( "GOL_Renderable" )
        
        self.dt = 0.0
        self.shader = Shader(
            vert = GOL_Renderable.vertex_shader,
            frag = GOL_Renderable.fragment_shader
            )
        
        # create an FBO texture
        # convert our image to a texture
        self.texture = ShaderGeneratedTexture(
            self.shader,
            dimensions,
            texture1 = self.create_initial_texture( dimensions ).get_texture()
            )

    def create_initial_texture( self, dimensions ):
        # we need RGBA textures
        # which is 4 bytes
        format_size = 4
        
        # populate our GoL board with some random data
        #numpy.random.seed( 0 )
        data = numpy.random.random_integers(
            low = 0,
            high = 1,
            size = (dimensions[ 0 ] * dimensions[ 1 ], format_size)
            )
        
        # convert any 1's to 255
        data *= 255
        
        # set the GBA (from RGBA) to 0
        data[ :, 1: ] = 0
        data[ :, 3 ] = 255
        
        # we need to flatten the array
        data.shape = -1
        
        # convert to GLubytes
        tex_data = (GLubyte * data.size)( *data.astype('u1') )
        
        # create an image
        return pyglet.image.ImageData(
                dimensions[ 0 ],
                dimensions[ 1 ],
                "RGBA",
                tex_data,
                pitch = dimensions[ 1 ] * format_size
                )
    
    def render_mesh( self ):
        # check if we should iterate
        #while self.dt >= 1.0:
        if True:
            # render our FBO
            self.texture.bind()
            
            # use texture layer 0
            self.texture.shader.uniformi('tex0', 0)
            
            # pass in the texture dimensions
            self.texture.shader.uniformf(
                'dimensions',
                float( self.texture.dimensions[ 0 ] ),
                float( self.texture.dimensions[ 1 ] )
                )
            
            # render to texture
            self.texture.render()

            # reset our opengl state
            self.texture.unbind()
            
            self.dt -= 1.0
        
        # use the result of the FBO as a texture
        glBindTexture( self.texture.texture.target, self.texture.texture.id )
        
        # disable texture filtering
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST )
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST )
        
        # render a quad at 0,0,0
        glBegin( GL_QUADS )
        
        x_size, y_size = 5, 5

        glTexCoord2f( 0.0, 0.0 )        
        glVertex3f(-x_size,-y_size, 0.0 )
        
        glTexCoord2f( 1.0, 0.0 )
        glVertex3f( x_size,-y_size, 0.0 )
        
        glTexCoord2f( 1.0, 1.0 )
        glVertex3f( x_size, y_size, 0.0 )
        
        glTexCoord2f( 0.0, 1.0 )
        glVertex3f(-x_size, y_size, 0.0 )
        
        glEnd()
        
        # unbind our texture
        glBindTexture( self.texture.texture.target, 0 )