다이렉트x 색상 함수로는 DWORD로 정의된 D3DCOLOR가 있다.
D3DCOLOR은 네개의 8bit 로 나누어 각각의 8bit당 색상의 진하기를 저장한다.
( 알파값 | 빨강값 | 초록값 | 파랑값 ) 으로 구성되어진다.
D3DXCOLOR_ARGB( 255, 255, 0, 0 ); // A R G B
D3DXCOLOR_XRGB( 255, 0, 0 ); // 알파값을 넣을 필요 없다.
이는 16진수로 간단히 표현할 수 있는데 다음과 같이 설정할 수 있다.
0x ff ff ff ff 첫번째 0x는 16진수를 뜻한다.
첫번째 ff는 알파값, 두번째 ff는 빨강값, 두번째 ff는 초록값, 세번째 ff는 파랑값을 뜻한다.
즉 ARGB이다. 색상별 표현은 아래와 같다.
0xffff0000 = 빨강
0xff00ff00 = 초록
0xff0000ff = 파랑
#define MY_FVF D3DFVF_XYZ | D3DFVF_DIFFUSE
D3DFVF_DIFFUSE 분산색상요소를 포함하는 버텍스 포맷
쉐이드모드 설정 ( 쉐이더 코드를 따로 만든게 아니라 파이프라인으로 하고있습니다. )
- 플랫, 고러드(스무스)를 사용할 수 있다.
플랫 쉐이딩
고러드 쉐이딩
// 플랫 쉐이딩 pDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_FLAT ); // 고러드 쉐이딩 pDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_GOURAUD );
플랫 쉐이딩 사용시엔 보간이 이루어지지 않지만 고러드 쉐이딩 사용시엔 색상간 서로 보간이 이루어진 모습을 모인다.
현재 광원설징이 없으므로 광원을 사용 안함으로 해야 색상이 보인다는것에 주의하자!
소스코드
winmain.cpp
#include#include #pragma comment ( lib, "d3d9.lib" ) #pragma comment ( lib, "d3dx9.lib" ) #pragma comment ( lib, "winmm.lib" ) //사용자 추가 전역 변수 int ActiveFlage = TRUE; // 반복 체크 LPDIRECT3D9 pDX = NULL; // dx객체 LPDIRECT3DDEVICE9 pDevice = NULL; // dx디바이스 D3DPRESENT_PARAMETERS stParam; // 파라메터 구조체 float lastTime = (float)timeGetTime(); // 마지막 시간 float y = 0.0f; // y축 회전값 struct Vertex { Vertex(){} // 생성자 Vertex( float _x, float _y, float _z, D3DCOLOR _color ) // 생성자 { x = _x; y = _y; z = _z; color = _color; } float x, y, z; D3DCOLOR color; }; Vertex* Vtx; WORD* Idx; IDirect3DVertexBuffer9 *VB = 0; IDirect3DIndexBuffer9 *IB = 0; #define MY_FVF D3DFVF_XYZ | D3DFVF_DIFFUSE // 사용자 추가 핸들 // 콜백 함수 LRESULT CALLBACK WndProc ( HWND, UINT, WPARAM, LPARAM ); // 다이렉트x 초기화 VOID Device_Init( INT , INT , HWND ); // 버텍스 인덱스 설정 VOID VertexIndex( VOID );// 버텍스와 인덱스를 설정하는 함수 // 회전 함수 VOID RotationCube ( VOID ); int WINAPI WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow ) { static TCHAR szAppName[] = "My Project"; MSG msg; HWND hwnd; WNDCLASSEX wndclass; //HDC hdc; int WIDTH = 800,\ HEIGHT = 600; int roop = 1; bool bWindow = TRUE; // 창모드 체크 wndclass.cbSize = sizeof( wndclass ); wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon( NULL, MAKEINTRESOURCE( IDI_APPLICATION ) ); wndclass.hCursor = LoadCursor( NULL, IDC_ARROW ); wndclass.hbrBackground = ( HBRUSH )GetStockObject( WHITE_BRUSH ); wndclass.lpszMenuName = NULL; // 메뉴없음 wndclass.lpszClassName = szAppName; wndclass.hIconSm = LoadIcon( NULL, IDI_APPLICATION ); RegisterClassEx ( &wndclass ); hwnd = CreateWindow( szAppName, szAppName, WS_SYSMENU, ( GetSystemMetrics( SM_CXSCREEN ) - WIDTH ) / 2, ( GetSystemMetrics( SM_CYSCREEN ) - HEIGHT ) / 2, WIDTH, HEIGHT, NULL, NULL, hInstance, NULL ); ShowWindow( hwnd, iCmdShow ); UpdateWindow ( hwnd ); //다이렉트 X 관련 Device_Init(WIDTH, HEIGHT, hwnd); D3DXMATRIX mWorld; // 월드 행렬 D3DXMATRIX mView; // 뷰 행렬 D3DXMATRIX mProj; // 투영 행렬 // 투영행렬 셋팅 D3DXMatrixPerspectiveFovLH ( &mProj, D3DX_PI * 0.5f, (float)WIDTH / (float)HEIGHT, 1.0f, 1000.0f ); pDevice->SetTransform( D3DTS_PROJECTION, &mProj ); // 투영행렬 적용 float fCamera_x = 0.0f; float fCamera_y = 0.0f; float fCamera_z = -5.0f; VertexIndex(); // 버텍스와 인덱스를 설정하는 함수 while( roop ) { while( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) != 0 ) { if( GetMessage( &msg, NULL, 0, 0 ) == 0 ) { roop = 0; } TranslateMessage( &msg ); DispatchMessage( &msg ); } if ( ActiveFlage == TRUE ) // 실제 게임 코딩영역 { if ( GetAsyncKeyState(VK_ESCAPE) ) { ActiveFlage = FALSE; roop = NULL; } if ( GetAsyncKeyState( 'W' ) ) { fCamera_z-=0.01f; } if ( GetAsyncKeyState( 'S' ) ) { fCamera_z+=0.01f; } if ( GetAsyncKeyState( 'A' ) ) { fCamera_x+=0.01f; } if ( GetAsyncKeyState( 'D' ) ) { fCamera_x-=0.01f; } if ( GetAsyncKeyState( VK_SPACE ) ) { fCamera_x = 0.0f; fCamera_y = 0.0f; fCamera_z = -5.0f; } RotationCube();//회전 // 카메라 셋팅 D3DXMatrixLookAtLH ( &mView, &D3DXVECTOR3(fCamera_x, fCamera_y, fCamera_z), &D3DXVECTOR3(0.0f, 0.0f, 0.0f), &D3DXVECTOR3(0.0f, 1.0f, 0.0f) ); pDevice->SetTransform(D3DTS_VIEW, &mView); // 뷰 행렬 적용 pDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0); // 화면을 흰색으로 지움 //pDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); // 필모드를 와이어 프레임으로 그래야 선이 보임 // 광원사용 안함 pDevice->SetRenderState( D3DRS_LIGHTING, false ); // 플랫 쉐이딩 //pDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_FLAT ); // 고러드 쉐이딩 pDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_GOURAUD ); pDevice->BeginScene();// 그리기 시작 pDevice->SetStreamSource(0, VB, 0, sizeof(Vertex)); pDevice->SetIndices(IB); pDevice->SetFVF(MY_FVF); pDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 8, 0, 12); pDevice->EndScene();// 그리기 종료 pDevice->Present( NULL, NULL, NULL, NULL );// 화면에 뿌려줌 lastTime = (float)timeGetTime(); } } pDevice->Release(); // 디바이스 해제 VB->Release(); IB->Release(); // 버퍼 해제 return msg.wParam; } LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { switch ( iMsg ) { case WM_ACTIVATE: { break; } case WM_CREATE: { ActiveFlage = TRUE; break; } case WM_CLOSE: { ActiveFlage = FALSE; PostQuitMessage(0); break; } case WM_PAINT: break; default: break; } return DefWindowProc( hwnd, iMsg, wParam, lParam ); } VOID Device_Init(INT WIDTH, INT HEIGHT, HWND hwnd) { stParam.AutoDepthStencilFormat = D3DFMT_D24X8; // 깊이 버퍼를 24비트로 만듬 stParam.BackBufferCount = 1; // 1개의 백버퍼를 만듬 stParam.BackBufferFormat = D3DFMT_X8R8G8B8; // 백버퍼 포멧형태 stParam.BackBufferHeight = HEIGHT; // 버퍼 크기 stParam.BackBufferWidth = WIDTH; // 버퍼 크기 stParam.EnableAutoDepthStencil = TRUE; // 스텐실 버퍼 자동생성 사용 stParam.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; // 시스템 자체가 백버퍼를 건딜 수 있게 한다 ( 하지만 작동 안함 ) stParam.Windowed = TRUE; // 창모드로한다 stParam.hDeviceWindow = hwnd; // 디바이스가 어느 윈도우랑 연결될지 체크 윈도우 핸들을 넣어준다 stParam.SwapEffect = D3DSWAPEFFECT_DISCARD; // 백버퍼에서 프론트버퍼로 가져올 방식 stParam.FullScreen_RefreshRateInHz = 0; // 모니터 주사율 창모드는 0 stParam.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; // 프레젠트 명령어가 호출되면 바로 프론트 버퍼에 뿌림 stParam.MultiSampleQuality = D3DMULTISAMPLE_NONE; // 멀티셈플링 옵션으로 안씀(느려서) pDX = Direct3DCreate9( D3D_SDK_VERSION ); pDX->CreateDevice(0, D3DDEVTYPE_HAL, hwnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &stParam, &pDevice ); // 맨앞 0번은 몇번째 그래픽 카드를 쓸것인지 0번이 현재 모니터에 뿌려주고있는 그래픽카드 } VOID VertexIndex( VOID ) { pDevice->CreateVertexBuffer( 8 * sizeof(Vertex), D3DUSAGE_WRITEONLY, MY_FVF, D3DPOOL_MANAGED, &VB, 0 ); pDevice->CreateIndexBuffer( 36 * sizeof(WORD), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &IB, 0 ); VB->Lock( 0, 0, (void**)&Vtx, 0 ); Vtx[0].x = -1.0f; Vtx[0].y = -1.0f; Vtx[0].z = -1.0f; Vtx[0].color = 0xffff0000; Vtx[1].x = -1.0f; Vtx[1].y = 1.0f; Vtx[1].z = -1.0f; Vtx[1].color = 0xff00ff00; Vtx[2].x = 1.0f; Vtx[2].y = 1.0f; Vtx[2].z = -1.0f; Vtx[2].color = 0xff0000ff; Vtx[3].x = 1.0f; Vtx[3].y = -1.0f; Vtx[3].z = -1.0f; Vtx[3].color = 0xffff0000; Vtx[4].x = -1.0f; Vtx[4].y = -1.0f; Vtx[4].z = 1.0f; Vtx[4].color = 0xff00ff00; Vtx[5].x = -1.0f; Vtx[5].y = 1.0f; Vtx[5].z = 1.0f; Vtx[5].color = 0xff0000ff; Vtx[6].x = 1.0f; Vtx[6].y = 1.0f; Vtx[6].z = 1.0f; Vtx[6].color = 0xffff0000; Vtx[7].x = 1.0f; Vtx[7].y = -1.0f; Vtx[7].z = 1.0f; Vtx[7].color = 0xff00ff00;//노가다 버전 /*Vtx[0] = Vertex( -1.0f, -1.0f, -1.0f, 0xffff0000 ); Vtx[1] = Vertex( -1.0f, 1.0f, -1.0f, 0xff00ff00 ); Vtx[2] = Vertex( 1.0f, 1.0f, -1.0f, 0xff0000ff ); Vtx[3] = Vertex( 1.0f, -1.0f, -1.0f, 0xffff0000 ); Vtx[4] = Vertex( -1.0f, -1.0f, 1.0f, 0xff00ff00 ); Vtx[5] = Vertex( -1.0f, 1.0f, 1.0f, 0xff0000ff ); Vtx[6] = Vertex( 1.0f, 1.0f, 1.0f, 0xffff0000 ); Vtx[7] = Vertex( 1.0f, -1.0f, 1.0f, 0xff00ff00 );// 단순 버전*/ VB->Unlock(); IB->Lock(0, 0, (void**)&Idx, 0); Idx[0] = 0; Idx[1] = 1; Idx[2] = 2; Idx[3] = 0; Idx[4] = 2; Idx[5] = 3; Idx[6] = 4; Idx[7] = 6; Idx[8] = 5; Idx[9] = 4; Idx[10] = 7; Idx[11] = 6; Idx[12] = 4; Idx[13] = 5; Idx[14] = 1; Idx[15] = 4; Idx[16] = 1; Idx[17] = 0; Idx[18] = 3; Idx[19] = 2; Idx[20] = 6; Idx[21] = 3; Idx[22] = 6; Idx[23] = 7; Idx[24] = 1; Idx[25] = 5; Idx[26] = 6; Idx[27] = 1; Idx[28] = 6; Idx[29] = 2; Idx[30] = 4; Idx[31] = 0; Idx[32] = 3; Idx[33] = 4; Idx[34] = 3; Idx[35] = 7; IB->Unlock(); } VOID RotationCube ( VOID ) { float currTime = (float)timeGetTime(); float fangle = (currTime - lastTime)*0.001f; // 1회 루프 돌은 시간 * 0.001 D3DXMATRIX Rx, Ry; D3DXMatrixRotationX(&Rx, 3.14f / 4.0f); // x축으로 pie/4 만큼 회전 // 매 프레임마다 y축 회전값 증가 y += fangle; D3DXMatrixRotationY(&Ry, y); // y축으로 회전 적용 // 한바퀴를 돌면 y축회전각을 리셋시킨다. if( y >= 6.28f ) y = 0.0f; // x와 y의 회전된 행렬을 p에 합쳐준다. D3DXMATRIX p = Rx * Ry; pDevice->SetTransform(D3DTS_WORLD, &p); // 월드행렬에 p를 대입 }
'Programming > DirectX' 카테고리의 다른 글
인덱스 버퍼(Index Buffer) / 버텍스 버퍼(Vertex Buffer) (1) | 2013.12.12 |
---|---|
DirectX Text 출력 클래스 (0) | 2013.11.30 |
기본 Winmain.cpp 다이렉트x 초기화 포함 (0) | 2013.11.30 |