
"""This sample demonstrates some very simple lightning effects."""

import math

import d3d11
import d3d11x
from d3d11c import *

def heightCallback(x, z, byteIndex, data):
    return data[byteIndex] * 0.03

class SampleLights(d3d11x.Frame):
    def onCreate(self):
        #Heightmap.
        #self.heightmap = d3d11x.HeightMap(self.device, None, (64, 64), heightCallback, (2, 1, 2), (8, 8), False)
        self.heightmap = d3d11x.HeightMap(self.device, d3d11x.getResourceDir("Textures", "heightmap.dds"), 
            (64, 64), heightCallback, (2, 1, 2), (8, 8), False)
        
        self.heightmap.textureView = self.loadTextureView("ground-marble.dds")

        #Sphere mesh.
        meshPath = d3d11x.getResourceDir("Mesh", "sphere.obj")
        self.sphere = d3d11x.Mesh(self.device, meshPath)
        self.sphere.textureView = self.loadTextureView("misc-white.bmp")
        
    def createLights(self):
        #Add 7 lights (maximum defined in 'Shared.fx').
        lights = []
        for i in range(1, 8): 
            #Each light is little farther than the previous one.
            distance = i * 5
            lightTime = self.time * (i * 0.5)
            #Use sin() and cos() to create a nice little movement pattern.
            x = math.sin(lightTime) * distance
            z = math.cos(lightTime) * distance
            y = self.heightmap.getHeight(x, z)
            pos = d3d11.Vector(x, y + 1,  z)
            #Set color (RGBA) (from 0.0 to 1.0). 30.0 is just a magic value which looks good.
            red = i / 30.0
            green = (7 - i) / 30.0
            color = (red, green, 0, 0)
            lights.append((pos, color))
        return lights
        
    def onRender(self):
        #View- and projectionmatrix.
        view = self.createLookAt((-50, 25, -50), (0, 0, 0))
        projection = self.createProjection(45, 0.1, 300.0)
    
        lights = self.createLights()
    
        #First the heightmap. 
        self.heightmap.setLights(lights)
        #Add some ambient lightning so that it is not so dark.
        self.heightmap.effect.set("lightAmbient", (0.5, 0.5, 0.5, 0))
        self.heightmap.render(d3d11.Matrix(), view, projection)
        
        #Then our "light spheres".
        self.sphere.setLights(lights) 
        for light in lights:
            #World matrix.
            meshWorld = d3d11.Matrix()
            lightPos = light[0]
            #Add little to y to lift the sphere off the ground.
            meshWorld.translate((lightPos.x, lightPos.y + 1, lightPos.z))
            #Set ambient to light color.
            self.sphere.effect.set("lightAmbient", light[1])
            self.sphere.render(meshWorld, view, projection)
           
if __name__ == "__main__":
    
sample = SampleLights("Lights - DirectPython 11", __doc__)
    sample.mainloop()