Direct3D 튜토리얼 2분석
다음과 같은 순차적 처리하여 버텍스 출력
1. 윈도우 클래스 등록
2. 윈도우 생성
3. D3D 초기화 : InitD3D() 호출
3-1. D3D 객체 생성
3-2. 디스플레이 모드 얻기
3-3. D3D 장치 생성
4. 버텍스 버퍼 초기화 : InitVB() 호출
4-1. 버텍스의 위치, RHW, 색상 지정
4-2. 버텍스를 저장할 버텍스 버퍼 생성
4-3. 버텍스 버퍼에 버텍스 값을 채워 넣기
5. ShowWindow()
6. 메시지 루프
if (메시지가 있으면)
메시지 처리
else
화면에 그리기 : Render() 함수 호출
6-1. 백버퍼 클리어
6-2. BeginScene()
6-3. 그래픽 출력
6-3-1. 스트림 소스(버텍스 버퍼) 지정
6-3-2. 셰이딩 모드 정의
6-3-3. 프리미티브 그리기 (삼각형)
6-4. EndScene()
6-5. Present() -> 플리핑을 의미
/*
참고 : RHW (Reciprocal of Homogeneous W)
The system requires that the vertex position you specify be already transformed. The x and y values must be in screen coordinates, and z must be the depth value of the pixel to be used in the z-buffer. Z values can range from 0.0 to 1.0, where 0.0 is the closest possible position to the user, and 1.0 is the farthest position still visible within the viewing area. Immediately following the position, transformed and lit vertices must include a reciprocal of homogeneous W (RHW) value. RHW is the reciprocal of the W coordinate from the homogeneous point (x,y,z,w) at which the vertex exists in projection space. This value often works out to be the distance from the eyepoint to the vertex, taken along the z-axis.
#define D3DFVF_TLVERTEX ( D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | \ D3DFVF_TEX1 )
D3DFVF_XYZRHW tells your system that your application is using transformed and lit vertices. Therefore, Direct3D doesn't transform your vertices with the world, view, or projection matrices, nor does it perform any lighting calculations. It passes them directly to the driver to be rasterized. D3DFVF_DIFFUSE indicates, that the Vertex format includes a diffuse color component. D3DFVF_SPECULAR indicates, that the vertex format includes a specular color component. D3DFVF_TEX1 shows us the number of texture coordinate sets for this vertex.
참고 : Projection Space
Frame of reference containing vertices after they are modified from their world space locations by the projection transformation. Projection space is a homogeneous cuboid space in which all vertices in a scene have x- and y-coordinates that range from ?1.0 to 1.0, and a z-coordinate that ranges from 0.0 to 1.0. Projection space is sometimes referred to as post-perspective homogeneous space.
*/
인제 튜토리얼을 보자.
#include < d3d8.h >
//-----------------------------------------------------------------------------
// Global variables
//-----------------------------------------------------------------------------
/*전역 변수들....*/
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, rhw; // The transformed position for the vertex
DWORD color; // The vertex color
};
// Our custom FVF, which describes our custom vertex structure
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|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;
}
// Device state would normally be set here
return S_OK;
}
HRESULT InitVB()
{
// Initialize three vertices for rendering a triangle
CUSTOMVERTEX g_Vertices[] =
{/*www.gamedial.com 안에 다이렉트3D 기본지식 슬라이드 19번 참조*/
{ 150.0f, 50.0f, 0.5f, 1.0f, 0xffffffff, }, // x, y, z, rhw, color
{ 250.0f, 250.0f, 0.5f, 1.0f, 0xffffffff, },
{ 50.0f, 250.0f, 0.5f, 1.0f, 0xff00ffff, },
{ 450.0f, 50.0f, 0.5f, 1.0f,0xffffff00, },
{ 550.0f, 250.0f, 0.5f, 1.0f,0xffff00ff, },
{ 350.0f, 250.0f, 0.5f, 1.0f,0xffffffff, },
};/*점3개 추가*/
// Create the vertex buffer. Here we are allocating enough memory
// (from the default pool) to hold all our 3 custom vertices. We also
// specify the FVF, so the vertex buffer knows what data it contains.
if( FAILED( g_pd3dDevice->CreateVertexBuffer( 6*sizeof(CUSTOMVERTEX),//6개의 점을 잡아요
0, D3DFVF_CUSTOMVERTEX,
D3DPOOL_DEFAULT, &g_pVB ) ) )
{
return E_FAIL;
}
// Now we fill the vertex buffer. To do this, we need to Lock() the VB to
// gain access to the vertices. This mechanism is required becuase vertex
// buffers may be in device memory.
VOID* pVertices;
/* VOID* <-임시 포인터 변수 ↙메모리 크기 만큼*/
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: Render()
// Desc: Draws the scene
//-----------------------------------------------------------------------------
VOID Render()
{
// Clear the backbuffer to a blue color
g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,255), 1.0f, 0 );
/*백버퍼 클리어 */
// Begin the scene
g_pd3dDevice->BeginScene();
g_pd3dDevice->SetStreamSource( 0, g_pVB, sizeof(CUSTOMVERTEX) );
/*버택스버퍼에서 CUSTOMVERTEX만큼씩 읽어 온다*/
g_pd3dDevice->SetVertexShader( D3DFVF_CUSTOMVERTEX );/*어떤형태로 그릴것인가?*/
g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0,2 );
/*어떤것을 그릴지 설정 삼각형을 0번부터 2개 그려라*/
// 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 02: Vertices",
WS_OVERLAPPEDWINDOW, 100, 100, 700, 400,
GetDesktopWindow(), NULL, wc.hInstance, NULL );
// Initialize Direct3D init 다이렉트 3D 생성
if( SUCCEEDED( InitD3D( hWnd ) ) ) // <- 메크로
{
// Create the vertex buffer
if( SUCCEEDED( InitVB() ) ) // 버텍스버퍼를 초기화 해주는부분
{
// 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;
}