Sign in to follow this  
nlraley

Starting DirectX9 - Need some advice on a few things...

Recommended Posts

I have been working on a project at work with DirectX9 in Borland, which has been a complete nightmare.

Since Borland is such a pain to get to work with DirectX9, and isn't even supported, I've decided to dive into learning DirectX9 at home this weekend with Visual Studio, which I much prefer, so I have some support, intellisense, documentation, and actual tutorials to go by to build what I need up from the ground up here, where I know it works, and then try and do the convert at work next week.

I've been diving through the samples and tutorials provided in the SDK, and so far I have easily created and initialized the device, displayed the solid blue background, and then also started working with the vertex example to get a triangle to display on the screen. My next step is to make that triangle into a square, which I know I'll simply need to add another vertex so that instead of drawing 3, I'll be drawing 4 to make a square. Once I have that I'll try and load an image texture into the vertex.

So I'm hoping for some advice and suggestions along my progression. My first one, is can someone explain the vertexes and the coordinate system to me a little better?

The example defines their vertex for the triangle as:

Vertex vertices[] =
{
{ 150.0f, 50.0f, 0.5f, 1.0f, 0xffff0000, }, // x, y, z, rhw, color
{ 250.0f, 250.0f, 0.5f, 1.0f, 0xff00ff00, },
{ 50.0f, 250.0f, 0.5f, 1.0f, 0xff00ffff, },
};


Which is simply using the structure:
struct Vertex
{
FLOAT x, y, z, rhw; // The transformed position for the vertex
DWORD color; // The vertex color
};


How do the x,y,z, rhw work with this? Are the x,y,z the pixel coordinates on the screen? So say 150.0f for the x is merely 150 pixels from the top left, which is 0,0?

Share this post


Link to post
Share on other sites
They are not screen coordinates, they are whats called object space coordinates. There is alot to take in and if I explained everything you would get lost and not remember what you read.

For now, it is enough to say that those coordinates are in the world. It is easier and quicker to learn if you just modify the values and see what happens. Somewhere in your code, you should create whats called your View matrix. The code to create it should be on a function D3DXMatrixLookAt . In that function you give it coordinates to look at, and your position. So, if you look at (0, 0, 0) and your position passed is (0, 0, -20) then you will look at the center of the world. You should also figure out what the heck the difference between a left handed coordinate system and a right handed coordinate system is; it will help you orient yourself and figure out why positive Z goes into the monitor for Directx. So, try changing your vertices to something around that area and see what happens. Then try messing with the Projection Matrix and your Field of View to see what that does too. After that you should have an idea of what the coordinates mean and you can dive off into other things like object to world transformations, figure out how to rotate objects, and scale them.

I HIGHLY recommend you read a couple of chapters in this book, it will help you SO MUCH

http://books.google.com/books?id=wCfWkc_E3GkC&printsec=frontcover&dq=3d+math+primer+for+graphics+and+game+development&hl=en&ei=Ogy6TJ_FCI6-sAP-1pjcDg&sa=X&oi=book_result&ct=result&resnum=1&ved=0CDIQ6AEwAA#v=onepage&q&f=false

Share this post


Link to post
Share on other sites
Well, my implementations for this should be in a 2d perspective, based in a windowed mode, and hopefully when I'm done will be displaying in a 1024x512 display window within my application.

I was just trying to figure out how those coordinates related to everything else. I'll take a look at the article you posted and see if any of it makes sense.

Share this post


Link to post
Share on other sites
I'll like to add, from the example they at least, for the most part, the x,y affect the pixel position of the vertices of the triangle in respect to the window.

Changing it to:
Vertex vertices[] =
{
{ 0.0f, 0.0f, 0.5f, 1.0f, 0xffff0000, }, // x, y, z, rhw, color
{ 200.0f, 200.0f, 0.5f, 1.0f, 0xff00ff00, },
{ 0.0f, 200.0f, 0.5f, 1.0f, 0xff00ffff, },
};


Places one vertex 100 pixels over, 0 pixels down.
Next one 200 pixels over, 200 pixels down.
0 Pixels over, 200 pixels down.

So I know have a

*



* *

Instead of a

*



* *

Share this post


Link to post
Share on other sites
How come changing the vertex array to:
    Vertex vertices[] =
{
{ 0.0f, 0.0f, 0.5f, 1.0f, 0xffff0000, }, // x, y, z, rhw, color
{ 200.0f, 200.0f, 0.5f, 1.0f, 0xff00ff00, },
{ 0.0f, 200.0f, 0.5f, 1.0f, 0xff00ffff, },
{ 200.0f, 0.0f, 0.5f, 1.0f, 0xff00ffff, }
};

And my vertex buffer definition to:
if( FAILED( d3d.d3d9Device->CreateVertexBuffer( 
4 * sizeof( Vertex ), // Length
0, // Usage -
D3DFVF_TLVERTEX, // Specifies Vertex Format
D3DPOOL_DEFAULT, // D3DPool
&d3d.d3d9VertexBuffer, // Pointer to the Direct3D Vertex Buffer
NULL // HANDLE
) ) )

Did not result in a square/quad?

Share this post


Link to post
Share on other sites
Imagine that you have one of the tube monitors ( I still use them ). And inside that tube monitor, its empty. Now, the inside of your monitor the center represents (0, 0, 0) Make sure you are Facing your monitor. Facing your monitor, Positive X goes out the right side of it, Positive Y Goes Up to the ceiling, and Positive Z goes Into the monitor out the back.

Knowing that, try again. Also, make sure your ViewMatrix is set to look at 0 0 0 and set it back some like 100 units back to make sure you can see your object. 100 units back would be a pos of (0, 0, -100) btw.

To know exactly what is what. Change your Colors so you can see where the verts move.

Share this post


Link to post
Share on other sites
Well, here is what I did...

Added a vertex to to vertexes:
    Vertex vertices[] =
{
{ 0.0f, 0.0f, 0.5f, 1.0f, 0xffff0000, }, // x, y, z, rhw, color
{ 200.0f, 0.0f, 0.5f, 1.0f, 0xff00ffff, },
{ 200.0f, 200.0f, 0.5f, 1.0f, 0xff00ff00, },
{ 0.0f, 200.0f, 0.5f, 1.0f, 0xff00ffff, },
};


I called this with 4 * instead of 3* as such:
if( FAILED( d3d.d3d9Device->CreateVertexBuffer( 
4 * sizeof( Vertex ), // Length
0, // Usage -
D3DFVF_TLVERTEX, // Specifies Vertex Format
D3DPOOL_DEFAULT, // D3DPool
&d3d.d3d9VertexBuffer, // Pointer to the Direct3D Vertex Buffer
NULL // HANDLE
) ) )
{
//-------------------
return E_FAIL;
//-------------------
}


Then I called the following:

d3d.d3d9Device->SetStreamSource( 0, d3d.d3d9VertexBuffer, 0, sizeof( Vertex ) );
d3d.d3d9Device->SetFVF( D3DFVF_TLVERTEX );
d3d.d3d9Device->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 1 );


I changed it to TriangleStrip so it should support the 4 vertexes, recognize the 4th is alone and connect it to accordingly.

Really not sure what else I need to do beyond that...

Share this post


Link to post
Share on other sites
On a note to your response, I did that with:
d3d.d3d9Device->CreateVertexBuffer(
4 * sizeof( Vertex ), // Length
0, // Usage -
D3DFVF_TLVERTEX, // Specifies Vertex Format
D3DPOOL_DEFAULT, // D3DPool
&d3d.d3d9VertexBuffer, // Pointer to the Vertex Buffer
NULL // HANDLE
)

Didn't I? That and changing it to the D3DPT_TRIANGLESTRIP instead of D3DPT_TRIANGLELIST should have taken care of it right?

Share this post


Link to post
Share on other sites
You may consider this book very useful if you getting started with DirectX -
http://www.amazon.com/Introduction-Programming-DirectX-Wordware-Graphics/dp/1556229135/ref=pd_cp_b_3

or if you will need shaders in your project try this one instead -
http://www.amazon.com/Introduction-Game-Programming-Direct-9-0c/dp/1598220160

Share this post


Link to post
Share on other sites
Quote:
Original post by nlraley
Would you recommend doing with a loadtexturefromfile and drawing the texture or using a sprite?

Even with a sprite (ID3DXSprite, I assume), you still have to provide the texture. So you have to load it from a file anyway.

You can either use ID3DXSprite or roll your own, which isn't *that* hard. Just two triangles with texture coordinates. The former is a bit easier, but the latter gives you more flexability, which may be helpful later on.

Share this post


Link to post
Share on other sites
What's the difference I keep seeing in the vertex formats?

For example, the DirectX Example provided in the SDK uses this format for the vertex structure:
struct Vertex
{
FLOAT x, y, z, rhw; // The transformed position for the vertex
DWORD color; // The vertex color
};


But nearly every other example I have found online uses this format for the vertex:
struct Vertex
{
FLOAT x, y, z, rhw; // The transformed(screen space) position for the vertex.
D3DCOLOR colour;
float u,v; // Texture coordinates
};


Is there anything particular I need to do to use the u,v with the vertex?

Share this post


Link to post
Share on other sites
I've succeeded in initializing my D3Device and Setting up the VertexBuffer which allowed me to render a triangle. I have moved to rendering a square with success.

No I'm trying to load the texture is coming up short for me for some reason. Can someone tell me what I'm doing wrong?

Here is what I have thus far:
After Initializing my D3D I call this function, which sets up the vertex buffer and the intial vertex for me:
//-------------------
HRESULT Direct3D::InitVB()
{
//-------------------
VOID* pVertices;
RECT tRect;
LPCSTR file;
char *cfile;
D3DXIMAGE_INFO SrcInfo;
//-------------------
cfile = "G:\\MGMapsCache\\GoogleMap\\18\\108341\\61585.png";
file = (LPCSTR)cfile;
//-------------------
if (FAILED(d3d.hr = D3DXCreateTextureFromFileEx(
d3d.d3d9Device,
file,
0,
0,
1,
0,
D3DFMT_A8R8G8B8,
D3DPOOL_MANAGED,
D3DX_FILTER_NONE,
D3DX_DEFAULT,
0xffff0000,
&SrcInfo,
NULL,
&d3d.d3dTexture
)))
return E_FAIL;
//-------------------

//------------------- Initialize three vertices for rendering a triangle
/*Vertex vertices[] =
{
{ 0.0f, 0.0f, 0.5f, 1.0f, 0xffff0000, }, // x, y, z, rhw, color
{ 256.0f, 256.0f, 0.5f, 1.0f, 0xff00ff00, },
{ 0.0f, 256.0f, 0.5f, 1.0f, 0xff00ffff, },
};*/

// x, y, z, rhw, tu, ty, color
Vertex vertices[] =
{
{ 0.0f, 0.0f, 0.5f, 1.0f, 0, 0, 0xffff0000 }, // Top Left
{ 2560.0f, 0.0f, 0.5f, 1.0f, 1, 0, 0xff00ffff }, // Top Right
{ 0.0f, 256.0f, 0.5f, 1.0f, 0, 1, 0xff00ffff }, // Bottom Left
{ 256.0f, 2560.0f, 0.5f, 1.0f, 1, 1, 0xff00ff00 } // Bottom Right
};


//-------------------
// Create the vertex buffer. Here we are allocating enough memory
// (from the default pool) to hold all our 3 custom vertices. We also
// specify the FVF, so the vertex buffer knows what data it contains.
//-------------------
if( FAILED( d3d.d3d9Device->CreateVertexBuffer(
4 * sizeof( Vertex ), // Length
0, // Usage -
D3DFVF_TLVERTEX, // Specifies Vertex Format
D3DPOOL_DEFAULT, // D3DPool
&d3d.d3d9VertexBuffer, // Pointer to the Direct3D Vertex Buffer
NULL // HANDLE
) ) )
{
//-------------------
return E_FAIL;
//-------------------
}
//-------------------
// Now we fill the vertex buffer. To do this, we need to Lock() the VB to
// gain access to the vertices. This mechanism is required becuase vertex
// buffers may be in device memory.
//-------------------
if( FAILED( d3d.d3d9VertexBuffer->Lock( 0, sizeof( vertices ), ( void** )&pVertices, 0 ) ) )
return E_FAIL;
memcpy( pVertices, vertices, sizeof( vertices ) );
d3d.d3d9VertexBuffer->Unlock();
//-------------------
return S_OK;
}


After that has been achieved I call Render thus executing:
//-------------------
if ( SUCCEEDED( d3d.d3d9Device->BeginScene() ) )
{
//-------------------
// Scene Rendering takes place Here
//-------------------
// Draw the triangles in the vertex buffer. This is broken into a few
// steps. We are passing the vertices down a "stream", so first we need
// to specify the source of that stream, which is our vertex buffer. Then
// we need to let D3D know what vertex shader to use. Full, custom vertex
// shaders are an advanced topic, but in most cases the vertex shader is
// just the FVF, so that D3D knows what type of vertices we are dealing
// with. Finally, we call DrawPrimitive() which does the actual rendering
// of our geometry (in this case, just one triangle).
//-------------------
d3d.d3d9Device->SetStreamSource( 0, d3d.d3d9VertexBuffer, 0, sizeof( Vertex ) );
d3d.d3d9Device->SetFVF( D3DFVF_TLVERTEX );
d3d.d3d9Device->SetTexture(0, d3d.d3dTexture);
d3d.d3d9Device->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
//------------------- End the Scene
d3d.d3d9Device->EndScene();
}


From what I've read that should load my Texture (a 256x256 png) into the Device and Render it to the screen. I'm probably missing something small. Any ideas?

Share this post


Link to post
Share on other sites
Work through the SDK tutorials; it's all explained there. You seem to be jumping ahead of your current level of knowledge, which is a sure way to get burned. 10 out of 10 for enthusiasm though, but you'll really be better off slowing down a little and digesting the stuff you're currently working on fully first.

The u/v members are texture coordinates, and there's a whole heap of background info on texture mapping that you need to know before any explanation will make sense. So work ahead and you'll get there. :)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this