Quad Particles

BlitzMax Forums/BlitzMax OpenGL Programming/Quad Particles

This I adapted from SimonH example with BMAX.
And want to have the particle effect work with OpenGL. So I firstly wrote it into B3D (which works great), and attempted to implement it with BMAX.

However it behaves very oddly, and I feel im doing allsorts of mistakes. Please could you help me fix it;? thanks.

Const XRES=640
Const YRES=480
Const RRES= 32

bglCreateContext(XRES,YRES,RRES,0,BGL_BACKBUFFER | BGL_DEPTHBUFFER | BGL_FULLSCREEN)
HideMouse


Global texname:Int

Global ParticleList:TList = New TList

'
' Create the Fireworks as a type.
'
Type Fireworks
	
	Field x#,y#,z#
	
	Field vy#
	
	Field xd#,yd#,zd#
	
	Field r#,g#,b#
	
	Field alpha#

End Type

Global ParticleCount

InitOpenGL()

	
While Not KeyHit(KEY_ESCAPE)
	
	If MouseHit(1) Then CreateFireworks()

	RenderOpenGL()
	
	bglSwapBuffers()
Wend



Function RenderOpenGL()

Local Update:Fireworks

glClear 		(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)					' Clear The Screen And The Depth Buffer
glLoadIdentity	()

glBindTexture	(GL_TEXTURE_2D,Texname)								' Select Our Texture
	
	For Update = EachIn ParticleList
		
		glColor4f( Update.r, Update.g, Update.b, Update.Alpha)

		glTranslatef	(Update.x,Update.y,Update.z)			
	
	
		glBegin		(GL_QUADS)								'Draw using Quads.

			glVertex3f(-1.0,  1.0, 0.0)							'Top Left.
			glVertex3f( 1.0,  1.0, 0.0)							'Top Right.
			glVertex3f( 1.0,- 1.0, 0.0)							'Bottom Right.
			glVertex3f(-1.0,- 1.0, 0.0)							'Bottom Left.

		glEnd()												'Done Drawing The Quad.
	
		
		Update.Alpha = Update.Alpha - .01
		
		If Update.Alpha <0
			ParticleList.Remove Update
		End If
		
		update.x		= update.x 		+ update.xd * 10
		update.y		= update.y 		+ update.yd * 10
		update.z		= update.z 		+ update.zd * 10
		
		update.y		= update.y		+ update.vy
		update.vy		= update.vy		+ 0.02
		
		
	Next
	
End Function



Function CreateFireworks()

'
' Here we go For starters.
'		
Local x#=Rand( -5, 5 )
Local y#=Rand( -5, 5 )
Local z#=-20

'
' Colour scheme For this New batch of fireworks,
'
Local r#=Rand( 2 )
Local g#=Rand( 2 )
Local b#=Rand( 2 )

Local create:Fireworks 

For Local amount=1 To 100

	Local speed# 	= Rand(0.05,0.01)

	Local ang1# 	= Rand( 360 )
	Local ang2# 	= Rand( 360 )

	create		= New Fireworks
	
	create.x		= x#
	create.y		= y#
	create.z		= z#

	create.xd		= Cos( ang1# ) * Cos( ang2# ) * speed#
	create.yd		= Cos( ang1# ) * Sin( ang2# ) * speed#
	create.zd		= Sin( ang1# ) * speed#
	
	create.r		= r
	create.g		= g
	create.b		= b
	
	create.alpha	= 1
	
	ParticleList.Addlast Create

Next

End Function


Function InitOpenGL()

	LoadGLTextures	()
	
	glEnable		(GL_TEXTURE_2D)									' Enable Texture Mapping
	glShadeModel	(GL_SMOOTH)										' Enable Smooth Shading
	
	glClearColor	(0.0, 0.0, 0.0, 0.0)								' Black Background
	glClearDepth	(1.0)											' Depth Buffer Setup
	
	glDisable		(GL_DEPTH_TEST)									' Disable Depth Testing
	glEnable		(GL_BLEND)										' Enable Blending
	
	glBlendFunc	(GL_SRC_ALPHA,GL_ONE)								' Type Of Blending To Perform
	glDepthFunc	(GL_LEQUAL)										' The Type Of Depth Testing To Do
	
	glHint		(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)				' Really Nice Perspective Calculations
	
	glViewport	(0,0,XRES,YRES)									' Set viewport
	glMatrixMode	(GL_PROJECTION)									' Select The Projection Matrix
	glLoadIdentity	()												' Reset The Projection Matrix
	
	gluPerspective	(45.0,Float(XRES)/Float(YRES),0.1,100.0)				' Calculate Aspect Ratio 
	glMatrixMode	(GL_MODELVIEW)										' Select The Modelview Matrix
	glLoadIdentity	()

End Function



Function LoadGLTextures()
	
	Local TextureImage:TPixmap
	
	TextureImage:TPixmap=LoadPixmap("media/Spark.png")					' Load Particle Texture
	
	glGenTextures	(1, Varptr Texname)									' Create One Texture
	
	glBindTexture	(GL_TEXTURE_2D, Texname)
	
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR)
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR)
	
	glTexImage2D	(GL_TEXTURE_2D, 0, 3, TextureImage.width, TextureImage.height,..
	 				0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage.pixels)
End Function


Huge Thanks,
Thumbz.

Any luck please?

Ive had another bash and no luck, does anyone know what is wrong with it?

Mega Thanks,
THUMBZ

First thing is the camera is directly on top the fireworks, ie the fireworks and camera are at the world origin 0,0,0 !!

Is this a program you wrote yourself or are you porting to BMAX?

Regards

It's a mix of porting a way I'd do it in B3D (which works), and inspired by SimonH's firework example.

How would the camera position effect it?

Do you have the original source to hand??

'How would the camera position effect it?'

The same way it effects everything in 3d. Try setting the quads at a z of -200 and set the far clip at about 1000.0 :

gluPerspective (45.0,Float(XRES)/Float(YRES),0.1,1000.0)

you can see something happening, but im not sure what your supposed to be getting.

Oh and you don't appear to be setting up any matrix's to tranform your geometry. It's like you only have half of the 3d code thats needed. If you post the original source I can help you get it working properly.

Regards

Uh.. sortof works.

Not exactly interested in fixing everything.

Const XRES=640
Const YRES=480
Const RRES= 32

bglCreateContext(XRES,YRES,RRES,0,BGL_BACKBUFFER | BGL_DEPTHBUFFER)
HideMouse


Global texname:Int

Global ParticleList:TList = New TList

'
' Create the Fireworks as a type.
'
Type Fireworks
	
	Field x#,y#,z#
	
	Field vy#
	
	Field xd#,yd#,zd#
	
	Field r#,g#,b#
	
	Field alpha#

End Type

Global ParticleCount

InitOpenGL()
glDisable(GL_CULL_FACE)
Print glGetError()
	
While Not KeyHit(KEY_ESCAPE)
	
	If MouseHit(1) Then CreateFireworks()

	RenderOpenGL()
	
	bglSwapBuffers()
Wend



Function RenderOpenGL()

Local Update:Fireworks

	glClear 		(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)					' Clear The Screen And The Depth Buffer
	glLoadIdentity	()
	
	glTranslatef(0,0,-20)

	For Update = EachIn ParticleList
		
		glPushMatrix()
		glColor4f( Update.r, Update.g, Update.b, Update.Alpha)

		glTranslatef	(Update.x,Update.y,Update.z)			
	
		glBegin		(GL_QUADS)								'Draw using Quads.

			glVertex2f(-1.0,  1.0)							'Top Left.
			glVertex2f( 1.0,  1.0)							'Top Right.
			glVertex2f( 1.0,- 1.0)							'Bottom Right.
			glVertex2f(-1.0,- 1.0)							'Bottom Left.

		glEnd()												'Done Drawing The Quad.
	
'		
		Update.Alpha = Update.Alpha - .001
		
		If Update.Alpha <0
			ParticleList.Remove Update
		End If
'		
'		update.x		= update.x 		+ update.xd * 10
'		update.y		= update.y 		+ update.yd * 10
'		update.z		= update.z 		+ update.zd * 10
'		
'		update.y		= update.y		+ update.vy
'		update.vy		= update.vy		+ 0.02
		glPopMatrix()
		
	Next
	
End Function



Function CreateFireworks()

'
' Here we go For starters.
'		
Local x#=Rand( -5, 5 )
Local y#=Rand( -5, 5 )
Local z#=-20

'
' Colour scheme For this New batch of fireworks,
'
Local r#=Rand( 2 )
Local g#=Rand( 2 )
Local b#=Rand( 2 )

Local create:Fireworks 

For Local amount=1 To 100

	Local speed# 	= .00001

	Local ang1# 	= Rand( 360 )
	Local ang2# 	= Rand( 360 )

	create		= New Fireworks
	
	create.x		= Rnd(-5,5)
	create.y		= Rnd(-5,5)
	create.z		= Rnd(-5,5)

'	create.xd		= Cos( ang1# ) * Cos( ang2# ) * speed#
'	create.yd		= Cos( ang1# ) * Sin( ang2# ) * speed#
'	create.zd		= Sin( ang1# ) * speed#
	
	create.r		= Rnd(1)
	create.g		= Rnd(1)
	create.b		= Rnd(1)
	
	create.alpha	= Rnd(1,1.5)
	
	ParticleList.Addlast Create

Next

End Function


Function InitOpenGL()

	LoadGLTextures	()
	
	glEnable		(GL_TEXTURE_2D)									' Enable Texture Mapping
	glShadeModel	(GL_SMOOTH)										' Enable Smooth Shading
	
	glClearColor	(0.0, 0.0, 0.0, 0.0)								' Black Background
	glClearDepth	(1.0)											' Depth Buffer Setup
	
	glDisable		(GL_DEPTH_TEST)									' Disable Depth Testing
	glEnable		(GL_BLEND)										' Enable Blending
	
	glBlendFunc	(GL_SRC_ALPHA,GL_ONE)								' Type Of Blending To Perform
	glDepthFunc	(GL_LEQUAL)										' The Type Of Depth Testing To Do
	
	glHint		(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)				' Really Nice Perspective Calculations
	
	glViewport	(0,0,XRES,YRES)									' Set viewport
	glMatrixMode	(GL_PROJECTION)									' Select The Projection Matrix
	glLoadIdentity	()												' Reset The Projection Matrix
	
	gluPerspective	(45.0,Float(XRES)/Float(YRES),0.1,100.0)				' Calculate Aspect Ratio 
	glMatrixMode	(GL_MODELVIEW)										' Select The Modelview Matrix
	glLoadIdentity	()

End Function



Function LoadGLTextures()
	
	Local TextureImage:TPixmap
	
	TextureImage:TPixmap=LoadPixmap("media/Spark.png")					' Load Particle Texture
	If TextureImage <> Null Then
		Print "Failed to load media/spark.png"
		Return
	EndIf
	
	glGenTextures	(1, Varptr Texname)									' Create One Texture
	
	glBindTexture	(GL_TEXTURE_2D, Texname)
	
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR)
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR)
	
	glTexImage2D	(GL_TEXTURE_2D, 0, 3, TextureImage.width, TextureImage.height,..
	 				0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage.pixels)
End Function


Doesn't seem to work at all in debug mode:
Unhandled Exception: Attempt to access field or method of Null object

Found the problem with that bit.

Const XRES=640
Const YRES=480
Const RRES= 32

bglCreateContext(XRES,YRES,RRES,0,BGL_BACKBUFFER | BGL_DEPTHBUFFER)
HideMouse


Global texname:Int

Global ParticleList:TList = New TList

'
' Create the Fireworks as a type.
'
Type Fireworks
	
	Field x#,y#,z#
	
	Field vy#
	
	Field xd#,yd#,zd#
	
	Field r#,g#,b#
	
	Field alpha#
	
	Field Blend%

End Type

Global ParticleCount

InitOpenGL()
glDisable(GL_CULL_FACE)
Print glGetError()
	
While Not KeyHit(KEY_ESCAPE)
	
	If MouseHit(1) Then CreateFireworks()

	RenderOpenGL()
	
	bglSwapBuffers()
	
	Delay 8
Wend



Function RenderOpenGL()

Local Update:Fireworks

	glClear 		(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)					' Clear The Screen And The Depth Buffer
	glLoadIdentity	()
	
	glTranslatef(0,0,-20)

	For Update = EachIn ParticleList
		
		glPushMatrix()
		glColor4f( Update.r, Update.g, Update.b, Update.Alpha)

		glTranslatef	(Update.x,Update.y,Update.z)			
	
		glBegin		(GL_QUADS)								'Draw using Quads.

			glVertex2f(-1.0,  1.0)							'Top Left.
			glVertex2f( 1.0,  1.0)							'Top Right.
			glVertex2f( 1.0,- 1.0)							'Bottom Right.
			glVertex2f(-1.0,- 1.0)							'Bottom Left.

		glEnd()												'Done Drawing The Quad.
	
		If update.Blend Then
			glBlendFunc(GL_SRC_ALPHA,GL_ONE)
		Else
			glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA)
		EndIf
	
'		
		Update.Alpha = Update.Alpha - .01
		
		If Update.Alpha <0
			ParticleList.Remove Update
		End If
'		
'		update.x		= update.x 		+ update.xd * 10
'		update.y		= update.y 		+ update.yd * 10
'		update.z		= update.z 		+ update.zd * 10
'		
'		update.y		= update.y		+ update.vy
'		update.vy		= update.vy		+ 0.02
		glPopMatrix()
		
	Next
	
End Function



Function CreateFireworks()

'
' Here we go For starters.
'		
Local x#=Rand( -5, 5 )
Local y#=Rand( -5, 5 )
Local z#=-20

'
' Colour scheme For this New batch of fireworks,
'
Local r#=Rand( 2 )
Local g#=Rand( 2 )
Local b#=Rand( 2 )

Local create:Fireworks 

For Local amount=1 To 100

	Local speed# 	= .00001

	Local ang1# 	= Rand( 360 )
	Local ang2# 	= Rand( 360 )

	create		= New Fireworks
	
	create.x		= Rnd(-5,5)
	create.y		= Rnd(-5,5)
	create.z		= Rnd(-5,5)

'	create.xd		= Cos( ang1# ) * Cos( ang2# ) * speed#
'	create.yd		= Cos( ang1# ) * Sin( ang2# ) * speed#
'	create.zd		= Sin( ang1# ) * speed#
	
	create.r		= Rnd(1)
	create.g		= Rnd(1)
	create.b		= Rnd(1)
	
	create.Blend = Rand(32) > 16
	
	create.alpha	= Rnd(1,1.5)
	
	ParticleList.AddLast Create

Next

End Function


Function InitOpenGL()

	glEnable		(GL_TEXTURE_2D)									' Enable Texture Mapping
	glShadeModel	(GL_SMOOTH)										' Enable Smooth Shading
	
	glClearColor	(0.0, 0.0, 0.0, 0.0)								' Black Background
	glClearDepth	(1.0)											' Depth Buffer Setup
	
	glDisable		(GL_DEPTH_TEST)									' Disable Depth Testing
	glEnable		(GL_BLEND)										' Enable Blending
	
	glDepthFunc	(GL_LEQUAL)										' The Type Of Depth Testing To Do
	
	glHint		(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)				' Really Nice Perspective Calculations
	
	glViewport	(0,0,XRES,YRES)									' Set viewport
	glMatrixMode	(GL_PROJECTION)									' Select The Projection Matrix
	glLoadIdentity	()												' Reset The Projection Matrix
	
	gluPerspective	(45.0,Float(XRES)/Float(YRES),0.1,100.0)				' Calculate Aspect Ratio 
	glMatrixMode	(GL_MODELVIEW)										' Select The Modelview Matrix
	glLoadIdentity	()

End Function


Thanks mate, what was it that you added? The GLPopMatrix?, and what else was wrong with it?

I'll work out the rest, thank you so much