Sign in to follow this  
f4cepl4nt

D3D9 Matrices

Recommended Posts

Ok here are some code snippets from a program I made. All it does right now is draw a triangle in 3d space. For some reason though, it won't appear on my screen, even though all the vectors for the view matrix and projection matrix appear to be ok. This first one initializes my vertices and vertex buffer:
void InitVertices()
{
	triVERTEX vertices[] = 
	{
		{0,1,0,0xFFFF0000},{1,-1,0,0xFF00FF00},{-1,-1,0,0xFF0000FF}
	};

	int vert_count=sizeof(vertices)/sizeof(triVERTEX);
	int byte_count=vert_count*sizeof(triVERTEX);
	void *vb_vertices;
	g_list_count=vert_count/3;

	D3DDevice->CreateVertexBuffer(byte_count,        //Length
                                       D3DUSAGE_WRITEONLY,//Usage
                                       tri_fvf,           //FVF
                                       D3DPOOL_MANAGED,   //Pool
                                       &VBuffer,        //ppVertexBuffer
                                       NULL);             //Handle


   VBuffer->Lock(0, //Offset
					  0, //SizeToLock
                      &vb_vertices, //Vertices
                      0);  //Flags

   memcpy( vb_vertices, vertices ,byte_count);

   VBuffer->Unlock();
}


This one is initializing my matrices. Oh yeah, the variables width and height were set at the beginning of the program to GetSystemMetrics(CMXSCREEN) and (CM_YSCREEN) (dont worry bout the probably wrong flags there, I just dont remember exactly what they were. But basically width and height are the windows width and height, so I don't know maybe that makes a difference):
void InitMatrices()
{
	D3DXMATRIX view_matrix;
	D3DXMATRIX projection_matrix;
	D3DXVECTOR3 eye_vector;
	D3DXVECTOR3 lookat_vector;
	D3DXVECTOR3 up_vector;
	D3DXMATRIX world_matrix;
	float aspect;
	
	   //Here we build our View Matrix, think of it as our camera.
	
	   //First we specify that our viewpoint is 8 units back on the Z-axis
	   eye_vector=D3DXVECTOR3( 0.0f, 0.0f,-8.0f );
	
	   //We are looking towards the origin
	   lookat_vector=D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
	
	   //The "up" direction is the positive direction on the y-axis
	   up_vector=D3DXVECTOR3(0.0f,1.0f,0.0f);
	
	   D3DXMatrixLookAtLH(&view_matrix,&eye_vector,
	                                   &lookat_vector,
	                                   &up_vector);
	
	   //Since our 'camera' will never move, we can set this once at the
	   //beginning and never worry about it again
	   D3DDevice->SetTransform(D3DTS_VIEW,&view_matrix);
	
	  aspect=((float)width / (float)height);
	
	   D3DXMatrixPerspectiveFovLH(&projection_matrix, //Result Matrix
	                              D3DX_PI/4,          //Field of View, in radians.
	                              aspect,             //Aspect ratio
	                              0.5f,               //Near view plane
	                              100.0f );           //Far view plane
	
	   //Our Projection matrix won't change either, so we set it now and never touch
	   //it again.
	   D3DDevice->SetTransform(D3DTS_PROJECTION, &projection_matrix);	
	
	
	   //The World Matrix transforms Model Coordinates into World Space coordinates.
	   //Setting it to Identity means there is no transformation, so Model Space is directly
	   //mapped onto World Space.
	   D3DXMatrixIdentity(&world_matrix);
	   D3DDevice->SetTransform(D3DTS_WORLD,&world_matrix);
}


And this last one renders my triangle (but it doesn't appear on screen for some reason)
void Render()
{
	D3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 0, 0);
	D3DDevice->BeginScene();
	D3DDevice->SetFVF(tri_fvf);
	D3DDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_SOLID);
	//Bind our Vertex Buffer
   D3DDevice->SetStreamSource(0,                   //StreamNumber
                                 VBuffer,           //StreamData
                                 0,                   //OffsetInBytes
                                 sizeof(triVERTEX)); //Stride


  //Render from our Vertex Buffer
   D3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, //PrimitiveType
                               0,                  //StartVertex
                               g_list_count);      //PrimitiveCount
	
	D3DDevice->EndScene();
	D3DDevice->Present(NULL, NULL, NULL, NULL);
}


So does anyone see something wrong with this? Because I sure dont. Thanks [Edited by - Coder on November 5, 2005 12:08:21 PM]

Share this post


Link to post
Share on other sites
But I don't have a ZBuffer...At least I don't think i do =) lol.

EDIT: When I tried to clear the zbuffer as well, I saw a flashing screen between white and black and a black triangle in the middle.

Share this post


Link to post
Share on other sites
Well at least now we know your triangle has been transformed into the right position. If you are rendering in 3D then you do have a z-buffer, you have to clear it each frame.

Another thing you are missing is these 3 renderstates:

// Turn off culling
D3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );

// Turn off D3D lighting
D3DDevice->SetRenderState( D3DRS_LIGHTING, FALSE );

// Turn on the zbuffer
D3DDevice->SetRenderState( D3DRS_ZENABLE, TRUE );

They only need to be set once, but can be done per frame.

ace

Share this post


Link to post
Share on other sites
Thanks a lot everyone, that was extremely helpful. I had a feeling it had something to do with lighting, but I wasn't sure how to approach it. And sorry moderators for the problem with source, I tried using the common (code) (/code) tags for it but I guess it wasn't the right one.

Also, how do I stop the flashing screen from occuring when I clear the ZBuffer?

Thanks again

Share this post


Link to post
Share on other sites
The flashing screen may be due to the fact that you don't have a Z buffer, as you thought.

The debug libraries change the backbuffer to make a flash if you don't touch every pixel, via a Clear or overdraw. If you ask Clear to clear buffers that don't exist, it fails, and does not clear anything. If you have no Z buffer, you're now not clearing the backbuffer, which is why you'll now see the flashing.

The easiest way to get a Z buffer is with your device creation call, by specifying a valid depth format in PresentParams.AutoDepthStencilFormat, such as D3DFMT_D24X8, and setting AutoDepthStencilEnable to true. For anything but the most basic sample you'll want a Z buffer, so it's a good exercise even if you don't need it yet.

Share this post


Link to post
Share on other sites
When I do what you told me to do in order to set up a Zbuffer, my triangle just disappears. Again, fooling around I discovered the triangle was still there: When I set the program to clear the stencil thingmy as well, it started flashing again (haha) and I could see my triangle though. So what is going on? Do I HAVE to use lighting now in order to use a ZBuffer?

Heres what I did to set up my Zbuffer:

pp.EnableAutoDepthStencil=true;

pp.AutoDepthStencilFormat = D3DFMT_D24X8;

D3DDevice->SetRenderState(D3DRS_ZENABLE, true);

And lastly typed in the D3DCLEAR_ZBUFFER flag in my D3DDevice->Clear function, which now looks like this:
D3DDevice->Clear(0, NULL,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 0, 0);

Share this post


Link to post
Share on other sites
you do need lighting in order to used the zbuffer. The zbuffer all it does is draw the correct pixel for you. For example if you draw two triangles and let's say the first z axis 10 and the second one z axis is 11 as you know 11 is behind 10 so the zbuffer is used to sort out your polygons. In lament term it makes sure that polygons are drawned where they supposed to be, even if you draw the Triangle with the depth of 10 first it will still draw it in front the one with depth of 11. If we had zbuffer off then whaterver we draw would lay ontop of whaterver is already on screen thus in this case if we draw the one with the depth of 10 first and draw 11 then 11 will be ontop of 10 which is not correct.

Share this post


Link to post
Share on other sites
Clear your Z to 1.0f, not 0. Since your triangle isn't closer than 0, it's not being drawn.

Note that after projection and divide by W (don't worry about it if you have no idea what that means), 1.0 is the highest depth value. A vertex with a Z of your projection matrix's "far" value will end up at 1.0f, while a vertex at your "near" plane will have a Z of 0.0.

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