Anaglyph test

BlitzMax Forums/BlitzMax Programming/Anaglyph test

deps(Posted 2008) [#1]
Hello,

Yesterday I ordered some cheap 3D glasses, the ones with a red eye and a cyan eye. I paid only $1 and it will probably take a week or more to arrive since I don't live in the states.
So, while I wait I wanted to try and create something to look at when they arrive.

Here is some code I wrote to render a bunch of spheres, hopefully they will look 3D when viewed with the 3d glasses on. But since I cannot test it yet I thought I should share the code with you and ask that someone who do have a pair of 3D glasses could try it out and tell me if it works or if I failed horribly. I didn't put this in the archive since this is untested and not very nicely written.
(uses OpenGL)

SuperStrict
Global eye_shift:Int

Type TEntity
	Global list:TList = CreateList()
	
	Function update_all()
		For Local e:TEntity = EachIn list
			e.update
		Next
	EndFunction
	
	Function draw_all()
		list.sort
		eye_shift = 0
		glColorMask( False, True,True,True )
		For Local e:TEntity = EachIn list
			e.pre_draw
			e.draw
		Next
		glColorMask( True, False,False,True )
		eye_shift = 5
		For Local e:TEntity = EachIn list
			e.pre_draw
			e.draw
		Next
		glCOlorMask( True,True,True,True )
	EndFunction

	Field x:Int,y:Int,z:Float, nz:Float

	Method New()
		list.addlast(Self)
		x = 0
		y = 0
		z = 0.0
	EndMethod
	
	Method compare:Int( o:Object )
		Local oe:TEntity = TENtity(o)
		If Not oe Then Return -1
		If Abs(oe.z - z) < 0.001 Then Return 0
		If oe.z > z Then Return 1
		Return -1
	EndMethod

	Method pre_draw()
		z = Max(Min(z,1), -1)
		nz = z*eye_shift
	EndMethod

	Method draw()
		SetColor 255,255,255
		DrawRect x-25+nz,y-25, 50,50 	
	EndMethod

	Method update()	
	EndMethod

	Method move( xo:Int,yo:Int,zo:Float )
		x :+ xo
		y :+ yo
		z :+ zo
	EndMethod
EndType

Type TBall Extends TEntity
	Field angle:Float
	Method draw()
		SetColor 64,64,64
		DrawOval x-50+nz,y-50, 100,100
		SetColor 255,255,255
		DrawOval x-48+nz,y-48, 96,96
	EndMethod
	Method update()
		x = 320+Cos(angle) * 200
		y = 240+Sin(angle) * 75
		z = Cos(angle+90)
		angle:+1
	EndMethod
EndType


Graphics 640,480,0

Local e:TEntity = New TEntity
e.x = 320
e.y = 240

For Local b:Int = 0 Until 10
	Local t:TBall = New TBall
	t.angle = b*36
Next

While Not KeyHit( KEY_ESCAPE )
	TEntity.draw_all

	SetColor 255,255,255
	DrawText "Move square with arrow keys", 0,0
	DrawText "Move it in or out of the screen with A/Z", 0,12
	Flip	
	Cls
	
	TEntity.update_all
	If KeyDown( KEY_A ) Then e.move(0,0,-0.1)
	If KeyDown( KEY_Z ) Then e.move(0,0,+0.1)
	If KeyDown( KEY_LEFT ) e.move(-1,0,0)
	If KeyDown( KEY_RIGHT ) e.move( 1,0,0)
	If KeyDown( KEY_UP ) e.move( 0,-1,0)
	If KeyDown( KEY_DOWN ) e.move( 0,1,0)
Wend



iprice(Posted 2008) [#2]
Anaglyph (3D stereoscopic) images use red and green/blue colours to create a 3D effect - this is only using black and white. It doesn't work.

See this image - it uses red and cyan




deps(Posted 2008) [#3]
Only black and white? I can see the red and cyan when I run it...
It is using OpenGL, and since I made it on a mac I didn't made sure it avoided DirectX. Maybe that's the problem if you only see black and white?


tonyg(Posted 2008) [#4]
It works OK with GL driver on Windows


deps(Posted 2008) [#5]
Thanks tonyg. Did you try it with some 3d glasses too? :)


tonyg(Posted 2008) [#6]
One eye half-shut.


deps(Posted 2008) [#7]
Ha, didn't know that worked. :)


iprice(Posted 2008) [#8]
I presume that my video card ATI Radeon 9800+ is too old to support some of the OpenGL commandset? Dunno.

The only colours I see are white - RGB 255,255,255 and grey - RGB 64,64,64 and black 0,0,0 for the background.


deps(Posted 2008) [#9]
As I wrote you might be running it with DirectX. Try adding this before the call to Graphics:
SetGraphicsDriver GLMax2DDriver()



iprice(Posted 2008) [#10]
D'oh! Why didn't I think of that

That works really well actually - not so much with the balls, but with the square in the background behind the balls the effect is very good.


Taron(Posted 2008) [#11]
Hmmm...just found this, which is almost something I was gonna do next...in fact it will be! However, I've added proper cyan/red color and decent settings, so now it works great for all those with cyan/red anaglyph glasses:


SuperStrict
Global eye_shift:Int

Type TEntity
	Global list:TList = CreateList()
	
	Function update_all()
		For Local e:TEntity = EachIn list
			e.update
		Next
	EndFunction
	
	Function draw_all()
		list.sort
		eye_shift = 10
		glColorMask( False, True,True,True )
		For Local e:TEntity = EachIn list
			e.pre_draw
			e.draw
		Next
		glColorMask( True, False,False,True )
		eye_shift = 5
		For Local e:TEntity = EachIn list
			e.pre_draw
			e.draw
		Next
		glCOlorMask( True,True,True,True )
	EndFunction

	Field x:Int,y:Int,z:Float, nz:Float

	Method New()
		list.addlast(Self)
		x = 0
		y = 0
		z = 0.0
	EndMethod
	
	Method compare:Int( o:Object )
		Local oe:TEntity = TENtity(o)
		If Not oe Then Return -1
		If Abs(oe.z - z) < 0.001 Then Return 0
		If oe.z > z Then Return 1
		Return -1
	EndMethod

	Method pre_draw()
		z = Max(Min(z,1), -1)
		nz = z*eye_shift
	EndMethod

	Method draw()
		SetColor 255,255,255
		DrawRect x-25+nz,y-25, 50,50 	
	EndMethod

	Method update()	
	EndMethod

	Method move( xo:Int,yo:Int,zo:Float )
		x :+ xo
		y :+ yo
		z :+ zo
	EndMethod
EndType

Type TBall Extends TEntity
	Field angle:Float
	Method draw()
		SetBlend lightblend
		SetColor 0,255,255
		DrawOval x-50+nz,y-50, 100,100
		SetColor 255,0,0
		DrawOval x-50,y-50, 100,100
	EndMethod
	Method update()
		x = 320+Cos(angle) * 200
		y = 240+Sin(angle) * 75
		z = Cos(angle+90)
		angle:+1
	EndMethod
EndType


Graphics 640,480,0

Local e:TEntity = New TEntity
e.x = 320
e.y = 240

For Local b:Int = 0 Until 10
	Local t:TBall = New TBall
	t.angle = b*36
Next

While Not KeyHit( KEY_ESCAPE )
	TEntity.draw_all

	SetColor 255,255,255
	DrawText "Move square with arrow keys", 0,0
	DrawText "Move it in or out of the screen with A/Z", 0,12
	Flip	
	Cls
	
	TEntity.update_all
	If KeyDown( KEY_A ) Then e.move(0,0,-0.1)
	If KeyDown( KEY_Z ) Then e.move(0,0,+0.1)
	If KeyDown( KEY_LEFT ) e.move(-1,0,0)
	If KeyDown( KEY_RIGHT ) e.move( 1,0,0)
	If KeyDown( KEY_UP ) e.move( 0,-1,0)
	If KeyDown( KEY_DOWN ) e.move( 0,1,0)
Wend