더블버퍼링
Project/Win32API로 던그리드 모작

더블버퍼링

Woon2World :: Programming & Art Life

 

 

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    HDC hDC;
    PAINTSTRUCT ps;
 
    // ...
 
    switch (uMsg)
    {
 
    // ...
 
    case WM_PAINT:
        hDC = BeginPaint(hWnd, &ps);
        BackBuffer.Draw(hDC);
        EndPaint(hWnd, &ps);
        break;
 
    // ...
 
    }
 
    // ...
 
}
cs

 

WM_PAINT 메시지가 발생할 때마다 DC에 새롭게 그림을 그리면

기존의 그림을 비우고 새로운 그림을 그리기까지의 시간이 있기 때문에 flickering 현상이 나타난다

BackBuffer에 그림을 미리 그려 놓고, DC에 BackBuffer의 내용을 복사하여

복사 완료 전 까지는 기존의 그림이 출력되도록 한다

 

BackBuffer는 또한 게임 내 다양한 함수에서 render를 통해 그림을 그릴 객체로, 싱글톤이다

 

 

// ...
 
#include <windows.h>
#include "singleton.h"
 
// ...
 
#define BackBuffer _BackBuffer::getinst()
class _BackBuffer : public Singleton<_BackBuffer>
{
public:
    void Draw(HDC h_dc)
    {
        buf_dc = CreateCompatibleDC(h_dc);
        HBITMAP bit_buf{ CreateCompatibleBitmap(h_dc, client.right, client.bottom) };
        SelectObject(buf_dc, bit_buf);
        BitBlt(h_dc, 00, client.right, client.bottom, buf_dc, 00, SRCCOPY);
        DeleteObject(bit_buf);
        DeleteDC(buf_dc);
    }
    operator HDC() { return buf_dc; }
 
    _BackBuffer(Singleton<_BackBuffer>::no_constructor_call) {}
 
private:
    HDC buf_dc;
};
cs

 

 

Draw 메서드는 현재 buf_dc의 내용을 매개변수로 전달받은 h_dc에 고속 복사한다

BackBuffer에 그림을 코드 어딘가에서 그렸다면, WM_PAINT에서 Draw를 호출해 그림을 복사함으로써 더블버퍼링이 수행된다

 

operator HDC()를 마련하여, HDC로의 암시적 형변환이 가능하도록 만들었다

HDC가 사용되는 맥락에서 무리없이 BackBuffer를 사용할 수 있다

 

 

 

백버퍼는 싱글톤 클래스를 실제로 구현한 예이다

https://jartlife.tistory.com/44

 

싱글톤 패턴

// singleton.h #ifndef _singleton #define _singleton template class Singleton { public:     static auto& getinst()     {         static T inst = no_constructor_call{};   ..

jartlife.tistory.com