shading.py

"""Draw shaded shapes.
   Opengl has different lighting models some of which are less complex
   than the one that is utilized by slut. Mixing different lighting
   models is usually not a good idea.

   It takes some experimentation and some understanding of the fundamentals
   to get a handle on lighting. You have been warned. Now go and hack!
   
   by stephan)
"""
from slut import *

class Atlantis(World):
    def onSetup(self):
        self.name = "Form Follows Computation Here"
        self.width = 800
        self.height = 600
        self.fullscreen = False
        self.showCoordinates = True

        #set up some materials for our spheres
        redmaterial = MaterialRed('matRed')
        whitematerial = MaterialWhite('matWhite')

        #create a bluish light and add it to the world (affects every object)
        globallight = LightBlue('blu', pos=(-2.0, 5.0, 0.0, 1.0), dir=(0.0, -1.0, 0.0))
        self.addLight(globallight)

        #create a ball that reflects the whole light spectrum
        Sphere(self, 'sph1')
        self.sprites['sph1'].setMaterial(whitematerial)
        #add a white light to this sphere
        #(only affects this sphere and also moves as the sphere is being moved)
        #place it 5 units above the  sphere and point it downwards
        mylocallight = LightWhite('l1', pos=(5.0, 0.0, 0.0, 1.0), dir=(-1.0, 0.0, 0.0))
        self.sprites['sph1'].addLight(mylocallight)

        #another sphere that reflects the whole spectrum
        Sphere(self, 'sph2')
        self.sprites['sph2'].moveBy(-0.5, 0.0, 2.0)
        self.sprites['sph2'].setMaterial(whitematerial)

        #a sphere that predominantely reflects the red spectrum
        Sphere(self, 'sph3')
        self.sprites['sph3'].moveBy(-1.0, 0.0, -2.0)
        self.sprites['sph3'].setMaterial(redmaterial)

        #have the two spheres move back and forth so one can see 
        #the difference between global and local light
        self.sprites['sph1'].moveBy(SineThrust(-6.0, 0.0, 0.0, 2.0))
        self.sprites['sph2'].moveBy(SineThrust(-6.0, 0.0, 0.0))

        #move the cam to a good spot
        self.camera.moveBy(0.0, 0.0, -10.0)
        self.camera.orbitBy(45.0, -45.0, 0.0)


class Sphere(Sprite):
    def onDraw(self):
        sphere(0, 0, 0, 1)


class MaterialWhite(Material):
    def onPreDraw(self):
        glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (0.3, 0.3, 0.3, 1.0))
        glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (0.3, 0.3, 0.3, 1.0))
        glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (0.3, 0.3, 0.3, 1.0))
        glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (0.0, 0.0, 0.0, 1.0))
        glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, 30.0)


class MaterialRed(Material):
    def onPreDraw(self):
        glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (0.3, 0.1, 0.1, 0.5))
        glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (0.5, 0.1, 0.1, 0.8))
        glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (1.0, 0.1, 0.1, 0.5))
        glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (0.0, 0.0, 0.0, 0.5))
        glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, 30.0)


class LightWhite(Light):
    def onPreDraw(self):
        glLightfv(self.GL_LIGHT, GL_SPECULAR, (1.0, 1.0, 1.0, 1.0))
        glLightfv(self.GL_LIGHT, GL_DIFFUSE, (1.0, 1.0, 1.0, 1.0))
        glLightfv(self.GL_LIGHT, GL_AMBIENT, (1.0, 1.0, 1.0, 1.0))
        glLightfv(self.GL_LIGHT, GL_SPOT_EXPONENT, 0.0)
        glLightfv(self.GL_LIGHT, GL_SPOT_CUTOFF, 90.0)


class LightBlue(Light):
    def onPreDraw(self):
        glLightfv(self.GL_LIGHT, GL_SPECULAR, (0.5, 0.5, 1.0, 1.0))
        glLightfv(self.GL_LIGHT, GL_DIFFUSE, (0.5, 0.5, 1.0, 1.0))
        glLightfv(self.GL_LIGHT, GL_AMBIENT, (0.5, 0.5, 1.0, 1.0))
        glLightfv(self.GL_LIGHT, GL_SPOT_EXPONENT, 0.0)
        glLightfv(self.GL_LIGHT, GL_SPOT_CUTOFF, 90.0)


atlantis = Atlantis()
atlantis.run()
Initiated by Stephan Hechenberger
Thanks to CADRE's 103