posted by REDFORCE 2017. 3. 13. 21:24

본 글에서는 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 파일의 전체 내용은 아래와 같습니다.


[GitHub - June_Engine Project : Graphics.cpp]