Dark Bit Factory & Gravity
PROGRAMMING => Freebasic => Topic started by: ScottyBrosious on December 26, 2006
-
Would anyone know how to use opengl's
stencil buffer for reflections in freebasic?
I would like to learn how to.
I've searched the net got some code but
can't seem to get anything working.
Please if you can help a little prog would be nice.
Thanks
and Merry Christmas!
-
Hi ScottyBrosious, the only way I can think of using the stencil buffer that would be effective is for some sort of planar reflections such as a large flat mirrored surface and not for something like reflections on objects like cars where i'd think cubemapping would be a better option.
To use the stencil buffer for a planar reflection:
clear all buffers
render your scene as normal
draw your reflective surface by writing some value (only has to be different from the clear value) to the stencil buffer
using the stencil test but disable the depth test, draw a quad to fill the z buffer value to maximum
reposition and orientation of camera so it's placed behind the reflective plane and looking out (how you do this'll depend on how your geometry works)
still using the stencil test, render your scene again with depth test enabled and that should render the reflected view onto whatever part of the screen passes the stencil test.
If you want any more detail on this, just ask and i'll try to help.
-
Could you show me what you just expalined with some
example code?
-
Do you have something working at the moment that you want to draw the reflections into?
-
yes a lit cube
here it is
TYPE vector
x AS SINGLE
y AS SINGLE
z AS SINGLE
END TYPE
DIM p1 AS vector
DIM p2 as vector
DIM p3 AS vector
DIM SHARED norm(2)
FUNCTION getnorm(p1 AS vector,p2 AS vector,p3 AS vector)
v1x = p1.x - p2.x
v1y = p1.y - p2.y
v1z = p1.z - p2.z
v2x = p2.x - p3.x
v2y = p2.y - p3.y
v2z = p2.z - p3.z
nx = (v1y * v2z) - (v1z * v2y)
ny = (v1z * v2x) - (v1x * v2z)
nz = (v1x * v2y) - (v1y * v2x)
lenght = SQR((nx * nx) + (ny * ny) + (nz * nz))
norm(0) = nx / lenght
norm(1) = ny / lenght
norm(2) = nz / lenght
END FUNCTION
'$INCLUDE: 'fmod.bi'
'DIM mySample AS INTEGER
' 48kHz sample rate, 8 channels.
FSOUND_Init(48000, 8, 0)
mySample = FSOUND_Sample_Load(FSOUND_FREE, "C:\FBFiles\Sounds\waves.wav", 0, 0, 0)
IF mySample = 0 THEN
PRINT "Error: Failed to load the sample!"
FSOUND_Close
END
END IF
'$include: 'GL/gl.bi'
'$include: 'GL/glu.bi'
'' Setup our booleans
const FALSE = 0
const TRUE = not FALSE
#include once "bmpload.bi"
declare function LoadGLTextures() as integer
dim shared texture(1) as GLuint '' Storage For One Texture ( NEW )
dim xrot as single '' X Rotation ( NEW )
dim yrot as single '' Y Rotation ( NEW )
dim zrot as single '' Z Rotation ( NEW )
ScreenWidth = 640
ScreenHeight = 480
SCREEN 18,32,,2
glMatrixMode (GL_PROJECTION)
glLoadIdentity ()
gluPerspective(60,ScreenWidth/ScreenHeight,0,256)
glMatrixMode (GL_MODELVIEW)
'glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_DST_ALPHA)
'glEnable (GL_BLEND)
'' Jump To Texture Loading Routine
if (not LoadGLTextures()) then
end 1 '' If Texture Didn't Load Quit
end if
'FSOUND_Sample_SetMode(mySample, FSOUND_LOOP_NORMAL)
'FSOUND_PlaySound(FSOUND_FREE, mySample)
'glClearColor(1,1,1,1)
Dim As Single Fog_Color(3) => { 1, 1, 1, 1 }
glFogi( GL_FOG_MODE, GL_EXP2)
glFogfv( GL_FOG_COLOR, @Fog_Color(0) )
glFogf( GL_FOG_DENSITY, 0.03)
glHint( GL_FOG_HINT, GL_DONT_CARE )
'glEnable( GL_FOG )
Dim As Single LightPos(3) => {-40,-30, 80, 0 }
Dim As Single Ambient(3) => { .5, .5, .5, 1}
glEnable(GL_LIGHTING) ' Turn on OpenGL Lighting
glEnable(GL_LIGHT0) ' Light Source 0 (0-7)
glLightfv(GL_LIGHT0,GL_POSITION,@LightPos(0)) ' Light Position
glLightfv(GL_LIGHT0,GL_AMBIENT,@Ambient(0)) ' Ambient Light Source (Overall Scene)
glEnable(GL_CULL_FACE)
do
glClear (GL_COLOR_BUFFER_BIT)
'glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT)
' Position camera
glLoadIdentity ()
glRotatef (-camang#, 0, 1, 0)
glTranslatef (0,0,-50)
'glEnable (GL_TEXTURE_2D)
glBindTexture (GL_TEXTURE_2D, texture(0))
glRotatef(xrot#,1.0,0.0,0.0) ' Rotate on the X axis
glRotatef(yrot#,0.0,1.0,0.0) ' Rotate on the Y axis
glRotatef(zrot#,0.0,0.0,1.0) ' Rotate on the Z axis
glBegin(GL_QUADS)
p1.x = -10
p1.y = -10
p1.z = 10
p2.x = 10
p2.y = -10
p2.z = 10
p3.x = 10
p3.y = 10
p3.z = 10
getnorm(p1,p2,p3)
glNormal3f(norm(0),norm(1),norm(2))
' Front face
glTexCoord2f(0.0, 0.0): glVertex3f(-10.0, -10.0, 10.0) ' Bottom left of the texture and quad
glTexCoord2f(1.0, 0.0): glVertex3f( 10.0, -10.0, 10.0) ' Bottom right of the texture and quad
glTexCoord2f(1.0, 1.0): glVertex3f( 10.0, 10.0, 10.0) ' Top right of the texture and quad
glTexCoord2f(0.0, 1.0): glVertex3f(-10.0, 10.0, 10.0) ' Top left of the texture and quad
p1.x = -10
p1.y = -10
p1.z = -10
p2.x = -10
p2.y = 10
p2.z = -10
p3.x = 10
p3.y = 10
p3.z = -10
getnorm(p1,p2,p3)
glNormal3f(norm(0),norm(1),norm(2))
' Back face
glTexCoord2f(1.0, 0.0): glVertex3f(-10.0, -10.0, -10.0) ' Bottom right of the texture and quad
glTexCoord2f(1.0, 1.0): glVertex3f(-10.0, 10.0, -10.0) ' Top right of the texture and quad
glTexCoord2f(0.0, 1.0): glVertex3f( 10.0, 10.0, -10.0) ' Top left of the texture and quad
glTexCoord2f(0.0, 0.0): glVertex3f( 10.0, -10.0, -10.0) ' Bottom left of the texture and quad
p1.x = -10
p1.y = 10
p1.z = -10
p2.x = -10
p2.y = 10
p2.z = 10
p3.x = 10
p3.y = 10
p3.z = 10
getnorm(p1,p2,p3)
glNormal3f(norm(0),norm(1),norm(2))
' Top face
glTexCoord2f(0.0, 1.0): glVertex3f(-10.0, 10.0, -10.0) ' Top left of the texture and quad
glTexCoord2f(0.0, 0.0): glVertex3f(-10.0, 10.0, 10.0) ' Bottom left of the texture and quad
glTexCoord2f(1.0, 0.0): glVertex3f( 10.0, 10.0, 10.0) ' Bottom right of the texture and quad
glTexCoord2f(1.0, 1.0): glVertex3f( 10.0, 10.0, -10.0) ' Top right of the texture and quad
p1.x = -10
p1.y = -10
p1.z = -10
p2.x = 10
p2.y = -10
p2.z = -10
p3.x = 10
p3.y = -10
p3.z = 10
getnorm(p1,p2,p3)
glNormal3f(norm(0),norm(1),norm(2))
' Bottom face
glTexCoord2f(1.0, 1.0): glVertex3f(-10.0, -10.0, -10.0) ' Top right of the texture and quad
glTexCoord2f(0.0, 1.0): glVertex3f( 10.0, -10.0, -10.0) ' Top left of the texture and quad
glTexCoord2f(0.0, 0.0): glVertex3f( 10.0, -10.0, 10.0) ' Bottom left of the texture and quad
glTexCoord2f(1.0, 0.0): glVertex3f(-10.0, -10.0, 10.0) ' Bottom right of the texture and quad
p1.x = 10
p1.y = -10
p1.z = -10
p2.x = 10
p2.y = 10
p2.z = -10
p3.x = 10
p3.y = 10
p3.z = 10
getnorm(p1,p2,p3)
glNormal3f(norm(0),norm(1),norm(2))
' Right face
glTexCoord2f(1.0, 0.0): glVertex3f( 10.0, -10.0, -10.0) ' Bottom right of the texture and quad
glTexCoord2f(1.0, 1.0): glVertex3f( 10.0, 10.0, -10.0) ' Top right of the texture and quad
glTexCoord2f(0.0, 1.0): glVertex3f( 10.0, 10.0, 10.0) ' Top left of the texture and quad
glTexCoord2f(0.0, 0.0): glVertex3f( 10.0, -10.0, 10.0) ' Bottom left of the texture and quad
p1.x = -10
p1.y = -10
p1.z = -10
p2.x = -10
p2.y = -10
p2.z = 10
p3.x = -10
p3.y = 10
p3.z = 10
getnorm(p1,p2,p3)
glNormal3f(norm(0),norm(1),norm(2))
' Left face
glTexCoord2f(0.0, 0.0): glVertex3f(-10.0, -10.0, -10.0) ' Bottom left of the texture and quad
glTexCoord2f(1.0, 0.0): glVertex3f(-10.0, -10.0, 10.0) ' Bottom right of the texture and quad
glTexCoord2f(1.0, 1.0): glVertex3f(-10.0, 10.0, 10.0) ' Top right of the texture and quad
glTexCoord2f(0.0, 1.0): glVertex3f(-10.0, 10.0, -10.0) ' Top left of the texture and quad
glEnd()
FLIP
xrot# = xrot# + .1 ' X axis rotation
yrot# = yrot# + .2 ' Y axis rotation
zrot# = zrot# + .3 ' Z axis rotation
FSOUND_Update
if inkey$ = "A" or inkey$ = "a" then camang# = camang# + 1
if inkey$ = "D" or inkey$ = "d" then camang# = camang# - 1
loop until inkey$ = chr$(27)
FSOUND_Close
END
'' Load Bitmaps And Convert To Textures
function LoadGLTextures() as integer
dim Status as integer = FALSE '' Status Indicator
dim TextureImage(1) as BITMAP_RGBImageRec ptr '' Create Storage Space For The Texture
' Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit
' TextureImage(0) = LoadBMP(exepath + "/textures/demon.bmp")
TextureImage(0) = LoadBMP("c:\FBFiles\Textures\gp.bmp")
TextureImage(1) = LoadBMP("c:\FBFiles\Textures\demon.bmp")
for i = 0 to 1
if TextureImage(i) then
Status = TRUE '' Set The Status To TRUE
glGenTextures 1, @texture(i) '' Create The Texture
' Typical Texture Generation Using Data From The Bitmap
glBindTexture GL_TEXTURE_2D, texture(i)
glTexImage2D GL_TEXTURE_2D, 0, 3, TextureImage(i)->sizeX, TextureImage(i)->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage(i)->buffer
glTexParameteri GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR
glTexParameteri GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR
end if
if TextureImage(i) then '' If Texture Exists
if TextureImage(i)->buffer then '' If Texture Image Exist
deallocate(TextureImage(i)->buffer) '' Free The Texture Image Memory
end if
deallocate(TextureImage(i)) '' Free The Image Structure
end if
next
return Status '' Return The Status
end function
-
ok, I can't get that working atm (using .17beta) but i can see from the code what you've got so far. I think I would recommend looking more into the geometry side of things and implementing some kind of camera system and less hardcoded object drawing (use arrays and/or types to store model data) before attempting any effects like reflections.
There's quite a bit of discussion in this thread about it, http://dbfinteractive.com/index.php?topic=875.0
of the 2 most (probably) common methods of planar reflections, 1 involves repositioning the camera to the opposite side of the reflective surface, and the other involves drawing a reversed copy of your scene geometry behind the reflective surface. Only the first method really needs a dynamic camera but both need some degree of control over the scene geometry.