Author Topic: OpenGL Reflections useing the stencil buffer.  (Read 3569 times)

0 Members and 1 Guest are viewing this topic.

Offline ScottyBrosious

  • C= 64
  • **
  • Posts: 25
  • Karma: 3
    • View Profile
OpenGL Reflections useing the stencil buffer.
« 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!

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
Re: OpenGL Reflections useing the stencil buffer.
« Reply #1 on: December 27, 2006 »
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.

Offline ScottyBrosious

  • C= 64
  • **
  • Posts: 25
  • Karma: 3
    • View Profile
Re: OpenGL Reflections useing the stencil buffer.
« Reply #2 on: December 28, 2006 »
Could you show me what you just expalined with some
example code?

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
Re: OpenGL Reflections useing the stencil buffer.
« Reply #3 on: December 28, 2006 »
Do you have something working at the moment that you want to draw the reflections into?

Offline ScottyBrosious

  • C= 64
  • **
  • Posts: 25
  • Karma: 3
    • View Profile
Re: OpenGL Reflections useing the stencil buffer.
« Reply #4 on: December 28, 2006 »
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


Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
Re: OpenGL Reflections useing the stencil buffer.
« Reply #5 on: December 28, 2006 »
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.