CAFE

メDirectX 3D

[강의]매트릭스에 돌입하자.

작성자Gloomy Sunday|작성시간02.09.27|조회수542 목록 댓글 0
3D03.txt

출처 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;
}




다음검색
현재 게시글 추가 기능 열기

댓글

댓글 리스트

카페 검색

카페 검색어 입력폼