Please help me:cry:

Posts: 105
Joined: 2007.03
Post: #1
I ran into a problem in programming my engine and for some reason, I just have a mental block where I cannot get around it, and so I'm desperate for help.

The engine is very simple, it's just a 2d(2/1 perspective) isometric sprite engine, using opengl to draw textured quads for game entities and tiles.

Now, I have two totally different coordinate systems in my game, one is the opengl coordinate system which all sprites are eventually rendered to, and the other is a separate coordinate system (which is like and imaginary grid of tiles size IMAGINARY_TILE_WIDTH, IMAGINARY_TILE_HEIGHT)which the entities exist in and (and from which I eventually translate to get the pixel coordinates of their sprites). I originally created this second coordinate system to make it easier for me to handle collision detection and entity movement etc...

My question is, while i have no problem converting imaginary world coords to opengl coords, I can't figure out how to convert opengl coordinates back to my world coordinates, for example, if I click on the screen how am I to figure out exactly where in my world tile grid I clicked?

Here are some screenshots to help visualize exactly what my problem is:
Quote this message in a reply
Posts: 105
Joined: 2007.03
Post: #2
I meant to do a Cry . Oh well.
Quote this message in a reply
Posts: 1,140
Joined: 2005.07
Post: #3
Can you give us more information on what you do to convert to your OpenGL coordinate system?
Quote this message in a reply
Posts: 105
Joined: 2007.03
Post: #4
akb825 Wrote:Can you give us more information on what you do to convert to your OpenGL coordinate system?

#define GRID_TILE_WIDTH 10


I keep an imaginary grid the size of the tile map:

0 10 20 30

if the players world position on this grid was 10,10 then the player would be drawn to the screen on exactly the tile coordinate 1,1. So if the player moves from 10,10 to 11,10 he will be moved 3.2 pixels right and 1.6 pixels down. For every x position on the world grid I move 3.2,1.6 pixels in opengl. Now if I move -x(or left) on the world grid it will move -3.2 pixels, and 1.6 pixels down etc...

Here's a function I use to convert a sprite position to a opengl coordinate:

#define PIXEL_OFFSET_X 3.2
#define PIXEL_OFFSET_Y 1.6


int remainder_world_x, remainder_world_y;
int remainder_pixel_x, remainder_pixel_y;
int tile_pixel_x, tile_pixel_y;
int tile_x, tile_y;
int world_x, world_y;
int half_tile_pixel_width, half_tile_pixel_height;
float sprite_pixel_x, sprite_pixel_y;

world_x = sprite->position.x;
world_y = sprite->position.y;

half_tile_pixel_width = PIXEL_TILE_WIDTH / 2;
half_tile_pixel_height = PIXEL_TILE_HEIGHT / 2;

tile_x = world_x / WORLD_TILE_WIDTH;
tile_y = world_y / WORLD_TILE_HEIGHT;

remainder_world_x = world_x % WORLD_TILE_WIDTH;
remainder_world_y = world_y % WORLD_TILE_HEIGHT;

remainder_pixel_x = (remainder_world_x * PIXEL_OFFSET_X) - (remainder_world_y * PIXEL_OFFSET_X);
remainder_pixel_y = -((remainder_world_x * PIXEL_OFFSET_Y) + (remainder_world_y * PIXEL_OFFSET_Y));

sprite_pixel_x = (tile_x * half_tile_pixel_width) - (tile_y * half_tile_pixel_width);
sprite_pixel_y = -((tile_y * half_tile_pixel_height) + (tile_x * half_tile_pixel_height));

sprite_pixel_x += remainder_pixel_x;
sprite_pixel_y += remainder_pixel_y;

if something is wrong in the code that fines, it's not the exact code from my engine but similar enough to demonstrate the general idea.
Quote this message in a reply
Posts: 1,140
Joined: 2005.07
Post: #5
Unfortunately, with that transformation you end up making it very difficult to take the inverse. What I would suggest is something that works much simpler: matrices. If you use your tile x and y as the x and z coordinates in 3D, and use an orthographic projection matrix, you can make things a lot simpler.

If you don't understand what I just said, that won't keep you from implementing it, though it would help if you do read up on some of this. What you can do is represent your world_x and world_y as a float array of the format {world_x, 0, world_y}. That way you have your 2D world in 3D coordinates. You can use a glRotatef command to tilt the camera and glTranslatef command to move the camera into place so you see an isometric view at the position you want. You can use a simple orthographic projection matrix (make sure it has a depth!) to project the scene onto the screen. (I'm assuming you already have one set up to display the pixels in the first place, though it may or may not have a depth associated with it) When you draw your sprites, you will want to make them parallel to the rotation you set, and position them at your normal world coordinates.

Once you have that set up, you can fairly easily find a point on the camera with a point on the screen to a point on the world. You can use the glGetFloatv() function to get the modelview and projection matrix for your scene, then use the function gluUnProject to find the point. It will take a little more work than just calling the function, though. First call it using the mouse x and y, and 0 for the z. Then use it calling the mouse x and y and 1 for the z. Use the 2 resulting points to find a line and see where that line crosses 0 for the y. The x and z of that point are the x and y coordinates in your world.

Though this helps with your mouse clicking, this will also help with a lot of other things, so despite the effort to redo your coordinate transformation and drawing I think it would be worth it. All occlusions due to one object being behind another is done for free as long as you have depth testing enabled, for instance. Plus all the transformations are done in hardware, which should speed up your game a bit, not to mention the fact that it's quite a bit more elegant. I'm not sure how much math background you have, so some of this might be confusing. I suggest you look up some of these topics if you don't know them already, and post here if you need some extra help.
Quote this message in a reply
Post Reply