League Of Legends - Link Select [winAPI 05] Double Buffering
๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿค“ Study/winAPI

[winAPI 05] Double Buffering

by GAMEMING 2024. 6. 4.
728x90

 

 

์ง€๊ธˆ๊นŒ์ง€ ๋ฐœ์ƒํ•˜๊ณ  ์žˆ๋Š” ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ด๋ณด์ž.

1. ๋ฌผ์ฒด๋ฅผ ์›€์ง์˜€์„ ๋•Œ ๋‚จ๋Š” ์ž”์ƒ ๋ฌธ์ œ๋Š” ๋งค๋ฒˆ ์ „์ฒด ํ”ฝ์…€์„ ๋ฌดํšจํ™” ํ•˜๊ณ  ๋‹ค์‹œ ๊ทธ๋ ค์ฃผ์–ด์•ผ ํ•œ๋‹ค. 

2. ๋ฌผ์ฒด๊ฐ€ ๋งŽ์ด ์ƒ์„ฑํ•  ๋•Œ ๊นœ๋นก ๊ฑฐ๋ฆฌ๋Š” ๋ฌธ์ œ๋Š” ๋”๋ธ” ๋ฒ„ํผ๋ง์„ ์ด์šฉํ•œ๋‹ค.

 

 

- ํ™”๋ฉด ์ „์ฒด ๋ฌดํšจํ™”

 ์ผ๋‹จ ์ „์ฒด ํ™”๋ฉด ํฌ๊ธฐ์˜ ํฐ์ƒ‰ ๋„ํ˜•์œผ๋กœ ๊ทธ๋ ค์ฃผ๋Š” ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•œ๋‹ค.

void Core::Render() 
{
	// ํ™”๋ฉด clear
	Rectangle(hDC, -1, -1, ptResolution.x + 1, ptResolution.y + 1);

	Vec2 vPos = obj.getPos();
	Vec2 vScale = obj.getScale();

	Rectangle(hDC,    
		int(vPos.x - vScale.x / 2.f),
		int(vPos.y - vScale.y / 2.f),
		int(vPos.x + vScale.x / 2.f),
		int(vPos.y + vScale.y / 2.f));

}

 

 

- ๋”๋ธ” ๋ฒ„ํผ๋ง

 ์šฐ๋ฆฌ๋Š” ํ˜„์žฌ ํ™”๋ฉด A์— ๊ทธ๋ฆฌ๊ณ  ๋ณด๊ณ  ์žˆ๋‹ค๊ณ  ํ•˜์ž. A ํ™”๋ฉด ๋’ค๋กœ B ํ™”๋ฉด์„ ํ•˜๋‚˜ ๋” ๋งŒ๋“ค์–ด์„œ ๊ธฐ์กด ๊ทธ๋ฆฌ๋Š” ์ž‘์—…์„ Bํ™”๋ฉด์— ๊ทธ๋ฆฌ๊ณ  ๋‹ค ๊ทธ๋ฆฐ ํ›„์— Aํ™”๋ฉด์œผ๋กœ ๋ณต์‚ฌํ•ด ์ „๋‹ฌํ•ด์ฃผ๋ฉด ๊ทธ๋ฆฌ๋Š” ํ™”๋ฉด์ด ์‚ฌ์šฉ์ž์—๊ฒ ๋ณด์ด์ง€ ์•Š๊ณ  ์ตœ์ข…์ ์œผ๋กœ ๊ทธ๋ ค์ง„ ํ™”๋ฉด๋งŒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

 

 ๋น„ํŠธ๋งต : ์šฐ๋ฆฌ๊ฐ€ ๋ณด๋Š” ์œˆ๋„์šฐ ์ฐฝ์˜ ํ”ฝ์…€์„ ๋ชจ๋‘ ํ•ฉ์ณ ์ผ์ปซ๋Š”๋‹ค.

 

// Core.h
class Core {
	SINGLE(Core);
private:
	HWND    handle;         
	POINT   ptResolution;
	HDC		hDC; 

	HBITMAP hBit;	// ์ถ”๊ฐ€!
	HDC     mDC;	// ์ถ”๊ฐ€!

private:
	void Update();
	void Render();

public:
	int Init(HWND _hWnd, POINT _ptResolution);
	void Progress();
	HWND getMainHandle() { return handle; }
};
// Core.cpp
#include "pch.h"
#include "Core.h"

#include "TimeManager.h"
#include "Object.h"

Object obj;

Core::Core()
	:handle(0)
	, ptResolution{}
	, hDC(0)
	, hBit(0)	// ์ดˆ๊ธฐํ™”
	, mDC(0)	// ์ดˆ๊ธฐํ™”
{

}

Core::~Core()
{
	ReleaseDC(handle, hDC);	

	DeleteDC(mDC);		// ์‚ญ์ œ
	DeleteObject(hBit);	// ์‚ญ์ œ
}

int Core::Init(HWND _handle, POINT _ptResolution)
{  
	handle = _handle;
	ptResolution = _ptResolution;

	RECT rt = {0, 0 , ptResolution.x, ptResolution.y };  

	AdjustWindowRect(&rt, WS_OVERLAPPEDWINDOW, true); 
	SetWindowPos(handle, nullptr, 100, 100, rt.right - rt.left, rt.bottom - rt.top, 0);  
	
	hDC = GetDC(handle);

	// ์ด์ค‘ ๋ฒ„ํผ๋ง ์šฉ๋„์˜ ๋น„ํŠธ๋งต๊ณผ DC๋ฅผ ๋งŒ๋“ ๋‹ค
	hBit = CreateCompatibleBitmap(hDC, ptResolution.x, ptResolution.y);
	mDC = CreateCompatibleDC(hDC);

	HBITMAP hOldBit = (HBITMAP)SelectObject(mDC, hBit);
	DeleteObject(hOldBit);

	// Manager์ดˆ๊ธฐํ™”
	TimeManager::Instance()->Init();

	obj.setPos(Vec2((float)(ptResolution.x / 2), (float)(ptResolution.y / 2)));
	obj.setScale( Vec2(100, 100 ));

	return S_OK;
}

void Core::Progress()
{
	// Manager update
	TimeManager::Instance()->update();
	Update();
	Render();
}


void Core::Update()   
{
	Vec2 vPos = obj.getPos();

	if (GetAsyncKeyState(VK_LEFT) & 0x8000) {   
		vPos.x -= 200.f * TimeManager::Instance()->getfDT();   
	}
	if (GetAsyncKeyState(VK_RIGHT) & 0x8000) {   
		vPos.x += 200.f * TimeManager::Instance()->getfDT();
	}

	obj.setPos(vPos);
}

void Core::Render() 
{
	// ํ™”๋ฉด clear
	Rectangle(mDC, -1, -1, ptResolution.x + 1, ptResolution.y + 1);

	Vec2 vPos = obj.getPos();
	Vec2 vScale = obj.getScale();

	Rectangle(mDC,    
		int(vPos.x - vScale.x / 2.f),
		int(vPos.y - vScale.y / 2.f),
		int(vPos.x + vScale.x / 2.f),
		int(vPos.y + vScale.y / 2.f));

	BitBlt(hDC, 0, 0, ptResolution.x, ptResolution.y,   // ๋ชฉ์ ์ง€, ๋ณต์‚ฌ ๋ฐ›์„ ๋ถ€์œ„
		mDC, 0, 0, SRCCOPY);  // ๋ณต์‚ฌ ๋Œ€์ƒ
}

 

 

์ค‘์š” ๋ถ€๋ถ„์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

 

 

 

๊ฐ™์€ ํ•ด์ƒ๋„ ํฌ๊ธฐ์˜ ๋น„ํŠธ๋งต์„ ํ•˜๋‚˜ ๋งŒ๋“ค๊ณ  ์ด ํ•ธ๋“ค ์•„์ด๋””๋ฅผ ๋ฐ›์•„, ์ด ๋น„ํŠธ๋งต์„ ์ƒ๋Œ€๋กœ ํ•˜๋Š” DC๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. ์ด์ค‘ ๋ฒ„ํผ๋ง์„ ๊ตฌํ˜„ํ•  ๋•Œ, ์ƒˆ๋กœ ์ƒ์„ฑ๋œ ๋น„ํŠธ๋งต์„ DC์— ์„ ํƒํ•˜์—ฌ ๊ทธ ๋น„ํŠธ๋งต์— ๊ทธ๋ฆผ์„ ๊ทธ๋ฆฌ๋„๋ก ์„ค์ •ํ•˜๋Š” ๊ฒƒ์ด ํ•„์š”ํ•œ๋ฐ ์ด ๊ณผ์ •์—์„œ ์ด์ „์— ์„ ํƒ๋œ ๋น„ํŠธ๋งต์„ ๋ฐ˜ํ™˜๋ฐ›์•„, ์‚ฌ์šฉ์ด ๋๋‚œ ํ›„์—๋Š” ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์ด๋ฅผ ์‚ญ์ œํ•ด์•ผ ํ•˜๋Š” ์ผ์„ ์ง„ํ–‰ํ•ด์•ผ ํ•œ๋‹ค.

 

 

์™„์„ฑ๋œ ๊ฒƒ์„ ๋ณต์‚ฌํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ํ•„์š”ํ•œ๋ฐ ์ด๋•Œ ์‚ฌ์šฉํ•˜๋Š” ํ•จ์ˆ˜๋Š” BitBlt()์ด๋‹ค.

BOOL BitBlt(
 	HDC   hdcDest,  // ๋ณต์‚ฌํ•  ๋Œ€์ƒ DC ํ•ธ๋“ค
 	int   xDest,    // ๋Œ€์ƒ DC ์™ผ์ชฝ ์œ„ ๋ชจ์„œ๋ฆฌ์˜ x์ขŒํ‘œ
	int   yDest,    // ๋Œ€์ƒ DC ์™ผ์ชฝ ์œ„ ๋ชจ์„œ๋ฆฌ์˜ y์ขŒํ‘œ
 	int   width,    // ๋ณต์‚ฌํ•  ๋น„ํŠธ๋งต์˜ ๋„ˆ๋น„
 	int   height,   // ๋ณต์‚ฌํ•  ๋น„ํŠธ๋งต์˜ ๋†’์ด
 	HDC   hdcSrc,   // ๋ณต์‚ฌํ•  ์›๋ณธ DC ํ•ธ๋“ค
 	int   xSrc,     // ์›๋ณธ DC์—์„œ์˜ x์ขŒํ‘œ
 	int   ySrc,     // ์›๋ณธ DC์—์„œ์˜ y์ขŒํ‘œ
 	DWORD rop       // ๋ž˜์Šคํ„ฐ ์ž‘์—… ์ฝ”๋“œ
);

 

์ด ํ•จ์ˆ˜๋Š” ํ•˜๋‚˜ํ•˜๋‚˜์˜ ํ”ฝ์…€์„ ์˜ฎ๊ธฐ๋Š” ๋ฐ˜๋ณต ํ–‰์œ„๋ผ ๋งŽ์ด ๋А๋ฆฌ๋‹ค (ํ”„๋ ˆ์ž„ ๋“œ๋ž ๋ฐœ์ƒ). CPU๋กœ ์ด ์ž‘์—…์„ ํ•˜๊ธฐ์— ๋„ˆ๋ฌด ๋‚ญ๋น„์ด๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค์ด๋ ‰ํŠธX๋ถ€ํ„ฐ๋Š” GPU๋ฅผ ํ™œ์šฉํ•˜๊ฒŒ ๋œ๋‹ค. winAPI์—์„œ๋Š” ๋А๋ฆฌ๊ธดํ•œ๋ฐ, ์ด๋ฏธ ํ•œ ํ”ฝ์…€ ๋‹จ์œ„๋กœ ์˜ฎ๊ธฐ๋ฏ€๋กœ ์—ฌ๊ธฐ์„œ ๋” ๋–จ์–ด์ง€์ง„ ์•Š๋Š”๋‹ค.

๊น”๊ผผ