Direct2D 관련 코드를 분리하여 D2DRenderer Class화 하기.
대충 main엔 이렇게만 코드가 실행될 예정이다.
Winmain()
{
DemoApp App;
App.Initialize(); // 윈도우 생성, D2DRenderer 초기화
App.Run(); // 게임 루프
App.Uninitialize(); // D2DRenderer 해제
}
여기서 DemoApp이 뭐냐면, 이제부터 만들 정적 라이브러리의 GameApp을 상속받아 만들어진 클래스다.
GameApp 클래스의 기능은 위의 주석에서 파악 할 수 있다.
Renderer를 만들기전에 생각해본 것들...
일단 D2D는 윈도우 화면에 띄워지는 것들이기 때문에 너무나 당연한 말 일 수 있지만, 윈도우 등록 및 초기화를 해야한다.
그리고 등록된 윈도우를 통해서 D2D에 필요한 요소들을 불러내어야 하기에, 먼저 GameApp에서 윈도우 초기화가 진행되도록 큰 틀을 잡았다.
#pragma once
#include "D2DRenderer.h"
class GameApp
{
public:
GameApp();
~GameApp();
virtual void Initialize(HINSTANCE _hInstance);
virtual void Run();
virtual void Update();
virtual void Render();
virtual void Uninitialize();
HWND RegisterWindow(HINSTANCE _hInstance);
static LRESULT WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
protected:
D2DRenderer m_Render;
private:
WNDCLASSEX wc{ 0 };
HINSTANCE m_hInstance; // 현재 인스턴스입니다.
//WCHAR szTitle[MAX_LOADSTRING]; // 제목 표시줄 텍스트입니다.
//WCHAR szWindowClass[MAX_LOADSTRING]; // 기본 창 클래스 이름입니다.
};
내가 생각하기에 전체적인 흐름 상 필요한 함수들을 미리 만들었고, 내용없이 아직 선언만 되어있는 상태다.
GameApp은 DemoApp의 부모가 될 예정이므로 다형성을 위해 virtual을 붙여 재정의가 가능하도록 해뒀다.
#include "framework.h"
#include "GameApp.h"
GameApp::GameApp()
{
}
GameApp::~GameApp()
{
}
void GameApp::Initialize(HINSTANCE _hInstance)
{
m_hInstance = _hInstance; // 인스턴스 핸들을 전역 변수에 저장합니다.
HWND hwnd = RegisterWindow(_hInstance);
m_Render.Initialize(hwnd);
}
HWND GameApp::RegisterWindow(HINSTANCE _hInstance)
{
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc; // 윈도우 프로시저 함수
wc.hInstance = m_hInstance; // 인스턴스 핸들
// NULL을 사용하면 현재 실행 중인 프로그램의 인스턴스 핸들을 사용하게 됩니다.두 번째 인자는 로드할 커서의 ID입니다.
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszClassName = L"DefaultWindow";
//윈도우 클래스 등록
if (!RegisterClassEx(&wc))
{
MessageBox(NULL, L"윈도우 클래스 등록 실패", L"에러", MB_OK | MB_ICONERROR);
}
HWND hWnd;
hWnd = CreateWindowEx(
0,
L"DefaultWindow",
L"D2DHam", //상단바에 뜨는 제목
WS_OVERLAPPEDWINDOW,
0 ,0,
1920, 1280,
NULL, NULL, _hInstance, NULL);
ShowWindow(hWnd, SW_SHOWNORMAL);
UpdateWindow(hWnd);
if (!hWnd)
{
MessageBox(NULL, L"윈도우 생성 실패", L"에러", MB_OK | MB_ICONERROR);
}
return hWnd;
}
void GameApp::Run()
{
MSG msg;
// 기본 메시지 루프입니다:
while (TRUE)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
break;
//윈도우 메시지 처리
TranslateMessage(&msg); // 키입력관련 메시지 변환 WM_KEYDOWN -> WM_CHAR
DispatchMessage(&msg);
}
else
{
Render();
}
}
}
void GameApp::Update()
{
}
void GameApp::Render()
{
m_Render.BeginDraw();
m_Render.EndDraw();
}
void GameApp::Uninitialize()
{
m_Render.UnInitailize();
}
LRESULT GameApp::WndProc(HWND _hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(_hwnd, msg, wParam, lParam);
}
return 0;
}
⭐⭐⭐윈도우 등록이 안된다면,,, 윈도우 초기화 때의 wc.lpszClassName = L"DefaultWindow"; 이 부분이
윈도우 생성할때의 값과 일치하는지를 확인해보자...
아주 기초적인 것을 놓쳐서 어제 마무리 짓는데 실행이 안되고 오류가 자꾸 바뀌어가며 나길래 돌아버리는줄 앎...
'D2D와 게임엔진' 카테고리의 다른 글
[D2D 게임만들기 1] WinAPI 알아보기 (0) | 2025.03.26 |
---|---|
엔진공부 3일차 (ResourceManager 만들기) (0) | 2024.08.08 |
Direct2D 기본 사용법 3 (이미지 출력) (1) | 2024.08.05 |
Direct2D 기본 사용법 2 (텍스트 출력) (0) | 2024.08.05 |
Direct2D 기본 사용법 1 (기하도형 출력) (0) | 2024.08.05 |