Exemplo n.º 1
0
    def testUseUsesTheShaderProgram(self, mockGl):
        program = ShaderProgram()
        program.getLinkStatus = lambda: True
        
        program.use()

        self.assertEquals(mockGl.glUseProgram.call_args, ((program.id,), {}))
Exemplo n.º 2
0
 def testUseRaisesOnLinkFailure(self):
     program = ShaderProgram()
     program.getLinkStatus = lambda: False
     program.getInfoLog = lambda: 'linkerror'
     try:
         program.use()
         self.fail('should raise')
     except LinkError, e:
         self.assertTrue('linkerror' in str(e))
Exemplo n.º 3
0
    def testUseCreatesProgram(self, mockGl):
        mockGl.glCreateProgram.return_value = 123
        program = ShaderProgram()
        program.getLinkStatus = lambda: True
        
        program.use()

        self.assertTrue(mockGl.glCreateProgram.called)
        self.assertEquals(program.id, 123)
Exemplo n.º 4
0
def install_shaders(fragment, vertex):
    fsrc = read_source(fragment)
    fshader = FragmentShader([fsrc])

    vsrc = read_source(vertex)
    vshader = VertexShader([vsrc])

    shader = ShaderProgram(fshader, vshader)
    shader.use()
Exemplo n.º 5
0
    def testUseCompilesAndAttachesShaders(self, mockGl):
        shader1 = Mock()
        shader2 = Mock()
        program = ShaderProgram(shader1, shader2)
        program.id = 123
        program._getMessage = DoNothing
        program.getLinkStatus = lambda: True
        
        program.use()

        self.assertEquals(shader1.compile.call_args, (tuple(), {}))
        self.assertEquals(shader2.compile.call_args, (tuple(), {}))
        self.assertEquals(mockGl.glAttachShader.call_args_list, [
            ((program.id, shader1.id), {}),
            ((program.id, shader2.id), {}),
        ])
Exemplo n.º 6
0
    def testUseReturnsConcatenatedMessages(self):
        shader1 = Mock()
        shader2 = Mock()
        shader1.getInfoLog = lambda: 's1'
        shader2.getInfoLog = lambda: 's2'
        program = ShaderProgram(shader1, shader2)
        program.getInfoLog = lambda: 'p0'
        program.getLinkStatus = lambda: True

        message = program.use()

        self.assertEquals(message, 's1\ns2\np0')
Exemplo n.º 7
0
class Ocean():
    def __init__(   self,
                    camera,
                    cubemap=None,
                    scale=1.0,
                    tileSize=128,
                    tilesX=1,
                    tilesZ=1,
                    depth=30.0,
                    waveHeight=3.125e-5,
                    wind=Vector2(64.0,128.0),
                    period=10.0,
                    photonScale=4.0,
                    photonIntensity=2.0):
                    
                    
        if cubemap:
            self.cubemapTexture = cubemap.texture
        else:
            self.cubemapTexture = None
            
        self.wind = wind                    # Ocean wind in X,Z axis
        self.waveHeight = waveHeight        # The phillips spectrum parameter
        self.oceanDepth = depth
        self.period = period                # Period of ocean surface anim
        self.drawSeaSurface = True
        self.drawSeaFloor = True
        self.enableCaustics = True
        self.photonIntensity = photonIntensity
        self.photonScale = photonScale
        
        self.tileSize = tileSize
        self.tilesX = tilesX
        self.tilesZ = tilesZ
        self.length = tileSize              # Ocean length parameter
        self.camera = camera
        self.scale = scale

        self.surfaceShader = shader.openfiles(  'shaders/ocean.vertex',
                                                'shaders/ocean.fragment')
        self.groundShader = shader.openfiles(   'shaders/oceanfloor.vertex',
                                                'shaders/oceanfloor.fragment')

        self.oceanFloorTexture = image.load('images/tiles.png').get_texture() 
        
        
        # Caustic texture
        self.causticTexture = image.DepthTexture.create_for_size(GL_TEXTURE_2D, 
                                                            self.tileSize, 
                                                            self.tileSize,
                                                            GL_RGBA)
        
        # Use Tessendorf FFT synthesis to create a convincing ocean surface.
        self.heightfield = Tessendorf(  self.tileSize,
                                        self.waveHeight, 
                                        self.wind,
                                        self.length,
                                        self.period)
                                           
        # The water surface
        self.surface = Surface( self.surfaceShader,
                                self.camera,
                                texture=self.oceanFloorTexture,
                                causticTexture=self.causticTexture,
                                cubemapTexture=self.cubemapTexture,
                                heightfield=self.heightfield,
                                tileSize=self.tileSize, 
                                tilesX=self.tilesX,
                                tilesZ=self.tilesZ,
                                scale=self.scale, 
                                offset=Vector3(0.0,self.oceanDepth,0.0))
                                
        # The caustics engine, uses the water surface to generate a caustic tex                      
        self.caustics = Caustics (  self.camera,
                                    self.surface,
                                    self.oceanDepth,
                                    self.causticTexture,
                                    self.photonScale,
                                    self.photonIntensity,
                                 )
        
        # The sea bed, an undisturbed mesh
        self.ground = Surface( self.groundShader,
                                self.camera,
                                texture=self.oceanFloorTexture,
                                causticTexture=self.causticTexture,
                                heightfield=None,
                                tileSize=1, 
                                tilesX=self.tilesX,
                                tilesZ=self.tilesZ,
                                scale=self.scale * self.tileSize, 
                                offset=Vector3(0.0,0.0,0.0))
                                
    def reloadShaders(self):
        from shader import FragmentShader, ShaderError, ShaderProgram, VertexShader
        
        def read_source(fname):
            f = open(fname)
            try:
                src = f.read()
            finally:
                f.close()
            return src
            
        fsrc = read_source('shaders/ocean.fragment')
        fshader = FragmentShader([fsrc])
        vsrc = read_source('shaders/ocean.vertex')
        vshader = VertexShader([vsrc])

        self.surfaceShader = ShaderProgram(fshader, vshader)
        self.surfaceShader.use()
        
        fsrc = read_source('shaders/oceanfloor.fragment')
        fshader = FragmentShader([fsrc])
        vsrc = read_source('shaders/oceanfloor.vertex')
        vshader = VertexShader([vsrc])

        self.groundShader = ShaderProgram(fshader, vshader)
        self.groundShader.use()

        self.surface.setShader(self.surfaceShader)
        self.ground.setShader(self.groundShader)
        
    def setCausticPhotonIntensity(self, intensity):
        self.photonIntensity = intensity
        self.caustics.photonIntensity = self.photonIntensity
    def setCausticPhotonScale(self, scale):
        self.photonScale = scale
        self.caustics.photonScale = self.photonScale
                                
    def setDepth(self, depth):
        self.oceanDepth = depth
        self.caustics.setDepth(self.oceanDepth)
        self.surface.setDepth(self.oceanDepth)
    
    def resetHeightfield(self):
        '''
        Recreate the heightfield engine with new initial parameters, this is
        required for heightfield engines such as Tessendorf as lookup tables
        are generated upon creation based on input paramters
        '''
        del self.heightfield
        self.heightfield = Tessendorf(  self.tileSize,
                                        self.waveHeight, 
                                        self.wind,
                                        self.length,
                                        self.period)
        self.surface.setHeightfield( self.heightfield)   
        
    def setWind(self, wind):
        self.wind = wind      
        self.resetHeightfield()
    def setWaveHeight(self, waveHeight):
        self.waveHeight = waveHeight                        
        self.resetHeightfield()  

    def draw(self,dt):
        if self.drawSeaSurface:
            self.surface.draw(dt)
        if self.drawSeaFloor:
            if self.enableCaustics:
                self.caustics.update(dt)
            self.ground.draw(dt)