How to Calculate CameraZoom for 1:1 pixels

Blitz3D Forums/Blitz3D Programming/How to Calculate CameraZoom for 1:1 pixels

Orca(Posted 2003) [#1]
Hey everyone,

I'm working on a single surface 2d thing, and I can't seem to get my head around this part.

I'm setting up my quads so that each blitz unit is equal to a pixel. That is, a 32x32 image would be converted to a 32x32 quad..

Problem is I cant seem to work out an accurate way of moving/zooming the camera so that 640x480 blitz units matches perfectly to 640x480 pixels. This seems like it wouldnt be that hard but I suck at "maths" :)

I've looked in the code sections here and on blitzcoder BUT (I'm probably just being thick) it seems the related code snippets I've looked at seem to do the opposite of what I want.. I need a proper way of figuring out how far on the z axis to move the camera back(or zoom level would work too) so I get the 1:1 thing.

If anyone could help it would be most appreciated. Spanks ;)


TartanTangerine (was Indiepath)(Posted 2003) [#2]
Surely you'd be wanting this..

http://www.blitzbasic.co.nz/codearcs/codearcs.php?code=773


Orca(Posted 2003) [#3]
Thanks. :D

I had looked at that already but I guess I really need to look thru that snippet and study it.


RiK(Posted 2003) [#4]
Now if ever there was a tutorial crying out to be made this was it....

Perhaps one day Anthony Flack will finish Cletus and tell us all how to do it :)


Orca(Posted 2003) [#5]
I think everyones seen it but anthonys post on bc was very informative...http://www.blitzcoder.com/cgi-bin/ubb-cgi/postdisplay.cgi?forum=Forum14&topic=000868

I got past the first steps, now I need to get this camera issue sorted OR find a plan b. I think I'm gonna revive that bc thread in hopes that hell enlighten us some more o_O


jfk EO-11110(Posted 2003) [#6]
this one uses the camerazoom in a simple way:

http://www.blitzbasic.com/codearcs/codearcs.php?code=321


EOF(Posted 2003) [#7]
Here is a basic 'bare-bones' version of my SpriteControl which will get your quads on screen with mimimum of fuss:
; "Sprite Control BASIC.bb" - 'Bare Bones' include

Global spritepivot,spritecamera

; Create a complete sprite display with camera/pivot
Function SpriteGraphics3D(gw,gh,d=0,m=0,dist#=1)
	Graphics3D gw,gh,d,m
	SetBuffer BackBuffer()
	spritecamera=CreateCamera()
	spritepivot=CreatePivot(spritecamera)
	Local aspect#=Float(gh)/Float(gw)
	Local scale#=2.0/gw
	PositionEntity spritepivot,-1,aspect,dist
	ScaleEntity spritepivot,scale,scale,scale
	Return spritepivot
End Function

; Loads an image into a texture and attaches it to sprite quad
Function LoadImage3D(file$,texflags=4,par=-1)
	; Create quad mesh
	If par=-1 par=spritepivot
	Local sprite=CreateMesh(par)
	Local s=CreateSurface(sprite)
	AddVertex s,0,0,0 ,0,0 : AddVertex s,2,0,0 , 1,0
	AddVertex s,0,-2,0 ,0,1 : AddVertex s,2,-2,0 , 1,1
	AddTriangle s,0,1,2 : AddTriangle s,3,2,1
	; transfer image into texture buffer (with alpha)
	Local tmpimage=LoadImage(file$)
	Local spritetexture=LoadTexture(file$,texflags)
	Local iw=ImageWidth(tmpimage) , ih=ImageHeight(tmpimage)
	Local tw=TextureWidth(spritetexture) , th=TextureHeight(spritetexture)
	If iw<>tw Or ih<>th
		ib=ImageBuffer(tmpimage)
		tb=TextureBuffer(spritetexture)
		For x=0 To iw-1
			For y=0 To ih-1
				rgbc=ReadPixel(x,y,ib) And $00ffffff
				If rgbc=((r Shl 16)+(g Shl 8)+b)
					WritePixel x,y,($00000000),tb
				Else
					WritePixel x,y,(rgbc Or $ff000000),tb
				EndIf
			Next
		Next
	EndIf
	FreeImage tmpimage
	; Texture and resize sprite. Move handle to top/left
	ScaleTexture spritetexture,Float(tw)/Float(iw),Float(th)/Float(ih)
	EntityTexture sprite,spritetexture
	EntityFX sprite,1+16 : EntityOrder sprite,-100
	ScaleEntity sprite,Float(iw)/2,Float(ih)/2,1
	PositionEntity sprite,-10000,-10000,0
	Return sprite
End Function

; Position 3d sprite at 2D screen coordinates
Function DrawImage3D(sprite,x,y,z=0)
	PositionEntity sprite,x+0.5,-y+0.5,0
End Function

; Flush out an existing quad sprite and it's texture
Function FreeImage3D(sprite)
	Local brush=GetEntityBrush(sprite)
	Local tex=GetBrushTexture(brush)
	If brush<>0 FreeBrush brush
	If tex<>0 FreeTexture tex
	If sprite<>0 FreeEntity sprite
End Function


An example piece of test code:
Include "Sprite Control BASIC.bb"

Const sw=640,sh=480

SpriteGraphics3D sw,sh
CameraClsColor spritecamera,50,10,70

; load and create quad sprite
quad=LoadImage3D("myimage.bmp")

; position the quad
DrawImage3D quad,sw/2,sh/2
RenderWorld
Flip
WaitKey

; cleanup
FreeImage3D quad

End

The above works with the main camera set at the default zoom ratio of 1.
If you zoom the main camera (1 onwards) then use this function which zooms the camera as well as the sprite pivot:
; Use this command to zoom the main camera and sprite pivot
; NOTE: Only positive values if 1 and greater can be used
Function CameraZoom3D(cam,z#)
	If z<1 z=1
	If EntityClass$(cam)="Camera" CameraZoom cam,z
	Local numchilds=CountChildren(cam)
	If numchilds>0
	For c=1 To numchilds
		Local child=GetChild(cam,c)
		If EntityName$(child)="SpriteControl Pivot"
			PositionEntity child,EntityX(child),EntityY(child),z+0.001
		EndIf
	Next
	EndIf
End Function


With the above example you would then use:
CameraZoom3D spritecamera,zoomamount#

Hope that helps.
Note: The above is mainly thanks to skidracer and his 'pixies' method for displaying pixel-perfect sprites.


Al Mackey(Posted 2003) [#8]
If you want some of the basic technical theory, these tips might help:

The camera, by default, has a zoom value of 1.0, which gives it a 90 degree field of view horizontally. This might be a little wide for full 3D stuff, but it's a fairly handy level of zoom to deal with for this sort of thing.

With a 90 degree field of view, an object that's one unit wide placed centered but one unit away from the camera will take up exactly the full width of the frame.

So if you have an object that's 640 units wide and 480 units tall, placed at 0, 0, 640 relative to the camera, it should have that 1:1 ratio you're looking for.

If you're keeping all your objects and sprites at the same distance away from the camera, remember that using EntityOrder() can be used to override the Z-buffer and tell the rendering engine what goes on top of what.


RiK(Posted 2003) [#9]
Al, thats useful info, thanks!


Shambler(Posted 2003) [#10]
Very useful, thanks for that Al.


RiK(Posted 2003) [#11]
Syntax Error's Sprite Control stuff is really interesting...

I'm in the final stages of a purely 2d game at the mo, but for my next project I'm planning to do 2d-in-3d and so the first item on the agenda is a single surface sprite engine.

Syntax Error and Skidracers positioning stuff will come in very useful I'm sure :)