Advertisement

Tiling methods (Height map?)

Started by July 13, 2000 10:10 PM
16 comments, last by cyberben 24 years, 5 months ago
Hi there, I''ve been developing an isometric engine for quite some time, but I''ve been looking over my methods and I wondered why do so many people use layers? Why no a height map, so each tile would have a height value, which would offset the y co-ord and thereny cause a raising effect? I mean with layers you have to run through your painting code (Usually some adaptation of a matrix painting scheme or grid) for every layer you have which can be quite high. How did they do the graphics for simcity? It''s got up to something like 25 layers! It must be a height map or something? It ran on a low pentium level machine. Is the source for any version of simcity been released yet or will it ever? What is the *best* method for tiling iso tiles? What advantages are there to each method? Thanks, Ben
__________________________Mencken's Law:"For every human problem, there is a neat, simple solution; and it's always wrong."
"Computers in the future may weigh no more than 1.5 tons."- Popular Mechanics, forecasting the relentless march of science in 1949
quote: Original post by cyberben

Why no a height map, so each tile would have a height value, which would offset the y co-ord and thereny cause a raising effect? I mean with layers you have to run through your painting code (Usually some adaptation of a matrix painting scheme or grid) for every layer you have which can be quite high.


Well I havent been programming iso for several year but I think the entire point of having layers would be so that you dont have to draw layers of the map that are not seen. Perhaps each map tile has a pointer to another tile (signalling there is another level - and you would iterate through the list X number of times - depending on what level you want displayed and just draw that tile.

If you where to use a y co-ord offest you would give it a raised effect but if the tiles are diamond then there would be a black space under where the tile should have been placed. Might be hard to visualize.

One possible suggestion would be to use hex tiles instead, and the flat corners would give it a 3d look. Of course the taller your hex tiles the more VRAM you eat up because each tile BMP is larger - but thats another topic...


Edited by - Leprosy on July 13, 2000 12:45:33 AM
Advertisement
Yah, I understand the "black" space under the tile, I have some odd shaped hill tiles which compensate for the raise. They look like the hills in AoE, it starts as a normal tile but then "roles" up a certain number of pixels...

So nobody here uses a height map? And nobody knows of a commercial game that uses a height map? I guess that''d make it a not so good idea? I may try it anyhow...

Anyone else got some ideas?
- Ben
__________________________Mencken's Law:"For every human problem, there is a neat, simple solution; and it's always wrong."
"Computers in the future may weigh no more than 1.5 tons."- Popular Mechanics, forecasting the relentless march of science in 1949
My engine uses the height value to lift and lower tiles vertex.
Goto turbo.gamedev.net for more info on Iso2k
Pekka Heikurapekka.heikura@mbnet.fi
You probably want to look at the articles on using direct3D to render a iso map.
I think it might be a good idea for the ground level, if you use lots of lighting and rollings hills. I also lets you zoom in and out freely and "might be faster". As far as using it for buildings I have to say that the iso2k engine isnt very useful in that you can only get ramps and not straight edges... but then mybe rendering the buildings as seperate objects is a good idea...
quote: Original post by cyberben

Hi there, I''ve been developing an isometric engine for quite some time, but I''ve been looking over my methods and I wondered why do so many people use layers? Why no a height map, so each tile would have a height value, which would offset the y co-ord and thereny cause a raising effect?



As far as I understands, layers are not generally used to create a height effect. They are used to reduce the ammount of needed tiles.

For example if you have a tree tile you would want to place in different location on your map: on grass, on dirt and so on. You could do that by having a seperate tree-on-grass and a tree-on-dirt tile but you could also have just a generic tree tile and draw it (transparently) on top of the grass or dirt tiles by using layers.

Regards

nicba
Advertisement
I dont run through layers like the normal person does, what I do is run through them only once, and then for each tile I run through all of its layers at that moment.

I start at the upper left tile and go right, and then go down a row and go across again until I end up at the lower right corner of the screen, and I do this only once per frame render. But at each individual tile I run through all of its layers. And I blit each layer right ontop of the previous layer, and I have to blit every single layer because there is always the potential to see the previous layer below, even if there are 25 layers.

Possibility
First: I think you mean planes (as in floor 1, floor 2, etc...) and not layers (as in base, fringe, etc...). If not, then ignore the rest of this post.

What I plan on doing is simple. I first have an array of MAPPTNODE as my map. MAPPTNODE is a simple struct:

typedef struct MAPPTNODE{
MAPPTNODE *Next; //The node in the list
cMapObj *MapObj; //Pointer to a map object class
---more information---
}* LPMAPPTNODE;

cMapObj is a base class that all my map objects (with includes tiles) inherit.

What this array stores is the head to a linked list of map objects over a give (X, Y) map point. When the map is to be drawn, I first start at the top-left visible map point. I add rendering information (such as location) to a rendering order linked list along with the pointer to the map object for each map object over the map point. This is repeat for all visible map points. As each MAPPTNODE''s informtion is added to the render list, it''s sort into the proper rendering order.

If you need more info, feel free to email me.



Dino M. Gambone

Good judgement is gained through experience. Experience, however, is gained through bad judgement.

Dino M. Gambone
Good judgment is gained through experience. Experience, however, is gained through bad judgment.

Currently working on Rise of Praxis MUD: http://www.riseofpraxis.net/

this is probably unrelated, but it''s been bugging me for quite a while.

for those familiar with the direct3d for iso map demo, if I use this technique to render the "ground" level/layer like what Leprosy mentioned, can I then proceed to render subsequent layers with DirectDraw? I mean blitting from offscreen surfaces that contain all the objects (buildings, units, weapons etc.)

reading this topic seems to suggest that rendering all layers for one tile then proceeding to the next is the way to go about it. and using a linked list too. is this how all the iso games out there do layering?

it''d be great if someone could provide me the guidelines to do all this; not the code but just what to do first, second and so on. i''ve been trying and i don''t really know how to sort things out. like when do I load in the bitmap that contains all the objects?

any help/comments is appreciated
quote: Original post by epic709

this is probably unrelated, but it's been bugging me for quite a while.

for those familiar with the direct3d for iso map demo, if I use this technique to render the "ground" level/layer like what Leprosy mentioned, can I then proceed to render subsequent layers with DirectDraw? I mean blitting from offscreen surfaces that contain all the objects (buildings, units, weapons etc.)

reading this topic seems to suggest that rendering all layers for one tile then proceeding to the next is the way to go about it. and using a linked list too. is this how all the iso games out there do layering?

it'd be great if someone could provide me the guidelines to do all this; not the code but just what to do first, second and so on. i've been trying and i don't really know how to sort things out. like when do I load in the bitmap that contains all the objects?

any help/comments is appreciated



I dont think there is any one way that is most perfered. but I would assume that all tiles for the ground level get loaded at the loading of the map. I would suggest trying to get this into VRAM because you end up blitting the tiles a couple hundred times per frame. If the primary surfaces are in VRAM and the tiles you want to blit are in VRAM it will take advantage of hardware blitting acceleration if present and be almost universally faster.

What im thinking of doing is having 2 types of objects drawn. The first would be the diamond tiles, that takes up the ground level and the other would be objects like houses, cars etc. You can do 2d and 3d blitting in the same surface btw. I think that if you try to build houses /trees etc by pieceing together composed tiles - like one tile lower left corner one tile lower right, etc etc to make the feel of a house it would be very difficult to conceptualize for the artist and lead to somewhat rigid artistic styles. in that everything looks like diamond shaped.

Say your diamonds are 64 by 32 - a good number because you can do binary math on 64 and speed your rendering loop. Ask if you want an example. Then draw a car thats on another bitmap by whatever dimensions say-100x100 and blit the entire car on the screen where you want it. From now on tile assumes the diamond when I use object I mean another non - diamond shaped picture. I your dont follow me its probably becuase im not being clear so feel free to ask.

How to store this information? that might be a little complicated. At first I though to use a linked list and the tile that originated the object would point to the object (aka the car) then when you render you would check wether or not each tile points to an object and draw it ( a tree, a car or some other object). A problem arises in the fact that parts of your car might be drawn on the screen without the tile being shown. Because the tile is only 64x32 and the car is 100x100 im sure you can imagine that it would look bad if the entire car just poped out of nowhere when the one tile that it originates in gets rendered. Moveing left to right up up and down...The I though maybe have an array of objects that all have RECT data members, and have the displayed window be a RECT (ie have 4 coordinates). Every render loop you would go through all the objects and see if the object overlaps the displayed window, if it did render it. This would become too combersome and expensive though because each map might have several hundred objects. Instead I thought of another way (probably thought of a million times before).

When you make the map, have each tile that the objects overlaps point to the object. Lets look at my car example again. lets say the cars upper left coordinats originate in tile A1.

A1 (grass)->Object (car)

now A1 is only 64x32 but the car is 100x100. so the car would overlap A1 its neighbor tile to the right A2 and 9 tiles down. the math is fairly simple 64 * 2 = 128 which is > 100 and 12 * 9 = 108 pixels.

so now I would have

A1 A2
B1 B2
C1 C2
D1 D2

etc etc all point to the car. this way when the b2 tile got rendered but the a1 tile didnt because you where moving left you would know when to render the car.

but you dont want the car to originate in b2, you still want it to originate in A1. this is where the object class comes in. the car will be an object as describd by many people pointing to its picture, and its origin. (whatever A1 offeset is) so all the tiles point to the SAME instance of the object. hope your following me so far.


Now we have another problem. the object is being pointed to by 18 different tiles but you only want to draw it once - I think at this point I would use an array of BOOLs to represent each object and when the object was drawn check if the value is FALSE, if it is draw it then flip its index in the array to TRUE. make sure to reset the array every loop render. Maybe getting a little abstract here but this topic probably require an entire article and computer programmers are nepharious for being bad at explaining themselves.

Your not done yet. 2 problems still remain. If you build your objects in the world out of pieces of tiles then you only draw each part of the screen once. If you use overlap objects you probably will end up drawing parts of the ground that never get shown because they are overlapped by the car. One possible way to fix this is to have your map tile array havea value for no draw. so lets say your array is defined like this
map[5][5] = {4,4,4,4,2},
{4,1,1,1,2),
{4,0,0,0,0},
{4,0,0,0,2},
{4,4,4,4,4};

in your render loop you will of course do something like if map[y-row][x-column] == 4 then draw mountain. **Actually the best way to do it is to make a framed object like the ones described in lemothes book and just say
tile.texture = textureBOB.frame = [map[y-row][x-column]];
if you dont have lemothes book you wont really understand it and i suggest getting it. but lets say you dont want to draw tiles with the value of 0. then just say
if (!map[y-row][x-column])
tile.texture = textureBOB.frame = [map[y-row][x-column]];
this way you dont end up drawing unnecessary tiles.

the last problem i have been debating was where to store these objects in memory. They will probably be draw often, but putting then in video memory would eat up VRAM extremely fast. What i suggest is either storing it in system memory or loading the picture when the get a screen and a half away and then destroy then when they are 2 screens away. But doing this every render loop might be hard. Some thoughts need to be put into this subect.

Anywho I hope that maybe gives you some idea on where to go. If your trying to make an atmosphere like diablo which is a guidline by which im going. you can see that the tiles are rendered in 3d if you turn the lighting quality down to shitty cause you can see all the different shaded diamonds from the players light radius. And by looking at there well detailed houses and objects you can tell that the arent collaborations of thousands of parts of diamond tiles.

I have a decent 2d engine up and running if anyone is interested in seeing any of the source code for how I do things... I think if everyone posted their code we might actually produce games that rival big companies. just a though

Lep

ps I know my grammar sucks but I hate correcting 1000 typing errors after writing a long article

Edited by - Leprosy on July 17, 2000 12:22:09 PM

This topic is closed to new replies.

Advertisement