본 글에서는 Graphics.cpp 에 대한 내용을 다루도록 하겠습니다.
Header에 대한 내용을 아직 읽고 오지 않으신 분은 먼저 .h 에 대한 내용을 참고하시기를 추천합니다.
[코드 전체는 최하단에 있습니다]
1. Graphics 생성자
- Graphics.h 에서 정의한 Graphics 클래스의 생성자 입니다.
- direct3d / device3d 등 미리 사용 될 변수들에 대해 초기화를 이루어집니다.
2. Graphics::initialize
- 핵심 부분인 initialize 입니다.
- 파라미터 값으로 device를 올린 window핸들값 HWND와 width , height, fullscreen
- direct3d = Direct3DCreate9(D3D_SDK_VERSION) 에서 볼 수 있듯이 본 엔진은 Direct9을 사용합니다.
- Direct3DCreate9 은 directX 함수로 현재 PC의 directX sdk 버전을 체크해서 directx를 생성합니다.
- 만약 널 값이면 알아서 에러뿜뿜..으로 처리했습니다.
- 그리고 InitD3Dpp() 함수를 수행합니다. (d3dpp 포맷이나 모드를 결정합니다)
- 그 외에 더럽게 많은 device나 sprite 등의 셋팅을 진행합니다.
모든 변수들과 내용을 일일이 설명하기엔 너무 글이 길어지므로
그냥 아 DirectX 함수로 디바이스 생성하고 초기화 하고 이런저런 셋팅을 하네~ 하고 보시면 됩니다.
- 그림이 하도 커져서 두개로 나누었습니다.
!! if(FAILED(result))
throw(GameError(gameErrorNS::FATAL_ERROR, "Error Creating Direct3D Device));
가 겹쳐 있습니다.
3. LoadTexture
- 앞으로 사용할 모든 텍스쳐 파일을 로드해올 때 사용하는 함수입니다.
- 파라미터 값으로
/ 파일의 경로 / transcolor 값 /텍스쳐 크기 / 담아둘 텍스쳐 포인터 / 를 받습니다.
- LoadTexture 함수는 일반적인 모든 Texture Image들을 받아옵니다. ( bmp, jpg, png 등 )
4. LoadTextureSystemMem
- LoadTexture 함수와 동일한 기능을 수행합니다.
- 큰 차이는 System Memory를 사용한다는 점 입니다.
- D3DXCreateTextureFromFileEx ( ) 를 보시면 D3DPOOL_SYSTEMMEM 값이 다른 것을 알 수 있습니다.
- bitmap 파일만 읽을 수 있습니다.
5. CreateVertexBuffer
- 버텍스 버퍼를 이용한 렌더시 사용하는 함수입니다.
- 주로 버텍스 버퍼를 이용하여 선이나 상자를 그릴 때 사용합니다.
- 버텍스버퍼에 대한 설명은 생략하겠습니다.
6. DrawQuad & DrawLine
- 버텍스 버퍼를 이용하여 선이나 네모 상자를 그릴 때 사용합니다.
7. showBackBuffer
- device를 이용해서 모든 그리기 작업이 끝나면 불려지는 함수 입니다.
- device3d->present(NULL, NULL, NULL, NULL) 을 수행합니다.
- 결과 값으로 HRESULT 값을 받은 것을 그대로 리턴~
8. DrawSprite
- 앞으로 더럽게 많이 쓰게 될 DrawSprite 함수 입니다.
- 2D Game에서 모든 그리기 작업은 이 함수를 통해 그리게 됩니다.
- 다소 설명이 들어가야 할 것 같으니 파라미터부터 설명해드리도록 하겠습니다.
(1) SpriteData 구조체 참조 값과 transcolor 값을 받습니다.
(2) 받아온 spriteData의 값을 토대로 VECTOR2 로 center / translate / scaling 작업을 하고 상하좌우 반전 여부를 체크하고 반전 시 그림을 반대로 반전시킵니다.
(3) D3DMatrix 로 출력할 내용을 2D 행렬로 변환 합니다.
(4) 변환 시킨 행렬의 내용을 device의 sprite->setTransform( ) 를 통해 transform을 setup 시킵니다.
(5) 마지막으로 Draw!!
Draw작업 시에는 SpriteData의 텍스쳐 / 텍스쳐에서 출력할 RECT 위치 / 투명 처리 시킬 color 값이 들어갑니다.
내용이 길어서 2장의 그림으로 나누었습니다.
매트릭스 부분부터 겹쳐 있으니 코드 보시는데 참고!
9. ChangeDisplayMode
- 혹여나 게임을 진행중에 DisplayMode가 변할 시 불려지는 함수 입니다.
- 파라미터 값으로 헤더에 선언해두었던 DISPLAY_MODE 열거형 값을 받습니다.
- 워낙 직관적인 내용들뿐이라 따로 설명은 안하겠습니다.
- 심플하게 전체화면이면 전체화면으로 돌리는 작업을 하면서 Device가 잡혀있는 Window(HWND)를 전체화면으로 변경합니다.
- 창모드는 반대로~
마찬가지로 2장의 사진이 겹쳐있습니다.
10. PixcelCollision
- 저도 다시 정리해보면서 확인을 해서 조금 충격먹었습니다. (픽셀 충돌 처리부분이 있었군요 ㅡ ㅡa)
- 실제 픽셀충돌에 대해서 처리를 하려면 device에서 renderstate로 설정해야 될 것들이 조금 많습니다만 일일이 설명드리기엔 역시나 너무 길어지므로 그냥 저런식으로 셋팅한다는 점만 보고 넘어가셔도 될 것 같습니다.
- 주요 부분은 픽셀 충돌 처리를 해야하는 SpriteData 구조체 A, B에서
- IDirect3DQuery9* 를 이용하여 DirectX 함수를 사용한다는 점 입니다.
- 이 함수가 알아서 두 sprite에서 픽셀충돌이 이뤄졌는지를 반환해줍니다.
- 최종적으로 pOcclusionQuery->GetData( ) 함수를 통해 얼마나 픽셀충돌이 이뤄졌는지를 알 수 있습니다.
- 반환 형은 DWORD 값! ( 충돌한 픽셀 사이즈 입니다 )
11. 그 외 디바이스 처리( 릴리즈 / 리셋 )
- 아래 3개의 함수는 우리가 위에서 만든 Device가 로스트 되거나 release를 할 시
사용 되는 함수들 입니다.
- 첫 번째 getDeviceState() 함수는 호출 시 Device가 갑자기 뒤져버렸을 때 다시 device를 reset 시킬 수 있는지 여부를 알아 낼 수 있습니다.
- 주로 전체화면 중에 갑자기 AltTab을 하다가 버벅버벅 거리던 중 화면이 까맣게만 되고 아무것도 안나오는 게임화면을 보신 적이 있을 겁니다. 그와 같은 경우에 이 함수를 이용하여 Device를 다시 얻어 낼 수 있는지 여부를 확인 할 때 사용합니다.
- 두 번째 releaseAll() 함수는 호출 시 Device에 담아두었던 모든 내용들을 해지 시키는 내용뿐입니다.
- safeRelease( )는 템플릿 형태의 매크로로 만들어둔 내용입니다.
- 세 번째 reset()
- reset 함수는 위의 getDeviceState() 를 통해 device가 다시 reset 될 수 있는지 여부를 알아 낸 후 호출되는 함수 입니다.
- 다시 initD3Dpp() 함수를 통해 디바이스 모드를 재설정하고
- sprite->OnLostDevice() 함수를 통해 sprite를 release 한 뒤,
- device3d -> reset( ) 함수를 작동시킵니다. ( 요기서 이제 우리의 DirectX Device가 리셋~)
- 다시 재기동 된 device의 renderState 값들을 재설정 해주고 혹여나 충돌 처리에서 썼던 값 또는 sprite를 박아두었던게 있다면 reset시켜 줍니다.
간추리고 요약해보려고 해도 이건 뭐 정리할 게 너무많아서 쉽지가 않은 것 같습니다.
Graphics.cpp 에 대한 내용은 워낙 방대한지라 기본적으로 알고 와야지 이해할 수 있을 법한 내용들이 많습니다.
따라서 독자 분들이 먼저 DirectX에 대해서 선행 한 뒤에 구독하시는 게 Graphics 클래스의 구조를 이해하시는데 도움이 될 거라 생각됩니다.
귀찮으면 그냥 graphics.h graphics.cpp 파일 복붙 해서 그냥 써버리세요.
솔직히 저도 다시 정리하면서 봐도 뭐가 뭔지 모르겠습니다. ㅡ, . ㅡ;;귀찮아서 그냥 복붙하고
쓰고말지...
중요한 것은 우리가 이 Graphics 클래스를 통해 directX Device에 대한 설정을 하나의 객체로 빼고 쓴다는 점입니다. 이게 어떻게 돌아가는지 하나하나 다 파고들려면 암걸려요. 암.
Graphics.cpp 파일의 전체 내용은 아래와 같습니다.
'Programming > Engine Journal' 카테고리의 다른 글
인텔이 제시하는 병렬 프로그래밍 엔진 (0) | 2017.03.14 |
---|---|
#04_EngineCore 제작 (0) | 2017.03.13 |
#03. Engine Graphics. Engine에 DirectX 올리기 [.h] (0) | 2017.03.13 |
#02_Engine WindowSystem. 엔진 GUI 설계 (0) | 2017.03.12 |
#01_두개의 렌더링 화면..? (0) | 2017.03.12 |