PDA

Click to See Complete Forum and Search --> : DD and surface sizes


sunnyl
Jul 7th, 2001, 08:44 PM
I've been working on a tile engine, and I've also made a tool to test the capabilities of the engine. When loading a map, its the normal stuff of a character representing a type of tile and then the surface of tiles is created.

I've found that on my test machine (compaq laptop PIII650 64MB) that when the surface of the map is about 400x400 tiles (each tile drawn at 16x16@24bit but DirectX at 640x480@16) I get out of memory errors when I create the surface. Is the a way to calculate the amount of memory a surface will use when I know it's dimensions?

Sastraxi
Jul 7th, 2001, 10:08 PM
Well you can tell DDraw to use different memory (virtual, physical, video) but I don't know how to find that out, may be as simple as getting the len() of the surface, I have no idea.

sunnyl
Jul 8th, 2001, 08:03 AM
How would I go about specifying DD to use virtual memory?

What I've been thinking is that it doesn't actually specify which type of memory ran out. So would it make a difference if I specified a type of memory to use or not?

Jotaf98
Jul 8th, 2001, 02:27 PM
The formula is Width * Height * Resolution

So a 10x10 image at 8 bits would occupy 800 bits in memory (or 100 bytes) ;)

sunnyl
Jul 8th, 2001, 05:43 PM
400^2 * (16 * 16 * 16) = 655360000bits = 81920000bytes = 80000kb = 78.125MB RAM

:eek: holy crap!

Jotaf98
Jul 8th, 2001, 06:26 PM
Where did you get 16*16*16 from?!

If the resolution is 8 bits, it's *8. If it's 16 bits, it's *16 and if it's 24 bits it's *24 :rolleyes:

kedaman
Jul 9th, 2001, 01:35 AM
Originally posted by sunnyl
400^2 * (16 * 16 * 16) = 655360000bits = 81920000bytes = 80000kb = 78.125MB RAM

:eek: holy crap!
160 000 sprites? I'm not sure but are you trying to create a map of 400x400 tiles with 16x16 size tiles. You probably won't need 160 000 sprites unless you want all sprites to be individual. instead enumerate a set of tiles you use by specifying index per tile.

Nirces
Jul 9th, 2001, 06:17 AM
Don't Load the entire thing into memory.

There are a number of ways to do it.

The Tile engine i'm working on, has a tileset object.

Each Tile object (subset of tileset) has a filename, InMemory Boolean, and a DD surface (may or may not be set)

When i try to draw the tile to the backbuffer, i have a piece of code like:

[code]
if tileset.tile(tileindex).InMemory = false then
'load tile.filename into loadbuffer surface
'copy from loadbuffer to backbuffer
else
copy from tileset.tile.ddsurface to backbuffer
end if

Each tile has a Load and Unload bitmap method aswell for memory handling.

sunnyl
Jul 9th, 2001, 06:57 AM
My mistake my mistake.....that original calculation is wrong, I had just woke up when I did that.

Anyhow, kedaman, I am making a map that is 400x400 tiles in size and each tile is 16x16@16bit. I'm not quite sure what you mean here: 'enumerate a set of tiles you use by specifying index per tile'

Jotaf98: I used height x width x res, which is 16 * 16 * 16 and since there is a matrix of 400x400 of them it was 400^2 * 16^3

Right now, I load the entire map into a map surface (from another surface containing all the tiles), then, depending on where the sprite is (relative to the map), I blit a portion of that map surface on to the backbuffer. Is there a problem with this current method?

Nirces, if the tiles are loaded and blitted on the run, then wouldn't that method be alot slower?

Nirces
Jul 9th, 2001, 11:19 AM
Depends, if your redrawing the entire map each frame then no.
but i assume your not.

Yes your way is faster, it also eats memory, and lots of it. which slows down windows which in turn slows down your app, maybe. (depends on how much memory there is, I have 1GB, so no problems for me :)

If you have each tile graphic in memory then you can blt everyone per frame, the slow down is slight.

another way is to spilt your map into screens, have 5 screens loaded into memory, each time you move into a new one, drop the old 3 from memory and load the new 3. this can use more or less memory depending on many tiles you got.

Speed / memory usage.

if your planning on releasing this engine, i advise putting some memory management optios in, i plan on Expanding mine.

Jotaf98
Jul 9th, 2001, 02:04 PM
If you're smart enough you can have it like this: at first you draw all the tiles that are visible on the screen to a surface. Every frame, you just blt from that surface to the screen.

Then, when you move like 1 tile up, you move the image that is on that surface 1 tile down, and draw the new row on it.

If the screen is 800x600 and each tile is 16x16, you would only have to draw 1875 tiles at first, and then 50 tiles every time the screen moves up or down, or 37.5 every time it moves left or right.

...Instead of having to draw 1875 tiles every frame or 1875 tiles every time the screen moves, or even a few hundred thousand tiles at first :)

Hum do you think I should ask for credit for my super-secret technique? :p

kedaman
Jul 9th, 2001, 02:49 PM
"super-secret technique" rolleyes
You won't win any performance but only loose the buffer size in memory, sorry to disappoint you jotaf, but t was intuitive i agree, but it's not as you think, because in both cases you will blitt the same amount of pixels.
the pro's way would be to render the whole frame without any buffers, and in case you're really smart you don't even use frames, but instead blit directly to the display buffer.

by 'enumerate a set of tiles you use by specifying index per tile'
i meant you draw re-usable tiles, say about 100's of them, and then instead of storing the surfaces in the map array, you store pointers to these surfaces, or if you wish index as byte or integer.
You'r current method will load a nasty amount of totally wasted memory.

Jotaf98
Jul 9th, 2001, 06:21 PM
You forgot the ":"s in : rolleyes : :rolleyes:

You didn't get what I'm trying to say. There are 2 ways to draw tiles from a map:

1) Look in the map which contains the "index" of each tile, and draw them. This is extremely slow but doesn't consume a lot of memory

2) Look in the map and draw it once to a huge surface. It's fast because you only have to blt from this map once in each frame, instead of having to blt from hundreds of them, but consumes a lot of memory

My way you have the best of these two techniques; the "huge surface" is only the size of the screen (so it doesn't take up a lot of memory), and you only have to draw the tiles as they become visible.

Nirces
Jul 10th, 2001, 04:50 AM
this doesn't work if you have a dynamic surface map, otherwise it works fine.

but even with that method you still have the problem of loading graphics.
Do you plan on storing all the graphics you need in memory?

if so, your talking about a small speed difference.

The time it takes to blt 100 images to and from memory is less than 1/10th of a second on a slow machine.

if you use the Zone method, Ie have the screen in memory and all the screens next to it.

if carefully done, you have have the new screens loading up in the background. and you don't need to store every graphic (1000 different tiles 32x32x16 = 16meg.

I do like the idea of merging your and My method...

have 9 screens in memory = 800x600x9 = 4.3 meg. but rather than redrawing a row of tiles at a time, when the user changes screens start loading the new 3 screens, setup so that the frames can continue while it is happening using events.

i need to think about this some more.

kedaman
Jul 10th, 2001, 10:51 AM
Originally posted by Jotaf98
You didn't get what I'm trying to say.
I did and I still have to disappoint you jotaf :p it's not how you think, buffering won't save you anything unless you blend or blit overlaps in a larger scale, maybe on isometrical maps you'll save some on static screens but the buffering itself will be a hog as well on the performance, so I don't recommend it.

have 9 screens in memory = 800x600x9 = 4.3 meg. but rather than redrawing a row of tiles at a time, when the user changes screens start loading the new 3 screens, setup so that the frames can continue while it is happening using events.

i need to think about this some more.

Same goes here. Unless your screen is not tilebased there's no need to buffer the whole screen, it'll just be a hog to load for both cpu and memory.

In case it didn't got clear, The time it takes for a blit is linear to the amount of pixels

Nirces
Jul 10th, 2001, 01:46 PM
Nope.

First each time you Blt your dumped back into compiled VB code which puts all kinds of buffer code around api calls. it should be a little slower but not much.

as for CPU, it doesn't require anymore CPU speed, just an extra 4meg of memory.

not really a hog on memory.

plus blting once, you don't have all the co-ord code for each piece running each frame.

On top of that, if your not storing every graphic into memory but using Harddisk, then loading once from harddisk rather than every frame is Alot better.

there are advantages to it.

not sure which method i will use, currently drawing each tile on the buffer on each frame, then flipping the back and front (not blting just telling the machine that the back buffer IS the frontbuffer and vice-versa, much faster)

kedaman
Jul 10th, 2001, 03:56 PM
Originally posted by Nirces
Nope.

First each time you Blt your dumped back into compiled VB code which puts all kinds of buffer code around api calls. it should be a little slower but not much.

as for CPU, it doesn't require anymore CPU speed, just an extra 4meg of memory.

not really a hog on memory.

plus blting once, you don't have all the co-ord code for each piece running each frame.

Have you tried? :rolleyes: or just speculating?
"which puts all kinds of buffer code around api calls"
And who told you that? vb calls dll's without any weird bufferings.
"4meg of memory."
That's a conciderable amount of memory, for such an unneeded task, which do take up cpu time to buffer up.
"plus blting once, you don't have all the co-ord code for each piece running each frame."
which in turn will be a lot more than what a decent tilemap rendering routine should take, and it's tiny if you compare the blit time itself.

On top of that, if your not storing every graphic into memory but using Harddisk, then loading once from harddisk rather than every frame is Alot better.

And how did this got relevant to our issue?

I had suggested some cases you could take bigger advantages, but I still don't suggest this method, due to the disadvantages.

Nirces
Jul 11th, 2001, 04:14 AM
VB does put buffering code around API calls and Object calls, it puts them around everything, its one of the reasons VB is so slow carepared to C++

but its such small speed differences its not really noticable.

I will proberley Write both methods into my graphics engine and let the game coder decide which he wants to use.

kedaman
Jul 12th, 2001, 02:26 PM
Why on earth would VB do that? And what would need to be buffered if I may ask? I know there are hundreds of rumors about VB's effectivity, I wouldn't pay attention to them. The reason why VB applications run slower than C++ is clear. C++ compilers optimizes and manages lowlevel instructions and use the registers with efficiency. VB has no optimizer, doesn't include lowelevel programming, all to enhance ease of use and security for RAD environment. All objects in VB are COM, which are much more complex than C++ structs, they are built for ActiveX environment. Nesting these and the robust and strict security checks results in the slowness and inefficience of VB, VBusers might refer to.

The api calls should work as fast as in c++. The stacking process is heavier than in C++ but could be counted in a few nano-seconds. Would that show in the framerate? Maybe if you ran your app for a day it would be one second faster.

Nirces
Jul 13th, 2001, 04:25 AM
First VB is intrupted into C++ code then it is compiled to Exe. (upto version 5, you used to be able to stop the compile process and view the c++ code, before it was ran through a C++ Compiler)

Most API that VB called are Buffered through the runtime.

For Example BitBlt that VB calls ISN'T the same as bitBlt that C++ calls.

Buffering code is added to protect VB from crashing from bad API calls.

C++ uses ActiveX aswell as VB, most ActiveX controls are written in C++.

Jotaf98
Jul 13th, 2001, 10:46 AM
Look Kedaman, the problem is not all the wrappers VB puts around those calls. Remember that in a tile engine you have to do multiplications for each tile. And loops in VB aren't very fast...

My Tyrian game was lightning fast before I implemented the tile engine, even with all the effects. Now it's so slow that it slows down when a 100x100 pixels effect shows up on the screen :(

I managed to optimize it by replacing the multiplications with additions:



Dim TileX as Long, TileY as Long 'Position of the tile in the map
Dim TilePosX as Long, TilePosY as Long 'Position of the tile in the screen

For TileX = 0 to 49
For TileY = 0 to 37
'Blt the tile. The position in the screen is TilePosX,TilePosY

TilePosY = TilePosY + 32
Next TileY

TilePosX = TilePosX + 32
Next TileX



In my RPG (the one that's gonna take a while until it's finished :) ) this technique made the FPS a lot faster (can't remember the exact numbers) ;)

kedaman
Jul 13th, 2001, 02:21 PM
Nirces
Can you choose which C++ compiler to use and set the flags yourself? I have VB5, but where do i choose to view the uncompiled C++ code? I want to see what the calls get's compiled to. Copymemory used to crash VB 5 but not 6, is this something to do with buffering? I know ActiveX is part of C++, but the equivalents of regualar classes are just UDT's in vb, much like structs in C.

Jotaf
;) hehe, so you reminded me of that now, why on earth would you need multiplications for? hehe :rolleyes: :p

Nirces
Jul 14th, 2001, 07:49 AM
theres no way to do it as standard, one of my Uni professers wrote a progam to do it. I have no idea how it works

You get to see some of the buffering code.

its code to stop VB hanging the entire system if the API fails

the compilier is built into VB, the C++ code VB generates will not run through a normal compiler, i don't know enough about C++ to tell you why

kedaman
Jul 14th, 2001, 11:54 AM
I'd be happy to have a look at some of the buffering code :)

ExplosiveNewt
Jul 14th, 2001, 05:39 PM
Vb doesn't Compile to C++ code anymore, it just compiles Directly to machine code and before it was compiled to P-Code not to C++ then Assembly

Jotaf98
Jul 17th, 2001, 12:43 PM
Kedaman, ALL of the tile engines/games I have downloaded use the following technique:



Dim TileX as Long, TileY as Long 'Position of the tile in the map

For TileX = 0 to 49
For TileY = 0 to 37
'Blt the tile. The position in the screen is TilePosX*32,TilePosY*32
Next TileY
Next TileX



Can you see the multiplications there? :p

kedaman
Jul 17th, 2001, 04:38 PM
Of course, because you haven't seen any decent tilebased game engines :) I've built several including both isometric and hexagonic tile engines and they didn't do any unnessesary multiplications. It all though comes down to vb and it's arrays, so multiplications can't totally be avoided unless you do pointer aritmetics in a language that supports them.

Jotaf98
Jul 20th, 2001, 07:01 PM
Yeah I know - so why don't you give me some good links then? ;)