class CEngine
{
public:
static CEngine* GetEngine()
{
static CEngine engine;
return &engine;
}
private:
CEngine();
CEngine(const CEngine& _other) = delete;
};
// define.h 안에 매크로 지정.
#define SINGLE(type) public:\
static CEngine* GetInst()\
{\
static type mgr;\
return &mgr;\
}\
private:\
type();\
type(const type& _other) = delete;\
public:\
~type();
\
를 쓰면 매크로가 계속 이어서 나간다.\
뒤에 공백 문자 있으면 인식이 안된다.(조심)// pch.h 내부
#include "define.h"
class CEngine
{
SINGLE(CEngine)
};
"define.h"
참조해서 오류 해결됨.CEngine
클래스의 싱글톤을 매크로 구문을 이용해서 작게 했다.GetEngine
함수엿는데 매크로는 다른데에서도 싱글톤을 쓸것이라 이름이 이상하다 그래서 GetInst
로 이름을 변경// CEngine.h의 CEngine클래스 내부
public:
int init();
init
함수 선언 이니셜라이져 초기화 함수(엔진 초기화 함수)// CEngine.cpp 내부
int CEngine::init()
{
// 3
FAILED(E_FAIL);
// 1
return S_OK;
// 2
return E_FAIL;
}
FAILED
매크로는 true
와 false
를 체크하는 매크로E_FAIL
이 들어가면 0보다 작기 때문에 true
다S_OK
을 넣으면 false
가 된다.// main.cpp 내부
// 1
if (FAILED(CEngine::GetInst()->init()))
{
// 2
MessageBox(nullptr, L"엔진 초기화 실패", L"에러 발생", MB_OK);
return 0;
}
전체 코드 Engine 초기화이다.
1번의 if문은 Engine의 초기화 성공 실패 여부를 따지는 코드다.
초기화 실패시 들어온다.
1번은 Engine 초기화 실패시 1번의 조건문 으로 들어옴 ==> 프로그램 종료
2번을 안적으면 프로그램이 키자마자 바로 꺼져서 왜 꺼진지 모른다.
간단하게 메세지를 출력해주는 MessageBox
함수
첫번쨰 인자인 부모 원도우 지정하라하는데 알빠노
두번쨰 인자는 원도우 내부에 띄울 메세지 넣는 인자
세번쨰 인자는 caption
은 생성되는 원도우의 머릿
말.
4번째 인자는 MB_OK
은 단순하게 가운데에 확인 버튼만 있는 것 나온다.
개발자 블로그에 올릴 형식으로 정리해 보겠습니다.
CEngine 클래스는 게임 개발에서 핵심적인 역할을 하는 클래스입니다. 이 클래스의 멤버를 결정하는 것은 게임의 전반적인 구조와 성능에 큰 영향을 미칩니다. 특히, 화면을 담당하는 멤버의 선택은 게임 프로그래밍의 중요한 측면 중 하나입니다.
// CEngine.h의 CEngine클래스 내부.
private:
// 1
HWND m_hMainWnd; // 메인 원도우 핸들
// 2
POINT m_Resoulution; // 메인 원도우의 해상도
1280 * 768
픽셀수(해상도), 1920 * 1080
커질수록 가로세로 픽셀(메모리 조각)수가 많아진다는 것.POINT
의 구조체는 맴버로 x,y밖에 없어서 나중에 자체적인 구조체를 따로 만들어서 POINT
를 안쓸것이다.// CEngine.h의 CEngine클래스 내부
public:
int init(HWND _hWnd, POINT _Resolution);
// main.cpp
// 1
if (FAILED(CEngine::GetInst()->init(g_hWnd, POINT{ 1280, 768 })))
{
// Engine 초기화 실패 ==> 프로그램 종료
MessageBox(nullptr, L"엔진 초기화 실패", L"에러 발생", MB_OK);
return 0;
}
// CEngine.cpp
CEngine::CEngine()
: m_hMainWnd(nullptr)
, m_Resoulution{}
{}
// CEngine.cpp 내부
// 1
int CEngine::init(HWND _hWnd, POINT _Resolution)
{
// 2
m_hMainWnd = _hWnd;
// 3
m_Resoulution = _Resolution;
// 4
return S_OK;
}
init(이니셜라이저) 초기화 함수의 구현 부분이다.
2번에서는 메인함수에서 전달해준 메인 원도우의 핸들값을 사용한다.
3번에서는 해상도를 메인함수에서 입력으로 준 해상도
4번은 초기화 함수가 걍 강제로 S_OK를 했으니 원도우 뜬다.
실제 원도우는 켜질떄 화면의 해상도는 자동 지정되기 때문에 우리가 원하는 수치 일리가 없다.
// CEngine.cpp의 init함수. 내부.
SetWindowPos(m_hMainWnd, nullptr, 0, 0, m_Resoulution.x, m_Resoulution.y, 0);
+
다.DC
가 중요하다.// CEngine.h의 CEngine 클래스 내부
private:
HWND m_hMainWnd; // 메인 원도우 핸들
POINT m_Resoulution; // 메인 원도우의 해상도
// 1
HDC m_hDC; // 3.3 메인원도우 DC
m_hDC = GetDC(m_hMainWnd);
// CEngine.cpp의 기본 생성자
CEngine::CEngine()
: m_hMainWnd(nullptr)
, m_Resoulution{}
// 1
, m_hDC(nullptr)
{}
CEngine::~CEngine()
{
// 2
// DC 삭제.
ReleaseDC(m_hMainWnd, m_hDC);
}
ReleaseDC
함수로 DC제거한다.// main.cpp의 메세지 처리 한 후의 게임로직 코드
else
{
// 메세지가 큐에 없을 때에는 게임 코드 실행
// 1
CEngine::GetInst()->progress();
}
메세지를 처리하고 이 메세지 없을떄는 else로 들어온다.
컴퓨터의 성능을 볼아서 메세지를 존나 빠르게 반복문을 돌아서 처리하고 계속 else(게임코드)쪽에서 돌고있다.
GetMessage함수였을때는 메세지가 없으면 먹통이였는데 PeekMessage함수로 바꾸고 메세지가 없을때는 else로 가게했다.
progress
함수를 둬서 계속 진행시킨다.// CEngine.h의 CEngine클래스 내부
public:
int init(HWND _hWnd, POINT _Resolution);
// 1
void progress();
// CEngine.cpp의 내부.
void CEngine::progress()
{
Ellipse(m_hDC, 0,0, 100, 100);
}
progress
함수의 구현부분Elliapse
함수는 동그라미를 그릴수 있게해주는 함수다.0,0, 100, 100
줬을떄 위치와 크기Elliapse
에서 말하는 0,0은 현재 원도우안에서의 좌상단이다.50,50, 100, 100
50,50, 150, 150
// CEngine.cpp의 내부.
void CEngine::progress()
{
Ellipse(m_hDC, 50, 50, 150, 150);
Rectangle(m_hDC, 50, 50, 150, 150);
}
비트맵에 렌더링하기 위해 필요한 필수 정보 집합체
화면에 렌더링하는 함수들은 인자로 DC를 항상 넣어달라한다.
장치에다 렌더링하기 위해 필요한것이다.(직역)
비트맵에 렌더링하기 위해 필요한 필수 정보 집합체
비트맵은 단순한 메모리 구조를 가지며, 픽셀 데이터는 압축되지 않습니다.
예를 들어, 1280x768 해상도는 약 백만 픽셀로 구성되며, 각 픽셀은 3바이트(레드, 그린, 블루 각각 1바이트)를 사용해 색상을 나타냅니다.
전체 이미지 크기는 대략 3백만 바이트(약 2.8MB)가 됩니다.
비트맵은 커널 오브젝트로, 운영체제(OS)가 관리합니다.
SetWindowPos
함수를 사용하여 원하는 해상도에 맞는 윈도우를 만들면, 해당 해상도의 비트맵이 메모리에 생성됩니다. 모니터는 주사율에 따라 비트맵 데이터를 받아 화면에 표시합니다.
프로그램을 실행하면 해당 해상도의 비트맵이 생성되고, 이 비트맵은 화면에 표시할 그래픽 정보를 담당합니다.
전체 바탕화면은 더 큰 메모리 판에 각 윈도우 프로그램의 비트맵이 해당 영역을 담당하고, 모니터는 이 정보를 받아 화면에 표시합니다.
컴퓨터 그래픽스에서는 때때로 간단한 도형을 화면에 그리는 것만으로도 예상치 못한 현상이 발생할 수 있습니다. 예를 들어, C++에서 Ellipse
함수와 Rectangle
함수를 사용하여 네모와 동그라미를 겹쳐 그릴 경우, 화면에서 깜빡이는 현상이 나타날 수 있습니다. 이는 다음과 같은 코드로 구현할 수 있습니다:
void CEngine::progress()
{
Ellipse(m_hDC, 50, 50, 150, 150); // 동그라미 그리기
Rectangle(m_hDC, 50, 50, 150, 150); // 네모 그리기
}
색상 채우기
Ellipse
와 Rectangle
함수는 테두리를 검은색으로 그릴 뿐만 아니라, 도형의 내부도 하얀색으로 채웁니다. 따라서, 네모와 동그라미가 서로를 덮어쓰면서 그려집니다.무한 반복
고속 렌더링
모니터 주사율
비트맵 메모리
운영체제의 역할
// 위의 코드 생략 그대로임
// Engine 초기화
if (FAILED(CEngine::GetInst()->init(g_hWnd, POINT{ 1280, 768 })))
{
// Engine 초기화 실패 ==> 프로그램 종료
MessageBox(nullptr, L"엔진 초기화 실패", L"에러 발생", MB_OK);
return 0;
}
// 아래코드도 생략 그대로임
#pragma once
// 위의 선언들 생략.
#include "define.h"
#pragma once
#define SINGLE(type) public:\
static CEngine* GetInst()\
{\
static type mgr;\
return &mgr;\
}\
private:\
type();\
type(const type& _other) = delete;\
public:\
~type();
#pragma once
class CEngine
{
SINGLE(CEngine)
private:
HWND m_hMainWnd; // 메인 원도우 핸들
POINT m_Resoulution; // 메인 원도우의 해상도
HDC m_hDC; // 3.3 메인원도우 DC
public:
int init(HWND _hWnd, POINT _Resolution);
void progress();
};
#include "pch.h"
#include "CEngine.h"
CEngine::CEngine()
: m_hMainWnd(nullptr)
, m_Resoulution{}
, m_hDC(nullptr)
{
}
CEngine::~CEngine()
{
// DC 삭제.
ReleaseDC(m_hMainWnd, m_hDC);
}
int CEngine::init(HWND _hWnd, POINT _Resolution)
{
m_hMainWnd = _hWnd;
m_Resoulution = _Resolution;
SetWindowPos(m_hMainWnd, nullptr, 0, 0, m_Resoulution.x, m_Resoulution.y, 0);
m_hDC = GetDC(m_hMainWnd);
return S_OK;
}
void CEngine::progress()
{
Ellipse(m_hDC, 50,50, 150, 150);
Rectangle(m_hDC, 50, 50, 150, 150);
}
1차 24.01.22
2차 24.01.23
3차 24.01.24
4차 24.01.25
5차 24.01.26