|
||||||||||||||||||
Add Forum to Favorites | Send Topic To a Friend | View Forum FAQ | Track this topic |
Last Thread Next Thread ![]() |
| 2D in Direct3D using Textured Quads |
|
![]() aboeing Member since: 1/11/2003 From: Perth, Australia |
||||
|
|
||||
| does anyone know of a way of achieving a similar thing without needing to use the rhw parameter? ie: by setting the projection&world matricies in such a way that drawing something at (20,20,0) would correspond to drawing at pixel location 20,20 in the window..? cheers |
||||
|
||||
![]() alnite Member since: 11/8/2002 From: Santa Ana, CA, United States |
||||
|
|
||||
quote:that is exactly what rhw for. Otherwise, drawing something at (20,20,0) would correspond to drawing at (78,78) on the screen. |
||||
|
||||
![]() Miksan Member since: 11/23/2002 From: Helsinki, Finland |
||||
|
|
||||
| Looks nice, thanks. How much faster/slower is this compared to ID3DXSprite? Is the rotation method better in ID3DXSprite? |
||||
|
||||
![]() Anonymous Poster |
||||
|
||||
| i thought the rhw was just the divideby value for the vertex, so setting it to 1 was basically saying to have no effect.. shouldnt it be possible to construct projection&view matricies so that they multiply out correctly? (actually, isnt this how 2d stuff is done with openGL?) |
||||
|
||||
![]() Robbo Member since: 12/15/2001 From: United Kingdom |
||||
|
|
||||
How about an orthographic, rather than a perspective projection? |
||||
|
||||
![]() GilliganCoder Member since: 6/5/2003 From: USA |
||||
|
|
||||
| In defense of this article, I just want to say that when I read it, I appreciated it. I have been looking for a way to use Direct3D for 2D and, regardless of how many articles are "out there," I haven't read anything like this yet. I'm new to 3D, not 2D, and something like this at least got the ideas started. No, it's not a perfect article, and others may be able to improve on it, but it's the first I've seen. If it could be done a lot better, I ask that someone would write it, instead of just criticizing this one. How about the Lock/Unlock issue -- how do you solve it? Maybe there should be a second edition of this article. Anyway, that's my two cents worth. [JESUS SAVES] |
||||
|
||||
![]() bpopp Member since: 5/3/2002 From: Memphis, USA |
||||
|
|
||||
| Rapid is right. It would probably be better to put all your vertices in some temporary structure (vector) and then lock/memcpy/unlock all at once. Then you can walk through the structure drawing each quad sorted by texture/state. Unfortuntely, for most 2d games it would be very rare to have two sprites with the same texture. Even if you batch, you're only going to be drawing a few quads per DrawPrimitive() call. If someone has a way around this, I'd love to hear it. bpopp (bpopp.net) |
||||
|
||||
![]() DrunkenHyena Member since: 1/17/2001 From: Winnipeg, Canada |
||||
|
|
||||
| I can understand why they'd skip batching in an intro article like this. But I seem to recall that there is at least 1 very similar article on GameDev already. Something more advanced would be good. Of course I've been meaning to put one together, but just haven't got around to it yet. Even if you're going to do a single quad at a time, at *least* use an Ortho projection and a transformation matrix. It's much cheaper than Locking and Unlock 4 vertices. The Lock/Unlock method works when doing batching. Though you can also do shader-based instancing it's not as flexible and has limits. Stay Casual, Ken Drunken Hyena |
||||
|
||||
![]() Zorbfish Member since: 5/6/2002 From: Lincoln, ME, United States |
||||
|
|
||||
| I wrote a D3D Blitter a few weeks ago. It uses a underlying container, like bppop suggested, to batch as many quads together as possible by texture, render state, then zdepth. Then once there's a enough vertices in the container they are moved into a dynamic vertex buffer and index buffer and rendered. It works really well on my computer and I too was thinking of writing an article about it. I'm hesistant because I have cannot profile my code yet (anyone know a free source profiler?) to test whether its really efficient or not. |
||||
|
||||
![]() Zorbfish Member since: 5/6/2002 From: Lincoln, ME, United States |
||||
|
|
||||
quote: Someone suggested to me a few days ago on these boards that you could combine a few small textures together. So after a quick check of the largest texture size the card can handle, you could make a large texture containing many of the 2D graphics you need. |
||||
|
||||
![]() DrunkenHyena Member since: 1/17/2001 From: Winnipeg, Canada |
||||
|
|
||||
quote: Enterprise Edition does, Standard Edition does not. I'm not sure about Professsional Edition. Unless you can get a student discount, few hobbyists can afford more than Standard. Stay Casual, Ken Drunken Hyena |
||||
|
||||
![]() Zorbfish Member since: 5/6/2002 From: Lincoln, ME, United States |
||||
|
|
||||
| Yea, I was looking into buying professional for the optimizer and profiler, but I can't afford to drop $1000 for the Visual Studio 2k3 Professional package when the only thing I'd be interested in using is C++ and maybe a little C#. My university does offer a student version, but we all know that's crap since under the student license you can't make an executable, therefore it's worthless. |
||||
|
||||
![]() ares32585 Member since: 6/6/2002 |
||||
|
|
||||
quote: Yeah, I had posted something, but then I decided it was unnecessarily confrontational and was far too close to being a personal attack than I would have liked, especially since I could have easily misinterpreted the tone of your post. [edited by - ares32585 on August 1, 2003 6:31:31 PM] |
||||
|
||||
![]() Anonymous Poster |
||||
|
||||
| Building FANS starting from one of the poly vertex is not good choice. Bulid FAN from the centre of the poly. Better look |
||||
|
||||
![]() DrunkenHyena Member since: 1/17/2001 From: Winnipeg, Canada |
||||
|
|
||||
quote: Or, don't use Fans at all for things like this because it kills any possibility of even trivial batching. Stay Casual, Ken Drunken Hyena |
||||
|
||||
![]() DrunkenHyena Member since: 1/17/2001 From: Winnipeg, Canada |
||||
|
|
||||
quote: There is a continuing need for articles targeting beginners. The problem with this article was the quality, not the target. Previous articles that covered similar topics also were pretty questionable. Does GameDev.net have quality control? I know my tutorials are far from perfect, but I try to make them solid. And when I show basic techniques I try to always point out that there are better and more advanced techniques. I may not always get around to showing the better techniques, but by telling the reader that they're there they can at least look around for more information (or bug me until I do crank out a tutorial on it). Stay Casual, Ken Drunken Hyena |
||||
|
||||
![]() glassJAw Member since: 3/14/2002 |
||||
|
|
||||
| Hey, I just got back from the cottage, which is why I havent been able to address any issues with my article. First of all, batching. The article was targetted at beginners, and as bpopp mentioned, it is rare to have more than one sprite on a texture. I thought adding batching techniques would just make the code a lot more confusing. Second, The locking of the vertex buffers. Yes it's expensive, but it keeps the code simple. Transformation matrices are a lot faster of course, but they're rather hard to use with vertex colour modulation, so I chose to leave them out. If RapidStunna doesn't, maybe I'll write a follow-up article about batching, and using matrices to speed things up. Anyways, this was my first article so I wasn't really expecting it to go over too well. Thanks to those who gave constructive criticism. In anything I write in the future, I'll take care to clearly explain the techniques I'm using and whatever better (but more complicated) ones are available. |
||||
|
||||
![]() glassJAw Member since: 3/14/2002 |
||||
|
|
||||
| An appendix for the article that addresses locking the vertex buffer (i.e. using matrix transformations instead), batching multiple images onto one texture, and a few other problems with the article is on the way. I should have it submitted by Friday. |
||||
|
||||
![]() glassJAw Member since: 3/14/2002 |
||||
|
|
||||
quote: Thanks. I'll try to get it right on the first go next time if I write another article. --------------------- After careful examination of the code, I noticed a little bug in CTexture::GarbageCollect(): When the call releases a texture, it will skip over the next texture in the list. Here is the corrected code:
//Release all unreferenced textures
int CTexture::GarbageCollect()
{
list<LOADEDTEXTURE*>::iterator it;
list<LOADEDTEXTURE*>::iterator itNext;
//Go through loaded texture list
for (it = loadedTextures.begin(); it != loadedTextures.end ();)
if ((*it)->referenceCount <= 0)
{
//Get next iterator
itNext = it;
itNext++;
//Release texture
if ((*it)->texture)
(*it)->texture->Release();
(*it)->texture = NULL;
//Delete LOADEDTEXTURE object
delete (*it);
loadedTextures.erase (it);
//Move to next element
it = itNext;
} else it++; //Increment iterator
//Successfully released unreferenced textures
return TRUE;
}And I also fixed up the rotation code. It's still not very fast, but it looks pretty good. This goes in the Blit() functions where the old rotation code is:
//Handle rotation
if (rotate != 0)
{
RECT rOrigin;
float centerX, centerY;
//Find center of destination rectangle
centerX = (float)(rDest->left + rDest->right) / 2;
centerY = (float)(rDest->top + rDest->bottom) / 2;
//Translate destination rect to be centered on the origin
rOrigin.top = rDest->top - (int)(centerY);
rOrigin.bottom = rDest->bottom - (int)(centerY);
rOrigin.left = rDest->left - (int)(centerX);
rOrigin.right = rDest->right - (int)(centerX);
//Rotate vertices about the origin
bufferVertices[index].x = rOrigin.left * cosf(rotate) -
rOrigin.top * sinf(rotate);
bufferVertices[index].y = rOrigin.left * sinf(rotate) +
rOrigin.top * cosf(rotate);
bufferVertices[index + 1].x = rOrigin.right * cosf(rotate) -
rOrigin.top * sinf(rotate);
bufferVertices[index + 1].y = rOrigin.right * sinf(rotate) +
rOrigin.top * cosf(rotate);
bufferVertices[index + 2].x = rOrigin.right * cosf(rotate) -
rOrigin.bottom * sinf(rotate);
bufferVertices[index + 2].y = rOrigin.right * sinf(rotate) +
rOrigin.bottom * cosf(rotate);
bufferVertices[index + 3].x = rOrigin.left * cosf(rotate) -
rOrigin.bottom * sinf(rotate);
bufferVertices[index + 3].y = rOrigin.left * sinf(rotate) +
rOrigin.bottom * cosf(rotate);
//Translate vertices to proper position
bufferVertices[index].x += centerX;
bufferVertices[index].y += centerY;
bufferVertices[index + 1].x += centerX;
bufferVertices[index + 1].y += centerY;
bufferVertices[index + 2].x += centerX;
bufferVertices[index + 2].y += centerY;
bufferVertices[index + 3].x += centerX;
bufferVertices[index + 3].y += centerY;
}There are more lines in the new rotation code, but less instructions per line, so the compiler may be able to optimize it a bit better. |
||||
|
||||
![]() CountSheep Member since: 8/28/2003 From: Claremont, USA |
||||
|
|
||||
| Question - For whatever reason when I apply the ->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); command, the graphics are not displayed. The background color however is still showing. Could Someone solve this puzzle? Im not sure if its my video card which is a TNT2. [edited by - CountSheep on August 28, 2003 12:34:17 AM] [edited by - CountSheep on August 28, 2003 12:34:58 AM] |
||||
|
||||
![]() Estauns Member since: 1/31/2001 From: Ontario, Canada |
||||
|
|
||||
| I enjoyed it, I learned quite a bit. I'm actually chipping away on a 2D Engine as we speak =) Maybe its not the most advanced way of doing something, but neither was the crap you put together in a Console window when you were learning C++. Now you're learning DirectX, and the more time you spend with the API the more efficient you'll get with it. I doubt the first renderer you wrote was blazing fast, rivaling Carmack. So whats the big deal that newbies learn through slower but easier to understand methods? You start throwing around Orthagonal Projection Matrices, Transforming and a whole bunch of other "technical crap" and you'll scare 'em off. Gotta learn in steps, not jumps. |
||||
|
||||
![]() Miksan Member since: 11/23/2002 From: Helsinki, Finland |
||||
|
|
||||
| Hello, anyone reading this still? How does that index buffer thing really work? I know something about them (I've made a simple cube), but I can't figure out what's happening here. Why is the index buffer filled the way it is? Why six indices? Why index buffer's size is 3x? Why fans cannot be used? Using matrixes to move batched sprites seems not to be possible? How to rotate individual sprites for example? I successfully converted this to work with c#/MDX, but it bothers a little when I don't understand it... [edited by - Miksan on March 12, 2004 7:08:07 AM] |
||||
|
||||
All times are ET (US)![]() |
Last Thread Next Thread ![]() |
|