|
||||||||||||||||||
Add Forum to Favorites | Send Topic To a Friend | View Forum FAQ | Track this topic Page: 1 2 3 »» |
Last Thread Next Thread ![]() |
| 2D Rendering in DirectX 8 |
|
![]() BadmanX Member since: 7/6/2001 |
||||
|
|
||||
| As you state in your conclusion, it IS a rather involved way of doing a blit...and I can't see how I could have two things on the same screen (like a static background and a movable sprite) without either using multiple vertex buffers (which requires a lot of setup and LOTS of memory if I have, say, 128 sprites I want to use) or locking and unlocking a single buffer (which is slow). Is there no better way to just blit data to the screen in DirectX 8? If so, then Direct3D and DirectDraw weren't merged; DirectDraw was simply eliminated. I can't see how I could wrap the code you've provided to create a generic "blit(texture, screenx, screeny);" function like I used to have in DOS. This is unfortunate, since most beginning game programmers shouldn't start by trying to write a 3D game; it's too overwhelming. Most game programmers start by writing 2D stuff, but now they can't; EVERYTHING must touch Direct3D somehow. |
||||
|
||||
![]() Anonymous Poster |
||||
|
||||
quote: Use one vertex buffer and index into it. |
||||
|
||||
![]() BadmanX Member since: 7/6/2001 |
||||
|
|
||||
| Wouldn't that still require me to lock/unlock the buffer in order to change what's in it? |
||||
|
||||
![]() Rykard Member since: 5/15/2001 From: Oscoda, USA |
||||
|
|
||||
| Finally! Thanks, Kelly. I really didn't like the idea of hunting odwn the DX7 docs just to do some 2d stuff. As for having to learn using 3d.. well, there are some 2d API/libs out there, if someone REALLY doesn't want to learn D3D. Mot of them are realy rappers for DD or D3d, so they will choke performance a little. But in a 2d APP, that usually isn't as much of a consideration, anyway. |
||||
|
||||
![]() Anonymous Poster |
||||
|
||||
| Why lock&unlock? Just draw the vertices 1, 2, 3 of the VB, then change the appropriate matrix to draw in a different screen position, then draw vertices 4, 5, 6 with a different texture, if you like. If you need other changes (texture coordinates), you would need to lock the small VB's too, if you make 1 VB for every object. |
||||
|
||||
![]() BadmanX Member since: 7/6/2001 |
||||
|
|
||||
| That's doable, but it's still far more complex than I'm used to just to blit a sprite onto a screen. |
||||
|
||||
![]() Buster Member since: 4/26/2000 From: USA |
||||
|
|
||||
| DOH! I've been using 2 triangles (6 v's). I didn't even think to use a fan and save 2 verts. |
||||
|
||||
![]() b2funny Member since: 5/24/2001 |
||||
|
|
||||
| If you only wanna do 2d graphics. I suggest that you take a look ID3DXSrite interface. You must use this interface like you use IDirect3DDevice interface. Check this interface under, Dx8SDK->DirectX Graphics->D3DX Reference. ID3DXSprite interface let you do 2D graphics in Dx8. You dont have to bother about matrices transformations, vertex buffer, index buffer and any other 3d related stuff. To use ID3DXSprite correctly, i suggest that u make or re-edit your own tile or sprite class. Make them use a Texture instead of a bitmap, then use ID3DXSprite to draw. simple render loop void Render() { m_pDirectXDevice8->Clear (...); // clear the back-buffer m_pDirectXDevice8->BeginScene (); // 2d graphics stuff (like : tiles, sprites, console, ...) m_pDxSprite->Begin(); // Here, call Draw of every 2d entity that you see. m_pDxSprite->End (); m_pDirectXDevice8->EndScene(); m_pDirectXDevice8->Present(0,0,0,0); } Simple drawing routine of a tile void Entity::Render (LPD3DXSPRITE pSpriteSys) { // the draw function of ID3DXSprite LPDIRECT3DTEXTURE8 pSrcTexture, // use your gfx texture CONST RECT* pSrcRect, // rect of the tile you want inside your texture CONST D3DXVECTOR2* pScaling, // if you want to scale it CONST D3DXVECTOR2* pRotationCenter, FLOAT Rotation, CONST D3DVECTOR2* pTranslation, // want it to move ! D3DCOLOR Color // Color keying, usefull to do alpha-blending } Anyway, check that interface for your new tile-based game. You wont regret it ! Jonathan |
||||
|
||||
![]() Owie Member since: 3/13/2000 |
||||
|
|
||||
| Is doing 2d in D3D really worth all the extra pain of thinking 3d while doing 2d?? Sure you can do different effects with it, but are those extra's worth it? |
||||
|
||||
![]() alexk7 Member since: 2/25/2000 From: Quebec, Canada |
||||
|
|
||||
| I think ID3DXSprite is now the easiest way to make a 2d game. It would be a great idea to update the "For beginner" section of gamedev.net for more information about this. It seems that even tutorial writers are too much deep in pure D3D to see that D3DXSprite is the replacement of DirectDraw ! Here is a simple tutorial that saved my life... (as I was choosing between dd7, d3d8 or even opengl... for a simple 2d game) : http://www.angelfire.com/realm/zeroone/2dsprite.htm |
||||
|
||||
![]() CrazedGenius Member since: 6/12/2001 |
||||
|
|
||||
| It's absolutely true that the sprite class is the easiest way to go, but it's good to explain the guts so that people would know what's going on under the hood. About locking - everyone always talks about locking, but I can think of very few instances where you absolutely need to. You could set up a framework that has one vertex buffer of a unit square with full texture coordinates, then use a matrix to rescale and reposition, and a texture matrix to mess with the tex coords if need be - no locking! Two things on one screen: //Scale/Position Background //Set Background texture //Draw //Scale/Position Sprite //Set Sprite Texture //Draw -One VB, no locking. The only memory usage is two textures and ONLY 4 vertices! About a generic Blit(Texture, X, Y) function - assuming the texture is a preloaded DX8 texture pointer, the function looks like: Blit(Texture, X, Y) { //use texture interface methods to find the size //Build my translation/scaling matrix based on X, Y, and size //set the transform to my matrix //set the current texture to my texture //draw my vertices } About thinking in 3D/complexity, etc. - Keep in mind that by doing things this way, you're not "thinking in 3D", you are "thinking like the card thinks". Like it or not, the card is REALLY good at dealing with vertices, vectors, and matrices. You can ignore all that and think in terms of blits, but you are ignoring alot of the horsepower available to you! Having said all that, the D3DXSprite class (or the wrapper) is easy to use, but for anyone who's interested, there are probably lots of custom optimizations you can make if you know what's under the hood (better vertex usage, texture usage, etc.) As far as I can tell, this is essentially how D3DXSprite is done. Edited by - CrazedGenius on July 6, 2001 4:16:18 PM |
||||
|
||||
![]() CrazedGenius Member since: 6/12/2001 |
||||
|
|
||||
| One thing missing from the article - make sure you release the interface pointers when the program terminates. (I'm hoping most people know that, but just in case...) |
||||
|
||||
![]() Alamar Member since: 5/10/2001 |
||||
|
|
||||
| BadmanX: DirectX has gotten easier to use with every revision, and Direct3D is a lot easier to do now, for 2D OR 3D graphics than DirectDraw was a few releases back. Sure, when you're beginning you need it easier than at any other point, but that's what this tutorial and the huge amount of tutorials/libs are for. Also, if you have 128 sprites, are they all facing the same way? How much memory does it take to have local copies of each direction it faces? It's going to be a lot smaller if you use a vertex buffer and ONE texture. And yes, using that tutorial you can come up with a way to get it down to one function call to blit an image to the screen. Just like in DirectDraw, it's not one function call, you have to set up your surface beforehand. There's not much of a difference now, it's just another type of setup. In the end, if you need to do something and you just don't want to learn how, get a tool. G'luck, -Alamar |
||||
|
||||
![]() alexk7 Member since: 2/25/2000 From: Quebec, Canada |
||||
|
|
||||
| It's true that D3DXSprite is just a D3D wrapper for 2d stuff but when beginners just want to get something on the screen, I think it should be the first thing to learn. Beginners simply don't want to learn 3D stuff first. If you compare D3DXSprite with DirectDraw, you can say it's better for a lot of simple things like alpha blending, rotation, filtering and it's still really simple ! I don't want to set up a 3d matrix when I just want an image on the screen. I don't care how the card work for now because I just want to have fun seeing my game working... After all, these optimization are not really needed for a simple 2d game. Optimization fever is really a bad thing. I want to program my game, not a new graphic engine. D3DXSprite is there and it's really what I need. That's all. alexk7@alexk7.com |
||||
|
||||
![]() Ratman Member since: 12/1/1999 |
||||
|
|
||||
| D3DXSprite has compatibility problems. If the video card does not support A1R3G3B3 pixel format then you cannot get transparency in hardware mode w/ out using an alpha channel (like dds files). This will require an extra bmp for every image you want to use. Its a huge pain. Plus you have problems w/ textures that arent in powers of 2. You can never be sure a video card supports any particular pixel format. I had a D3D8 2D engine, but gave it up and went back to DirectDraw to get more compatibility. I sure do miss the alpha blending though... ratman --------------- Ratfest.org |
||||
|
||||
![]() CrazedGenius Member since: 6/12/2001 |
||||
|
|
||||
| Ratman - are you sure about that? On pixel formats - I think you can use D3DXCreateTextureFromFileEx and specify a format that works plus a color key value. I haven't tried this in all possible combinations, but it should work. You can also find out which formats are supported, and I think A8R8G8B8 is a pretty safe bet and alpha/ColorKey friendly. On powers of 2 - Yes, but a couple things... 1. That's changing, newer hardware can handle arbitrary sizes and you can ask the device if it needs powers of 2. 2. You can write a pretty simple function to load bitmaps, figure out the nearest power of 2, and copy the bitmap into the texture. You'll also have to take that into account when you specify coordinates. 3. Yes, it's a real pain in the behind, no argument. I guess the only reason I like it is because it is more efficient and that ultimately means less trips across the pipe. |
||||
|
||||
![]() BadmanX Member since: 7/6/2001 |
||||
|
|
||||
| Thanks to everyone who replied, especially alexK7, b2Funny and CrazedGenius. I found out what I wanted to know, which is the interface that recreates DirectDraw under DirectX 8. While the docs for DX8 _are_ complete, they are not terribly well-organized, IMO. Thanks again. |
||||
|
||||
![]() Sly Member since: 7/28/2000 From: Brisbane, Australia |
||||
|
|
||||
quote: Direct3D 8.0 does not have a software renderer, so it will not function on purely 2D hardware. It has a pluggable renderer function, but it is the application developer who must write the software renderer. Steve 'Sly' Williams Code Monkey Krome Studios |
||||
|
||||
![]() Guimo Member since: 5/17/2000 From: Lima, Peru |
||||
|
|
||||
| I can remember installing D3D8 SDK and found that the samples didn't work on older non3d video cards. The reason is that D3D8 don't have a Software rastrerizer and forced to use its reference rasterizer which is TOO slow. So, I can't run this in D3D8 but its ok for D3D7 which has a SW raster AND the D3DX interfaces (which are really good). |
||||
|
||||
![]() Anonymous Poster |
||||
|
||||
| Useful article for us newbies, thanks. However... Anyone actually try and type in the code from this article? I assume that in the line: //Set all the colors to white pVertices[0].d = pVertices[1].d = pVertices[2].d = pVertices[3].d = 0xffffffff; the .d fields should actually be .color? Even still, I ended up with a green window, with no rectangle (at the point in the article before texturing). |
||||
|
||||
![]() Anonymous Poster |
||||
|
||||
quote: Ignore me, unlocking the VB TOTALLY helps. |
||||
|
||||
![]() CrazedGenius Member since: 6/12/2001 |
||||
|
|
||||
| yes - .d = .color that's the problem with pasting code from multiple projects... Other than that, it should work. |
||||
|
||||
![]() Lantz Member since: 7/12/2001 From: Sweden |
||||
|
|
||||
| Hmm, that whole tutorial seems a little bit inefficient. Why not use pretransformed verices when doing 2D? Sending the triangles directly to the rasterizer is much more effective than sending them through the transformation pipeline first. Seems very stupid. |
||||
|
||||
![]() Anonymous Poster |
||||
|
||||
| I was first using DX7. To perform alpha-blending, I used pretransformed triangles directly sent to the rasterizer as well as the method described in the tutorial. Performance decrease was only significant for really large amount of sprites (above 300 in high resolution), and I am almost convinced (after some trials) that this decrease is due to 3D card fillrate and not to matrix calculation (performed by CPU or card for newer system). When I switch to DX8, the use of ID3DXSprite interface simplified the whole procedure, for even better performances. The tutorial describes a good and efficient method. The author says that his method is not optimized, and some improvement could be done. Yet, I would have been really happy to find such a tutorial when I was learning this part of DX. It's definitely a good tutorial, and a good introduction to DX8 2D rendering. |
||||
|
||||
|
Page: 1 2 3 »» All times are ET (US) ![]() |
Last Thread Next Thread ![]() |
|