Moving a textured quad with transformed coordinates

Started by
7 comments, last by DrGUI 19 years, 4 months ago
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.
Advertisement
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.x + g_objDeltaX;
newY = pMoveVertices.y + g_objDeltaY;

pMoveVertices.x = newX;
pMoveVertices.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]
** boolean010 **
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?
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?
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 thisInit_Geom();while(condition){//message dispacthRender();}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.
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.
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.
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.
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]

This topic is closed to new replies.

Advertisement