GLSL Shadowmapping 2


Tweet blitzmax opengl shaders code-archives
(Posted 1 year ago) RonTek

Yet another shadowmapping snippet by Kronos, w/ addendum by fredborg

BlitzMax Shadowmapping GLSL

'shadowMap mark2


GLGraphics 800,600,0,2,GRAPHICS_BACKBUFFER|GRAPHICS_DEPTHBUFFER

Global LIGHT_POS:Float[] = [ -60.0, 25.0, 0.0, 1.0 ]
Global CAMERA_POS:Float[] = [0.0, 100.0, 150.0, 1.0 ]

Global WHITE:Float[] =[ 1.0, 1.0, 1.0, 1.0]
Global BLACK:Float[] =[ 0.0, 0.0, 0.0, 0.0]
Global GREY:Float[] =[ 0.3, 0.3, 0.3, 0.3 ]
Global DARK_GREY:Float[] = [0.1, 0.1, 0.1, 0.1]
Global m_shadowMap:Int
Global   m_bounce:Float = 0.0
Global showShadowMap:Int = False
Global noShadows:Int = False
Global ambientShadowAvailable:Int = False
Global  m_windowHeight = 768
Global  m_windowWidth = 1024
Global sPlane:Float[] = [1.0, 0.0, 0.0, 0.0]
Global TPlane:Float[] = [0.0, 1.0, 0.0, 0.0]
Global rPlane:Float[] = [0.0, 0.0, 1.0, 0.0]
Global qPlane:Float[] = [0.0, 0.0, 0.0, 1.0]
Global m_quadric:Byte Ptr
m_quadric = gluNewQuadric()
gluQuadricNormals(m_quadric, GLU_SMOOTH)
Global modelview:Float[16], projection:Float[16]
Global texsize:Int = 128

'****************************************************
init()

'main loop
While Not AppTerminate() And Not KeyDown(KEY_ESCAPE)
update(0.5)
render()

Flip 1
If KeyHit(Key_N) showshadowmap = True
If KeyHit(KEY_m) showshadowmap = False
If KeyHit(KEY_O) noshadows = True
If KeyHit(KEY_P) noshadows = False
Wend

End

'*****************************************************

Function Init()

glewinit()


  glEnable(GL_DEPTH_TEST)
  glDepthFunc(GL_LEQUAL)


  glGenTextures(1, Varptr m_shadowMap)
  glBindTexture(GL_TEXTURE_2D, m_shadowMap)

  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
  glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY)
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE)

  glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)
  glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)
  glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)
  glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)

  glEnable(GL_LIGHT0)
  glEnable(GL_COLOR_MATERIAL)
  glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR)

  glPolygonOffset(4.0, 0.0)


End Function
'****************************************************************

Function SetupProjection(width:Int, height:Int)

    glViewport( 0, 0, width, height )

'   // set up a perspective projection
    glMatrixMode( GL_PROJECTION )
    glLoadIdentity()
    gluPerspective( 45.0, Float(width)/Float(height), 1.0, 1000.0 )
End Function
'*****************************************************************
Function Update( dt:Float )

  m_bounce :+ 10 * dt
End Function
'*****************************************************************

Function Render()

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
  GenerateShadowMap()

  '// Track camera angle
  glMatrixMode(GL_PROJECTION)
  glLoadIdentity()
  gluPerspective(45.0, 1.0, 1.0, 1000.0)
  glMatrixMode(GL_MODELVIEW)
  glLoadIdentity()
  gluLookAt(CAMERA_POS[0], CAMERA_POS[1], CAMERA_POS[2],0.0, 0.0, 0.0, 0.0, 1.0, 0.0)
  glViewport(0, 0, 1024,768)

  '// Track light position
  glLightfv(GL_LIGHT0, GL_POSITION, LIGHT_POS)

  '// Clear the window with current clearing color
  glClear(GL_DEPTH_BUFFER_BIT)

  If showShadowMap = True Then

   ' // Display shadow map For educational purposes
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()
    glMatrixMode(GL_TEXTURE)
    glPushMatrix()
    glLoadIdentity()
    glEnable(GL_TEXTURE_2D)
    glDisable(GL_LIGHTING)
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
    '// Show the shadowMap at its actual size relative To window
    glBegin(GL_QUADS)
    glTexCoord2f(0.0, 0.0)
    glVertex2f(-1.0, -1.0)
    glTexCoord2f(1.0, 0.0)
    glVertex2f((Float(texsize)/Float(1024))*2.0-1.0,-1.0)
    glTexCoord2f(1.0, 1.0)
    glVertex2f((Float(texsize)/Float(1024))*2.0-1.0,Float(texsize)/Float(768)*2.0-1.0)
    glTexCoord2f(0.0, 1.0)
    glVertex2f(-1.0,Float(texsize)/Float(768)*2.0-1.0)
    glEnd()
    glDisable(GL_TEXTURE_2D)
    glEnable(GL_LIGHTING)
    glPopMatrix()
    glMatrixMode(GL_PROJECTION)
    gluPerspective(45.0, 1.0, 1.0, 1000.0)
    glMatrixMode(GL_MODELVIEW)

  Else If noShadows = True

   ' // Set up some simple lighting
    glLightfv(GL_LIGHT0, GL_AMBIENT, GREY)
        glLightfv(GL_LIGHT0, GL_DIFFUSE, WHITE)

    '// Draw objects in the scene
   RenderObjects(False)

  Else

      If ambientShadowAvailable = False Then


      '// Because there is no support For an "ambient"
      '// shadow compare fail value, we'll have to
      '// draw an ambient pass first...
      glLightfv(GL_LIGHT0, GL_AMBIENT, GREY)
      glLightfv(GL_LIGHT0, GL_DIFFUSE, DARK_GREY)

      '// Draw objects in the scene
      RenderObjects(False)
      '// Enable alpha test so that shadowed fragments are discarded
      glAlphaFunc(GL_GREATER, 0.9)
      glEnable(GL_ALPHA_TEST)
    EndIf

    glLightfv(GL_LIGHT0, GL_AMBIENT, grey)
    glLightfv(GL_LIGHT0, GL_DIFFUSE, WHITE)

    '// Set up shadow comparison
    glEnable(GL_TEXTURE_2D)
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE,GL_COMPARE_R_TO_TEXTURE)


    '// Set up the eye plane For projecting the shadow map on the scene
    glEnable(GL_TEXTURE_GEN_S)
    glEnable(GL_TEXTURE_GEN_T)
    glEnable(GL_TEXTURE_GEN_R)
    glEnable(GL_TEXTURE_GEN_Q)
    glTexGenfv(GL_S, GL_EYE_PLANE, sPlane)
    glTexGenfv(GL_T, GL_EYE_PLANE, TPlane)
    glTexGenfv(GL_R, GL_EYE_PLANE, rPlane)
    glTexGenfv(GL_Q, GL_EYE_PLANE, qPlane)

    '// Draw objects in the scene
    RenderObjects(False)
    glDisable(GL_ALPHA_TEST)
    glDisable(GL_TEXTURE_2D)
    glDisable(GL_TEXTURE_GEN_S)
    glDisable(GL_TEXTURE_GEN_T)
    glDisable(GL_TEXTURE_GEN_R)
    glDisable(GL_TEXTURE_GEN_Q)

EndIf
End Function
'********************************************************************
Function RenderObjects(isShadowPass:Int)

  glPushMatrix()
  glColor3f(0.2, 0.9, 0.3)
  glTranslatef(0.0, 5 + 5 * Sin(m_bounce), 0.0)
  glRotatef(-90.0, 1.0, 0.0, 0.0)
  gluCylinder(m_quadric, 10, 0, 20, 20, 20)

  glPopMatrix()

  glPushMatrix()
  glColor3f(0.75, 0.2, 0.1)
  glTranslatef(15.0, 5.0, 12 * Cos(m_bounce/3.0))
  glusphere(M_quadric,5,20,20)

  glPopMatrix()

  glPushMatrix()
  glColor3f(0.5, 0.1, 0.9)
  glTranslatef(28.0, 6.0, -24.0)
  glRotatef(30.0, 0.0, 1.0, 0.0)
  glucylinder(m_quadric,6, 6, 20, 20, 20)
  glPopMatrix()

glDisable(GL_LIGHTING)
    glPushMatrix()
    glColor3f(1,1,1)    
    glTranslatef(light_pos[0],light_pos[1],light_pos[2])
    glusphere(m_quadric,1,20,20)
    glPopMatrix()

glEnable(GL_LIGHTING)   


  glPushMatrix()
glColor3f(.75,.75,.95)

For Local i = -50 To 50 Step 20
For Local j = -50 To 50 Step 20
glBegin(GL_QUADS)
glNormal3f(0,1,0)
glVertex3f(i+10,0,j+10)
glVertex3f(i-10,0,j+10)
glVertex3f(i-10,0,j-10)
glVertex3f(i+10,0,j-10)
glEnd()
Next
Next
glPopMatrix()

End Function
'*************************************************************
Function GenerateShadowMap()

  Local lightToSceneDistance:Float, nearPlane:Float, fieldOfView:Float
  Local lightModelview:Float[16], lightProjection:Float [16]

  '// Save the depth precision For where it's useful
  lightToSceneDistance = Sqr(LIGHT_POS[0]*LIGHT_POS[0]+LIGHT_POS[1]*LIGHT_POS[1]+LIGHT_POS[2]*LIGHT_POS[2])
  nearPlane = lightToSceneDistance - 150.0
  If nearPlane < 50.0  nearPlane = 50.0
  '// Keep the scene filling the depth texture
  fieldOfView = 17000.0 / lightToSceneDistance



 glViewport(0, 0, texsize, texsize)
  glMatrixMode(GL_PROJECTION)
  glLoadIdentity()
  'glFrustum(-12.0, 12.0, -20.0, 5.0, 13.0, 150.0)
 gluPerspective( 60,1, 13, 1000 )
    glGetFloatv(GL_PROJECTION_MATRIX, lightProjection)
  '// Switch To light's point of view
  glMatrixMode(GL_MODELVIEW)
  glLoadIdentity()
  gluLookAt(LIGHT_POS[0], LIGHT_POS[1], LIGHT_POS[2],0.0, 0.0, 0.0, 0.0, 1.0, 0.0)
  glGetFloatv(GL_MODELVIEW_MATRIX, lightModelview)

  '// Clear the window with current clearing color
  glClear(GL_DEPTH_BUFFER_BIT)

  '// All we care about here is resulting depth values
  glShadeModel(GL_FLAT)
  glDisable(GL_LIGHTING)
  glDisable(GL_COLOR_MATERIAL)
  glDisable(GL_NORMALIZE)
  glColorMask(0, 0, 0, 0)

  '// Overcome imprecision
  glEnable(GL_POLYGON_OFFSET_FILL)

  '// Draw objects in the scene
  RenderObjects(True)

  '// Copy depth values into depth texture
  glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT,0, 0, texsize, texsize, 0)

  '// Restore normal drawing state
  glShadeModel(GL_SMOOTH)
  glEnable(GL_LIGHTING)
  glEnable(GL_COLOR_MATERIAL)
  glEnable(GL_NORMALIZE)
  glColorMask(1, 1, 1, 1)
  glDisable(GL_POLYGON_OFFSET_FILL)

  '// Set up texture matrix For shadow map projection
  glMatrixMode(GL_TEXTURE)
  glLoadIdentity()
  glTranslatef(0.5, 0.5, 0.5)
  glScalef(0.5, 0.5, 0.5)
  glMultMatrixf(lightProjection)
  glMultMatrixf(lightModelview)

End Function
'********************************************************

Reply To Topic (minimum 10 characters)

Please log in to reply