System.out.println("Hello, World");

'프로그래밍/3D 프로그래밍'에 해당되는 글 13건

  1. 2012.04.19 3D프로그래밍기본 - 행렬
  2. 2012.04.19 3D프로그래밍기본 - 벡터
  3. 2012.03.24 1. CreateDevice

행렬(Matrix)

-행렬이란 2차원으로 배열된 순서쌍.

 - 가로로된 숫자 나열을 행(row)

 - 세로로 된 숫자 나열을 열(columm).


 - m과 n이 같은 행렬을 정방행렬이라고 한다.


○ 대각행렬(diagonal matrix)

 - 행렬의 기본 Aij에서 i와 j가 같은 원소를 대각선 성분이라고 함.

 - 대각선 성분을 제외한 모든 성분이 0인 특별한 형태의 행렬이 가능


○ 단위행렬(identity matrix)

 - 단위 행렬은 실수의 곱에서 1과 같은 역할을 한다.

 - AI = IA = A


○ 전치행렬(transpose matrix)

 - 행을 열로 자리바꿈하거나, 열을 행으로 자리바꿈한 행렬



○ 행렬의 덧셈


○ 행렬의 뺄셈


○ 행렬의 곱셈

 - AB = C


○ 행렬과 스칼라의 곱

KA = AK


○ 행렬의 연산 법칙

 - 덧셈법칙

A + B = B + A

(A+B)+C = A+(B+C)

A + 0 = 0 + A

A + (-A) = 0


-곱셈법칙

AB ≠ BA ( 교환법칙)

A(BC) = (AB)C (결합법칙)

A(B±C) = AB ± AC

AI = IA = A

k(AB) = (kA)B = A(kB)


-스칼라의 곱 법칙

(K+I)A = kA + IA

K(A+B) = kA + kB

(KI)A = K(IA)

(-I)A = -A

0A = 0


-정방행렬 A에 대하여

  - A0 = I

 - A1 = A

 - An+1 = AnA

 - AmAn = Am+n


○ 역행렬

 - 역행렬이란 정방행렬에서만 존재

 - 다음 조건을 만족시키는 행렬의 이미

AA-1 = A-1A = I

 - 정방행렬 이라고 해서 모두 역행렬이 존재하는 것은 아니다. 역행렬이 존재하는 행렬을 가역(inverible)행렬이라고 하고 

    존재하지 않는 행렬을 특이(singular)행렬이라 함.






Posted by 김마농

벡터 Vector

[스칼라]

크기만으로 정해지는 양을 스칼라(scalar)라 한다.


[벡터]

○ 개요

 - 힘, 속도, 도형의 평행이동과 같이 크기와 방향을 함꼐 가지는 양을 벡터라고 한다.

 - 벡터란 크기와 방향을 나타내는 수학적인 도구

 - 일반적으로 벡터를 시각화할때에는 화살표로 표시한다.


시점 A의 위치에는 관계없이 크기와 방향만을 생각하여 로 나타낸다.

○ 동등벡터

 - 벡터는 크기와 방향을 나타내기 때문에 벡터의 시작점은 의미가 없다.

 - 크기와 방향이 같은 벡터를 동등 벡터라고 한다.


○ 성분

 - 벡터의 성분이란 벡터 V의 괄호안의 V1, V2, Vn을 말한다.(말 그대로 벡터의 성분을 의미한다.)

 - 벡터의 성분은 하나의 좌표계로 표현한다.


○ 평행이동

 시점 A의 위치에 관계없이 크기와 방향만을 생각하는 이유

 - 시점 A가 어떤 점에 위치하더라도 도형의 각 점 P에서 AB와 같은 방향이면서 평행이고 또 길이가 

    같은 선분 PP'를 그어 점 P가 옮겨지는 점 P'를 구할 수 있음


○ 단위 벡터

 - 벡터의 크기는 1이며 방향만을 나타낸다.

 - 크기가 1이 아닌 벡터를 단위 벡터로 만들어 주는 것을 벡터의 정규화(Normalization)라고 한다.


○ 주의점!

- 위와 같은 그림에서도 하나의 점으로 표현되긴 하지만 벡터다.


○ 벡터의 덧셈

A + B =[ A1+B1, A2+B2, A3+B3,…,An+Bn]

ex) A=[2.3] B = [6,1]

A+B = [2+6,3+1] =[8,4]

○ 벡터의 뺄셈

A - B = A+(-B)A1-B1, A2-B2, A3-B3,…,An-Bn]

ex) A=[2,3] B=[6,1]

A+B = [2-6],[3-1] = [-4.2]


○ 벡터의 외적(Cross product)

 - 벡터의 외적은 벡터 곱셈의 또 다른 형태

 - 두 벡터에 모두 수직한 벡터를 결과값으로 갖는다.

 - 크로스곱(Cross Product) 또는 벡터 곱(Vector Product)이라고도 한다.

 - A X B ≠ B X A

A X B = (|A| * |B| Sinθ) E  [E : A X B 방향의 단위 벡터]


○ 벡터의 내적(dot product)

 - 벡터의 곱셈은 내적과 외적으로 정의한다.

 - 벡터의 내적은 결과값이 스칼라이므로 스칼라 곱이라도 하며, 점곱이라고도 한다.

 - 내적은 벡터의 방향 관계를 얻는 도구로 사용된다.

 - 두 벡터의 각도, 사이값을 구할때 쓰이기도 한다.


A ● B = |A| * |B| * cosθ


○ 벡터의 투영

 - 하나의 벡터A를 다른 벡터 B에 투영하여 B에 평행한 벡터와 수직인 벡터로 분해한다.





 


Posted by 김마농
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
{
    /// 윈도우 클래스 등록
    WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L, 
                      GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
                      "D3D Tutorial", NULL };
    RegisterClassEx( &wc );

    /// 윈도우 생성
    HWND hWnd = CreateWindow( "D3D Tutorial", "D3D Tutorial 01: CreateDevice", 
                              WS_OVERLAPPEDWINDOW, 100, 100, 300, 300,
                              GetDesktopWindow(), NULL, wc.hInstance, NULL );

    /// Direct3D 초기화
    if( SUCCEEDED( InitD3D( hWnd ) ) )
    { 
        /// 윈도우 출력
        ShowWindow( hWnd, SW_SHOWDEFAULT );
        UpdateWindow( hWnd );

        /// 메시지 루프
        MSG msg; 
        while( GetMessage( &msg, NULL, 0, 0 ) )
        {
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        }
    }

    /// 등록된 클래스 소거
    UnregisterClass( "D3D Tutorial", wc.hInstance );
    return 0;
}

 


1. RegisterClassEx()로 생성하고자 하는 윈도우의 클래스를 등록한다.
2. CreateWindow()로 윈도우를 생성한다.
3. InitD3D() 함수에서 Direct3D를 초기화한다.
4. ShowWindow(), UpdateWindow()로 윈도우를 화면에 표시한다.
5. GetMessage(), TranslateMessage(), DispatchMessage()로 이루어진 메시지 루프를 수행한다.
6. 메시지 루프를 빠져나올경우 초기화한 Direct3D를 메모리에서 해제한다.
7. 프로그램을 종료한다.

대부분의 DirectX인터페이스는 초기화 시점에서 윈도우의 핸들(HWND)을 필요로 한다. 그렇기 떄문에 CreateWindow()로 윈도우를 생성한 다음 InitD3D()를 호출하고 있다. 그리고 프로그램이 종료된 다음에 생성한 Direct3D 인터페이슬ㄹ 메모리에서 해제하기 위해 메시지 루프 이후에 CelanUp() 함수를 호출 하고 있다. 이 순서 역시 상당히 중요하다. WM_CLOSE나 WM_DESTORY 등의 메시지에서 Direct3D를 해제할 경우 메시지 루프에서 문제가 생길 수 있다. 


InitD3D()함수
 * Direct3D 초기화
 *------------------------------------------------------------------------------
 */
HRESULT InitD3D( HWND hWnd )
{
    /// 디바이스를 생성하기위한 D3D객체 생성
    if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
        return E_FAIL;

    D3DPRESENT_PARAMETERS d3dpp;                /// 디바이스 생성을 위한 구조체
    ZeroMemory( &d3dpp, sizeof(d3dpp) );        /// 반드시 ZeroMemory()함수로 미리 구조체를 깨끗이 지워야 한다.
    d3dpp.Windowed = TRUE;                      /// 창모드로 생성
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;   /// 가장 효율적인 SWAP효과
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;    /// 현재 바탕화면 모드에 맞춰서 후면버퍼를 생성

    /// 디바이스를 다음과 같은 설정으로 생성한다.
    /// 1. 디폴트 비디오카드를 사용(대부분은 비디오카드가 1개 이다.)
    /// 2. HAL디바이스를 생성한다.(HW가속장치를 사용하겠다는 의미)
    /// 3. 정점처리는 모든 카드에서 지원하는 SW처리로 생성한다.(HW로 생성할경우 더욱 높은 성능을 낸다.)
    if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                      &d3dpp, &g_pd3dDevice ) ) )
    {
        return E_FAIL;
    }

    /// 디바이스 상태정보를 처리할경우 여기에서 한다.

    return S_OK;


그리기 함수(Render() 함수)
VOID Render()
{
    if( NULL == g_pd3dDevice )
        return;

    /// 후면버퍼를 파란색(0,0,255)으로 지운다.
    g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,255), 1.0f, 0 );
    
    /// 렌더링 시작
    if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
    {
        /// 실제 렌더링 명령들이 나열될 곳
    
        /// 렌더링 종료
        g_pd3dDevice->EndScene();
    }

    /// 후면버퍼를 보이는 화면으로!
    g_pd3dDevice->Present( NULL, NULL, NULL, NULL );

Render()함수의 알고리즘
1. 먼저 화면을 깨끗이 지운다(Clear())
2. 이제부터 폴리곤을 그리겠다고 D3D에게 알린다.(BeginScene())
3. 폴리곤을 다 그렸다고 D3D에게 알린다.(EndScene())
4. 화면에 나타나게 한다.(Present())

-인터페이스를 메모리에서 해제하기
VOID Cleanup()
{
    if( g_pd3dDevice != NULL) 
        g_pd3dDevice->Release();

    if( g_pD3D != NULL)
        g_pD3D->Release();
}
디바이스(g_pd3dDevice)는 D3D 인터페이스보다 나중에 생성되었다. 해제할때는 반드시 생성 순서의 역순으로 해제해줘야 한다. 그것만 주의하면 된다.

<생성화면>
 


Posted by 김마농