Mirror Effect MiniB3D


Tweet blitzmax blitzmax-ng code-archives effects openb3d
(Posted 5 months ago) RonTek

Simple Mirror Effect for MiniB3D

Author: SLotman

Image

Import sidesign.minib3d

Graphics3D 800,600,0,2
Global camera:TCamera=CreateCamera()
CameraZoom Camera, 1.0 / Tan(45.0/2.0)

THardwareInfo.displayinfo()

AmbientLight 128,128,128

Local light:TLight=CreateLight()
LightColor light, 128,128,128

Local cone:TMesh=CreateCone(32)
MoveEntity cone, 0, 1.05, 0
EntityColor cone, 0,200,200

Local cube:TMesh=CreateCube()
MoveEntity cube, 4, 1.1, 0
EntityColor cube, 200,0,0

Local sphere:TMesh=CreateSphere(32)
MoveEntity sphere, -3.5, 1.1, 0
EntityColor sphere, 200,200,64

Local mirror:TMesh = TMirror.createMirror(False,True)
ScaleEntity mirror, 6,0.01,6
EntityColor mirror, 0,0,255
EntityAlpha mirror, 0.5

MoveEntity cube, 0, 0.02, 0
MoveEntity light, 0, 100, 0

Global p:TPivot=CreatePivot()
Global angle#=0

While Not KeyHit(KEY_ESCAPE)
	UpdateWorld 

	TMirror.renderMirror(camera)
	
	' render everything normal now
	RenderWorld
	
	Flip
	Delay 1
	
	TurnEntity cube, 0, 0.75, 0
	TurnEntity cone, 0, 0.75, 0
	TurnEntity sphere, 0, 0.75, 0

	'PositionEntity cone, 0, Cos(angle)*2, 0
	PositionEntity camera, Cos(angle)*20, 4*Cos(angle*2), Sin(angle)*20
	PointEntity camera, p
	angle:+0.5
		
Wend


Type TMirror
	Global hidden_geometry_list:TList=CreateList()
	Global mirror:TMesh
	Global showMesh%

	Function createMirror:TMesh(infinite%=False, show_Mesh%=False)
	       mirror=CreateCube()
	    showMesh = show_Mesh
		Return mirror
	End Function

	Function hideMeshes()
		ClearList hidden_geometry_list
		For Local fmesh:TMesh=EachIn TEntity.entity_list
			If fmesh<>mirror And fmesh.parent=Null And fmesh.brush.alpha>0 And fmesh.hidden()=False Then 
			   HideEntity fmesh
			   ListAddLast hidden_geometry_list, fmesh
			End If
		Next
		ShowEntity mirror
	End Function
	
	Function showMeshes()
		For Local fmesh:TMesh=EachIn hidden_geometry_list
			ShowEntity fmesh
		Next
	    HideEntity mirror
	End Function
	
	Function flipMeshes(sign%=1)
		' flip every light
		For Local llight:TLight=EachIn TLight.light_list			
		     PositionEntity llight,llight.px, -llight.py, llight.pz, True
	  	     ScaleEntity llight, llight.sx, -llight.sy, llight.sz, True
		Next
	
		' flip every mesh
		For Local fmesh:TMesh=EachIn TEntity.entity_list
	      If fmesh.parent=Null Then
		     PositionEntity fmesh, fmesh.px, -fmesh.py+(sign*mirror.py), fmesh.pz
	   	     ScaleEntity fmesh, -fmesh.sx, -fmesh.sy, fmesh.sz
	      End If
		Next
	End Function
	
	Function renderMirror(cam:TCamera)
		CameraClsMode cam,True,True

		If EntityY(camera)<mirror.py Then Return		
	
		' prepare to use the stencil buffer
		glClear(GL_ACCUM_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)
	    glDisable(GL_DEPTH_TEST)
	    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE)
	
	    ' Draw into the stencil buffer.
	    glEnable(GL_STENCIL_TEST)
	    glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE)
	    glStencilFunc(GL_ALWAYS, 1, $ffffffff)
	
		' draw only the mirror (the actual 'mask' where objects will be drawn)
		hideMeshes()
			
	    RenderWorld
	
	    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
	    glEnable(GL_DEPTH_TEST);
	
	    ' Now, only render where stencil is set To 1
	    glStencilFunc(GL_EQUAL, 1, $ffffffff)	' draw If stencil ==1 
	    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP)
	
	    ' draw everything but the plane
		showMeshes()
	
		' invert mesh and light position, to appear reflected
		flipMeshes(1)
		
		RenderWorld
			
		' okay! everything done!
	    glDisable(GL_STENCIL_TEST);
			
		' shows plane, and re-render everything normally
		CameraClsMode cam,False, False
		If showMesh Then ShowEntity mirror Else HideEntity mirror
		flipMeshes(-1)
	End Function
End Type

Reply To Topic (minimum 10 characters)

Please log in to reply