출처 http://www.gamedial.com/
Direct3D 튜토리얼 3 : 매트릭스를 이용한 변환 방법
다음 변환을 위하여 4 x 4 매트릭스가 필요함
1. 3D 변환 (이동, 회전, 크기변환)
2. 카메라 설정
3. 프로젝션 설정
변환의 세 가지 단계
1. 월드 변환 (이동, 회전, 확대/축소)
2. 뷰 변환(카메라 위치, 바라보는 위치, 카메라의 자세)
3. 프로젝션 변환 (3D 씬을 2D 뷰포트에 프로젝트)
본 예제에서 사용하는 버텍스 타입
// A structure for our custom vertex type
struct CUSTOMVERTEX
{
FLOAT x, y, z; // The untransformed, 3D position for the vertex
DWORD color; // The vertex color
};
// Our custom FVF, which describes our custom vertex structure
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)
Render() 함수의 렌더링 순서
1. 화면 클리어
2. BeginScene()
3. 변환 및 버텍스 출력
3-1. 변환
SetupMatrices()
3-2. 버텍스 출력
SetStreamSource() : 버텍스 소스 지정
SetVertexShader() : 버텍스 셰이더 지정
DrawPrimitive() : 출력 모양 지정
4. EndScene()
5. Present()
SetUpMatrices() 함수 내의 변환 내용
1. 월드 변환
1-1. 월드 매트릭스 선언
1-2. 회전 변환으로 설정
1-3. 변환 매트릭스 전달
2. 뷰 변환
2-1. 뷰 매트릭스 선언
2-2. 뷰 매트릭스 설정
2-3. 뷰 매트릭스 전달
3. 프로젝션 변환
3-1. 프로젝션 매트릭스 선언
3-2. 프로젝션 매트릭스 설정
3-3. 프로젝션 매트릭스 전달
3단계 변환에 대한 코드 설명
1. 월드 변환
// World 좌표계의 y 축 회전
D3DXMATRIX matWorld;
D3DXMatrixRotationY( &matWorld, timeGetTime()/150.0f );
g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
2. 뷰 변환
// View Matrix 설정
D3DXMATRIX matView;
// 관찰자의 위치 설정
D3DXMatrixLookAtLH( &matView, &D3DXVECTOR3( 0.0f, 3.0f,-5.0f ),
// 관찰자가 바라보는 지점 설정
&D3DXVECTOR3( 0.0f, 0.0f, 0.0f ),
// 관찰자의 Up Vector 설정
&D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) );
g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
3. 프로젝션 변환
// Projection Matrix 설정
D3DXMATRIX matProj;
// FOV Ratio(x/y)
D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f,
//Near Clipping Value Far Clipping Value
1.0f, 100.0f );
g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
/***********************************************************************************/
소스 보기
#include < d3dx8.h >
#include < mmsystem.h >
LPDIRECT3D8 g_pD3D = NULL; // Used to create the D3DDevice
LPDIRECT3DDEVICE8 g_pd3dDevice = NULL; // Our rendering device
LPDIRECT3DVERTEXBUFFER8 g_pVB = NULL; // Buffer to hold vertices
// A structure for our custom vertex type
struct CUSTOMVERTEX
{
FLOAT x, y, z; // The untransformed, 3D position for the vertex
DWORD color; // The vertex color
};
// Our custom FVF, which describes our custom vertex structure
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)
//-----------------------------------------------------------------------------
// Name: InitD3D()
// Desc: Initializes Direct3D
//-----------------------------------------------------------------------------
HRESULT InitD3D( HWND hWnd )
{
// Create the D3D object.
if( NULL == ( g_pD3D = Direct3DCreate8( D3D_SDK_VERSION ) ) )
return E_FAIL;
// Get the current desktop display mode, so we can set up a back
// buffer of the same format
D3DDISPLAYMODE d3ddm;
if( FAILED( g_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm ) ) )
return E_FAIL;
// Set up the structure used to create the D3DDevice
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp) );
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = d3ddm.Format;
// Create the D3DDevice
if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp, &g_pd3dDevice ) ) )
{
return E_FAIL;
}
// Turn off culling, so we see the front and back of the triangle
g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
// Turn off D3D lighting, since we are providing our own vertex colors
g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: InitGeometry()
// Desc: Creates the scene geometry
//-----------------------------------------------------------------------------
HRESULT InitGeometry()
{
// Initialize three vertices for rendering a triangle
CUSTOMVERTEX g_Vertices[] =
{
{ 20.0f, 0.0f, 0.0f, 0x00ffff00, }, //x축 선
{-20.0f, 0.0f, 0.0f, 0x00ffff00, },
{ 0.0f, 20.0f, 0.0f, 0x0000ff00, },// y축 선
{ 0.0f,-20.0f, 0.0f, 0x0000ff00, },
{ 0.0f, 0.0f, 20.0f, 0x00ffff00, },// z축 선
{ 0.0f, 0.0f,-20.0f, 0x00ffff00, },
{ -1.0f,-1.0f, 0.0f, 0xffff0000, }, // 삼각형을 그릴 버택스
{ 1.0f,-1.0f, 0.0f, 0xff0000ff, },
{ 0.0f, 1.0f, 0.0f, 0xffffffff, },
};
// Create the vertex buffer.
if( FAILED( g_pd3dDevice->CreateVertexBuffer( 9*sizeof(CUSTOMVERTEX),
0, D3DFVF_CUSTOMVERTEX,
D3DPOOL_DEFAULT, &g_pVB ) ) )
{
return E_FAIL;
}
// Fill the vertex buffer.
VOID* pVertices;
if( FAILED( g_pVB->Lock( 0, sizeof(g_Vertices), (BYTE**)&pVertices, 0 ) ) )
return E_FAIL;
memcpy( pVertices, g_Vertices, sizeof(g_Vertices) );
g_pVB->Unlock();
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: Cleanup()
// Desc: Releases all previously initialized objects
//-----------------------------------------------------------------------------
VOID Cleanup()
{
if( g_pVB != NULL )
g_pVB->Release();
if( g_pd3dDevice != NULL )
g_pd3dDevice->Release();
if( g_pD3D != NULL )
g_pD3D->Release();
}
//-----------------------------------------------------------------------------
// Name: SetupMatrices()
// Desc: Sets up the world, view, and projection transform matrices.
//-----------------------------------------------------------------------------
VOID SetupMatrices()
{
D3DXMATRIX matWorld;
D3DXMatrixRotationY( &matWorld, timeGetTime()/150.0f ); // 회전 시키는 함수
// D3DXMatrixRotationX(); D3DXMatrixRotationY(); D3DXMatrixRotationZ();
g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );//매트릭스 전달.
D3DXMATRIX matView; //뷰 설정
D3DXMatrixLookAtLH( &matView, &D3DXVECTOR3( 4.0f, 4.0f,-10.0f ),
&D3DXVECTOR3( 0.0f, 0.0f, 0.0f ),
&D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) );
g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
D3DXMATRIX matProj;
D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f );
g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
}
//-----------------------------------------------------------------------------
// Name: Render()
// Desc: Draws the scene
//-----------------------------------------------------------------------------
VOID Render()
{
// Clear the backbuffer to a black color
g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0 );
// Begin the scene
g_pd3dDevice->BeginScene();
// Setup the world, view, and projection matrices
SetupMatrices();
// Render the vertex buffer contents
g_pd3dDevice->SetStreamSource( 0, g_pVB, sizeof(CUSTOMVERTEX) );
g_pd3dDevice->SetVertexShader( D3DFVF_CUSTOMVERTEX );
g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 6, 1 ); // 배열 6번째 값부터 3개로 1개의 삼각형을 그린다.
D3DXMATRIX matWorld;
D3DXMATRIX matWorld2;
D3DXMatrixIdentity(&matWorld);//월드 좌표 초기화
D3DXMatrixTranslation( &matWorld, 1.0, 1.0, 0.0 );// 이동 매트릭스 설정
D3DXMatrixIdentity(&matWorld2);//월드 좌표 초기화
D3DXMatrixScaling(&matWorld2, 1.0, 0.5, 1.0); // 스케일링 Matrix 생성
D3DXMatrixMultiply(&matWorld, &matWorld, &matWorld2); // 두가지를 곱하는 함수
D3DXMatrixIdentity(&matWorld2); //월드 좌표 초기화
D3DXMatrixRotationY( &matWorld2, timeGetTime()/150.0f ); //회전
D3DXMatrixMultiply(&matWorld, &matWorld2, &matWorld); // 두가지를 곱하는 함수
g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld ); //매트릭스 전달
g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 6, 1 );//삼각형을 그린다.
// 이동하고 크기 변화 시키고 회전하는 삼각형을 그린다.
// 중요한것은 이동, 크기변환, 회전의 순서가 바뀌면 출력되는 모양도 다르다.
D3DXMatrixIdentity(&matWorld);
g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
// 좌표 그리기.
g_pd3dDevice->SetStreamSource( 0, g_pVB, sizeof(CUSTOMVERTEX) );
g_pd3dDevice->SetVertexShader( D3DFVF_CUSTOMVERTEX );
g_pd3dDevice->DrawPrimitive( D3DPT_LINELIST, 2, 1 ); //2번부터 2개의 점으로 하나의 라인 생성
for (int i = -20; i < 20; i++) { // x와 z축 선을 40개씩 출력해 보자.
D3DXMatrixIdentity(&matWorld);
D3DXMatrixTranslation( &matWorld, 0.0, 0.0, i );
g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
g_pd3dDevice->DrawPrimitive( D3DPT_LINELIST, 0, 1 );
D3DXMatrixIdentity(&matWorld);
D3DXMatrixTranslation( &matWorld, i, 0.0, 0.0 );
g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
g_pd3dDevice->DrawPrimitive( D3DPT_LINELIST, 4, 1 );
}
// End the scene
g_pd3dDevice->EndScene();
// Present the backbuffer contents to the display
g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}
//-----------------------------------------------------------------------------
// Name: MsgProc()
// Desc: The window's message handler
//-----------------------------------------------------------------------------
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
switch( msg )
{
case WM_DESTROY:
PostQuitMessage( 0 );
return 0;
}
return DefWindowProc( hWnd, msg, wParam, lParam );
}
//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: The application's entry point
//-----------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
{
// Register the window class
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
"D3D Tutorial", NULL };
RegisterClassEx( &wc );
// Create the application's window
HWND hWnd = CreateWindow( "D3D Tutorial", "D3D Tutorial 03: Matrices",
WS_OVERLAPPEDWINDOW, 100, 100, 256, 256,
GetDesktopWindow(), NULL, wc.hInstance, NULL );
// Initialize Direct3D
if( SUCCEEDED( InitD3D( hWnd ) ) )
{
// Create the scene geometry
if( SUCCEEDED( InitGeometry() ) )
{
// Show the window
ShowWindow( hWnd, SW_SHOWDEFAULT );
UpdateWindow( hWnd );
// Enter the message loop
MSG msg;
ZeroMemory( &msg, sizeof(msg) );
while( msg.message!=WM_QUIT )
{
if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
Render();
}
}
}
// Clean up everything and exit the app
Cleanup();
UnregisterClass( "D3D Tutorial", wc.hInstance );
return 0;
}
다음검색