round camera view

Blitz3D Forums/Blitz3D Programming/round camera view

I want to make a round radar screen at the bottom left of my game. I would like to use a second camera to render to this area. Is there any possible way to get it to render to a circular portion of the screen?

I'm not a whiz at this sort of thing, but an idea comes to mind...
1. render your normal screen
2. copy the rectangular portion of the screen where you will be drawing the circular image to another buffer BUT ONLY the outside 'ring' portion (i.e. what would be left if you cut a circle out of a square). That's only 14% of the square that has to be copied.
3. render to the square area with your second camera (remember to use CameraClsMode)
4. copy back to that square the outside ring that you saved earlier.

Or...

Render to an imagebuffer
Make the outside bits of the circle 255,0,255 (or whatever mask colour)
drawimage the resultant image with a mask of 255,0,255 after the renderworld


Bit of code to demostrate... move the mouse around!
Graphics3D 640,480

For n=1 To 100
	b=CreateCube()
	PositionEntity b,Rnd(-50,50),0,Rnd(-50,50)
	RotateEntity b,Rnd(0,360),Rnd(0,360),Rnd(0,360)
Next

camera1 = CreateCamera()
CameraClsColor camera1,100,100,100
PositionEntity camera1,0,100,0
RotateEntity camera1,90,0,0
light = CreateLight()
RotateEntity light,45,0,0

camera2 = CreateCamera()
CameraViewport camera2,0,0,128,128
HideEntity camera2

player = CreateCube()
EntityColor player,255,0,0

radar = CreateImage(128,128)
MaskImage radar,255,0,255

rmx=1:rmy=1

Repeat
	; Mouse pointer type affair
	mx# = MouseXSpeed()
	my# = -MouseYSpeed()
	MoveMouse 320,240
	
	TranslateEntity player,mx*.2,0,my*.2
	PositionEntity camera2,EntityX(player),0,EntityZ(player)
		
	; Render the radar and copy to the radar image
	HideEntity camera1:ShowEntity camera2
	RenderWorld
	CopyRect 0,0,128,128,0,0,BackBuffer(),ImageBuffer(radar)
	
	; Render the regular camera
	HideEntity camera2:ShowEntity camera1
	RenderWorld
	
	; Lock the radar for drawing the mask
	LockBuffer ImageBuffer(radar)
	For x=-64 To 63
	For y=-64 To 63
		If (x*x)+(y*y)>(63*63) Then WritePixelFast x+64,y+64,255+(65536*255),ImageBuffer(radar)
	Next
	Next
	UnlockBuffer ImageBuffer(radar)
	
	; draw the radar
	DrawImage radar,rx,ry
	
	; move the radar around the screen
	rx=rx+rmx
	ry=ry+rmy
	If rx<=0 Or rx>=512 Then rmx=-rmx
	If ry<=0 Or ry>=352 Then rmy=-rmy
	
	Flip
Until KeyHit(1)


I do this in my game. I render to the backbuffer then copy the image to a texture. Then I display a circular mesh (like a pie) made from triangles with the texture mapped to it.

No need to mess with pixels at all.

Sounds like a better solution!

You can see a round window in this vid:

http://www.zee-3.com/video/chunks.wmv

It's fast enough for realtime use - my game has up to four of these on screen at once. A nice feature is that the window can be rotated\scaled\alpha'd etc.

Ah, I was wondering recently how you were doing your circular camera views, John. The masking method discussed above immediately occured to me but it's flawed, since the camera image itself could feasibly contain mask-coloured pixels.

The textured 'pie' mesh seems such an obvious solution, now.

Thanks! I thought that this would be much harder, but now it seems so easy!

Thanks a million!

One more question,
John, how many triangles do you use for your circular mesh?

I'm only using about 17 at the moment. The mesh has the smallest number of triangles I could get away with but I draw a sprite over the top which gives it a perfectly circular frame.

Hi John,

I've been trying to recreate this effect myself without much luck. Could you post some basic code so we can see how it's implemented?

Cheers!

Which bit are you having problems with? Rendering the texture, creating the pie-mesh or displaying it?

Displaying it is the problem. I created an object in Lightwave (a disc with 16 tri segments), converted it to .b3d and load it into my scene. It displays fine but the texture I output is frozen on the first frame. I guess I might have a problem somewhere in my program loop :-/