Sign in to follow this  

Moving a textured quad with transformed coordinates

This topic is 4760 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Stupid question? Okay, so I've got my textured quad being displayed (using transformed coordinates). Let's say I want my arrow keys to move it around the screen? What's the easiest way to do that? Edit: All the code I've found online seems to deal with untransformed coordinates.

Share this post


Link to post
Share on other sites
I'm not sure if this would be the best/easiest way to do it, but this is what i'd tried.

1. Add the following variables at the top of your program:
int g_updateVB = 0; 0 = dont move quad, 1 = move quad

const float DELTA_X = 0.5f; // how much to move in x
const float DELTA_Y = 0.5f; // how much to move in y

float g_objDeltaX = 0; // -DELTA_X or +DELTA_X ( left, right )
float g_objDeltaY = 0; // -DELTA_Y or +DELTA_Y ( up, down )


2. Add the following to your message loop
case WM_KEYDOWN:

g_objDeltaX = g_objDeltaY = 0.0f;

switch ( wParam )
{
case VK_LEFT:
g_objDeltaX = -DELTA_X;
g_updateVB = 1;
break;

case VK_RIGHT:
g_objDeltaX = DELTA_X;
g_updateVB = 1;
break;

case VK_UP:
g_objDeltaY = -DELTA_Y;
g_updateVB = 1;
break;

case VK_DOWN:
g_objDeltaY = DELTA_Y;
g_updateVB = 1;
break;
}
break;


3. Add this function to your program

HRESULT UpdateVB()
{
g_updateVB = 0;

// Now we fill the vertex buffer. To do this, we need to Lock() the VB to
// gain access to the MoveVertices. This mechanism is required becuase vertex
// buffers may be in device memory.
CUSTOMVERTEX* pMoveVertices;
if( FAILED( g_pVB->Lock( 0, sizeof(CUSTOMVERTEX), (void**) &pMoveVertices, 0 ) ) )
return E_FAIL;

float newX = 0, newY = 0;

for ( int i=0; i<4; i++ )
{
newX = pMoveVertices[i].x + g_objDeltaX;
newY = pMoveVertices[i].y + g_objDeltaY;

pMoveVertices[i].x = newX;
pMoveVertices[i].y = newY;
}
g_pVB->Unlock();
return D3D_OK;

}


4. Modify your Render function with the following

if ( g_updateVB )
UpdateVB();

if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
{

g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(CUSTOMVERTEX) );
g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 2 );

// End the scene
g_pd3dDevice->EndScene();
}

[Edited by - boolean010 on November 30, 2004 4:48:11 PM]

Share this post


Link to post
Share on other sites
I guess my question has more to do with the rendering. What should my render function look like? Here's what it looks like now:


void Render()
{
// ShowCursor(TRUE);

CUSTOMVERTEX triangleVertices[] =
{
{100.0f, 200.0f, 0.0f, 1.0f, D3DCOLOR_XRGB(255,0,0),},
{100.0f, 100.0f, 0.0f, 1.0f, D3DCOLOR_XRGB(255,0,0),},
{200.0f, 200.0f, 0.0f, 1.0f, D3DCOLOR_XRGB(255,0,0),},
{200.0f, 100.0f, 0.0f, 1.0f, D3DCOLOR_XRGB(255,0,0),},
};

IDirect3DVertexBuffer8* pVertexBuf = NULL;
HRESULT hResult = g_pDirect3DDevice->CreateVertexBuffer(4*sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX, 3DPOOL_DEFAULT, &pVertexBuf);

if (FAILED(hResult))
{
DXTRACE_ERR("Error creating vertex buffer.", hResult);
return;
}

void* pVertices;
hResult = pVertexBuf->Lock(0, 0, (BYTE**)&pVertices, 0);

if (FAILED(hResult))
{
DXTRACE_ERR("Error locking vertex buffer.", hResult);
return;
}

memcpy(pVertices, triangleVertices, sizeof(triangleVertices));
pVertexBuf->Unlock();

g_pDirect3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0);
g_pDirect3DDevice->SetStreamSource(0, pVertexBuf, sizeof(CUSTOMVERTEX));
g_pDirect3DDevice->SetVertexShader(D3DFVF_CUSTOMVERTEX);

g_pDirect3DDevice->BeginScene();
g_pDirect3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
g_pDirect3DDevice->EndScene();

g_pDirect3DDevice->Present(NULL, NULL, NULL, NULL);

if (pVertexBuf)
pVertexBuf->Release();
}






How would I set it up so that I can just specify new x,y coords and move the image there?

Share this post


Link to post
Share on other sites
I have another question... I'm creating a 2D tile based game in Direct3D. For all of my tiles should I use the ID3DXSprite interface for all my tiles or just the sprites? (Sorry, I'm pretty much unfamiliar with the ID3DXSprite interface.)

Or instead would I use the ID3DXSprite interface for my sprites and textured quads for the tiles/background?

Share this post


Link to post
Share on other sites
Garry,
i think u must change a litle for your render code, because in your render code, u redundat your vertex buffer and vertices, since your vertice never change why u must create, destroy vertex buffer for so many times??
Try this, u must seperate your code like this:


void Init_Geometry()
{
CUSTOMVERTEX triangleVertices[] =
{
{100.0f, 200.0f, 0.0f, 1.0f, D3DCOLOR_XRGB(255,0,0),},
{100.0f, 100.0f, 0.0f, 1.0f, D3DCOLOR_XRGB(255,0,0),},
{200.0f, 200.0f, 0.0f, 1.0f, D3DCOLOR_XRGB(255,0,0),},
{200.0f, 100.0f, 0.0f, 1.0f, D3DCOLOR_XRGB(255,0,0),},
};

IDirect3DVertexBuffer8* pVertexBuf = NULL;
HRESULT hResult = g_pDirect3DDevice->CreateVertexBuffer(4*sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX, 3DPOOL_DEFAULT, &pVertexBuf);

if (FAILED(hResult))
{
DXTRACE_ERR("Error creating vertex buffer.", hResult);
return;
}

void* pVertices;
hResult = pVertexBuf->Lock(0, 0, (BYTE**)&pVertices, 0);

if (FAILED(hResult))
{
DXTRACE_ERR("Error locking vertex buffer.", hResult);
return;
}

memcpy(pVertices, triangleVertices, sizeof(triangleVertices));
pVertexBuf->Unlock();
}

void Render()
{
g_pDirect3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0);
g_pDirect3DDevice->SetStreamSource(0, pVertexBuf, sizeof(CUSTOMVERTEX));
g_pDirect3DDevice->SetVertexShader(D3DFVF_CUSTOMVERTEX);

g_pDirect3DDevice->BeginScene();
g_pDirect3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
g_pDirect3DDevice->EndScene();

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

void Shutdown()
{
if (pVertexBuf)
pVertexBuf->Release();
}

//and your code goes like this

Init_Geom();

while(condition)
{
//message dispacth
Render();
}

Shutdown();


To draw 2d enggine, the easiest way is using ID3DXSprite, but if u use it to much can hoog your fps so much, cause for each ID3DXSprite draw function is followed with set Render State.

i hope it will help u a bit.

Share this post


Link to post
Share on other sites
Creating and destroying vertex buffers each frame is on the big list of "never, ever, do this". Create a dynamic buffer at startup. lock, update, unlock, draw each frame. Destroy at cleanup. Destroy and re-create as necessary on a lost device if you want alt-tab to work for you.

Also, on that big list is drawing each quad one at a time. You'll want to put as many quads into the VB at once as you can, then draw them all at once.

Share this post


Link to post
Share on other sites
Quote:
Original post by Namethatnobodyelsetook
Creating and destroying vertex buffers each frame is on the big list of "never, ever, do this". Create a dynamic buffer at startup. lock, update, unlock, draw each frame. Destroy at cleanup. Destroy and re-create as necessary on a lost device if you want alt-tab to work for you.

Also, on that big list is drawing each quad one at a time. You'll want to put as many quads into the VB at once as you can, then draw them all at once.


Where can I get this list? ;) Seriously, thanks for the advice. Anything else you can give me would be greatly appreciated.

Share this post


Link to post
Share on other sites
Actually some parts of the list really do exist. nVidia has a Top 10 performance killers in Direct3D paper. Check the developer whitepaper section on both nVidia's and ATI's websites. Most of the recent papers are all about making use of the latest shader models properly, however if you dig to the older papers, you'll find some good ones that they're assuming everyone knows by now.

Share this post


Link to post
Share on other sites
I don't think its possible to shift transformed co-ords with a matrix, but that would be good.

EDIT: actually could you say the vertices are untransformed, then transform them with 1 simple matrix?


[Edited by - DrGUI on December 4, 2004 10:47:40 AM]

Share this post


Link to post
Share on other sites

This topic is 4760 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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