Post by DJLinux on Nov 26, 2009 23:34:05 GMT -5
I tryed shadowmaps from here in Basic4GL.
this two extensions "GL_ARB_depth_texture" and "GL_ARB_shadow" are needed
Joshy
this two extensions "GL_ARB_depth_texture" and "GL_ARB_shadow" are needed
Joshy
dim ext1 = ExtensionSupported ("GL_ARB_depth_texture")
dim ext2 = ExtensionSupported ("GL_ARB_shadow")
if (ext1=FALSE) or (ext2=FALSE) then
printr "Sorry this demo needs GL extensions!"
beep():input$():end
end if
' Constants
const GL_DEPTH_TEXTURE_MODE_ARB = 0x884B
const GL_TEXTURE_COMPARE_MODE_ARB = 0x884C
const GL_TEXTURE_COMPARE_FUNC_ARB = 0x884D
const GL_COMPARE_R_TO_TEXTURE_ARB = 0x884E
'
' a box and sphere as OpenGL list
dim BoxList, SphereList
'
'Camera & light positions
dim cameraPosition#(3)= vec4(-2.5, 3.5,-2.5,1.0)
dim lightPosition#(3) = vec4( 2.0, 3.0,-2.0,1.0)
'
'Size of shadow map
dim shadowMapWidth =512 'WindowWidth()
dim shadowMapHeight=512 'WindowHeight()
'
' Textures
dim shadowMapTexture
dim Dummy(shadowMapWidth-1,shadowMapHeight-1)
'
' window size
dim Width#
dim Height#
'
'Matrices
dim lightProjectionMatrix#(3,3)
dim lightViewMatrix#(3,3)
dim cameraProjectionMatrix#(3,3)
dim cameraViewMatrix#(3,3)
dim textureMatrix#(3,3)
dim biasMatrix#(3,3)
'
' vars
dim white#(3) =vec4(1.0, 1.0, 1.0, 1.0)
dim black#(3) =vec4(0.0, 0.0, 0.0, 0.0)
'dim red#(3) =vec4(1.0, 0.0, 0.0, 1.0)
'dim green#(3) =vec4(0.0, 1.0, 0.0, 1.0)
'dim blue#(3) =vec4(0.0, 0.0, 1.0, 1.0)
'dim cyan#(3) =vec4(0.0, 1.0, 1.0, 1.0)
'dim magenta#(3)=vec4(1.0, 0.0, 1.0, 1.0)
'dim yellow#(3) =vec4(1.0, 1.0, 0.0, 1.0)
dim angle#
'
' ###############################
' # create a unit 1 x 1 x 1 box #
'###############################
function CreateCube()
dim ret = glGenLists(1)
glNewList(ret,GL_COMPILE)
glBegin(GL_QUADS)
glNormal3f(0,0,1)
glVertex3f(-0.5, 0.5, 0.5):glVertex3f(-0.5,-0.5, 0.5)
glVertex3f( 0.5,-0.5, 0.5):glVertex3f( 0.5, 0.5, 0.5)
glNormal3f(1,0,0)
glVertex3f( 0.5, 0.5, 0.5):glVertex3f( 0.5,-0.5, 0.5)
glVertex3f( 0.5,-0.5,-0.5):glVertex3f( 0.5, 0.5,-0.5)
glNormal3f (0,0,-1)
glVertex3f( 0.5, 0.5,-0.5):glVertex3f( 0.5,-0.5,-0.5)
glVertex3f(-0.5,-0.5,-0.5):glVertex3f(-0.5, 0.5,-0.5)
glNormal3f(-1,0,0)
glVertex3f(-0.5, 0.5,-0.5):glVertex3f(-0.5,-0.5,-0.5)
glVertex3f(-0.5,-0.5, 0.5):glVertex3f(-0.5, 0.5, 0.5)
glNormal3f(0,1,0)
glVertex3f(-0.5, 0.5,-0.5):glVertex3f(-0.5, 0.5, 0.5)
glVertex3f( 0.5, 0.5, 0.5):glVertex3f( 0.5, 0.5,-0.5)
glNormal3f(0,-1,0)
glVertex3f(-0.5,-0.5, 0.5):glVertex3f(-0.5,-0.5,-0.5)
glVertex3f( 0.5,-0.5,-0.5):glVertex3f( 0.5,-0.5, 0.5)
glEnd()
glEndList()
return ret
end function
'
' ##################################
' # create a unit 1 x 1 x 1 sphere #
'##################################
function CreateSphere()
const segments = 30
const US# = (m_PI*2) / segments
const VS# = m_PI / segments
const NumOfPoints = (segments + 1) * (segments + 1)
dim PS#(NumOfPoints*3-1)
dim ret,pc,yc,xc,p0,p1,p2,p3
dim VW#,UW#,UR#,YP#,VR#,VA#(2)
For yc = 0 To segments
UR# = Sin(VW#) * 0.5
YP# = Cos(VW#) * 0.5
VR# = Sin(VW#) * 0.5
VW# = VW#+VS#
UW# = 0
For xc = 0 To segments
PS#(PC*3+0)=Sin( UW#) * UR#
PS#(PC*3+1)=YP#
PS#(PC*3+2)=Cos(m_PI+UW#) * VR#
PC=PC+1: UW#=UW#+US#
Next
Next
'
ret=glGenLists(1)
glNewList (ret, GL_COMPILE)
glBegin (GL_TRIANGLES)
For yc= 0 To segments - 1
For xc= 0 To segments - 1
P0 = ((yc + 0) * (segments + 1) + (xc + 0))*3
P1 = ((yc + 0) * (segments + 1) + (xc + 1))*3
P2 = ((yc + 1) * (segments + 1) + (xc + 1))*3
P3 = ((yc + 1) * (segments + 1) + (xc + 0))*3
VA#=Vec3(PS#(p0),PS#(p0+1),PS#(p0+2))
glNormal3fv(Normalize(VA#)):glVertex3fv(VA#)
VA#=Vec3(PS#(p1),PS#(p1+1),PS#(p1+2))
glNormal3fv(Normalize(VA#)):glVertex3fv(VA#)
VA#=Vec3(PS#(p3),PS#(p3+1),PS#(p3+2))
glNormal3fv(Normalize(VA#)):glVertex3fv(VA#)
VA#=Vec3(PS#(p1),PS#(p1+1),PS#(p1+2))
glNormal3fv(Normalize(VA#)):glVertex3fv(VA#)
VA#=Vec3(PS#(p2),PS#(p2+1),PS#(p2+2))
glNormal3fv(Normalize(VA#)):glVertex3fv(VA#)
VA#=Vec3(PS#(p3),PS#(p3+1),PS#(p3+2))
glNormal3fv(Normalize(VA#)):glVertex3fv(VA#)
Next
Next
glEnd()
glEndList()
return ret
end function
'
' return a row from matrix()()
function GetRow#(m#()(),p) ()
return vec4(m#(0,p),m#(1,p),m#(2,p),m#(3,p))
end function
'
'update all matrixes
sub Reshape()
'Save new window size
Width# =WindowWidth()
Height#=WindowHeight()
'Calculate & save matrices
glPushMatrix()
'
glLoadIdentity()
gluPerspective(45.0, Width#/Height#, 1.0, 100.0)
glGetFloatv(GL_MODELVIEW_MATRIX, cameraProjectionMatrix#)
'
glLoadIdentity()
gluLookAt(cameraPosition#(0), cameraPosition#(1), cameraPosition#(2), 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)
glGetFloatv(GL_MODELVIEW_MATRIX, cameraViewMatrix#)
'
glLoadIdentity()
gluPerspective(45.0, 1.0, 1.0, 10.0)
glGetFloatv(GL_MODELVIEW_MATRIX, lightProjectionMatrix#)
'
glLoadIdentity()
gluLookAt(lightPosition#(0), lightPosition#(1), lightPosition#(2), 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)
glGetFloatv(GL_MODELVIEW_MATRIX, lightViewMatrix#)
'
glPopMatrix()
end sub
'
'Called for initiation
sub Init()
dim Textures(0)
'
SphereList=CreateSphere()
BoxList =CreateCube()
'
biasMatrix#(0)=vec4(0.5, 0.0, 0.0, 0.0)
biasMatrix#(1)=vec4(0.0, 0.5, 0.0, 0.0)
biasMatrix#(2)=vec4(0.0, 0.0, 0.5, 0.0)
biasMatrix#(3)=vec4(0.5, 0.5, 0.5, 1.0)
'
'Load identity modelview
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
'
'Shading states
glShadeModel(GL_SMOOTH)
glClearColor(0.0, 0.0, 0.0, 0.0)
glColor4f(1.0, 1.0, 1.0, 1.0)
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)
'
'Depth states
glClearDepth(1.0)
glDepthFunc(GL_LEQUAL)
glEnable(GL_DEPTH_TEST)
glEnable(GL_CULL_FACE)
'
'We use glScale when drawing the scene
glEnable(GL_NORMALIZE)
'
'Create the shadow map texture
glGenTextures(1,Textures)
shadowMapTexture=Textures(0)
glBindTexture(GL_TEXTURE_2D, shadowMapTexture)
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadowMapWidth, shadowMapHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, dummy)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
'
' Use the color as the ambient and diffuse material
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE)
glEnable(GL_COLOR_MATERIAL)
'
' White specular material color, shininess 16
glMaterialfv(GL_FRONT, GL_SPECULAR, white#)
glMaterialf(GL_FRONT, GL_SHININESS, 16.0)
'
'Calculate & save matrices
Reshape()
end sub
sub DrawScene(ang#)
'
glColor3f(0.0, 0.0, 1.0)
glPushMatrix()
glScalef(3.0, 0.15, 3.0)
glCallList(BoxList)
glPopMatrix()
'
glColor3f(1.0, 0.0, 0.0)
glPushMatrix()
glTranslatef(0,0.5,1)
glScalef(0.5,1,0.5)
glCallList(BoxList)
glPopMatrix()
'
glPushMatrix()
glColor3f(0.0, 1.0, 0.0)
glRotatef(ang#, 0.0, 1.0, 0.0)
glScalef(0.5,0.5,0.5)
'
glColor3f(0.0, 1.0, 1.0)
glTranslatef(0.45, 0.5, 0.45)
glCallList(SphereList)
'
glColor3f(1.0, 1.0, 0.0)
glTranslatef(-0.9, 0.5, 0.0)
glCallList(SphereList)
'
glColor3f(1.0, 0.0, 1.0)
glTranslatef(0.0, 0.5,-0.9)
glCallList(SphereList)
'
glColor3f(0.0, 1.0, 0.0)
glTranslatef(0.9, 0.5, 0.0)
glCallList(SphereList)
glPopMatrix()
end sub
'
' Called to draw scene
sub Display()
' angle of spheres in scene.
angle#=angle#+1
if angle#>=360 then angle#=0:endif
'
' First pass - from light's point of view
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT)
'
glMatrixMode(GL_PROJECTION)
glLoadMatrixf(lightProjectionMatrix#)
'
glMatrixMode(GL_MODELVIEW)
glLoadMatrixf(lightViewMatrix#)
'
'Use viewport the same size as the shadow map
glViewport(0, 0, shadowMapWidth, shadowMapHeight)
'
' Draw back faces into the shadow map
glCullFace(GL_FRONT)
'
'Disable color writes, and use flat shading for speed
glShadeModel(GL_FLAT)
glColorMask(0, 0, 0, 0)
'
'Draw the scene
DrawScene(angle#)
'
'Read the depth buffer into the shadow map texture
glBindTexture(GL_TEXTURE_2D, shadowMapTexture)
glCopyTexSubImage2D(GL_TEXTURE_2D, 0,0,0,0,0, shadowMapWidth, shadowMapHeight)
'
'restore states
glCullFace(GL_BACK)
glShadeModel(GL_SMOOTH)
glColorMask(1, 1, 1, 1)
'
'
' 2nd pass - Draw from camera's point of view
glClear(GL_DEPTH_BUFFER_BIT)
'
glMatrixMode(GL_PROJECTION)
glLoadMatrixf(cameraProjectionMatrix#)
'
glMatrixMode(GL_MODELVIEW)
glLoadMatrixf(cameraViewMatrix#)
'
glViewport(0, 0,int(Width#),int(Height#))
'
'Use dim light to represent shadowed areas
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition#)
glLightfv(GL_LIGHT0, GL_AMBIENT, white#*0.2)
glLightfv(GL_LIGHT0, GL_DIFFUSE, white#*0.2)
glLightfv(GL_LIGHT0, GL_SPECULAR, black#)
glEnable(GL_LIGHT0)
glEnable(GL_LIGHTING)
'
DrawScene(angle#)
'
'3rd pass Draw with bright light
glLightfv(GL_LIGHT0, GL_DIFFUSE, white#)
glLightfv(GL_LIGHT0, GL_SPECULAR, white#)
'glLightfv(GL_LIGHT1, GL_SPECULAR, white#)
'
'Calculate texture matrix for projection
'This matrix takes us from eye space to the light's clip space
'It is postmultiplied by the inverse of the current view matrix when specifying texgen
textureMatrix#=biasMatrix#*lightProjectionMatrix#*lightViewMatrix#
'
'Set up texture coordinate generation.
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)
glTexGenfv(GL_S, GL_EYE_PLANE, GetRow#(textureMatrix#,0))
glEnable(GL_TEXTURE_GEN_S)
'
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)
glTexGenfv(GL_T, GL_EYE_PLANE, GetRow#(textureMatrix#,1))
glEnable(GL_TEXTURE_GEN_T)
'
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)
glTexGenfv(GL_R, GL_EYE_PLANE, GetRow#(textureMatrix#,2))
glEnable(GL_TEXTURE_GEN_R)
'
glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)
glTexGenfv(GL_Q, GL_EYE_PLANE, GetRow#(textureMatrix#,3))
glEnable(GL_TEXTURE_GEN_Q)
'
' Bind & enable shadow map texture
glBindTexture(GL_TEXTURE_2D, shadowMapTexture)
glEnable(GL_TEXTURE_2D)
'
' Enable shadow comparison
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB)
'
' Shadow comparison should be true (ie not in shadow) if r<=texture
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL)
'
' Shadow comparison should generate an INTENSITY result
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY)
'
' Set alpha test to discard false comparisons
glAlphaFunc(GL_GEQUAL, 0.01)
glEnable(GL_ALPHA_TEST)
'
DrawScene(angle#)
'
'Disable textures and texgen
glDisable(GL_TEXTURE_2D)
glDisable(GL_TEXTURE_GEN_S)
glDisable(GL_TEXTURE_GEN_T)
glDisable(GL_TEXTURE_GEN_R)
glDisable(GL_TEXTURE_GEN_Q)
'
' Restore other states
glDisable(GL_LIGHTING)
glDisable(GL_ALPHA_TEST)
'
SwapBuffers()
end sub
'
'
Init()
'
dim frames#
while TRUE
cameraPosition#(0)=cos(frames#/100)*5
cameraPosition#(1)=sin(frames#/100)*2 + 5
cameraPosition#(2)=sin(frames#/100)*5
lightPosition#(0)=cos(frames#/300)*3
lightPosition#(2)=sin(frames#/300)*3
Reshape()
Display()
WaitTimer(1000/50)
frames#=frames#+1
wend