Skip to main content
gamedev.net
🔒 Locked

Displaying/Moving multiple objects

Started by Squall Darken 12 replies 1.2k views
Original Post
Squall Darken
Squall Darken
Hello, I'm trying to understand the principles of displaying objects on screen and moving them using Direct3d 9. I actually have a triangle displayed on screen, as I followed the tutorials that came with the SDK. I fully understand what I'm doing, as I have been reading a lot. I'm now getting into the matrices, and there's something I don't quite get. 1 - Creating the vertices and copying them to the buffer. 2 - Displaying them. (a triangle for now). How do I proceed if I want to add a second triangle ??? Do I create a second vertex buffer and set the stream source to this one before making a second call to DrawPrimitive() ??? And now, I'm getting into matrices and suppose I want to move one triangle on its x-axis and the other one on its y-axis. How do I set up matrices for that and use transformations different for each object ??? thanks !!! Squall Darken [edited by - Squall Darken on November 20, 2003 10:53:21 PM]
Squall Darken
Sean Doherty
Sean Doherty
You can render a second triangle using the same Vertex Buffer by simply doing the following:

1) build a new world matrix
2) call set Transform for the world matrix
3) Draw


_______________________________________
Understanding is a three edged sword...
_______________________________________Understanding is a three edged sword...Freelance Games - Home of XBLIG Starchonwww.FreelanceGames.com
Squall Darken
Squall Darken
I tried to work on it, and now I seem to have problems using matrices... which is quite weird because I think I understand how they work, and I follow the tutorials and it is just not working.

I'm trying to draw a square. It has been declared as 4 vertices centered around 0. So, my guess is that is I use a world transformation (in 2D, with view = identity and projection = orthogonal) i should be able to translate this square in the middle of my screen, but it is not working. Here is the code...


CUSTOMVERTEX vertices[] =
{

{ 50.0f, 50.0f, 0.0f, 1.0f, 0xffff0000, }, // x, y, z, rhw, color

{ -50.0f, 50.0f, 0.0f, 1.0f, 0xff00ff00, },
{ -50.0f, -50.0f, 0.0f, 1.0f, 0xff00ffff, },
{ 50.0f, -50.0f, 0.0f, 1.0f, 0xff00ffff, }
};

if(FAILED(pD3DDevice->CreateVertexBuffer(3*sizeof(CUSTOMVERTEX),
0 /* Usage */, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &pVertexBuffer, NULL)))
{
return E_FAIL;
}

VOID* pVertices;

if(FAILED(pVertexBuffer->Lock(0, sizeof(vertices), (void**)&pVertices, 0)))
{
return E_FAIL;
}

memcpy(pVertices, vertices, sizeof(vertices) );

pVertexBuffer->Unlock();

// GAME MAIN !!!!


D3DXMATRIX matOrtho;
D3DXMATRIX matIdentity;

D3DXMatrixOrthoLH(&matOrtho, 800, 600, 0.0f, 1.0f);
D3DXMatrixIdentity(&matIdentity);
pD3DDevice->SetTransform (D3DTS_PROJECTION, &matOrtho);
pD3DDevice->SetTransform (D3DTS_WORLD, &matIdentity);
pD3DDevice->SetTransform (D3DTS_VIEW, &matIdentity);



while(TRUE)
{
if (PeekMessage(&uMsg,NULL,0,0,PM_REMOVE))
{
if (uMsg.message == WM_QUIT)
{
break;
/* on sort de notre message loop */
}

else
{

TranslateMessage(&uMsg);


DispatchMessage(&uMsg);
}
}

// Clear the back buffer to a blue color

pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,255), 1.0f, 0 );

// Begin the scene.

pD3DDevice->BeginScene();

// Rendering of scene objects happens here.


// World matrix for translation

D3DXMATRIX matWorldTranslation;
D3DXMatrixTranslation(&matWorldTranslation, 200.0f, 200.0f, 0.0f);

pD3DDevice->SetTransform(D3DTS_WORLD, &matWorldTranslation);

pD3DDevice->SetStreamSource(0, pVertexBuffer, 0, sizeof(CUSTOMVERTEX));
pD3DDevice->SetFVF(D3DFVF_CUSTOMVERTEX );
pD3DDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);

// End the scene.

pD3DDevice->EndScene();

pD3DDevice->Present( NULL, NULL, NULL, NULL );
}


Thanks !


Squall Darken

[edited by - Squall Darken on November 22, 2003 1:29:07 AM]
Squall Darken
Squall Darken
Squall Darken
I just noticed that matrix transformations won''t work since my vertices are defined as rhw = already transformed.

How can I make it work though ? I changed my vertex definition to remove the rhw part and declared my array to copy to the buffer accordingly. Now, nothing is diplayed.

I''m trying to use 2D so.. is my projection matrix the problem ???

What about it''s z-near and z-far (in the projection matrix definition). I put them back to 1.0f, 10.0f as i have seen in an example and it doesn''t work either...

any idea on what is the problem ??



Squall Darken
Squall Darken
Sean Doherty
Sean Doherty
I looked quickly; your z-values are zero; that is before the default camera frustum of 1.0f.

Here is some code that sets up the projection and view matrices:



D3DXMatrixPerspectiveFovLH(

D3DXMatrixIdentity(&proj),
D3DX_PI/4, float(1024) / float(768),
0.1f, 1000.0f);
m_pD3DDevice->SetTransform(D3DTS_PROJECTION, &proj);
D3DXVECTOR3 eye(0.0f, 0.0f, -5.0f),
where(0.0f, 0.0f, 0.0f),
up(0.0f, 1.0f, 0.0f);
D3DXMatrixLookAtLH(D3DXMatrixIdentity(&proj),
&eye, &where, &up);
m_pD3DDevice->SetTransform(D3DTS_VIEW, &proj);


_______________________________________
Understanding is a three edged sword...



[edited by - Sean Doherty on November 22, 2003 8:32:02 PM]
_______________________________________Understanding is a three edged sword...Freelance Games - Home of XBLIG Starchonwww.FreelanceGames.com
S1CA
S1CA
quote:
Original post by Squall Darken
Bump

Squall Darken


You''ve already discovered your original problem (i.e. using a vertex format with RHW in tells D3D the vertices are already transformed so it ignores the matrices for those).

I''d actually suggest getting used to D3D transformation matrices in 3D then move that to 2D.

In particular work through the Tut03_Matrices tutorial in the DirectX SDK samples to get familiar with the setup of each of the world, view and projection matrices. Add a second Draw*Primitive*() call and a second SetTransform() for the world matrix of the second object/triangle.

Briefly, the matrices control the following things:

WORLD - how the next Draw*Primitive*() call will transform vertices from "model" (aka "object") space into world space.

VIEW - the camera. How the next Draw*Primitive*() call will transform vertices from world space into "view" (aka "camera") space. This essentially pulls all the vertices in toward the camera lens.

PROJECTION - in 3D this determines how perspective is applied to the vertices in view (aka camera) space and how the vertices will be converted into clip space (to handle polygons that are half on the screen and half off it) and screen space (flat 2D triangles on the 2D screen).


Once you are fully familiar with exactly how the above three matrices affect things in 3D, change your projection matrix to an "orthographic" one. You can do this using D3DXMatrixOrthoLH() rather than the D3DXMatrixPerspectiveFovLH() matrices used by the SDK tutorials.

--
Simon O''Connor
3D Game Programmer &
Microsoft DirectX MVP
Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site
Squall Darken
Squall Darken
Thanks, i''ll take a look...

the only thing is that I already tried with values of z at 1.0f and it''s not working either.

In fact, nothing is getting displayed on screen since I changed my vertex format to remove the rhw part. Anyone has an idea why or to make it work ?

Until then, I''ll keep checking different examples (I''ve been doing a lot to try and understand the problem).



Squall Darken
Squall Darken
Supernat02
Supernat02
I noticed in your code that you call "3*sizeof(CUSTOMVERTEX)" which is not correct because you want to create a square with four points. Either use sizeof(vertices) or sizeof(4*CUSTOMVERTEX). You also set the square way out at 200.0f in the x and y direction while keeping the z at 0. Think about what that really means. If you, the camera, are standing at 0, 0, 0. Your square is at 200, 200, 0, but only 50 units wide. So it''s way off the screen...which should be fine, but may not be if your projection matrix isn''t setup correctly. Also, you may have culling turned on. If any of these things confuse you, respond and I''ll explain a bit further.

Try the following code, see if it does what you need. I''m going to convert your triangle_fan into triangle_strip. Otherwise, most of it is the same. The structure is defined as "float x, y, z; DWORD color". The FVF is defined as XYZ | DIFFUSE. (shorthand of course)

CUSTOMVERTEX vertices[] = { {-1.0f, 1.0f, 1.0f, 0xffff0000, }, // x, y, z, color {-1.0f, -1.0f, 1.0f, 0xff00ff00, },
{ 1.0f, 1.0f, 1.0f, 0xff00ffff, },
{ 1.0f, -1.0f, 1.0f, 0xff00ffff, } };

if(FAILED(pD3DDevice->CreateVertexBuffer(sizeof(vertices), 0 /* Usage */, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &pVertexBuffer, NULL))) { return E_FAIL; }

Here I''ve created vertices in counter clockwise order, so you would want to use clockwise culling and always create your other vertices in counter-clockwise order. That is done by saying:

if (FAILED(pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW)))
return E_FAIL;

Or you can just turn culling off for now, which will help in debugging!
if (FAILED(pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE)))
return E_FAIL;

Just call this function once after creating the device. Moving on...

VOID* pVertices;
if(FAILED(pVertexBuffer->Lock(0, sizeof(vertices), (void**)&pVertices, 0)))
{
return E_FAIL;
}
memcpy(pVertices, vertices, sizeof(vertices) );
pVertexBuffer->Unlock(); // GAME MAIN !!!!
D3DXMATRIX matProjection;
D3DXMatrixPerspectiveFovLH(&matProjection, D3DX_PI/4, 1.0f, 1.0f, 1500.0f);
lpD3DDevice->SetTransform(D3DTS_PROJECTION, &matProjection);
D3DXMATRIX matIdentity;
D3DXMatrixIdentity(&matIdentity);
pD3DDevice->SetTransform (D3DTS_PROJECTION, &matProjection);
pD3DDevice->SetTransform (D3DTS_WORLD, &matIdentity);
pD3DDevice->SetTransform (D3DTS_VIEW, &matIdentity);

Notice that I changed the call of Ortho to the Perspective call. The 1.0 to 1500.0f parameters (last two) tell the near plane to be cut off at 1 and far plane cut off at 1500. So you should be able to see your square when its z is between 1 and 1500.

while(TRUE)
{
if (PeekMessage(&uMsg,NULL,0,0,PM_REMOVE))
{
if (uMsg.message == WM_QUIT) { break; /* on sort de notre message loop */ } else { TranslateMessage(&uMsg); DispatchMessage(&uMsg); } } // Clear the back buffer to a blue color pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,255), 1.0f, 0 ); // Begin the scene.

pD3DDevice->BeginScene(); // Rendering of scene objects happens here. // World matrix for translation
D3DXMATRIX matWorldTranslation;
D3DXMatrixTranslation(&matWorldTranslation, 0.0f, 0.0f, 1.5f);
pD3DDevice->SetTransform(D3DTS_WORLD, &matWorldTranslation);
pD3DDevice->SetStreamSource(0, pVertexBuffer, 0, sizeof(CUSTOMVERTEX));
pD3DDevice->SetFVF(D3DFVF_CUSTOMVERTEX );
pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); // End the scene. pD3DDevice->EndScene();
pD3DDevice->Present( NULL, NULL, NULL, NULL ); }

I centered the square in the world (at 0, 0) and moved it away from the camera at z = 1.5 (into the monitor).

These are the major changes I could think of. Hopefully it will get you started.

Good luck,
Chris
Chris ByersMicrosoft DirectX MVP - 2005
Squall Darken
Squall Darken
I just figured out what wasn''t working.

I never specified the culling mode to the device. Now i''m turning it off and it works really well

Anyone can explain ??
I thought culling was to specify not to show the back faces of 3D objects when they are hidden. How does it affect a 2d scene exactly ??

Squall Darken
Squall Darken
Sean Doherty
Sean Doherty
quote:

I thought culling was to specify not to show the back faces of 3D objects when they are hidden. How does it affect a 2d scene exactly ??



You have a 3D scene; you camera is just configured to project the scene as 2D. I believe the default culling mode is Counter Clock Wise (D3DCULL_CCW).

_______________________________________
Understanding is a three edged sword...
_______________________________________Understanding is a three edged sword...Freelance Games - Home of XBLIG Starchonwww.FreelanceGames.com
Namethatnobodyelsetook
Namethatnobodyelsetook
Your scene isn''t 2D, it''s 3D, but your pretending like it''s 2D. D3D doesn''t know you''re pretending it''s 2D.

Culling is based on vertex ordering... whether the points in the triangle are clockwise or counterclockwise when drawn on screen. Setting D3DCULL_CCW culls counterclockwise triangles, and keeps clockwise triangles.

You can disable culling, like you did, or learn how to make triangles that face the appropriate way. Disabling is fastest and easiest, and if you''re doing 2D, has no speed loss, so it''s a good choice, but just for educational purposes, here''s some things you should know about culling.

You can change the vertex order of a triangle by swapping any two vertices with each other. If you''re using indices, you just need to swap the two indices.

If you''re using tristrips, the culling alternates every triangle.
Sean Doherty
Sean Doherty
quote:

If you''re using tristrips, the culling alternates every triangle.



Are you sure that is correct? Wouldn''t that mean if I rendered a Quad made of Triangle Strips with the culling mode set to D3DCULL_CCW, that I would only see the face of every other strip?

_______________________________________
Understanding is a three edged sword...
_______________________________________Understanding is a three edged sword...Freelance Games - Home of XBLIG Starchonwww.FreelanceGames.com
Supernat02
Supernat02
I believe that is what you would see yes...but I can''t promise that. The culling may only look at the first real triangle in the strip and determine the culling from that (shrugs) but that would be crazy, because the second strip might be right in front of the first one and it wouldn''t cull the backside in that case, defeating it''s purpose in life.

Chris
Chris ByersMicrosoft DirectX MVP - 2005

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.