본문 바로가기
C++/WinAPI

[WinAPI] 그리기

by sihyeong 2022. 11. 13.

좌표

  • 좌표를 기준으로 그리게 됨
  • 좌표 x,y 좌표에서의 1은 1픽셀을 의미한다.

 

case WM_PAINT:
{
    PAINTSTRUCT ps;
    HDC hdc = BeginPaint(hWnd, &ps); // 렌더링 관련 핸들 받아옴
  	// DC가 그릴 장소 : hWnd
    // DC의 기본 펜 색상 : 검정색
    // DC의 기본 브러쉬 색상 : 흰색

    HPEN hRedPen = CreatePen(PS_SOLID, 1, RGB(225, 0, 0)); // 빨간펜 생성
    HBRUSH hGrayBrush = (HBRUSH)GetStockObject(GRAY_BRUSH); // 시스템 제공 회색브러쉬 받아옴
    
    HPEN hDefaultPen = (HPEN)SelectObject(hdc, hRedPen); // 빨간펜 장착, 기존의 펜은 반환됨
    HBRUSH hDefaultBrush = (HBRUSH)SelectObject(hdc, hGrayBrush); // 회색브러쉬 장착

    Rectangle(hdc, 10, 10, 110, 110); // 사각형 그리기
    SelectObject(hdc, hDefaultPen); // 다시 기본펜 장착
    SelectObject(hdc, hDefaultBrush); // 다시 기본브러쉬 장착

    DeleteObject(hRedPen); // 사용 끝난 빨간펜 삭제
    //DeleteObject(hGrayBrush); //GetStockObject는 기본적으로 생성되어 있는 Object라서 삭제시키면 안됨

    EndPaint(hWnd, &ps); // 렌더링처리 끝
}
break;

 

WM_PAINT

  • 그리기 메시지가 호출되었을 때 (무효화 영역이 발생되었을 때)

BeginPaint(hWnd, &ps)

  • 렌더링 관련 핸들 받아옴

GetStockObject(stock)

  • 시스템에서 생성하여 제공하는 오브젝트 받아옴

SelectObject(hdc, hObject)

  • 렌더링 관련 핸들(hdc)에 hObject를 사용
  • 호출 시 기존에 사용되던 hObject는 반환된다.

DeleteObject(hObject)

  • 사용이 끝난 hObject 삭제
  • GetStockObject() 에서 받아온 오브젝트는 우리가 만든게 아니기 때문에 삭제하면 안된다.

EndPaint(hWnd, &ps)

  • 렌더링 처리 종료

 

BeginPaint(), EndPaint() 문제점

  • BeginPaint()와 GetStockObject()는 메시지 처리 전용 함수이다.
  • 무효화 영역에 관한 처리를 추가로 하기 때문에 WM_PAINT와 같이 동작할 수 있다.
  • EndPaint는 무효화 영역이 해제되었다는 것을 알리기 때문에 안써주면 무한으로 갱신된다.

 

화면 갱신 (WM_PAINT 호출)

InValidateRect(hWnd, nullptr(전체영역), BOOl bErase)

  • WM_PAINT의 무효화 영역 강제 발생
  • 무효화 영역을 발생시키면 WM_PAINT가 호출되고 화면의 영역이 다시 그려진다.
  • 화면을 다시 그리고 싶을 때(갱신) 호출해서 사용한다.
  • bErase값이 true라면 전체영역을 지우고 다시 그린다.
  • false라면 지우지 않고 그 위에 다시 그려버린다.

 

 

게임 렌더링

  • WM_PAINT는 메시지가 발생했을 때 동작하기 때문에 메시지가 발생하지 않아도 동작하는 게임에 어울리지 않는다.
  • 계속해서 많은 오브젝트를 그리게 되면 오브젝트를 그리고 있는 렌더링 도중의 모습까지 보여지기 때문에 끊겨보인다.
  • 위의 문제를 해결하기 위해 더블버퍼링을 사용함

GetDC()

  • GDI(Graphic Device Interface)가 그림을 그릴 때 그래픽 장치의 정보가 저장되어 있는 DC(Device Context)를 필요로 하기에 그리기를 위해 DC를 받아와 사용한다.
  • DC는 그래픽 장치를 사용하도록 만들어지기 때문에 DC를 이용해서 GDI함수를 호출하면 렌더링된다.
  • GetDC(NULL)을 사용하게 되면 모니터의 전체 영역을 받아오기 때문에 응용 프로그램의 좌표나 영역에 제한을 받지 않고 모니터상에 원하는대로 그림을 그릴 수 있다.

ReleaseDC()

  • 생성한 DC 반환

'C++ > WinAPI' 카테고리의 다른 글

[WinAPI] DC, BITMAP, 더블버퍼링  (0) 2022.11.15
[WinAPI] 윈도우 크기 지정  (0) 2022.11.15
[WinAPI] Win32API 기본  (0) 2022.11.13
[WinAPI] DeltaTime(델타타임) 구현  (0) 2022.10.10
[WinAPI] 자동 생성 기본 구조 해석  (0) 2022.10.10