2d camera?
BlitzMax Forums/MiniB3D Module/2d camera?
| ||
Hi all, i don't suppose anyone has got any code floating around that makes the MiniB3D camera behave like it would in Max2D, i.e. have 0,0 in the top left corner and 800*600 or whatever in the bottom right? I was looking at the possibility of making a 2d-in-3d style game based on some existing code that uses these coordinates, and just wanted to replace the drawing commands and not the logic. Cheers Charlie |
| ||
Sory I don't have a sample off hand but look into CameraProjMode() setting the projection mode to orthographic essentially removes the depth perspective from the view (but not depth itself), then it's just a matter of setting CameraZoom and the distance to your objects. you will probably need to make a converter between pixel positons and 3d positions as 800 is a pretty big number in 3d unless you scale everything up. However one nice thing about using a 3d as 2d view is that the scale will stay the same regardless of the screen resolution (as long as you don't change the screen ratio) so moving your object 2 units to the right does the same thing at 800x600 as it does at 1280x960, all the smoothing and pixel precision is taken care of by the 3d engine. You can do it without using orthographic view if you want to keep visible depth but I found it's a bit harder, though far from impossible to get the camera lined up right. the bigger problem is getting the layer order right and keeping track of it. if you want to draw everything at the same depth to keep the same scale, use collision etc. you need to use EntityOrder() to set the draw order of you get graphical glitches from objects drawing through each other. Hope that gets you started. I'm using some 3d as 2d in one of my current projects, I'll try to dig out a sample if you need more help. |
| ||
some absolutely for dummies sample code would be awesome, especially if as you say the scale would stay the same despite the resolution. either way i'll take a look at using orthographic view. Cheers Charlie |
| ||
ok, after a bit of fiddling, i managed to come up with the following code, which is ok but the y coords appear upside down (as they should i guess, cartesian coordinates are this way up). is there any way to 'flip' the camera upside down so that 0,0 appears at the top left instead of the bottom left? i know that it wouldn't be too difficult to allow for this in my code, but it would mean changing quite a lot of stuff, and i'd like to avoid this ideally. Import sidesign.minib3d Graphics3D 800, 600 camera:TCamera = CreateCamera() PositionEntity camera, 400, 300, - 400 CameraRange (camera, 1, 2000) light:TLight = createLight() RotateEntity light, 400, 300, -100 'cube 0,0 cube1:TMesh = createCube() 'EntityColor cube1, 255, 0, 0 ScaleEntity (cube1, 10, 10, 10) PositionEntity cube1,0,0,0 'cube 800,600 cube2:TMesh=CreateCube() EntityColor cube2, 0, 255, 0 ScaleEntity cube2, 5, 5, 5 PositionEntity cube2, 800, 600, 0 Local x:Float = 0, y:Float = 0, z:Float = 0 Local count:Int = 0 While Not KeyDown(KEY_ESCAPE) count:+1 RotateEntity(cube1, count, count, 0) Local d:Float If KeyDown(KEY_UP) d = -3 TranslateEntity(cube1, 0, d, 0) End If If KeyDown(KEY_DOWN) d:Float = 3 TranslateEntity(cube1,0,d,0) End If If KeyDown(KEY_LEFT) d:Float = -3 TranslateEntity(cube1, d, 0, 0) End If If KeyDown(KEY_RIGHT) d:Float = 3 TranslateEntity(cube1, d, 0, 0) End If RenderWorld Flip Wend End Cheers Charlie |
| ||
untested:Function SetView( x1, y1, x2, y2, z1, z2) 'camera glMatrixMode(GL_PROJECTION) 'work on the projection matrix glLoadIdentity() glOrthof(x1 , x2 , y2 , y1 , z1 , z2) 'left, right, top, bottom, near, far - coordinate system glMatrixMode(GL_MODELVIEW) end function I'm working in C++ now so its just from memory but from what I know, max uses standard opengl calls and constants under the hood. glOrthof sets your opengl viewport to remove all perspective and act as 2D while setting the view dimensions to whatever you want. For example SetView(0 , 0 , 640 , 480 , -1 , 1); Should give a basic 2D flat rendering window. Might be rotated wrong and need a camera transform. If you wanted to do this on top of existing 3D you need to use the opengl push and pop, which is a way of keeping the state intact. Middleware for AAA games use push and pop to keep the state of existing rendering engines saved while they mess with stuff. Look on opengl.org docs - they are comprehensive and will give you a command reference, it just takes looking. glOrthof will actually remove any kind of depth though, so if you move something far away, it will appear the same size still. It should work out of the box as above after setting up minib3d normally. |
| ||
Oh and give the Z values a massive amount of space if you can't see anything. That is after all, your Z buffer. The x,y stuff: you larger values to fit more on screen (or was that smaller? can't remember) you use it to determine the coordinate space you work in, so it has the affect of scaling the entire world without changing your coordinates if used like that. |
| ||
thanks, but i don't get it :( any chance of an example? Cheers Charlie |
| ||
Just call that function and it will make your game 2D? its safe to call it at any time. |
| ||
well, i couldn't get that to go. i figured out orthographic view via the camera project example, although i had to fiddle with camera zoom to get it to look right. thanks everyone for the help :) Cheers Charlie |
| ||
@jkrankie, would really like to do this myself any chance of you posting your findings? |
| ||
@Nigel, sure thing. While i strongly suspect that there is a better way of doing it, this suits my needs. Basically i'm positioning the camera at 400,-300 (to effect an 800*600 2d screen), the only thing to remember is that you will need to draw your stuff at -y. Here is a quick bit of code that demonstrates this. You can change the resolution to what ever you want and it will all scale ok if you keep to 4:3 screen ratios. if you want to do wide screen you'll have to zoom the camera out a bit more SuperStrict Import sidesign.minib3d graphics3d 800,600,32,7,70 'create a camera Local camera:tcamera=createcamera() 'move the camera positionentity camera,400,-300,-400 camerarange camera,1,2000 'set projection mode to orthograpic cameraprojmode camera,2 'zoom the camera out a long way. camerazoom camera,0.0025 Local light:tlight=createlight(2) positionentity light,400,-300,-10 'quick point type Type point Field x:Float,y:Float Field xvel:Float,yvel:Float Field mesh:tmesh=Null End Type Local spheres:point[50] 'create some spheres For Local i:Int=0 To 49 spheres[i]=New point spheres[i].x=Rand(0,800) spheres[i].y=Rand(0,600) spheres[i].xvel=Rand(-5,5) spheres[i].yvel=Rand(-5,5) spheres[i].mesh=createsphere(4) Next 'begin main loop Local count:Float=0 While Not KeyHit(key_escape) 'update everythin as if it were 2d For Local i:Int=0 To 49 spheres[i].x:+spheres[i].xvel spheres[i].y:+spheres[i].yvel If spheres[i].x<0 spheres[i].x=0 spheres[i].xvel=-spheres[i].xvel Else If spheres[i].x>800 spheres[i].x=800 spheres[i].xvel=-spheres[i].xvel EndIf If spheres[i].y<0 spheres[i].y=0 spheres[i].yvel=-spheres[i].yvel Else If spheres[i].y>600 spheres[i].y=600 spheres[i].yvel=-spheres[i].yvel EndIf rotateentity spheres[i].mesh, count, count, count 'scale up the spheres, remember that your camera is quit a distance from 0 scaleentity spheres[i].mesh,20,20,20 'draw the mesh, but - the y value positionentity spheres[i].mesh,spheres[i].x,-spheres[i].y,0 count:+0.01 Next renderworld Flip Wend For Local i:Int=0 To 49 freeentity spheres[i].mesh Next EndGraphics() End |
| ||
if you roll the camera upside down (making y work the way you would like, but inverting X) you could then yaw it 180deg (thus inverting the inverted X) and position it at 400,300,400 you might fix the Y problem... untested just a thought. this would turn things upside down, but you could roll the meshes, or if you use sprites you can just set them to match the camera roll (they do by default)... come to think of it -y is probably the easier fix hehe, but if you were to be using this as a basis for porting an existing 2d game to 3d for effects or whatever it could make life easier than finding everything at interacts with a y value... Thanks for the sample! |
| ||
Yep, i was porting a 2d game. Also, wouldn't rolling the camera round make the x axis the wrong way round? Cheers Charlie |
| ||
yea, that's why you'd also need to yaw the camera (making it face the other way, which should reverse X and since it's reversed it will set it right) and then put it on the other side of 0 since it's facing backwards thinking about it again, that would be just pitching it 180, that would do the upside down and the backwards at once... |