FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Zooming
Goto page 1, 2  Next
 
Post new topic   Reply to topic     Forum Index -> ArcLib
View previous topic :: View next topic  
Author Message
ChristianK



Joined: 26 Sep 2006
Posts: 159
Location: Berlin, Germany

PostPosted: Wed Oct 04, 2006 12:39 pm    Post subject: Zooming Reply with quote

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
View user's profile Send private message
Phr00t



Joined: 03 Mar 2006
Posts: 203

PostPosted: Wed Oct 04, 2006 5:25 pm    Post subject: Reply with 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 Very Happy
Back to top
View user's profile Send private message
ChristianK



Joined: 26 Sep 2006
Posts: 159
Location: Berlin, Germany

PostPosted: Thu Oct 05, 2006 2:32 am    Post subject: Reply with quote

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. Smile

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
View user's profile Send private message
Phr00t



Joined: 03 Mar 2006
Posts: 203

PostPosted: Thu Oct 05, 2006 7:54 am    Post subject: Reply with quote

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! Laughing
Back to top
View user's profile Send private message
Lutger



Joined: 25 May 2006
Posts: 91

PostPosted: Thu Oct 05, 2006 8:43 am    Post subject: Reply with quote

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
View user's profile Send private message
clayasaurus



Joined: 21 May 2004
Posts: 857

PostPosted: Thu Oct 05, 2006 9:51 am    Post subject: Reply with quote

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
View user's profile Send private message AIM Address
Lutger



Joined: 25 May 2006
Posts: 91

PostPosted: Fri Oct 06, 2006 6:08 am    Post subject: Reply with quote

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
View user's profile Send private message
clayasaurus



Joined: 21 May 2004
Posts: 857

PostPosted: Fri Oct 06, 2006 9:46 am    Post subject: Reply with quote

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
View user's profile Send private message AIM Address
ChristianK



Joined: 26 Sep 2006
Posts: 159
Location: Berlin, Germany

PostPosted: Fri Oct 06, 2006 10:01 am    Post subject: Reply with quote

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
View user's profile Send private message
Lutger



Joined: 25 May 2006
Posts: 91

PostPosted: Fri Oct 06, 2006 11:25 am    Post subject: Reply with quote

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
View user's profile Send private message
clayasaurus



Joined: 21 May 2004
Posts: 857

PostPosted: Sun Oct 08, 2006 7:04 pm    Post subject: Reply with quote

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
View user's profile Send private message AIM Address
clayasaurus



Joined: 21 May 2004
Posts: 857

PostPosted: Sun Oct 08, 2006 7:17 pm    Post subject: Reply with quote

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 Smile

Actually can you just tell me what line and file of freeuniverse this is in? Thanks.

~ clay
Back to top
View user's profile Send private message AIM Address
ChristianK



Joined: 26 Sep 2006
Posts: 159
Location: Berlin, Germany

PostPosted: Mon Oct 09, 2006 6:53 am    Post subject: Reply with quote

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
View user's profile Send private message
Lutger



Joined: 25 May 2006
Posts: 91

PostPosted: Mon Oct 09, 2006 8:29 am    Post subject: Reply with quote

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
View user's profile Send private message
clayasaurus



Joined: 21 May 2004
Posts: 857

PostPosted: Mon Oct 09, 2006 8:43 am    Post subject: Reply with quote

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
View user's profile Send private message AIM Address
Display posts from previous:   
Post new topic   Reply to topic     Forum Index -> ArcLib All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
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