-
렌더링 시점과 DC에 대한 이해 , RGB컬러MFC 2025. 4. 14. 17:50
렌더링 시점
- 윈도우 화면은 기본적으로 2회 렌더링
- WM_PAINT
- WM_ERASEBKGND - WM_PAINT 메시지 처리시에는 반드시 CPaintDC를 사용 (렌더링 완료 통지)
우리 눈에 보이는 것이 다 비트맵 이미지다.
렌더링은 그림을 그린다고 생각하면 된다. 선을 그리고, 도형을 그리고, 색을 칠하다보면 그림을 그릴 수 있다.
우리는 MFC에서 함수를 통해 그림을 그릴 수 있다.
렌더링 될때 호출되는 함수 순서는 WM_ERASEBKGND 가 먼저 호출되고, WM_PAINT가 호출된다.
배경을 지우개로 지우고 그림을 그린다고 생각하면 된다.
렌더링이 됐으면 OS한테 완료 됐다는 표시를 보내줘야 하는데 처리가 느려진다는 것은 응답 없는 상태로 인지하는 이유 중 하나가 된다. (뺑글뺑글 돌아가면서 대기화면)
DC에 대한 이해 (Device Context)
- 윈도우에 대한 DC를 생성한 후 렌더링 인터페이스로 활용
- 생성한 DC(GetDC())는 수동으로 삭제 (RealeaseDC()) - 렌더링 도구 객체를 DC에 적용 (SelectObject())
- CPen, CBrush, CFont 등 다수
- 시스템이 제공하는 객체 존재 (Stock object) - 구형 GDI와 신형 GDI+
- DC 종류
- CDC, CClientDC, CPaintDC, CMetaFileDC - DC가 비트맵을 갖지 않으면 출력 불가
- 특정 윈도우에 대한 DC는 비트맵을 가짐
- 비트맵은 대상 윈도우 화면과 동일 - 여러 DC를 생성해 이미지를 합성하는 것이 가능
- 모니터 화면이 아닌 비트맵에 그리기 가능
- 여러 비트맵에 그린 후 한 화면에 합성
- 화면에 출력은 비트맵 출력보다 느림
DC에 비트맵이 존재하고, 윈도우에 그리는것이 아닌 비트맵에 그린다.
비트맵에 그림이 완성되면, 메모리에 저장된 이미지가 되고, 원하면 파일로 저장할 수 있다.
완성된 비트맵은 DC라는걸 통해서 모니터에 한번에 보여준다. (블릿)
GDI 리소스 개수는 윈도우에서 관리한다. (적게 쓸수록 좋은것)
DC가 선, 색에대한 객체를 선택한 뒤 선택한 것으로 그린다.
RGB 컬러
- Red, Green, Blue 등 빛의 3원색을 각각 부호가 ㅇ벗는 8비트 정수(0 ~ 255)로 기술
- RGB() 매크로를 이용해 색상값 정의
- Alpha (투명도)
원색 빨간색을 표현하는 방법은 RGB (255, 0, 0) 이런식으로 표현하고, 255는 레드, 그린은 0, 블루도 0을 의미한다.
펜과 선
- 펜(CPen)객체를 DC에 적용한 후 그리기 시작
- 별도 펜을 지정하지 않을 경우 기본 펜(1픽셀, 검정색)적용
- CPoint 클래스를 이용하여 MoveTo(좌표)
- 외곽선을 그리지 않으려면 NULL펜 설정 - 선은 펜 속성에 따라 모양 결정
- 색상 및 굵기
- 실선(Solid)
- 점선
- 사용자 정의 패턴
실제로 코드를 확인해보면 View클래스에서 OnPaint() 함수를 생성해준다.
void CPenSampleView::OnPaint() { CPaintDC dc(this); // device context for painting dc.MoveTo(100, 100); dc.LineTo(200, 100); // 그리기 메시지에 대해서는 CView::OnPaint()을(를) 호출하지 마십시오. }
CView::OnPaint함수를 호출하지말라는 이유는 백지상태가 되기 때문이다.
dc.MoveTo(100, 100)은 처음 좌표를 이동하는것을 의미하고, LineTo 함수는 지정된 위치까지 선을 그리는것을 의미한다.
void CPenSampleView::OnPaint() { CPaintDC dc(this); // device context for painting CPen pen(PS_SOLID, 5, RGB(255, 0, 0)); // 빨간색 실선 펜 생성 dc.SelectObject(&pen); // 펜 선택 dc.MoveTo(100, 100); dc.LineTo(200, 100); // 그리기 메시지에 대해서는 CView::OnPaint()을(를) 호출하지 마십시오. }
pen 객체를 생성하고, 5는 5픽셀을 의미한다. 펜을 더 두껍게 사용하고싶으면 수치를 늘리면 된다.
dc.SelectObject 함수를 통해 펜을 선택해야 적용이 된다.
이렇게 펜 객체를 추가해서 다른 색상도 추가할 수 있다.
COLORREF cBlue = RGB(0, 0, 192); CPen penBlue(PS_SOLID, 25, cBlue);
위와 같이 COLORREF를 사용해서 색상을 변경할 수도 있다.
도형과 브러시
- 기본 도형은 네모와 원 두가지
- 결과적으로 2차원 화면상의 모든 도형은 네모
- 원은 네모 속에 존재
- CRect, CPoint, CSize (네모는 CRect, 좌표 얘기는 CPoint, 폭과 높이 얘기할 떄는 CSize) - 도형 외각은 DC가 선택한 Pen으로 그려지며 그 내부는 브러시로 채워짐
- CPen, CBrush
CRect rect(0, 0, 300, 300); dc.Rectangle(&rect);
CRect는 사각형 클래스이며, dc.Rectangle(&rect);은 사각형을 그리는 함수다.
주소를 넘기는 이유는 함수가 포인터를 요구하기 때문이다.
렌더링 순서에 따라 화면에 보이는 순서도 달라지기 때문에,
사각형을 먼저 그리고 선을 나중에 그려야 선이 위에 보인다.nullPen 객체를 추가해서 테두리에 PS_Null값을 주어 테두리가 안보인다.
안에 색상은 brush객체를 사용해서 표현할 수 있다.'
만약 흰 배경 전체를 회색으로 칠하고싶으면 GetClientRect() 함수를 사용해서 전체 크기를 구할 수 있다.
CRect rect; this->GetClientRect(&rect); // 클라이언트 영역 크기 가져오기
위와 같은 경우로, 배경을 꽉채우는걸 만들고싶다면 FillSolidRect함수를 사용하면 간편하다.
NullPen과 brush를 사용하지 않아도 된다.
//배경 CRect rect; this->GetClientRect(&rect); // 클라이언트 영역 크기 가져오기 dc.FillSolidRect(&rect, RGB(245, 245, 245)); // 배경색으로 채우기
'MFC' 카테고리의 다른 글
비트맵 리소스 다루기 (0) 2025.04.15 글꼴과 문자열 출력 (0) 2025.04.14 툴바와 상태바 (0) 2025.04.13 팝업 메뉴 (0) 2025.04.09 토글 메뉴 (0) 2025.04.09 - 윈도우 화면은 기본적으로 2회 렌더링