DX optimization |
EACam | Alrighty...i've heard a lot about this, but never a solid statement answering this question:
Which is better: using lots of small textures and switching textures often during run-time, or using few larger textures holding multiple tiles in them and switching less but having to use the large textures and texture coordinates?
Lots of smaller textures is obviously easier (except in the case of animations)...and I've heard people say "Don't using large textures!" and others say "Don't switch textures often!"
What's the deal? |
VBBR | Having multiple textures per file has the advantage that you can have non-square textures. Also I think loading a big texture is faster than loading a lot of small textures that summed up have the same size.
One drawback is that a lot of video cards doesn't support textures larger than 256x256 and some doesn't support even textures larger than 128x128. |
EACam | Thanks. I'll go with with 256x256 grouped tile files...unless...
128x128? Really that small? Is it worth designing a game to have compatability with that type of card (considering it must be ancient)? I've heard 256 mostly, but a lot of people go for 512, right? |
Peter | Basically, each texture calls in D3D are relatively slow, so the fewer you have of them the faster your game will run. |
VBBR | I don't know... ask Eric, I think he knows a lot about old cards like the Voodoo series. |
EACam | ok.
Eric? |
masterbooda | What I have done is load 256x256 textures and then create smaller say 16x16 textures and blit from the larger into the smaller then destroy the larger one... I do all this at the begining...
I have noticed when the texture coordinates are 0 and 1, instead of calculated texture coordinates, it runs a little faster...
Also this gets rid of the artifacts on the edges... which can be pretty annoying...
Also when doing animation you just have to change the texture instead of recalculating the texture coordinates each time... which saves some process time..
This process is time consuming, yes I know, but you only have to do it once... and the memory used is the same, once you destroy the larger texture..
DaBooda out...
|
Eric Coleman | I would suggest using a large texture, this will allow you to batch together anything that uses tiles from that texture into a single draw primitive call. DirectX operates faster when you batch many primitives together.
You might want to consider doing the opposite of what masterbooda suggested. Instead of having a large texture and creating small textures, you could enumerate the video card to find its largest texture size, generally 256x256 will be the fastest even if the card supports larger texture sizes, and then assemble large textures with all of the tiles used for that map. |
EACam | Hmmm... interesting. I think i'll do that...only one problem:
How? All I know how to do is load with the D3DX.LoadTextureFromFile and LoadTextureFromFileEx...i've never done it any other way.[V] |
masterbooda | yeah why listen to a squire...........har har har..........
Actually for maps, erics suggestion is best, but for sprites... I found that by doing my method works best... because its always changing...
Actually its up to programmer's preference... but keeping the largest texture to 256x256 is a must... regardless...I am a blithering idiot........ weeeeeeeeeeee
DaBooda out... |
Almar Joling | [img]http://vulcanus.its.tudelft.nl/~unreal/sponge/images/yalgtex.png[/img]
Old picture I made for YALG. I can simply make huge batches of vertices and render them instantly. Animations are just done by movign the tu coordinates to the right, or the .tv to the bottom. It's that easy. This way is absolutely the way to go.
1x DrawPrimitive vs 100x with 100 textures is so much faster. |
masterbooda | But aren't you making a call to set the texture with every render pass anyways...... I mean are you really saving any time......... Is there a way around this... If so please explain...... I really would like to know....
Because for a large game..... you are going to have more than one texture.... is there a way to say which primitives use what texture initially ... instead of setting the texture with the
Direct3DDevice.SetTexture
During every render...... and if you are just setting texture coordinates....... you are going to be reseting those with every pass too.... with animations...... I mean it works well with no animation... but that would be a pretty boring sprite...
Maybe texture pooling........please give examples.....
DaBooda out...... |
EACam | Yeah, I'm a little confused as well...what exactly are you doing Almar?
Just for your information, my game could have over 350 different tiles rendering at all times...considering i've got the map, but then there's the grass and stuff that goes on top of the dirt (actually, there'll be at least 3 layers for every tile), so that's another render, and then i've got sprites...talk about massive. |
VBBR | I think the best way to discover it is trial. Try, try, and try until you find the way it works faster in your case. |
Eric Coleman | VBBR is right, just create some test programs, and then use whatever method you're comfortable with.
If you batch your textures together, then there will be fewer texture changes. In reality, changing textures is hardly the slowest part of any game.
In Almars case, if he were to keep his tiles seperate, then that would be 64 SetTexture calls, and 64 DrawPrimitive calls. By batching them togehter, instead of 128 function calls, he can make just one SetTexture and one DrawPrimitive, which is faster. |
masterbooda | And there you have it........ it is up to you and what the game really calls for......
And I'm not writing this to get the last word...... nope not booda...... not me
DaBooda out......
P.S. Last Word!!! |
EACam | Great!
But still...HOW do I create a texture with code inserting lots of other little textures? |
Eric Coleman | If you use DirectX, then you might run into some problems with incompatibilities when rendering to a texture. I might be mistaken, but I think that you can simply bitblt from a surface to a texture in directx 7, but then there may be some card compatibility problems.
The easiest way would be to create temporary bitmap files. In pseudo code it would be something like
Start DirectX and fine largest texture size supported by the video card.
Resize Picturebox1 to that size
For Each Tile
Load Image into Picturebox2
BitBlt or Paintpicture to a location in PictureBox1
End Type
Save PictureBox1 As temp.bmp
Load temp.bmp into a Directx surface |
EACam | I could do that...but it'd be slow. Spose that's why there's a loading screen! Thanks. |