2D to 3D and back in LandStalker world

Started by
7 comments, last by wondersonic 19 years, 4 months ago
Hello, I'm currently working on an isometric game engine and I would like to reproduce LandStalker (an old genesis / megadrive video game) rendering. The engine will be based on Open GL and I've got the diamond tiles of LandStalker as well as their positions on the screen. My question is: how can I manage my quads and the tiles (transparent gif images) to render a world like LandStalker? 1/ Work on the tiles and transform it into 64x64 transparent png and apply them on the quads. This would looks not so good since the tiles are 32x16 pixels. 2/ Let the tiles diamond and... after I don't know how to create the quads so that the whole thing will just looks like LandStalker. 3/ Other ideas? Thanks in advance for any comment, WS
Advertisement
Quote:Original post by wondersonic
Hello,
I'm currently working on an isometric game engine and I would like
to reproduce LandStalker (an old genesis / megadrive video game) rendering.

The engine will be based on Open GL and I've got the diamond tiles of LandStalker as well as their positions on the screen.

My question is: how can I manage my quads and the tiles (transparent gif images) to render a world like LandStalker?


I've never played LandStalker so it might be useful if you could link to some screenshots of it. I'm going to assume it's a top down isometric game with diamond tiles based on your questions.

Quote:
1/ Work on the tiles and transform it into 64x64 transparent png
and apply them on the quads. This would looks not so good since the
tiles are 32x16 pixels.


The image format shouldn't matter too much, save that you need to have a library to load whatever format you choose. I'm guessing that the reason you want to transform the tiles here is to get them into a power of 2 square texture. Instead, try packing multiple tiles onto one texture and using texture coords to pick between them. This will help you reduce texture changes and batch your quads which you will want to do later anyway. This way you can pack 8 tiles into a 64x64 texture, but I'd recomend useing larger textures with even more tiles (maybe 1024).

Quote:
2/ Let the tiles diamond and... after I don't know how to create the quads so that the whole thing will just looks like LandStalker.


I could really use a screenshot here to reference. But since you have diamond tiles with transparency on textures that you want to cover the screen with using quads, I can make a guess here. Basicly you are going to want rows of quads that overlap so that the diamonds mesh together. Start with a vertex array, if you got all your tiles on one texture then you can put all your quads in the same array. Otherwise you'll need one array for each texture, and you'll have to sort your quads into the proper arrays. The arrays only need texture coords and vertex positions. The vertex positions are easy to calculate based on the x,y coords of the tile. The texture coords are based on the type of the tile.
Quote:Original post by Solias
Quote:Original post by wondersonic
Hello,
I'm currently working on an isometric game engine and I would like
to reproduce LandStalker (an old genesis / megadrive video game) rendering.

The engine will be based on Open GL and I've got the diamond tiles of LandStalker as well as their positions on the screen.

My question is: how can I manage my quads and the tiles (transparent gif images) to render a world like LandStalker?


I've never played LandStalker so it might be useful if you could link to some screenshots of it. I'm going to assume it's a top down isometric game with diamond tiles based on your questions.


Here is a link to an old thread on this forum I posted a long time ago: old post

And you suppose well! I've added some code to an emulator to be able to get sprites and tiles since my goal is to revive this great game.

The tiles are 32x16 pixels but they are sliced into 8x8 pixels.

Quote:
Quote:
1/ Work on the tiles and transform it into 64x64 transparent png
and apply them on the quads. This would looks not so good since the
tiles are 32x16 pixels.


The image format shouldn't matter too much, save that you need to have a library to load whatever format you choose. I'm guessing that the reason you want to transform the tiles here is to get them into a power of 2 square texture. Instead, try packing multiple tiles onto one texture and using texture coords to pick between them. This will help you reduce texture changes and batch your quads which you will want to do later anyway. This way you can pack 8 tiles into a 64x64 texture, but I'd recomend useing larger textures with even more tiles (maybe 1024).



Yes the image format is not a problem, I'm using Java and it supports png format. Yes, you guess well again.

Since I'm really new to Open GL I would like to know if I understand well what you write: I can apply a diamond texture onto a quads?

ie, say I've got a 32x16 (or 8 times 32x16 pixels into a 64x64 image), I can map my tile onto a quad like that?
(sorry for my ASCII art ;o) ):

diamond tile:
    <----------64----->^   |    A-|   |  --  -- |   |D-      -B64  |  --  --|   |    -C|   ||   |v   |


mapped quad:
A----B|    ||    |D----C


then display the quad in orthogonal mode as I want.

Is that what you suggest or rather what open gl allows to do?

Quote:
Quote:
2/ Let the tiles diamond and... after I don't know how to create the quads so that the whole thing will just looks like LandStalker.


I could really use a screenshot here to reference. But since you have diamond tiles with transparency on textures that you want to cover the screen with using quads, I can make a guess here. Basicly you are going to want rows of quads that overlap so that the diamonds mesh together. Start with a vertex array, if you got all your tiles on one texture then you can put all your quads in the same array. Otherwise you'll need one array for each texture, and you'll have to sort your quads into the proper arrays. The arrays only need texture coords and vertex positions. The vertex positions are easy to calculate based on the x,y coords of the tile. The texture coords are based on the type of the tile.


Okay, I'll wait for the next comments but I begin to understand what you mean, thank you very much ;)

If what I think is bad, please, don't hesitate to tell me!!!
Quote:Original post by wondersonic

Yes the image format is not a problem, I'm using Java and it supports png format. Yes, you guess well again.

Since I'm really new to Open GL I would like to know if I understand well what you write: I can apply a diamond texture onto a quads?

ie, say I've got a 32x16 (or 8 times 32x16 pixels into a 64x64 image), I can map my tile onto a quad like that?
(sorry for my ASCII art ;o) ):

then display the quad in orthogonal mode as I want.

Is that what you suggest or rather what open gl allows to do?



To start with lets just consider one tile. It should be stored in a format that supports an alpha chanel for transparency. Once it's loaded and ready to be used as an ogl texture it will be in an array that looks something like this:

r, g, b, a, r, g, b, a ...

For the tiles the alpha will be 1.0 (255) in the diamond part of the tile and 0.0 (0) in the corners. Obviously this is going to waste a lot of space, but if you have the diamond tiles already they are probably in this format.

It's possible your tiles are using color key transparency (a uncommon color such as magenta is used to represent transparent areas). If that is the case you'll want to convert them to use alpha either ahead of time (by converting to a format with alpha) or at load time. I'd recomend the first choice unless you have a good reason to use a file format that does not support alpha (never worked with png before, so I'm not sure about it).

Load the tile into a 32 bit texture and then turn on alpha testing (GL_ALPHA_TEST and glAlphaFunc()). Now when you draw a quad using the tile, the transparent areas will not be drawn, so the quads will look like diamonds. You'll use this same trick with your sprites, although if you want to have semi-transparent sprites you'll need to look into alpha blending.

Since you have many tiles packed into a single texture you will need to set texture coords for each quad that map to the part of the texture with the tile to be displayed on that quad.

Okay, now I understand what you say :o).

Here is what I want to do:



You can see two pictures, the texture (64x64 with 8 diamond tiles) on the left and the rendered quad textured as the diamond!!!

I've used the following coords:

GL11.glTexCoord2f( 0.015625f, 0.875f );
GL11.glVertex3f( -50.0f, -50.0f, 0.0f ); // Bottom Left Of The Texture and Quad
GL11.glTexCoord2f( 0.25f, 1.0f );
GL11.glVertex3f( 50.0f, -50.0f, 0.0f ); // Bottom Right Of The Texture and Quad
GL11.glTexCoord2f( 0.46875f, 0.859375f );
GL11.glVertex3f( 50.0f, 50.0f, 0.0f ); // Top Right Of The Texture and Quad
GL11.glTexCoord2f( 0.234375f, 0.75f );
GL11.glVertex3f( -50.0f, 50.0f, 0.0f ); // Top Left Of The Texture and Quad

But in fact, I think I've got to play with the view port coords and the rotations angles so that the redered quad looks exactly like my 2D diamond except that the whole quad is textured!!!
Look like you are on the right track here.

Quote:Original post by wondersonic
Okay, now I understand what you say :o).

Here is what I want to do:

image

You can see two pictures, the texture (64x64 with 8 diamond tiles) on the left and the rendered quad textured as the diamond!!!



Hmm, it looks like you have a couple problems here. First, the texture is being distorted because the quad is square, but the tile texture region mapped to it is a rectangle. Second, there is a little bit of white bleeding into your tile on the edges. This is because you are using linear interpolation for your texture fliter and the size and aspect ratio of the quad are different than the size and aspect ratio of the texture region.

There are a few steps you can take to fix this. First, you probably want the size of the quad (in pixels) to be as close as possible to the size of the tile texture. Since your tiles are 32x16, if your display is 640x480 the size of a quad should be: (32/640) * (viewport width in world units), (16/480) * (viewport height in world units). At the very least you need to make sure that the quad has the same aspect ratio as the texture region mapped to it.

This should fix the texture distortion, if you are still seeing white edges you can also try going to nearest mode for the texture filter or adjusting the alpha test cutoff value. However if the quad and the texture are exactly the same size in pixels there shouldn't be any filtering artifacts.


Quote:
I've used the following coords:

GL11.glTexCoord2f( 0.015625f, 0.875f );
GL11.glVertex3f( -50.0f, -50.0f, 0.0f ); // Bottom Left Of The Texture and Quad
GL11.glTexCoord2f( 0.25f, 1.0f );
GL11.glVertex3f( 50.0f, -50.0f, 0.0f ); // Bottom Right Of The Texture and Quad
GL11.glTexCoord2f( 0.46875f, 0.859375f );
GL11.glVertex3f( 50.0f, 50.0f, 0.0f ); // Top Right Of The Texture and Quad
GL11.glTexCoord2f( 0.234375f, 0.75f );
GL11.glVertex3f( -50.0f, 50.0f, 0.0f ); // Top Left Of The Texture and Quad


Those texture coords look odd. Shouldn't they be: (0.0, 0.0) -> (0.5, 0.25)? As mentioned above the quad is also the wrong size. As a quick fix try (-50, -25) -> (50, 25) and see if that doesn't look a lot better. That will get you the right 2:1 aspect ratio at least, however you probably want to get the quad to exactly the right size as I described above to get rid of any filtering.

Quote:
But in fact, I think I've got to play with the view port coords and the rotations angles so that the redered quad looks exactly like my 2D diamond except that the whole quad is textured!!!


I'm not sure why you would be doing any rotation here, maybe I'm still not fully understanding what you are trying to do.
Thank you very much, your remarks greatly helped me!!!

I finally understood what I wanted to do:

The diamond tiles I have are the rendered quads!
I just want to get back the square 64x64 textures :o)

In fact, I want to use open GL orthogonal mode to be able to manage
scene with bridge or more than one floor... with traditional 2D isometric engine, this is a pain, with open GL, this would be easy because of the z axis :o)

So it is very simple:
-1- I take all my diamond tiles and resize them from 32x16 to 32x32 then 64x64 (in fact the 32x32 step is not useful, this is just to show that I've to transform the aspect ratio to 1:1).

-2- rotate the diamond with a graphic application.

My problem now is the second part, because the program I use right now doesn't rotate the image the way I wish.

It blends the pixels with the transparent area (white color).

Any idea?

Quote:Original post by wondersonic
Thank you very much, your remarks greatly helped me!!!

I finally understood what I wanted to do:

The diamond tiles I have are the rendered quads!
I just want to get back the square 64x64 textures :o)


Alright, I understand what you are after now. I'm not sure this is really going to work too well, but let's keep going for now.

Quote:
In fact, I want to use open GL orthogonal mode to be able to manage
scene with bridge or more than one floor... with traditional 2D isometric engine, this is a pain, with open GL, this would be easy because of the z axis :o)


I do think there are some cool things that can be done with tile based 3d isometric engines. I also think that using 3d techniques in more classic 2d setups can help solve so of the more difficult challenges you run into in those settings.

Quote:
So it is very simple:
-1- I take all my diamond tiles and resize them from 32x16 to 32x32 then 64x64 (in fact the 32x32 step is not useful, this is just to show that I've to transform the aspect ratio to 1:1).

-2- rotate the diamond with a graphic application.

My problem now is the second part, because the program I use right now doesn't rotate the image the way I wish.

It blends the pixels with the transparent area (white color).

Any idea?


Ok I see a few problems here. The first is that there is probably no point in trying to create a 64x64 texture out of 32x16 pixels of data. You are going to lose some quality just converting to a square image, and resizing pixels up won't give you better quality, it will just take up more space. Probably you want to end up with 32x32 tiles.

Rotation in a standard 2d paint program also is unlikely to give you the results you want. Remember that the isometric prespective includes 2 rotations in 3d space. Also most standard paint programs really aren't up to this kind of task. It could probably be done in photoshop with some extra work, psp probably isn't up to it (altough it's a nice program in other regards). The program I would use though is Texture Maker which has a tool for doing perspective correction when extracting textures from images. I think they have a free trial too with some limitations.

However I have a few reservations on how well this whole approach is going to work. The landstalker artwork is pretty low res, and it was most likely created by hand as diamond tiles. Once you transform it, the results may not look very good. Also think of it this way, you are using a paint program to turn a diamond into a square so you can use opengl to turn it back into a diamond. Both of these operations will result in some distortion of the texture. You may be better off creating you own tiles. Then again I guess it can't hurt to try and see what happens.

Another issue is that these sorts of transformations are much less likely to work on other sprites, so you are still going to have to deal with them in isometric perspective.

Anyway, good luck. I'd be interested in seeing how this turns out.
YES!

Texture maker was the software I was looking for!

Here I am:



Legend:
-1- the loop that render 10 x 10 tiles; you can see rotation on X and Z axis
  ^y |  |  -----> x (z axis  goes through the monitor)

-2- original diamond tile
-3- extracted texture with Texture maker (see menu Tools, Textractor)
-4- the open gl rendered 10 x 10 textured quads that really look like the original diamond.

For the other diamond tiles, I'll make a little program that will automatically generate the 64x64 texture. I just have to look at how the 64x64 pixels from the extracted texture are put according to the diamond tile.

Again, thank you very much!!!
WS

This topic is closed to new replies.

Advertisement