Archived

This topic is now archived and is closed to further replies.

dacrisxp

DirectX 8, where's DirectDraw??

Recommended Posts

dacrisxp    122
I''m currently making a game engine using the Direct3D 8 SDK. I would like to know where to find some source code for writing a basic DirectDraw wrapper for Direct3D 8. Your help is appreciated.

Share this post


Link to post
Share on other sites
DoctorK    122
But if you have the choice, it will probably be better doing it with DX7. This way you should get (AFAIK): more speed than with using the 3d stuff, more versatility (in some cases), and some other pros. I think that, at the current time, that decision of taking DD away was a bad move... but in the future D3d will surely be a better option.


--DK
--H. Hernán Moraldo
http://www.hhm.com.ar/

Share this post


Link to post
Share on other sites
Krunk    122
quote:
Original post by DoctorK
This way you should get (AFAIK): more speed than with using the 3d stuff


AFAIK, Modern 3D cards (3dfx voodoo 3 upwards) are heavily optimised for drawing textured triangles at the expense of framebuffer access (pixel plotting and blitting). Its even worse for cards like the GeForce, because while you have the framebuffer locked to write pixels to it, the GPU has to idle.

If you`re planning to use modern hardware, you get more speed and flexibility by using D3D8 (you can use alpha blending, and hardware accelerated scaling and rotation). Its harder to write though...

The tutorial InvaderX mentioned is well worth a look.

Share this post


Link to post
Share on other sites
CrazedGenius    156
Agreed. It should be just as fast or faster, expecially if you are doing rotation, scaling, and blending.

If you have a geForce3, watch nVidia''s image processing sample. It can do a find edges filter at 100+ fps. That''s really, really fast (and 2D).

Share this post


Link to post
Share on other sites
dacrisxp    122
Thanks a lot, but you''re kinda late . I already figured out a wrapper (without D3DXSprite), and I''m no longer in the mood to learn another wrapper :D. However, how do I make my program load a 640x480 texture and display it correctly? Currently, the texture is loaded w/ default parameters (0,0 for width&height), and it looks like a 256x256 texture stretched to 640x480! How do I make it not stretch? (In other words, can I load just one part (256x256) from the texture and display that on one part (0.4 x 0.5333) of the material, and then load the next part, and display it on the next part of the material?

Here''s the code for my simple wrapper functions:

// Create Rectangle (Creates a rectangular primitive w/ size specified)
LPDIRECT3DVERTEXBUFFER8 CreateRectangle(float x, float y, float w, float h)
{
LPDIRECT3DVERTEXBUFFER8 g_pVertices = NULL;
float PanelWidth = w;
float PanelHeight = h;

dx8.pd3dDevice->CreateVertexBuffer(4 * sizeof(PANELVERTEX), D3DUSAGE_WRITEONLY,
D3DFVF_PANELVERTEX, D3DPOOL_MANAGED, &g_pVertices);

PANELVERTEX* pVertices = NULL;
g_pVertices->Lock(0, 4 * sizeof(PANELVERTEX), (BYTE**)&pVertices, 0);

//Set all the colors to white
pVertices[0].d = pVertices[1].d = pVertices[2].d = pVertices[3].d = 0xffffffff;

//Set positions and texture coordinates
pVertices[0].x = pVertices[3].x = -320 + x;
pVertices[1].x = pVertices[2].x = -320 + PanelWidth + x;

pVertices[0].y = pVertices[1].y = 240 - y;
pVertices[2].y = pVertices[3].y = 240 - PanelHeight - y;

pVertices[0].z = pVertices[1].z = pVertices[2].z = pVertices[3].z = 1.0f;
pVertices[1].u = pVertices[2].u = 1.0f;
pVertices[0].u = pVertices[3].u = 0.0f;

pVertices[0].v = pVertices[1].v = 0.0f;
pVertices[2].v = pVertices[3].v = 1.0f;

g_pVertices->Unlock();

return g_pVertices;
}

// similar to DDraw one, but sets a texture & displays a rectangular primitive.
void Blt(LPDIRECT3DTEXTURE8 texture, int x, int y, int w, int h)
{
dx8.pd3dDevice->SetTexture(0, texture);
dx8.pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
dx8.pd3dDevice->SetVertexShader(D3DFVF_PANELVERTEX);
dx8.pd3dDevice->SetStreamSource(0, CreateRectangle((float)x, (float)y, (float)w, (float)h), sizeof(PANELVERTEX));
dx8.pd3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
}

// Loads texture & returns pointer to it
LPDIRECT3DTEXTURE8 LoadTexture(char *filename, int w, int h)
{
LPDIRECT3DTEXTURE8 pd3dTexture;
// Set black as our source color key. Use 0xFFFF00FF for magenta instead.
// Use 0x00000000 for no ''color key'' substitution
D3DCOLOR colorkey = 0xFF000000;
// The D3DX function will fill in the following image info for us
//D3DXIMAGE_INFO SrcInfo; // Optional

// Load image from file - maintain size of original file.
// It is also possible to specify a new height/width and ask D3DX to filter
// the image to the new size (stretch/shrink). See SDK docs for details.
D3DXCreateTextureFromFileEx( dx8.pd3dDevice, filename, w, h, 0, 0,
D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT,
colorkey, NULL , NULL, &pd3dTexture);
// Check the return value here, etc

// Remember, textures sizes may be larger or smaller than your image,
// to allow for legal texture sizes & maximums on user''s hardware
return pd3dTexture;
}

Please look over my code, and suggest a method to solve the problem mentioned above.

Thanks for all your help!

Share this post


Link to post
Share on other sites
CrazedGenius    156
D3DX tries to do alot of work for you, but in some cases, it may produce suboptimal results.

Try this...

1. Create a 256x256 texture (remember, you can ask the device what it''s max dimensions are before you load textures)

2. Call IDirect3DTexture8->GetSurfaceLevel to get the surface interface.

3. Call D3DXLoadSurfaceFromFileA to load only a subset into that surface.

Yes, sometimes it can be alot of work, but once you get the wrapper together, this is much better than DirectDraw looking forward to "modern cards". Also, current cards support much bigger textures and future cards will drop the powers of 2 requirements. So, you have to jump through some hoops, but Direct3D is still a better way to go from the standpoint of learning longer term skills.

Share this post


Link to post
Share on other sites
dacrisxp    122
ok.. I kind of get what you mean, but I''m a beginner in D3D programming and I would really appreciate it if you could show me just a few code snippets of how I would do this.

thanks

Share this post


Link to post
Share on other sites
CrazedGenius    156
To Fresh:

No.

My geForce2Go has 2048x2048 textures. I''ll have to check the GF3, it''s either 2048 or 4096...

That''s the whole point of the CAps structure - the API is not explicitly limited. Please don''t mislead people.

To dacrisxp: Use surface level 0. After that, just display the texture like always. Take a look at the docs - they are much more explanatory than code snippets. It''ll take longer, but you''ll learn much more.

Share this post


Link to post
Share on other sites
SikCiv    122
quote:
Original post by F_r_e_s_h
The max size for textures in DX8 is 256X256. If you want to display larger stuff you have to create a surface.


Actually it depends on the 3D Accelerator. On my GeForce I can load 2048x2048 sized textures and blit them with no problems, though its not a good idea to have large textures since many cards are limited to 256x256 sized textures, specifically the Voodoo3 card.

As for creating a D3D 2Dwrapper without D3DXSprite, in my opinion both techniques have the same performance when programmed correctly, though D3DXSprite it the better of the two since it supports scaling, rotation, and alpha, implementing these features without D3DXSprite would be a major hassle... why re-invent the wheel? - well its up to u.

  Downloads:  ZeroOne Realm

Share this post


Link to post
Share on other sites
CrazedGenius    156
SikCiv - I agree with not reinventing the wheel, but this is actually a case where it might make sense because it sounds like he may have to rework the texture part.

About scaling, rotation, etc. It''s no hassle at all...

D3DXSprite supports DrawTransform, which just means that it passes a matrix to the device. Doing that is just a matter of calling SetTransform.

Implementing your own version of D3DXSprite->Draw is just a matter of passing the Draw parameters to the D3DXMatrix... functions and building the transform.

Share this post


Link to post
Share on other sites
DoctorK    122
quote:
Original post by Krunk

AFAIK, Modern 3D cards (3dfx voodoo 3 upwards) are heavily optimised for drawing textured triangles at the expense of framebuffer access (pixel plotting and blitting). Its even worse for cards like the GeForce, because while you have the framebuffer locked to write pixels to it, the GPU has to idle.

If you`re planning to use modern hardware, you get more speed and flexibility by using D3D8 (you can use alpha blending, and hardware accelerated scaling and rotation). Its harder to write though...

The tutorial InvaderX mentioned is well worth a look.


Hmm... To be honest, I''m focusing in way older hardware for my games.


--DK
--H. Hernán Moraldo
http://www.hhm.com.ar/

Share this post


Link to post
Share on other sites