Jump from directdraw to d3d
Hello everyone, first post.
Going to attempt to learn direct3d by remaking, and adding features to, a game I made in directdraw. I’m interested in doing 2d graphics with the 3d hardware, then moving on to 3d graphics from there [using the 2d stuff to learn the 3d functionality differences]. But when I read up on direct3d, some things really worries me, like the functions involving changing textures [specifically the word ‘slow’ and it’s use with this function, I don’t want to kill my program performance over something so stupid], and the use of floats to specify texture coordinates. So here are my questions.
If I am going to be making a tiled game with d3d, how should I store the tile set? A single texture for each tile [a lot of changing of the texture, and no drawing in sets, which seems to be the recommended way of doing things], or a single texture with a bunch of tiles [in which case, how do I make sure that the floating point texture coordinate doesn’t attempt to draw the edge of one tile while drawing another tile, how do I make sure there is no overlapping, since the measures are not so discrete].
How much does changing the texture actually hurt performance [I’m paranoid about this kind of thing, if it says ‘hurt performance’, I’m going to try to find a way to never do it], and how best can I minimize this sort of problem occurring.
For the tiled ground, what is the best way to store the tiles. Should I draw each tile separate, or attempt to draw the entire ground as a single object, or segment it into a few objects [like 4 by 4 tile chunks].
Concerning animated sprites, how is best to break these up into textures [or draw them as one big texture] and how is best to handle the need to constantly change the texture coordinates? Or should I just use a vertex buffer defining each animation frame separately, and treat it sort of like how I treated animation in direct draw [call each frame separate.]
Thanks for the input.
i believe this question would be better answered in the DirectX forum.
edit: thanks jolly [smile]
edit: thanks jolly [smile]
Quote:Original post by Peachy keenWelcome [smile]
Hello everyone, first post.
Quote:Original post by Peachy keenSounds like a good plan to me.
I’m interested in doing 2d graphics with the 3d hardware, then moving on to 3d graphics from there [using the 2d stuff to learn the 3d functionality differences].
Quote:Original post by Peachy keenSetTexture() isn't a general sort of slow - calling it won't just automagically knock your applications performance. A better way of thinking about it might be "excessive use of SetTexture() can become a performance problem".
But when I read up on direct3d, some things really worries me, like the functions involving changing textures [specifically the word ‘slow’ and it’s use with this function, I don’t want to kill my program performance over something so stupid]
Quote:Original post by Peachy keenGet familiar with the "Directly Mapping Texels To Pixels" article in the SDK [wink]
the use of floats to specify texture coordinates.
Quote:Original post by Peachy keenI wouldn't advise this. You'll also start hitting the overhead of Draw**() calls as well if you split things up like this [oh]
If I am going to be making a tiled game with d3d, how should I store the tile set? A single texture for each tile [a lot of changing of the texture, and no drawing in sets, which seems to be the recommended way of doing things]
Quote:Original post by Peachy keenYou need to be very careful with the texture coordinates and the filtering options. The aforementioned article should clear a few things up.
a single texture with a bunch of tiles [in which case, how do I make sure that the floating point texture coordinate doesn’t attempt to draw the edge of one tile while drawing another tile, how do I make sure there is no overlapping, since the measures are not so discrete].
A tricky situation is where incorrect coordinates cause the linear filtering to fetch texels from the neighbouring tile. If you've got your texture coordinates aligned properly then it shouldn't be a problem (add/subtract a 0.5px offset to target the center of the texel). Sometimes a simple "gutter" between tiles sorts some of these problems out.
In my experience the best way of getting good performance from a tile renderer in Direct3D is to:
1. Store all tiles on a "texture palette". If your tiles are 30x30 then store a 16x16 grid of tiles inside a 512x512 texture. This way you need only change the texture *once* for the whole tile rendering
2. Store all geometry in a vertex buffer, probably as a triangle-list. With correct texture coordinates you can render all the tiles in a single DrawPrimitive() call.
3. If you want animated tiles, then just still keep them on the larger "texture palette" - just make it 1024x1024 (etc..) until it stores enough tiles. Make sure that the vertex buffer is set with appropriate flags (D3DUSAGE_DYNAMIC), and don't update the animations on every frame. Running a simple timer so you only update at 15hz/20hz/30hz should mean you can avoid an expensive Lock() call on a large percentage of the frames.
In my personal experience as well as what I've seen on these forums, people trying to use Direct3D the same way they did DirectDraw get performance problems. Yes, they're both graphics API's - but they do require different mentalities and usage [smile]
hth
Jack
Quote:Original post by Alpha_ProgDesI thought it was when I clicked on it [lol]. I'll move it over now for you...
i believe this question would be better in the DirectX forum.
Cheers,
Jack
Quote:Original post by jollyjeffersThis is what I was thinking, but the thought of my tiles pulling any sort of residual color over from neighboring tiles made the hair on the back of my neck stand up, and looked to just be a huge mess. I'm reading that bit in the sdk now though, looks like it'll help. This also means that it would be impossible to have the verteces representing the corners of my tiles be shared by neighboring tiles [since the texture coordinates would be different] right?
1. Store all tiles on a "texture palette". If your tiles are 30x30 then store a 16x16 grid of tiles inside a 512x512 texture. This way you need only change the texture *once* for the whole tile rendering
2. Store all geometry in a vertex buffer, probably as a triangle-list. With correct texture coordinates you can render all the tiles in a single DrawPrimitive() call.
Quote:Original post by jollyjeffersWasn't really thinking about animated tiles, but animated characters, but suppose that would work similarly, but instead of using dynamic vertexs, can I store them as individual frames in the vertex buffer? [perhaps a better question is, would this be better]. And as far as drawing the entire tile set in one draw call, is it actually efficient to let the graphics hardware do the culling on that sort of thing? or should I take the time to throw out as much as I can first, then let it pick up the scraps [seems like for a large tile map, I'd have to at least throw some out with space partitioning, so the graphics hardware doesn't end up drawing 100 tiles on a 100K tile chunk of data, not that my levels are that big, but for future reference]. Seems like it would make sense to not even have the whole level in geometric form at a given time [leave some tiles as just single byte representation on a sort of old style 2d grid when they are far enough out of sight]
3. If you want animated tiles, then just still keep them on the larger "texture palette" - just make it 1024x1024 (etc..) until it stores enough tiles. Make sure that the vertex buffer is set with appropriate flags (D3DUSAGE_DYNAMIC)...
Oh, and sorry about posting in the wrong section. I usually try to hold onto my 'forgive the retarded newbie' token a little longer than that. First post and I have already goofed up :P
Quote:Original post by Peachy keenYes, but for a tile-based renderer I wouldn't worry about it too much. The number of triangles (especially if they're pre-transformed) used in a 2D tile game is not likely to get close to stressing out even a low-end 3D card [smile]
This also means that it would be impossible to have the verteces representing the corners of my tiles be shared by neighboring tiles [since the texture coordinates would be different] right?
Quote:Original post by Peachy keenThat would be an interesting way of doing it, and yes, probably would be faster. One of the big things you want to avoid when using D3D is modifying resources - e.g. ::Lock() calls. If you can re-arrange your data so that you need only change the parameters to a Draw**() call then thats A Good Thing™.
can I store them as individual frames in the vertex buffer? [perhaps a better question is, would this be better].
Quote:Original post by Peachy keenYes and no... there isn't really a clear-cut answer to this. Complex algorithms to guarantee that only visible polys get rendered and absolutely nothing else are often worse for performance. Throwing a few 100 extra triangles at the screen and keeping the algorithm simple/efficient is better. However, if you throw 1000's or millions of extra triangles then you might start to get problems...
And as far as drawing the entire tile set in one draw call, is it actually efficient to let the graphics hardware do the culling on that sort of thing?
It all depends how big your whole 2D tilemap is, and what proportion of that you'll actually see on screen at any given time.
Quote:Original post by Peachy keenI would recommend a Quad-Tree algorithm. Works amazingly well with terrain engines, and you can combine it with index buffers to make it stupidly fast when it comes to rendering [grin]
or should I take the time to throw out as much as I can first, then let it pick up the scraps [seems like for a large tile map, I'd have to at least throw some out with space partitioning, so the graphics hardware doesn't end up drawing 100 tiles on a 100K tile chunk of data, not that my levels are that big, but for future reference].
Quote:Original post by Peachy keenUnless your level is absolutely huge (and I mean several 1000 tiles in height/width) this would be an overkill optimization. The VRAM consumption for geometry is pretty insignificant compared to both texture usage as well as the huge amount most hardware has installed these days...
Seems like it would make sense to not even have the whole level in geometric form at a given time [leave some tiles as just single byte representation on a sort of old style 2d grid when they are far enough out of sight]
Quote:Original post by Peachy keen[lol] You didn't "goof up" as such; just that with so many sub-forums on GDNet its not always easy to pick the best place for questions. Nothing wrong with putting it in "For Beginners", but you'd normally get a better response to this from "DirectX"...
Oh, and sorry about posting in the wrong section. I usually try to hold onto my 'forgive the retarded newbie' token a little longer than that. First post and I have already goofed up :P
hth
Jack
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement