View previous topic :: View next topic |
Author |
Message |
ChristianK
Joined: 26 Sep 2006 Posts: 159 Location: Berlin, Germany
|
Posted: Wed Oct 04, 2006 12:39 pm Post subject: Zooming |
|
|
With modern-day 2d graphics being done through 3d libraries, wouldn't it be rather simple to implement zooming and correct draw order?
For zooming, you would just alter the camera's distance from the viewplane - or increase the viewable area in case of orthogonal projections and to make OpenGL handle the draw order, you would use the z coordinate.
I have to admit that I have no experience with raw OpenGL, nor do I know how Arc implements its image drawing. My question at the moment: Is it already possible to adjust the camera and the z coordinates for objects in Arc at the moment? If not, what are your feelings about it?
I've already poked at the code a bit. Am I right that one could already do the camera-zooming by calling setVirtualSize and mode2D from arc.io.window? Adjusting the z coordinate per sprite seems not possible at the moment, but I assume setting the unused coordinate in the
Code: |
glTranslatef(pos.getX,pos.getY,0);
|
call in arc.gfx.prim would do the trick? |
|
Back to top |
|
|
Phr00t
Joined: 03 Mar 2006 Posts: 203
|
Posted: Wed Oct 04, 2006 5:25 pm Post subject: |
|
|
Woah, what would be awesome for FreeUniverse (if you werent thinking this already) -- is to adjust the zoom on the player's ship according to how fast the player is flying |
|
Back to top |
|
|
ChristianK
Joined: 26 Sep 2006 Posts: 159 Location: Berlin, Germany
|
Posted: Thu Oct 05, 2006 2:32 am Post subject: |
|
|
Quote: | Woah, what would be awesome for FreeUniverse (if you werent thinking this already) -- is to adjust the zoom on the player's ship according to how fast the player is flying |
This is indeed what I was thinking about.
It would also enable us to add really large (in the region of half the screen) player pilotable ships. When the player gets in one of these, we'd simply adjust the zoom level so he can still see where he's going. (large ships have a bunch of other issues too, though)
Technically, we could already implement a zoom effect by adjusting sizes and positions of all sprites. It could even be the better solution, since if we mess with the camera we also need to adjust the user interface sizes and positions in order for it to stay the same size and position.
It'd be nice to have different camera settings for user interface and main action, but that's probably beyond the scope of a 2d library. |
|
Back to top |
|
|
Phr00t
Joined: 03 Mar 2006 Posts: 203
|
Posted: Thu Oct 05, 2006 7:54 am Post subject: |
|
|
Quote: | It would also enable us to add really large (in the region of half the screen) player pilotable ships. When the player gets in one of these, we'd simply adjust the zoom level so he can still see where he's going. (large ships have a bunch of other issues too, though) |
I thought about large ships too -- but we would need to scale up the planet / station graphics -- which would always need to be bigger than any ship. And, turning / firing would be a challenge -- I thought of having a "turret" weapon where you could use the mouse to "point" where you want the weapon to shoot... maybe an upgrade for the captain cruiser?
Quote: | user interface sizes and positions in order for it to stay the same size and position. |
Ahhh... forgot about the UI... hrm, I wonder how much of a performance impact this zooming feature would create if we are changing sprite positions / sizes... becuase you also have to include more sprites to be drawn when you are zoomed out that were outside the normal view... have to look into this...
Maybe we should move this to FreeUniverse forum? We are taking over! bwahahah! |
|
Back to top |
|
|
Lutger
Joined: 25 May 2006 Posts: 91
|
Posted: Thu Oct 05, 2006 8:43 am Post subject: |
|
|
Sequoh, these are good ideas. Since Clay is refactoring Arc (i like his new design 100?), some of this could get in.
There are two issues I think: z-order and basic camera functionality.
As for zooming, you're right it's very possible, easy and don't cost a thing in performance. It would also be easy to set different zoom levels for interface and the game itself. Additional functionality I would like to see myself (in the future) is split-screen rendering and a 3D mode for mixing 3D in 2D.
Z-ordering is somewhat different, but also not too difficult. I would think of it as layers, and expose functions in Arc as such. Perhaps a layer system can also be used for parallax scrolling.
If I have some time, I can try looking at what's needed. Perhaps zooming already works, it depends on how projection matrix is set up. Try inserting this in your main loop before rendering:
glLoadIdentity();
glTranslatef(0, 0, -0.5); // try different values for third parameter |
|
Back to top |
|
|
clayasaurus
Joined: 21 May 2004 Posts: 857
|
Posted: Thu Oct 05, 2006 9:51 am Post subject: |
|
|
Here is what I've come up with, but I don't know if I should put this functionality in arc.io.window or create an arc.io.camera module.
.setPosition(Pos p) // will set position of 'camera' translating entire world contents. This is feasable and I can just so some arithmatic to 'mouse' to make the mouse X and Y values still accurate for the given world.
.setAngle(float angle);
.setAngle(float angle, Pivot p);
// again, this is feasable. I will allow for rotation around a pivot point which in your case will probably be the players ship. I'll have to rotate mouse values for them to stay accurate.
.setZoom(float zoom) // zoom will have to be achieved by having a global zoom and multiplying everything by it. It is really the only way to do this with a 2D game engine. The other option would be to make this a 'semi-2d' engine with real zooming but then it would destory all my mouse selecting, I would need ray picking, etc.
//// Draw order /////
I can specify the draw order just by allowing the user to specify a 'z-value' to force one image to be drawn on top of another. The default argument for this would probably be zero.
I havn't implemented these yet (just basic testing to see what is possible), so I havn't run into any problems, but I am pretty sure they will work.
old writing wrote: |
I think these 2 features would be nice. It would require me to
1) Treat my 2d world as a 3D world, complete with a camera which will be moved in x, y, and z directions.
2) Adding an extra variable to specify draw order. Correct draw order can be achieved already by simply drawing objects in the correct order.
I'll have to think about how these would work, hrm..
|
|
|
Back to top |
|
|
Lutger
Joined: 25 May 2006 Posts: 91
|
Posted: Fri Oct 06, 2006 6:08 am Post subject: |
|
|
Clay, I'm curious how you will implement this. I'm studying a bit of opengl and it seems there are several options, it's not as easy as I thought:
1. Set up a perspective projection matrix and map screen pixels to near clipping plane or some other plane.
This allows for easy zooming and 2d positioning, plus allows mixing in 3d. But then the z-order affects size of objects because it's faking 2D in 3D mode, and compensating for that in drawing code might get ugly.
2. Set up orthographic projection with depth buffer.
This allows for easy Z-ordering not affecting objects size but then you'll have to write zooming code for each object as translation in the Z-axis will have no effect.
Ah, I understand you go for option 2) to not destroy mouse selection etc, right?
My 2 cents is to put it in arc.io.camera. Window is just for creating a window and context, camera may be used more often and has a different purpose. Plus it'll be easier to extend it in the future if so desired. If you are careful to let all drawing depend only on camera, it might even be an option to create a class and then use different camera objects. Let one camera at a time be the default, then the user could create different camera's for GUI and game, and select which one to use. It would also allow to switch different views on the spot.
For ease of use, arc.io.window could create a default camera when initialized.
EDIT1: why is the package called io btw? I would think this and window would fit more in arc.core.
EDIT2: just thinking, a camera class would allow for some fast and cool effects like a moving camera. Things like: Camera.fly(Point from, Point to, uint ms); |
|
Back to top |
|
|
clayasaurus
Joined: 21 May 2004 Posts: 857
|
Posted: Fri Oct 06, 2006 9:46 am Post subject: |
|
|
Lutger wrote: |
2. Set up orthographic projection with depth buffer.
This allows for easy Z-ordering not affecting objects size but then you'll have to write zooming code for each object as translation in the Z-axis will have no effect.
|
Yes, this is what I will be doing. However, I learned that in order to get z-ordering I need GL_DEPTH_TEST, and GL_DEPTH_TEST kills transparency. Look here http://www.idevgames.com/forum/archive/index.php/t-6031.html .
Quote: |
My 2 cents is to put it in arc.io.camera. Window is just for creating a window and context, camera may be used more often and has a different purpose. Plus it'll be easier to extend it in the future if so desired. If you are careful to let all drawing depend only on camera, it might even be an option to create a class and then use different camera objects. Let one camera at a time be the default, then the user could create different camera's for GUI and game, and select which one to use. It would also allow to switch different views on the spot.
For ease of use, arc.io.window could create a default camera when initialized.
EDIT1: why is the package called io btw? I would think this and window would fit more in arc.core.
EDIT2: just thinking, a camera class would allow for some fast and cool effects like a moving camera. Things like: Camera.fly(Point from, Point to, uint ms); |
io stands for 'input/output'
yes, I agree that I should just have a camera module to control the camera with
--- Progess ----
'camera' moving and rotation seems to be working, although I need to move and rotate the mouse coords with it which I havn't tried yet.
'camera' zooming, I am having problems with this. It is pretty much a global zoom value at this point which is multiplied to all sprite sizes and positions, but it isn't quite working how I want it to.
as for multiple camera objects, I would need multiple rendering contexts to acheive those, i think |
|
Back to top |
|
|
ChristianK
Joined: 26 Sep 2006 Posts: 159 Location: Berlin, Germany
|
Posted: Fri Oct 06, 2006 10:01 am Post subject: |
|
|
Quote: | 2. Set up orthographic projection with depth buffer.
This allows for easy Z-ordering not affecting objects size but then you'll have to write zooming code for each object as translation in the Z-axis will have no effect. |
Arc currently uses an orthographic projection matrix for the camera, so the z coordinate won't affect the object sizes, but is useful for setting draw order. However, it is possible to increase the area the camera covers to effectively shrink everything uniformly.
Quote: | zoom will have to be achieved by having a global zoom and multiplying everything by it. It is really the only way to do this with a 2D game engine. |
Hm, I don't see how zooming is more complicated to get right than rotation and translation? Can you elaborate on this?
Quote: | I don't know if I should put this functionality in arc.io.window or create an arc.io.camera module. |
I'd prefer something with camera in its name. Also I agree with Lutger that I wouldn't expect it in "io". Somehow I associate io with file io.
-- Update for Clay's post --
Quote: | However, I learned that in order to get z-ordering I need GL_DEPTH_TEST, and GL_DEPTH_TEST kills transparency. |
Meh. So much for making use of automatic z-ordering.
Quote: | 'camera' zooming, I am having problems with this. It is pretty much a global zoom value at this point which is multiplied to all sprite sizes and positions, but it isn't quite working how I want it to. |
In my test FreeUniverse code I do
Code: | screen_x = screen_width / 2 + (x - scroll_x_translation - screen_width / 2) / zoom |
To scale away from the center. Works nicely. Still, what's bad about modifying the projection size? |
|
Back to top |
|
|
Lutger
Joined: 25 May 2006 Posts: 91
|
Posted: Fri Oct 06, 2006 11:25 am Post subject: |
|
|
Quote: | Arc currently uses an orthographic projection matrix for the camera, so the z coordinate won't affect the object sizes, but is useful for setting draw order. However, it is possible to increase the area the camera covers to effectively shrink everything uniformly. |
Of course you're right:
glOrtho(0.0f, wWidth2D * zoom, wHeight2D * zoom, 0.0,-1.0f,1.0f);
But it will not do what you think as the scene is not centered at 0,0. So modified it will be (something like):
glOrtho(-(wWidth * zoom ), wWidth2D * zoom, wHeight2D * zoom, -(wHeight2D * zoom),-1.0f, 1.0f);
Quote: | However, I learned that in order to get z-ordering I need GL_DEPTH_TEST, and GL_DEPTH_TEST kills transparency. |
Forgot about that. You'll have to render non-transparent stuff first and then render transparent things back to front with depth test disabled. Besides the performance improvement, I don't know if that will actually help making things easier.
Quote: | as for multiple camera objects, I would need multiple rendering contexts to acheive those, i think |
No need, this can simply be a class for mode2d and the translation / rotation commands. It will only have to remember rotation, translation and zoom factors, be able to apply them and set up ortho projection matrix. |
|
Back to top |
|
|
clayasaurus
Joined: 21 May 2004 Posts: 857
|
Posted: Sun Oct 08, 2006 7:04 pm Post subject: |
|
|
Lutger wrote: |
Of course you're right:
glOrtho(0.0f, wWidth2D * zoom, wHeight2D * zoom, 0.0,-1.0f,1.0f);
|
Hrm.. this looks promising for zooming... but something else needs to be done to make all the zooming/rotation/transformation work together correctly. I'll have to toy with it later. |
|
Back to top |
|
|
clayasaurus
Joined: 21 May 2004 Posts: 857
|
Posted: Sun Oct 08, 2006 7:17 pm Post subject: |
|
|
Sequoh wrote: |
Hm, I don't see how zooming is more complicated to get right than rotation and translation? Can you elaborate on this?
|
1) I've spent more time on rotation and translation
2) rotation and translation is just a matter of some rotation math (most of which in in Point) and some openGL calls. I have to use rotation math to get the mouse X and Y coords to still seem 'relative' to the user, it looks something like...
Code: |
// translate virutal coords and camera
xy2D.setX( /*Virt coord transform*/(xy.getX/(arc.io.window.getWidth/arc.io.window.getVirtualWidth))
/*Camera transform*/+arc.io.camera.getPosition.getX-(arc.io.window.getSize.getWidth/2));
xy2D.setY( /*Virt coord transform*/(xy.getY/(arc.io.window.getHeight/arc.io.window.getVirtualHeight))
/*Camera transform*/+arc.io.camera.getPosition.getY-(arc.io.window.getSize.getHeight/2));
// rotate mouse position to match current screen
xy2D.rotate(arc.io.camera.getPosition, -arc.io.camera.getAngle);
|
Quote: |
In my test FreeUniverse code I do
Code: | screen_x = screen_width / 2 + (x - scroll_x_translation - screen_width / 2) / zoom |
To scale away from the center. Works nicely. Still, what's bad about modifying the projection size? |
How would you suggest? Can you send me some sample code to play with? If you figure out how to get everything to work then I'll implement it your way
Actually can you just tell me what line and file of freeuniverse this is in? Thanks.
~ clay |
|
Back to top |
|
|
ChristianK
Joined: 26 Sep 2006 Posts: 159 Location: Berlin, Germany
|
Posted: Mon Oct 09, 2006 6:53 am Post subject: |
|
|
The code I posted was for performing zooming without altering the camera. If we can alter the camera's projection settings (Lutger posted the code), everything should look ok already.
Now for transforming the mouse screen coordinates to camera coordinates:
Let the camera be set to
glOrtho(-(vWidth * zoom) / 2, (vWidth * zoom) / 2, (vHeight * zoom) / 2, -(vHeight * zoom) / 2,-1.0f, 1.0f);
i.e. focused on (0,0) with a total width and height of vWidth * zoom and vHeight * zoom.
Objects shall first be rotated around the origin by rotation counterclockwise and then be translated by (-translate_x, -translate_y). You can do these two the other way around, but this way the translation will always happen with respect to the already rotated coordinate system.
Let (mouse_x, mouse_y) be the mouse coordinates in the window. Now apply the inverse transformation to these coordinates:
transformed_mouse = rotate_inv( translate_inv( window_to_virtual( mouse ) ) )
That means:
virtual_x = mouse_x / wWidth * vWidth * zoom - vWidth * zoom / 2
translated_x = virtual_x + translate_x
rotated_x = cos(rotation) * translated_x - sin(rotation) * translated_y
I only remembered you couldn't transform the camera (is this true?) half way through writing this, so I hope I didn't make stupid errors while adjusting for that.
By the way, if it is possible to adjust the camera, we at FreeUniverse will probably want do it more than once per frame (once for space items and once for user interface) and we'd need both: the mouse coordinates with respect to the interface coordinate system and the mouse coordinates with respect to the space coordinate system. |
|
Back to top |
|
|
Lutger
Joined: 25 May 2006 Posts: 91
|
Posted: Mon Oct 09, 2006 8:29 am Post subject: |
|
|
Sequoh wrote: | The code I posted was for performing zooming without altering the camera. If we can alter the camera's projection settings (Lutger posted the code), everything should look ok already.
Now for transforming the mouse screen coordinates to camera coordinates:
Let the camera be set to
glOrtho(-(vWidth * zoom) / 2, (vWidth * zoom) / 2, (vHeight * zoom) / 2, -(vHeight * zoom) / 2,-1.0f, 1.0f);
i.e. focused on (0,0) with a total width and height of vWidth * zoom and vHeight * zoom.
Objects shall first be rotated around the origin by rotation counterclockwise and then be translated by (-translate_x, -translate_y). You can do these two the other way around, but this way the translation will always happen with respect to the already rotated coordinate system.
Let (mouse_x, mouse_y) be the mouse coordinates in the window. Now apply the inverse transformation to these coordinates:
transformed_mouse = rotate_inv( translate_inv( window_to_virtual( mouse ) ) )
That means:
virtual_x = mouse_x / wWidth * vWidth * zoom - vWidth * zoom / 2
translated_x = virtual_x + translate_x
rotated_x = cos(rotation) * translated_x - sin(rotation) * translated_y |
I'm not sure if I understand the problem. Is this done to get the coordinates of your 'world' that match the screen mouse position, to, for example, see if the mouse is over some sprite? If this is the case, gluUnproject can be of help: http://www.rush3d.com/reference/opengl-bluebook-1.0/ch06.html#id5562033
Quote: | I only remembered you couldn't transform the camera (is this true?) half way through writing this, so I hope I didn't make stupid errors while adjusting for that. |
What do you mean with transforming the camera?
Quote: | By the way, if it is possible to adjust the camera, we at FreeUniverse will probably want do it more than once per frame (once for space items and once for user interface) and we'd need both: the mouse coordinates with respect to the interface coordinate system and the mouse coordinates with respect to the space coordinate system. |
This is simply done with push and pop, opengl can have a -limited- stack of projection and modelview matrixes, alternatively a history of adjustments can be stored. |
|
Back to top |
|
|
clayasaurus
Joined: 21 May 2004 Posts: 857
|
Posted: Mon Oct 09, 2006 8:43 am Post subject: |
|
|
Quote: |
Let the camera be set to
glOrtho(-(vWidth * zoom) / 2, (vWidth * zoom) / 2, (vHeight * zoom) / 2, -(vHeight * zoom) / 2,-1.0f, 1.0f);
i.e. focused on (0,0) with a total width and height of vWidth * zoom and vHeight * zoom.
Objects shall first be rotated around the origin by rotation counterclockwise and then be translated by (-translate_x, -translate_y). You can do these two the other way around, but this way the translation will always happen with respect to the already rotated coordinate system.
|
What is the origin, (0,0) or (halfWindowWidth, halfWindowHeight) ?
Oh and what I meant was that you can not zoom with glTranslatef, I didn't realize you could by using glOrtho. |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|