how to move vertex not using lock()?

Started by
7 comments, last by littlewater 18 years, 10 months ago
recently, i read a lot of articles about direct3d on 2d about vertex-drawing, most of them said that " you should not often use lock and unlock function , that 's wait of resouce and time " , but i want to make a class which could have texture and move , most of these articles talk about only static picture or what some people called " sprite ", some of them give an example but only 1 sprite on screen and i find they use the world_matrix to move ,then what about 2 or more ? now , the method i use is like following: first , create a sprite ,and then i will set the position of it ( i ignore other parameters but there are a lot...) that means i change the value of vertices array with their x,y,z position ,and the next i use the lock function in each frame/say game loop...... but what about the efficience ? i will go on finding the resolution and i hope sb. can give me a good way to draw thx.
À´×ÔÖйúµÄÇóѧÕß¡­¡­
Advertisement
The way you are currently doing it is very inefficient: you are moving all vertices by hand while the main advantage of graphics hardware is that you don't need to. Have a look at this topic for a short explanation. Search the internet for more information.

Greetz,

Illco
If you're doing 2D, you may as well use the ID3DXSprite interface, it's highly optimized for drawing sprites.
yes, I will use it ID3DXSPRITE later... but i want to know how to change the position of the sprite?

i saw the explanation , but unfortunately i was not understanding their methods ... why the moving about the WORLD not really move the world? and when i use setTransform function all of the item on screen are moved ...

maybe i should re-read the definition about the view and projection ?
À´×ÔÖйúµÄÇóѧÕß¡­¡­
after read again ... i fell more confused ... if someone can help me to explain the result of the following code ?..

// Set view and projection transforms; usually fixed per frame
device->settransform( view )
device->settransform( projection )

but one of the concepts about " moving world " ...
that's my fault , but the result is true that the objects in the world moved , any one can say the reason ?

[Edited by - littlewater on June 4, 2005 12:56:41 PM]
À´×ÔÖйúµÄÇóѧÕß¡­¡­
It's not 2D, but maybe this tutorial will give you some more insight into matrices and moving multiple objects independantly.
Thanks a lot! After end this post, i will see it.

I try to summary it :

vertices, after you setup it, is in the model-space, (*)

then you should use the socalled T&L pipeline to dealwith them

by multiplying matrix : (**)

(1) world matrix
(2) view matrix (***)
(3) projection matirx
(4) cube matrix
(5) other such as light and viewport

and cube space is the destination

direct3d will do all these things after you setup each space their own matrix and use the function setTransform(..) to tell the directx.

all above is my conclusion came from recent study, any one could point out mistakes so that they can be corrected.

and some more question i quote by (*) and so on
(*) i find some one use x,y,z and set the value between 0.0 - 1.0, others using different, and my question is: what is the standard value bound to setup in modelspace? e.g. i want to setup a quad, what should i set? (0.0, 0.0) (1.0, 0.0) (0.0, 1.0) (1.0, 1.0) or
(-0.5, -0.5) (0.5, -0.5) (-0.5, 0.5) (0.5, 0.5) or even more than the upbound value 1 such as 2 or 10?

(**) is there an order to setup these matrices? but i guess direct3d itself will use these matrices in order... e.g. i setup viewmatrix first then projection and worldmatrix the last, and it equals to the usual order.

(***) what is the view matrix coordinate? i means if i want to setup the matrixtranslation what should i set the value x, y, z? using the value in model space? i see the code in the book -- Focus on 2D in direct3d , the author use it.

And another question after i saw the source is : which world should i often use? i see the code rotation the projection matrix to rotate the chessboard, but i feel i could rotate it in the world matrix . (This also confuses me)

The next post i will copy the source full code.

That's all, thought there are much more question during the research, I feel that if I can understand these matrix , i will solve the question about this subject.
I will go on.
À´×ÔÖйúµÄÇóѧÕß¡­¡­
// all the following code is the Example11_2 of the book -- Focus on 2D in direct3d//Example11_2//main.cpp//Ernest Pazera//16NOV2001//TGO-11-C//Libs: d3d8.lib, d3dx8.lib#include <windows.h>	//include windows stuff#include <stdio.h>		//standard input/output#include <math.h>#include "D3D8.h"	//include direct3d8 stuff#include "D3DX8math.h" //vector and matrix//custom vertex contains xyz and diffuse#define CUSTOM_VERTEX_FVF D3DFVF_XYZ | D3DFVF_DIFFUSEstruct CustomVertex{	D3DVECTOR pos ;	DWORD diffuse ;} ;//constants	//window class name	const char* WINDOWCLASS = "3D42DGP" ;	//window title	const char* WINDOWTITLE = "Example 11.1 (TGO-11-C): Multiplying Transformations" ;	//screen width and height	const int SCREENWIDTH = 640 ;	const int SCREENHEIGHT = 480 ;	//pi	const float PI = 3.14159 ;//globals	//instance handle	HINSTANCE g_hInstance = NULL ;	//window handle	HWND g_hWnd = NULL ;	//IDirect3D8 pointer	IDirect3D8* g_pd3d = NULL ;	//device type in use	D3DDEVTYPE g_devtype ;	//device pointer	IDirect3DDevice8* g_pd3ddev = NULL ;	//main viewport	D3DVIEWPORT8 g_vpmain ;	//vertices	CustomVertex vert [ 2 ] [ 4 ] ;	//matrices	D3DXMATRIX matWorld ;	D3DXMATRIX matView ;	D3DXMATRIX matProj ;	D3DXMATRIX matRotate ;//function prototypes	//winmain	int WINAPI WinMain ( HINSTANCE hInstance , HINSTANCE hPrevInstance , LPSTR lpCmdLine , int nShowCmd ) ;	//window procedure	LRESULT CALLBACK TheWindowProc ( HWND hWnd , UINT uMsg , WPARAM wParam , LPARAM lParam ) ;	//initialization	void Prog_Init ( ) ;	//clean up	void Prog_Done ( ) ;	//redraw frame	void RedrawFrame ( ) ;//window procedureLRESULT CALLBACK TheWindowProc ( HWND hWnd , UINT uMsg , WPARAM wParam , LPARAM lParam ){	//which message did we get?	switch ( uMsg )	{	case WM_KEYDOWN:	//a key has been pressed		{			//keyboard controls			switch ( wParam ) 			{			case VK_ESCAPE :				{					DestroyWindow ( hWnd ) ;				} break ;			}			//return 0			return ( 0 ) ;		} break ;	case WM_DESTROY : //window being destroyed		{			//quit			PostQuitMessage ( 0 ) ;			//message handled, return 0			return ( 0 ) ;		} break ;	default:  //all other messages, send to default handler		return ( DefWindowProc ( hWnd , uMsg , wParam , lParam ) ) ;	}}//winmainint WINAPI WinMain ( HINSTANCE hInstance , HINSTANCE hPrevInstance , LPSTR lpCmdLine , int nShowCmd ){	//grab instance handle	g_hInstance = hInstance ;	//redirect stderr and stdout output	freopen ( "stdout.txt" , "w" , stdout ) ;	//fill in window class	WNDCLASSEX wc ;	wc.cbClsExtra = 0 ;	//no extra class information	wc.cbSize = sizeof ( WNDCLASSEX ) ; //size of structure	wc.cbWndExtra = 0 ;	//no extra window information	wc.hbrBackground = ( HBRUSH ) GetStockObject ( BLACK_BRUSH ) ;	//black brush	wc.hCursor = LoadCursor ( NULL , MAKEINTRESOURCE ( IDC_ARROW ) ) ;	//arrow cursor	wc.hIcon = NULL ;	//no icon	wc.hIconSm = NULL ;	//no small icon	wc.hInstance = g_hInstance ;	//instance handle	wc.lpfnWndProc = TheWindowProc ;	//window procedure	wc.lpszClassName = WINDOWCLASS ;	//name of class	wc.lpszMenuName = NULL ;	//no menu	wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_OWNDC ;	//class styles	//register window class	RegisterClassEx ( &wc ) ;	//create window	g_hWnd = CreateWindowEx ( 0 , WINDOWCLASS , WINDOWTITLE , WS_POPUP , 0 , 0 , 640 , 480 , NULL , NULL , g_hInstance , NULL ) ;	//show the window	ShowWindow ( g_hWnd , nShowCmd ) ;	//initialization	Prog_Init ( ) ;	MSG msg ;	//message pump	for ( ; ; ) 	{		//check for a message		if ( PeekMessage( &msg , NULL , 0 , 0 , PM_REMOVE ) )		{			//message exists			//check for quit message			if ( msg.message == WM_QUIT ) break ;			//translate the message			TranslateMessage ( &msg ) ;			//dispatch the message			DispatchMessage ( &msg ) ;		}		else		{			//no message, update frame			RedrawFrame ( ) ;		}	}	//clean up	Prog_Done ( ) ;	//exit	return ( msg.wParam ) ;}//initializationvoid Prog_Init ( ) {	//create the IDirect3D8 object	g_pd3d = Direct3DCreate8 ( D3D_SDK_VERSION ) ;	//error check	if ( g_pd3d )	{		//success		fprintf ( stdout , "IDirect3D8 object created successfully.\n" ) ;	}	else	{		//failure		fprintf ( stdout , "IDirect3D8 object creation failed.\n" ) ;		//cannot proceed, so return		return ;	}	//find display mode	D3DDISPLAYMODE mode ;	UINT nDisplayModeCount = g_pd3d->GetAdapterModeCount ( D3DADAPTER_DEFAULT ) ;	//loop through display modes	for ( UINT nDisplayMode = 0 ; nDisplayMode < nDisplayModeCount ; nDisplayMode ++ ) 	{		//check next display mode		g_pd3d->EnumAdapterModes ( D3DADAPTER_DEFAULT , nDisplayMode , &mode ) ;		//if it matches desired screen width, break out of loop		if ( mode.Width == SCREENWIDTH && mode.Height == SCREENHEIGHT ) break ;	}	//check for proper sized mode	if ( mode.Width != SCREENWIDTH || mode.Height != SCREENHEIGHT ) 	{		//did not find mode		//post quit message		PostQuitMessage ( 0 ) ;		//report		fprintf ( stdout , "Did not find display mode!\n" ) ;		//return		return ;	}	else	{		//found mode		//report		fprintf ( stdout , "Found display mode.\n" ) ;	}	//set up presentation parameters	D3DPRESENT_PARAMETERS parms;	//back buffer information	parms.BackBufferWidth = mode.Width ; //use mode width	parms.BackBufferHeight = mode.Height ; //use mode height	parms.BackBufferFormat = mode.Format ; //use format of mode	parms.BackBufferCount = 1 ; //make one back buffer	//multisampling 	parms.MultiSampleType = D3DMULTISAMPLE_NONE ;	//swap effect	parms.SwapEffect = D3DSWAPEFFECT_COPY ; //we want to copy from back buffer to screen	//destination window	parms.hDeviceWindow = g_hWnd ; 	parms.Windowed = FALSE ;	//depth buffer information	parms.EnableAutoDepthStencil = FALSE ;	parms.AutoDepthStencilFormat = D3DFMT_UNKNOWN ;	//flags	parms.Flags = 0 ;	//refresh rate and presentation interval	parms.FullScreen_RefreshRateInHz = mode.RefreshRate ; //use mode's refresh rate	parms.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT ;	//attempt to create a HAL device	HRESULT hr ; //store return values in this variable	hr = g_pd3d->CreateDevice ( D3DADAPTER_DEFAULT , D3DDEVTYPE_HAL , g_hWnd , D3DCREATE_SOFTWARE_VERTEXPROCESSING , &parms , &g_pd3ddev ) ;	//error check	if ( FAILED ( hr ) )	{		//could not create HAL device		fprintf ( stdout , "Could not create HAL device!\n" ) ;		//attempt to make REF device		hr = g_pd3d->CreateDevice ( D3DADAPTER_DEFAULT , D3DDEVTYPE_REF , g_hWnd , D3DCREATE_SOFTWARE_VERTEXPROCESSING , &parms , &g_pd3ddev ) ;		if ( FAILED ( hr ) )		{			//could not create REF device			fprintf ( stdout , "Could not create REF device!\n" ) ;			//post a quit message			PostQuitMessage ( 0 ) ;		}		else		{			//successfully made REF device, store this value in a global			g_devtype = D3DDEVTYPE_REF ;			//report			fprintf ( stdout , "Successfully created REF device.\n" ) ;		}	}	else	{		//successfully made a HAL device, store this value in a global		g_devtype = D3DDEVTYPE_HAL ;		//report		fprintf ( stdout , "Successfully created HAL device.\n" ) ;	}	//set up viewports	//main viewport	g_vpmain.X = 0 ;	g_vpmain.Y = 0 ;	g_vpmain.Width = SCREENWIDTH ;	g_vpmain.Height = SCREENHEIGHT ;	g_vpmain.MinZ = 0.0f ;	g_vpmain.MaxZ = 1.0f ;	//set the viewport	g_pd3ddev->SetViewport ( &g_vpmain ) ;	//turn off lighting	g_pd3ddev->SetRenderState ( D3DRS_LIGHTING , FALSE ) ;	//set vertex shader	g_pd3ddev->SetVertexShader ( CUSTOM_VERTEX_FVF ) ;	//set up vertices	//dark square	vert [ 0 ] [ 0 ].pos.x = 0.0 ;	vert [ 0 ] [ 0 ].pos.y = 0.0 ;	vert [ 0 ] [ 0 ].pos.z = 0.0 ;	vert [ 0 ] [ 0 ].diffuse = D3DCOLOR_XRGB( 128 , 128 , 128 ) ;	vert [ 0 ] [ 1 ].pos.x = 1.0 ;	vert [ 0 ] [ 1 ].pos.y = 0.0 ;	vert [ 0 ] [ 1 ].pos.z = 0.0 ;	vert [ 0 ] [ 1 ].diffuse = D3DCOLOR_XRGB( 128 , 128 , 128 ) ;	vert [ 0 ] [ 2 ].pos.x = 0.0 ;	vert [ 0 ] [ 2 ].pos.y = 1.0 ;	vert [ 0 ] [ 2 ].pos.z = 0.0 ;	vert [ 0 ] [ 2 ].diffuse = D3DCOLOR_XRGB( 128 , 128 , 128 ) ;	vert [ 0 ] [ 3 ].pos.x = 1.0 ;	vert [ 0 ] [ 3 ].pos.y = 1.0 ;	vert [ 0 ] [ 3 ].pos.z = 0.0 ;	vert [ 0 ] [ 3 ].diffuse = D3DCOLOR_XRGB( 128 , 128 , 128 ) ;	//light square	vert [ 1 ] [ 0 ].pos.x = 0.0 ;	vert [ 1 ] [ 0 ].pos.y = 0.0 ;	vert [ 1 ] [ 0 ].pos.z = 0.0 ;	vert [ 1 ] [ 0 ].diffuse = D3DCOLOR_XRGB( 192 , 192 , 192 ) ;	vert [ 1 ] [ 1 ].pos.x = 1.0 ;	vert [ 1 ] [ 1 ].pos.y = 0.0 ;	vert [ 1 ] [ 1 ].pos.z = 0.0 ;	vert [ 1 ] [ 1 ].diffuse = D3DCOLOR_XRGB( 192 , 192 , 192 ) ;	vert [ 1 ] [ 2 ].pos.x = 0.0 ;	vert [ 1 ] [ 2 ].pos.y = 1.0 ;	vert [ 1 ] [ 2 ].pos.z = 0.0 ;	vert [ 1 ] [ 2 ].diffuse = D3DCOLOR_XRGB( 192 , 192 , 192 ) ;	vert [ 1 ] [ 3 ].pos.x = 1.0 ;	vert [ 1 ] [ 3 ].pos.y = 1.0 ;	vert [ 1 ] [ 3 ].pos.z = 0.0 ;	vert [ 1 ] [ 3 ].diffuse = D3DCOLOR_XRGB( 192 , 192 , 192 ) ;	//set up projection matrix	D3DXMatrixScaling ( &matProj , 0.1875 , -0.25 , 1.0 ) ;		//set the projection matrix	g_pd3ddev->SetTransform ( D3DTS_PROJECTION , &matProj ) ;	//set up view matrix	D3DXMatrixTranslation ( &matView , -1.0 , -1.0 , 0.0 ) ;	//set the view matrix	g_pd3ddev->SetTransform ( D3DTS_VIEW , &matView ) ;	//set up the rotation matrix	D3DXMatrixRotationZ ( &matRotate , PI / 180.0 ) ;	//redraw the frame	RedrawFrame ( ) ;}//clean upvoid Prog_Done ( ) {	//safe release of device	if ( g_pd3ddev ) 	{		//release		g_pd3ddev->Release ( ) ;		//set to null		g_pd3ddev = NULL ;		//report		fprintf ( stdout , "IDirect3DDevice8 object released.\n" ) ;	}	//safe release of IDirect3D8 object	if ( g_pd3d )	{		//release		g_pd3d->Release ( ) ;		//set to null		g_pd3d = NULL ;		//report action		fprintf ( stdout , "IDirect3D8 object released.\n" ) ;	}}//redraw framevoid RedrawFrame ( ) {	//clear the screen	g_pd3ddev->Clear ( 0 , NULL , D3DCLEAR_TARGET , D3DCOLOR_XRGB ( 0 , 0 , 0 ) , 0.0f, 0 ) ;	//begin the scene	g_pd3ddev->BeginScene ( ) ;	//loop through board squares	int oddeven ;	for ( int y = 0 ; y < 8 ; y ++ )	{		for ( int x = 0 ; x < 8 ; x ++ )		{			//determine color of square			oddeven = ( x + y ) & 1 ;			//set up world matrix			D3DXMatrixTranslation ( &matWorld , ( float ) x , ( float ) y , 0.0 ) ;			//set world transformatin			g_pd3ddev->SetTransform ( D3DTS_WORLD , &matWorld ) ;			//draw the square			g_pd3ddev->DrawPrimitiveUP ( D3DPT_TRIANGLESTRIP , 2 , vert [ oddeven ] , sizeof ( CustomVertex ) ) ;		}	}	//end the scene	g_pd3ddev->EndScene ( ) ;	//multiply the rotation matrix by the view matrix, set as the new view matrix	g_pd3ddev->MultiplyTransform ( D3DTS_PROJECTION , &matRotate ) ;	//present the scene	g_pd3ddev->Present ( NULL , NULL , NULL , NULL ) ;}


[Edited by - Coder on June 5, 2005 11:18:21 AM]
À´×ÔÖйúµÄÇóѧÕß¡­¡­
this time i try to change some code :
my destination is to let each square in the chessboard not only move round but also
rotation with themselves' center.

in the source code , the author move the view down&right (maybe my concept of view coordinate is something wrong? i wish somebody point out the correct coordinate...the current conclusion is the camara or called view is opposite to the direction you set )

i delete this code :

-- g_pd3ddev->SetTransform ( D3DTS_VIEW , &matView ) ;

and the main different results are:
(1) each square is on the right&down 4 compare to the origin position .
this i guess that because of the movement of the view.
(2) all squares move around the up&left point not i expected still move around the chessboard's center . maybe the z-axis also changed according to the viewspace? maybe directx will always makes the center-into direction as the z-axis? here so far i still be confused ...

and the next try i made like follows:
(1) change back to the origin source code
(2) add a matrix named mattemp and add some D3DXMatrix function to achieve the target:
move to center - rotate - move back and pos the correct postion...

here is the render code:

//redraw frame
void RedrawFrame ( )
{
//clear the screen
g_pd3ddev->Clear ( 0 , NULL , D3DCLEAR_TARGET , D3DCOLOR_XRGB ( 0 , 0 , 0 ) , 0.0f, 0 ) ;

//begin the scene
g_pd3ddev->BeginScene ( ) ;

//loop through board squares
int oddeven ;
for ( int y = 0 ; y < 8 ; y ++ )
{
for ( int x = 0 ; x < 8 ; x ++ )
{
//determine color of square
oddeven = ( x + y ) & 1 ;
/*
//set up world matrix
D3DXMatrixTranslation ( &matWorld , ( float ) x , ( float ) y , 0.0 ) ;
*/
//****A test:*****//
// (1) first turn them upleft each 0.5
D3DXMatrixTranslation ( &mattemp , -0.5 , -0.5 , 0.0 ) ;
matWorld = mattemp ;

// (2) rotate them
D3DXMatrixRotationZ( &mattemp , timeGetTime() * PI / 360 );
matWorld = matWorld * mattemp ;

// (3) move them to the correspond position
D3DXMatrixTranslation ( &mattemp , ( float ) ( 3.5 - x ) , ( float ) ( 3.5 - y ) , 0.0 ) ;
matWorld = matWorld * mattemp ;

// (4) the last is to set world transformatin
g_pd3ddev->SetTransform ( D3DTS_WORLD , &matWorld ) ;

//draw the square
g_pd3ddev->DrawPrimitiveUP ( D3DPT_TRIANGLESTRIP , 2 , vert [ oddeven ] , sizeof ( CustomVertex ) ) ;
}
}

//end the scene
g_pd3ddev->EndScene ( ) ;

//multiply the rotation matrix by the view matrix, set as the new view matrix
g_pd3ddev->MultiplyTransform ( D3DTS_PROJECTION , &matRotate ) ;

//present the scene
g_pd3ddev->Present ( NULL , NULL , NULL , NULL ) ;
}

if you pay attention to this movement (-0.5, -0.5 , 0.0)
here is the third question : the z-axis is changed (here i suppose 2nd conclusion is right) why i should put -0.5, -0.5 not like: x - 0.5 , y - 0.5 ?
À´×ÔÖйúµÄÇóѧÕß¡­¡­

This topic is closed to new replies.

Advertisement