Code archives/3D Graphics - Misc/OpenGL-like Point Primitives

This code has been declared by its author to be Public Domain code.

Download source code

OpenGL-like Point Primitives by Pepsi2004
Please read me comments at the top of the file at least! Thankyou...
; OpenGL-Like Point Primitives - Free for all! No $$$ required!
; History:
; Version 1
; - Original code by: Todd Riggins
; Version 2
; - Optimized for MORE speed and some code cleanup  By: DJWoodgate
; Version 3
; - Removed if statments with comparing projx/y to the point's size in which
;   eliminated unwanted graphic glitches.
; ------------------------------------------------------------------------
; Directions and notes
; ------------------------------------------------------------------------
; Use arrows to move around
; right mouse click to rotate camera
; - Notice how the square-ish points remain the same size no matter how close they
;   are to the camera! 
; - Unfortunitly this system is not fast enough for big "group vertice selections" like
;   you would want in moddeling editors. It's definitely fast enough for level editors like Maplet!
; - This system is all in 3D. Didn't want to use 2D graphics here. Doing this in 3D help'd me
;   mimic OpenGl point primitives pretty much To the T.
; !!!! If anybody has any ideas to speed this up, please let me know. Moving the vertices around all
; the time is what slows this system down the more point primitives you have.

; ------------------------------------------------------------------------
;  Superior Documentation...
; ------------------------------------------------------------------------
; thisPoint.POINTPRIMITIVE=AddPoint.POINTPRIMITIVE( x#, y#, z#)
;  		AddPoint returns a type handle to a newly created point primitive.
;        x#, y#, z# parameters = initial 3d location for point primitive.
; ------------------------------------------------------------------------
; PositionPoint(thisPoint.POINTPRIMITIVE, x#, y#, z#)
;		Position's an already created point primitive in a new 3d location.
; ------------------------------------------------------------------------
; PointSize(thisPoint.POINTPRIMITIVE,size)
; 		Make the point primitive smaller or bigger. Default = 2
; ------------------------------------------------------------------------
; PointBias(thisPoint.POINTPRIMITIVE,bias#)
;       Move the point closer to or further from the camera. Helps in 
;       z-buffering fighting issues. Default = 0.25
; ------------------------------------------------------------------------
; ColorPoint(thisPoint.POINTPRIMITIVE,red,green,blue)
; 		Be artistic! Color your point your favorite color! :P
; ------------------------------------------------------------------------
; DeletePoint(thisPoint.POINTPRIMITIVE)
;		Delete Point.
; ------------------------------------------------------------------------
; UpdatePoints(mycamera)
; 		Need this in the main loop! Pass your camera's handle in the parameter!
; ------------------------------------------------------------------------


; NOTE: xCameraControls is there just for example sakes...

Graphics3D 640, 480, 0, 2
SetBuffer BackBuffer(  )
Global grwidth = GraphicsWidth(), grheight=GraphicsHeight()
Global grhalfwidth = grwidth/2, grhalfheight = grheight/2

;camera
camera=CreateCamera()
CameraRange camera,0.1,1000
CameraClsColor camera,40,100,60	
PositionEntity camera, 0, 10, -25 

;light
Global light
light=CreateLight()
LightColor light,32,32,32
TurnEntity light,45,45,0

; various camera control variable helpers
Global dest_cam_yaw#
Global dest_cam_pitch#
Global mfb=0

; the point primitive structure 
Type POINTPRIMITIVE
	Field Px#
	Field Py#
	Field Pz#
	Field size
	Field bias#
	Field red
	Field green
	Field blue
	Field vi0
	Field vi1
	Field vi2
	Field vi3
	Field Deleted
End Type

; Single Surface Partical System For Point Primitives
; - All points use the same surface of the mesh, but they
; - own their own vertices each...

Global PointQuads=CreateMesh()
Global PQsSurf=CreateSurface(PointQuads)
EntityFX PointQuads,3 ; Points are vertex colored and fullbright

; !!!!!!!!!!!!!!!!!
; change 'number' to make more or less points
; !!!!!!!!!!!!!!!!!
number=15
For i=-number To number
	For j=-number To number
		thisPoint.POINTPRIMITIVE=AddPoint(i,0,j)
		ColorPoint(thisPoint,Rnd(127)+128,Rnd(127)+128,Rnd(127)+128)
	Next
Next

; ------------
; MAIN Example
; ------------
Repeat
	xCameraControls(camera)
	UpdatePoints(camera)
	RenderWorld
	Flip
Until KeyHit(1) = True

Function AddPoint.POINTPRIMITIVE(px#,py#,pz#)
	For newpoint.POINTPRIMITIVE = Each POINTPRIMITIVE
		If newpoint\deleted=True Then newpoint\deleted=False : Exit
	Next	
	If newpoint = Null Then
		newpoint.POINTPRIMITIVE = New POINTPRIMITIVE
		newpoint\vi0=AddVertex(PQsSurf, 0, 0,0);,0,0 ; 0 left top
		newpoint\vi1=AddVertex(PQsSurf, 0, 0,0);,1,0 ; 1 right top
		newpoint\vi2=AddVertex(PQsSurf, 0, 0,0);,0,1 ; 2 left bottom
		newpoint\vi3=AddVertex(PQsSurf, 0, 0,0);,1,1 ; 3 right bottom
		AddTriangle PQsSurf,newpoint\vi2,newpoint\vi0,newpoint\vi1 ; and 2 triangles...
		AddTriangle PQsSurf,newpoint\vi2,newpoint\vi1,newpoint\vi3
	EndIf
	PositionPoint(newpoint,px,py,pz)
	ColorPoint(newpoint,255,0,0)
	Pointsize(newpoint,2)
	PointBias(newpoint,0.25)
	Return newpoint	
End Function


Function PositionPoint(thisPoint.POINTPRIMITIVE,px#,py#,pz#)
	thisPoint\px = px : thispoint\py = py : thispoint\pz = pz
End Function

Function PointSize(thisPoint.POINTPRIMITIVE,size)
	thisPoint\size=size
End Function

Function PointBias(thisPoint.POINTPRIMITIVE,bias#)
	thisPoint\bias#=bias#
End Function

Function ColorPoint(thisPoint.POINTPRIMITIVE,red,green,blue)
	thisPoint\red=red
	thisPoint\green=green
	thisPoint\blue=blue
	VertexColor PQsSurf,thisPoint\vi0,thisPoint\red,thisPoint\green,thisPoint\blue
	VertexColor PQsSurf,thisPoint\vi1,thisPoint\red,thisPoint\green,thisPoint\blue
	VertexColor PQsSurf,thisPoint\vi2,thisPoint\red,thisPoint\green,thisPoint\blue
	VertexColor PQsSurf,thisPoint\vi3,thisPoint\red,thisPoint\green,thisPoint\blue
End Function

Function DeletePoint(thisPoint.POINTPRIMITIVE)
	VertexCoords PQsSurf,thisPoint\vi0,0,0,0
	VertexCoords PQsSurf,thisPoint\vi1,0,0,0
	VertexCoords PQsSurf,thisPoint\vi2,0,0,0
	VertexCoords PQsSurf,thisPoint\vi3,0,0,0
	thisPoint\deleted=True
End Function

Function UpdatePoints(mycamera)
	Local TlX#, TLY#, TLZ#, TRX#, TRY#, TRZ#, BLX#, BLY#, BLZ#, BRX#, BRY#, BRZ#
	Local Zdist#, ProjX#, ProjY#

	; loop through and update points...
	For thisPoint.POINTPRIMITIVE = Each POINTPRIMITIVE
		If Not thispoint\deleted 	
			; Project point position to screen
			CameraProject mycamera,thispoint\px,thispoint\py,thispoint\pz
			projx = ProjectedX() : projy = ProjectedY()
			; if on screen then...
			If ProjectedZ()>0 
				; Get distance of point from the camera viewplane
				TFormPoint thispoint\px,thispoint\py,thispoint\pz, 0,mycamera
				zdist = TFormedZ()-thispoint\bias
				; project our box back into worldspace
				Reverseproject(mycamera,projx-thispoint\size,projy-thispoint\size,Zdist)
					TLX#=TFormedX#()
					TLY#=TFormedY#()
					TLZ#=TFormedZ#()
				Reverseproject(mycamera,projx+thisPoint\size,projy-thisPoint\size,Zdist)
					TRX#=TFormedX#()
					TRY#=TFormedY#()
					TRZ#=TFormedZ#()
				Reverseproject(mycamera,projx-thisPoint\size,projy+thisPoint\size,Zdist)
					BLX#=TFormedX#()
					BLY#=TFormedY#()
					BLZ#=TFormedZ#()
				Reverseproject(mycamera,projx+thisPoint\size,projy+thisPoint\size,Zdist)
					BRX#=TFormedX#()
					BRY#=TFormedY#()
					BRZ#=TFormedZ#()
				; Update the point in worldspace
				VertexCoords PQsSurf,thisPoint\vi0,TLX#,TLY#,TLZ#
				VertexCoords PQsSurf,thisPoint\vi1,TRX#,TRY#,TRZ#
				VertexCoords PQsSurf,thisPoint\vi2,BLX#,BLY#,BLZ#
				VertexCoords PQsSurf,thisPoint\vi3,BRX#,BRY#,BRZ#
			EndIf
		EndIf
	Next							
End Function

; Reverse project a point. Need to specify camzoom and Z
; will not deal with scaled cameras so don't!
Function Reverseproject(cam,sx#,sy#,z#,zoom#=1,dest=0)
	Local f#,x#,y#
	f# = Zoom * grhalfwidth
	x = ((sx-grhalfwidth)/f)  * z
	y = ((grhalfheight-sy)/f) * z
	TFormPoint x,y,z,cam,dest ; camera to dest (0 for world)
End Function


Function xCameraControls(mycamera)

	Local thisspeed#=0.25
	Local thisUnitSqr#=1.0

	If MouseDown(1)=0 And MouseDown(2)=0 Then mfb=0

		;zoom
	   	If KeyDown(208) Then MoveEntity mycamera,0,0,-thisspeed#
	   	If KeyDown(200) Then MoveEntity mycamera,0,0,thisspeed#
	
		;straff left/right
		If KeyDown(203) Then MoveEntity mycamera,-thisspeed#,0,0
		If KeyDown(205) Then MoveEntity mycamera,thisspeed#,0,0
   
		;elevate up/down
		If KeyDown(157) Then MoveEntity mycamera,0,-thisspeed#,0
		If KeyDown(54) Then MoveEntity mycamera,0,thisspeed#,0

		If MouseDown(2)=True And mfb=0
			mfb=1
			MoveMouse GraphicsWidth()/2,GraphicsHeight()/2
		EndIf

		If MouseDown(2)=False And mfb=1
			mfb=0
		EndIf	
	
		If mfb>0
			mxs#=MouseXSpeed()
			mys#=MouseYSpeed()
	
			dest_cam_yaw#=dest_cam_yaw#-mxs#
			dest_cam_pitch#=dest_cam_pitch#+mys#
			RotateEntity mycamera,dest_cam_pitch#,dest_cam_yaw#,0
			MoveMouse GraphicsWidth()/2,GraphicsHeight()/2
		EndIf
	
End Function

Comments

N2004
As you mentioned, moving the vertices around does slow it down. As such, I think a good idea would be to just free the surface and recreate all the vertices and triangles again. That seems to have an effect for the better on most operations.

Also, instead of using CameraPick you should consider utilizing some other system for aligning the points correctly. (I don't want to write up another reply concerning that though ;] )

Funky work though, anything similar to OpenGL is good in my book :)


Pepsi2004
I'll look into the recreation way.

Being that this system needs to have all other pickable entities hidden, HideEntity them all, where as it only has it's own quad plane to pick from, would CameraPick be that slow to try to come up with an alternative math solution? I know the math to do my own "linepicks", it's just easier this way. :/

Thanks for the feedback


DJWoodgate2004
I do not think you need those updateworlds() in Updatepoints. Removing those speeds it up a bit. And my guess is that the built in camerapick or linepick are EVIL in this context. (Perhaps as Noel is suggesting?)

Avoid them like the PLAGUE. Vertexcoords itself is plenty fast as single surface particle systems would lead you to suspect, so if you can find another way of doing this using your own routines you will not need to rebuld the mesh.

I seem to remember that the explanation "from the top" is that using the "pick" functions forces blitz to rebuild its internal collision model whenever you change a mesh, and as you are changing a mesh every frame..., well you get the picture. Its not that they are of themselves particularly slow, in this context anyway.

Of course this begs the question of why this should happen if the mesh in question is not even pickable and has no collisions set. Maybe Mark can clear this one up?


DJWoodgate2004
The pwoof of the pudding. Not making any claims about its accuracy mind, but it is a tad faster.

; OpenGL-Like Point Primitives - By: Todd Riggins - Free for all! No $$$ required!
; Version Ooo.err.4 (D. Woodgate)  Fixes the nasty graphic glitches by another means and added a 
; camerazoom option and chasecam to the example. Is it any faster than before - err, no not really :(
 
; Use arrows to move around
; right mouse click to rotate camera
; - Notice how the square-ish points remain the same size no matter how close they
;   are to the camera! 
; - Unfortunitly this system is not fast enough for big "group vertice selections" like
;   you would want in moddeling editors. It's definitely fast enough for level editors like Maplet!
; - This system is all in 3D. Didn't want to use 2D graphics here. Doing this in 3D help'd me
;   mimic OpenGl point primitives pretty much To the T.
; !!!! If anybody has any ideas to speed this up, please let me know. Moving the vertices around all
; the time is what slows this system down the more point primitives you have.

; ------------------------------------------------------------------------
;  Superior Documentation...
; ------------------------------------------------------------------------
; thisPoint.POINTPRIMITIVE=AddPoint.POINTPRIMITIVE( x#, y#, z#)
;  		AddPoint returns a type handle to a newly created point primitive.
;        x#, y#, z# parameters = initial 3d location for point primitive.
; ------------------------------------------------------------------------
; PositionPoint(thisPoint.POINTPRIMITIVE, x#, y#, z#)
;		Position's an already created point primitive in a new 3d location.
; ------------------------------------------------------------------------
; PointSize(thisPoint.POINTPRIMITIVE,size)
; 		Make the point primitive smaller or bigger. Default = 2
; ------------------------------------------------------------------------
; PointBias(thisPoint.POINTPRIMITIVE,bias#)
;       Move the point closer to or further from the camera. Helps in 
;       z-buffering fighting issues. Default = 0.25
; ------------------------------------------------------------------------
; ColorPoint(thisPoint.POINTPRIMITIVE,red,green,blue)
; 		Be artistic! Color your point your favorite color! :P
; ------------------------------------------------------------------------
; DeletePoint(thisPoint.POINTPRIMITIVE)
;		Delete Point.
; ------------------------------------------------------------------------
; UpdatePoints(mycamera)
; 		Need this in the main loop! Pass your camera's handle in the parameter!
; ------------------------------------------------------------------------


; NOTE: xCameraControls is there just for example sakes...

Graphics3D 800, 600;, 0, 2
SetBuffer BackBuffer(  )
Global grwidth = GraphicsWidth(), grheight=GraphicsHeight()
Global grhalfwidth = grwidth/2, grhalfheight = grheight/2

;camera
camzoom# = 1
camera=CreateCamera()
CameraRange camera,0.1,1000
CameraClsColor camera,40,100,60	
PositionEntity camera, 0, 10, -25
chasecam=CreateCamera(camera)
PositionEntity chasecam,0,0,-5
;RotateEntity overcam,90,0,0
CameraViewport chasecam,600,0,200,200
CameraClsColor chasecam,30,80,50
HideEntity chasecam

;light
Global light
light=CreateLight()
LightColor light,32,32,32
TurnEntity light,45,45,0

; various camera control variable helpers
Global dest_cam_yaw#
Global dest_cam_pitch#
Global mfb=0

; the point primitive structure 
Type POINTPRIMITIVE
	Field Px#
	Field Py#
	Field Pz#
	Field size
	Field bias#
	Field red
	Field green
	Field blue
	Field vi0
	Field vi1
	Field vi2
	Field vi3
	Field Visible
	Field Deleted
End Type

; Single Surface Partical System For Point Primitives
; - All points use the same surface of the mesh, but they
; - own their own vertices each...

Global PointQuads=CreateMesh()
Global PQsSurf=CreateSurface(PointQuads)
EntityFX PointQuads,3 ; Points are vertex colored and fullbright

; !!!!!!!!!!!!!!!!!
; change 'number' to make more or less points
; !!!!!!!!!!!!!!!!!

pointsize=2
number=25
For i=-number To number
	For j=-number To number
		thisPoint.POINTPRIMITIVE=AddPoint(i,0,j, pointsize)
		ColorPoint(thisPoint,Rnd(127)+128,Rnd(127)+128,Rnd(127)+128)
	Next
Next

; ------------
; MAIN Example
; ------------
newsize=pointsize
Ftime=MilliSecs()+1000
Repeat
	If KeyHit(57) Then chaseview=Not chaseview ; spacebar
	If chaseview Then ShowEntity chasecam Else HideEntity chasecam
	If KeyDown(201) Then camzoom=camzoom+0.1 ; Pageup
	If camzoom>10 Then camzoom=10
	If KeyDown(209) Then camzoom=camzoom-0.1 ; Pagedown
	If camzoom<0.1 Then camzoom=0.1
	CameraZoom camera,camzoom

	If KeyHit(78) Then newsize=pointsize+1 ; numpad +
	If KeyHit(74) Then newsize=pointsize-1 ; numpad -
	If newsize>50 Then newsize=50
	If newsize<1 Then newsize=1
	If newsize<>pointsize Then pointsize=newsize : pointsize(Null,pointsize)
	

	xCameraControls(camera)
	time=MilliSecs()
	UpdatePoints(camera,camzoom)
	time=MilliSecs()-time
	RenderWorld

	Text 0,0,TrisRendered()+" "+time+" "+fps
	frame=frame+1 : If MilliSecs()>=ftime Then fps=frame : frame=0 : Ftime=ftime+1000
	Flip
Until KeyHit(1) = True

Function AddPoint.POINTPRIMITIVE(px#,py#,pz#, pointsize=2)
	Local newpoint.POINTPRIMITIVE = Last POINTPRIMITIVE
	; deleted points are stuck at the end of the list, so
	If newpoint<>Null
		If newpoint\deleted ; if last entry was deleted then reuse it
			newpoint\deleted=False 
			Insert newpoint Before First POINTPRIMITIVE
		Else
			newpoint = Null ; no deleted points to reuse
		EndIf
	EndIf
	; there is no deleted point to reuse so make a new one
	If newpoint=Null 
		newpoint.POINTPRIMITIVE = New POINTPRIMITIVE
		Insert newpoint Before First POINTPRIMITIVE
		newpoint\vi0=AddVertex(PQsSurf, 1000000, 1000000, 1000000);,0,0 ; 0 left top
		newpoint\vi1=AddVertex(PQsSurf, 1000000, 1000000, 1000000);,1,0 ; 1 right top
		newpoint\vi2=AddVertex(PQsSurf, 1000000, 1000000, 1000000);,0,1 ; 2 left bottom
		newpoint\vi3=AddVertex(PQsSurf, 1000000, 1000000, 1000000);,1,1 ; 3 right bottom
		AddTriangle PQsSurf,newpoint\vi2,newpoint\vi0,newpoint\vi1 ; and 2 triangles...
		AddTriangle PQsSurf,newpoint\vi2,newpoint\vi1,newpoint\vi3
	EndIf
	PositionPoint(newpoint,px,py,pz)
	ColorPoint(newpoint,255,0,0)
	Pointsize(newpoint,pointsize)
	PointBias(newpoint,0.25)
	Return newpoint	
End Function


Function PositionPoint(thisPoint.POINTPRIMITIVE,px#,py#,pz#)
	thisPoint\px = px : thispoint\py = py : thispoint\pz = pz
End Function

Function PointSize(thisPoint.POINTPRIMITIVE,size)
	If thispoint=Null Then
		For thispoint = Each POINTPRIMITIVE 
			thispoint\size=size
		Next
	Else
		thisPoint\size=size
	EndIf
End Function

Function PointBias(thisPoint.POINTPRIMITIVE,bias#)
	thisPoint\bias#=bias#
End Function

Function ColorPoint(thisPoint.POINTPRIMITIVE,red,green,blue)
	thisPoint\red=red
	thisPoint\green=green
	thisPoint\blue=blue
	VertexColor PQsSurf,thisPoint\vi0,thisPoint\red,thisPoint\green,thisPoint\blue
	VertexColor PQsSurf,thisPoint\vi1,thisPoint\red,thisPoint\green,thisPoint\blue
	VertexColor PQsSurf,thisPoint\vi2,thisPoint\red,thisPoint\green,thisPoint\blue
	VertexColor PQsSurf,thisPoint\vi3,thisPoint\red,thisPoint\green,thisPoint\blue
End Function

Function DeletePoint(thisPoint.POINTPRIMITIVE)
	VertexCoords PQsSurf,thisPoint\vi0,1000000,1000000,1000000
	VertexCoords PQsSurf,thisPoint\vi1,1000000,1000000,1000000
	VertexCoords PQsSurf,thisPoint\vi2,1000000,1000000,1000000
	VertexCoords PQsSurf,thisPoint\vi3,1000000,1000000,1000000
	thisPoint\deleted=True
	Insert thisPoint After Last POINTPRIMITIVE
End Function

Function UpdatePoints(mycamera,zoom#)
	Local TLX#, TLY#, TLZ#, TRX#, TRY#, TRZ#, BLX#, BLY#, BLZ#, BRX#, BRY#, BRZ#
	Local Zdist#, ProjX#, ProjY#

	; loop through and update points...
	For thisPoint.POINTPRIMITIVE = Each POINTPRIMITIVE
		If thispoint\deleted Then Exit 	; All deleted points are put at end of type list
		; Project point position to screen
		CameraProject mycamera,thispoint\px,thispoint\py,thispoint\pz
		projx = ProjectedX() : projy = ProjectedY() : onscreen = False

		If ProjectedZ()>0 	; if in front of camera then check if on screen
			If projx+thispoint\size>=0 And projx-thispoint\size<=grwidth 
				If projy+thispoint\size>=0 And projy-thispoint\size<=grheight
					thispoint\visible=True : onscreen = True
					; Get distance of point from the camera viewplane
					TFormPoint thispoint\px,thispoint\py,thispoint\pz, 0,mycamera
					zdist = TFormedZ()-thispoint\bias
					; project our square back into worldspace
					Reverseproject(mycamera,projx-thispoint\size,projy-thispoint\size,Zdist,zoom)
						TLX = TFormedX()
						TLY = TFormedY()
						TLZ = TFormedZ()
					Reverseproject(mycamera,projx+thisPoint\size,projy+thisPoint\size,Zdist,zoom)
						BRX = TFormedX()
						BRY = TFormedY()
						BRZ = TFormedZ()
					Reverseproject(mycamera,projx+thisPoint\size,projy-thisPoint\size,Zdist,zoom)
						TRX = TFormedX()
						TRY = TFormedY()
						TRZ = TFormedZ()
					Reverseproject(mycamera,projx-thisPoint\size,projy+thisPoint\size,Zdist,zoom)
						BLX = TFormedX()
						BLY = TFormedY()
						BLZ = TFormedZ()
					; Update the point in worldspace
					VertexCoords PQsSurf,thisPoint\vi0,TLX#,TLY#,TLZ#
					VertexCoords PQsSurf,thisPoint\vi1,TRX#,TRY#,TRZ#
					VertexCoords PQsSurf,thisPoint\vi2,BLX#,BLY#,BLZ#
					VertexCoords PQsSurf,thisPoint\vi3,BRX#,BRY#,BRZ#
				EndIf
			EndIf
		EndIf
		If Not onscreen	; if point not onscreen this frame...
			If thispoint\visible Then ; but it was onscreen last time hide it away and...
				thispoint\visible=False	; record that it is no longer visible
				VertexCoords PQsSurf,thisPoint\vi0,1000000,1000000,1000000
				VertexCoords PQsSurf,thisPoint\vi1,1000000,1000000,1000000
				VertexCoords PQsSurf,thisPoint\vi2,1000000,1000000,1000000
				VertexCoords PQsSurf,thisPoint\vi3,1000000,1000000,1000000
			EndIf						
		EndIf
	Next							
End Function

; Reverse project a point. Need to specify camzoom and Z
; will not deal with scaled cameras so don't!
Function Reverseproject(cam,sx#,sy#,z#,zoom#=1,dest=0)
	Local f#,x#,y#
	f# = Zoom * grhalfwidth
	x = ((sx-grhalfwidth)/f)  * z
	y = ((grhalfheight-sy)/f) * z
	TFormPoint x,y,z,cam,dest ; camera to dest (0 for world)
End Function


Function xCameraControls(mycamera)

	Local thisspeed#=0.25
	Local thisUnitSqr#=1.0

	If MouseDown(1)=0 And MouseDown(2)=0 Then mfb=0

		;zoom
	   	If KeyDown(208) Then MoveEntity mycamera,0,0,-thisspeed#
	   	If KeyDown(200) Then MoveEntity mycamera,0,0,thisspeed#
	
		;straff left/right
		If KeyDown(203) Then MoveEntity mycamera,-thisspeed#,0,0
		If KeyDown(205) Then MoveEntity mycamera,thisspeed#,0,0
   
		;elevate up/down
		If KeyDown(157) Then MoveEntity mycamera,0,-thisspeed#,0
		If KeyDown(54) Then MoveEntity mycamera,0,thisspeed#,0

		If MouseDown(2)=True And mfb=0
			mfb=1
			MoveMouse GraphicsWidth()/2,GraphicsHeight()/2
		EndIf

		If MouseDown(2)=False And mfb=1
			mfb=0
		EndIf	
	
		If mfb>0
			mxs#=MouseXSpeed()
			mys#=MouseYSpeed()
	
			dest_cam_yaw#=dest_cam_yaw#-mxs#
			dest_cam_pitch#=dest_cam_pitch#+mys#
			RotateEntity mycamera,dest_cam_pitch#,dest_cam_yaw#,0
			MoveMouse GraphicsWidth()/2,GraphicsHeight()/2
		EndIf
	
End Function




Pepsi2004
Very Nice Indeed! :))))

An example compared to my old way:

On my machine, in my original code, updating 1024 vertices got pretty slow and choppy to move around.

Now with your code, to get that same slowness, I would have to update around 10,500 vertices.

I think that is a very big improvement! Now one can probably make a good low poly modeller with these points if so desired. Thanks for the very cool improvement, David! :D Now to look to see what ya did...

Edit: Archive updated...


Pepsi2004
There is a little side effect where if you use your mouse and while moving left or right in a cicle above the plane of points, some wierd things happen to points to the side as they move into view.

Tis not that bad and won't worry about that for now. Still though, I'm totally grateful for the speedup, David! Thanks again and again! :D


DJWoodgate2004
Yes, I think that is mostly due to the way I have applied the bias. It can push the projection point behind the camera near plane which is a no no. Probably best to apply the bias against the normals of your target object vertices.


Pepsi2004
In the function "UpdatePoints(mycamera)", I removed the if statements comparing projx/y with the size of the point and the graphical glitches went away.


DJWoodgate2004
Yes, I know :) Trouble is that does slow things down a tad. It works though because now anything in front on the camera is updated. The quads are dumped in the wrong positions behind the camera near plane. So when you move the camera a bit you see those meshes, but the actual points they refer to are not necessarily in view, so they do not get updated correctly. However it is a fix of sorts I suppose. I did try to limit the bias to the camera near plane, but it still failed... I am overlooking something obvious here no doubt. Anyway another alternative might be to determine the appropriate size of the quads in camera space, clip to the view frustrum and align them to the camera view plane without all this reverse projection nonsense. Better perhaps, but not quite so easy for me to figure out :)


Pepsi2004
Still can't see what your seeing... still trying...


DJWoodgate2004
Stop then :) I was missing the obvious. The biased point quad will not be in the same position or orientation when you move the camera, and so the check to see if the actual point is on screen is neither here or there because the biased quad might be. So its probably easier to just to update everything in front of the camera plane, rather than add yet more checks to see if the biased quad is also on screen. In fact if you get particularly acrobatic with the camera that still might not be good enough.


Pepsi2004
Aight, yeah I was just thinking about how much clipping would slow down something like this... :)


big10p2004
Interesting stuff. It just so happens that I've been working on a similar system for inclusion in a simple model viewer I'm doing. However, I've taken the different approach of trying to build the point quads to the correct size instead of doing the 'reverse projection' method you use.

It's been mostly successful except for the occasional glitch where a point quad is rendered at slightly the wrong size. For some reason, this effect is especially noticeable in 640x480 mode - I'm not sure why. Not a prob for me, though, as my app runs in 800x600. Got more testing/tweaking to do so I might be able to improve things, anyway.

Its pretty nippy(ish), too - I get about 38FPS displaying a full 10,000 points on my 1GHZ/GF2 machine. Works with zoomed and/or scaled cameras, also.

Anyway, if anyone's interested, I could post the code here? Thought I better ask beforehand as I don't want to hog your achive entry, Todd. ;)


Pepsi2004
Hey no problem! Up to you. :) "IF" I where you I would just go ahead and submit it to the archives as a seperate entry. As the old saying goes... "there's alot of different ways to do the same thing in programming!". Anyways, looking forward to see your method! :)


big10p2004
OK, I'll post as a separate archive when it's ready. Having a bit of a setback at the mo as my PSU decided to blow and cause merry havoc. :/


Code Archives Forum