API-그리기모드(흑백모드)
- 프로그래밍/WindowsAPI
- 2011. 5. 13. 11:23
1.흑백에서의 그리기모드
화면에 무엇인가가 그려져 있는 상황에서 그 위에 다른 무엇인가를 출력하면
원래 그려져 있던 그림은 새로 그려지는 그림에 덮여 지워진다.
디스플레이 표면은 2차원적인 평면이므로 새로운 그림이 그려지면 그 아래에 있던 그림은 지워질 수 밖에 없다.
화면에 그려진 그림은 비디오 램에 저장되는데 , 램이 동시에 두 개의 값을 기억할 수는 없으므로
타원이 있던 자리에 사각형을 그리면 , 타원은 덮여져 사라지는 것이 당연하다.
그러나 이런 당연한 현상도 그리기 모드를 변경하면 달라진다.
그리기 모드란 도형이 그려질 때 원래 그려져 있던 그림과 , 새로 그려지는 그림과의 관계를 정의하는 것이다.
그리기 모드를 개념적으로 이해하기 위해 아주 단순한 흑백의 그래픽 환경을 가정해 본다.
무엇인가를 화면에 그린다는 것은 비디오 메모리에 그림의 이미지를 기록해 넣는 동작을 말하며
이 때 원래 비디오 메모리에 있던 값과 새로 써지는 값 사이의 관계를 생각해 볼 수 있다.
가장 단순하게는 새로 그려지는 값으로 원래 있던 값을 덮어 버리는 경우가 있으며 비트 논리 연산에 의해 두 값을 적당히 혼합하는 방법들도 있다.
( COPY , OR , AND , XOR )
COPY : 그림을 원본에 복사 ( 원본이 지워지고 COPY 그림으로 대체 )
OR : 원본그림과 카피 그림을 둘다 그림
AND : 원본 그림과 카피 그림의 교집합만을 그림
XOR : 원본 그림과 카피 그림의 여집합만을 그림
2.윈도우즈API 그리그모드 함수
윈도우즈 에서 사용하는 디폴트 그리기 모드는 R2_COPYPEN 모드이다.
그래서 그려지는 그림이 기존 그림을 덮어버린다.
int SetROP2( HDC hdc, int fnDrawMode );
int GetROP2( HDC hdc );
첫 번째 인수 hdc 는 그리기 모드를 변경( 또는 조사 ) 하고자 하는 DC 의 핸들이며
SetROP2 함수의 두 번째 인수에 다음과 같은 그리기 모드값을 넘겨준다.
그리기 모드 | 설명 |
R2_BLACK | 항상 검정색 이다 |
R2_WHITE | 항상 흰색 이다 |
R2_NOP | 아무런 그리기도 하지 않는다 |
R2_NOT | 원래의 그림을 반전 시킨다 |
R2_COPYPEN | 원래의 그림을 덮어버리고 새 그림을 그린다 |
R2_NOTCOPYPEN | 새 그림을 반전시켜 버린다 |
R2_NOTXORPEN | XOR 한 결과의 반대값을 써 넣는다 |
R2_MERGEPEN | OR 연산으로 두 그림을 합친다 |
R2_MASKPEN | AND 연산으로 겹치는 부분만 그린다 |
R2_XORPEN | XOR 연산으로 겹치는 부분만 반전 시킨다 |
이 외에도 몇 가지 그리기 모드가 있지만, 현실적으로 거의 사용되지 않는다.
GetROP2 함수는 DC 에 설정되어 있는 현재 그리기 모드값을 리턴한다
3.그리기 모드를 사용하는 예제
마우스가 이동하는 대로 선을 그리되 선이 그려지는 중간 과정을 보여준다.
즉 , 마우스 버튼을 누른 위치에서 부터 시작해서 마우스 버튼을 놓는 자리까지 선을 긋되
버튼을 누른 채로 마우스를 움직이면 , 그려질 선의 모양을 보여주는 것이다.
sx , sy : 처음 마우스를 누른 위치를 가진다.
oldx , oldy : 지워져야 할 선의 좌표를 가진다.
bNowDraw : 현재 선을 그리고 있는 중인가의 flag 정보를 가진다.
마우스 왼쪽 버튼을 누르면 bNowDraw 를 TRUE 로 만들어
선 그리기를 시작하며 버튼이 눌러진 좌표를 시작점 , 끝점에 모두 대입한다.
즉 , 처음 선을 그리기 시작할 때는 시작점과 끝점이 같은 상태에서 시작하며
이 상태에서 마우스를 움직이면 끝점이 움직이면서 선이 마우스를 따라 늘어나게 된다.
선이 늘어나는 처리는 마우스 이동시인 WM_MOUSEMOVE 에서 처리하는데
선을 그려야 하므로 일단 DC 를 먼저 얻는다.
어디까지나 임시적인 그리기 이므로 GetDC 함수로 DC 를 얻었다.
마우스가 이동할 때 먼저 bNowDraw 값을 점검해 보고 이 값이 TRUE 일 경우만 선을 긋는다.
버튼을 누르지 않은 상태에서 마우스만 이동할 때는 선을 그을 필요가 없다.
SetROP2 함수를 호출하여 그리기 모드를 R2_NOT 로 변경하고 ( sx , sy ) - ( oldx , oldy ) 선을 먼저 지운다.
이 좌표에 선을 그을 때 왜 선이 지워지는가 하면
이미 그려진 그림 위에 반전 모드로 똑같은 그림을 다시 출력하면 지워지는 반전 연산의 특수성 때문이다.
검정색이 있는 위치를 반전시키면 이 점은 흰색이 되어 버리는 것이다.
이전 선을 지운 후 현 마우스 좌표를 구해 oldx , oldy 에 대입하고 다시 새로운 선을 그린다.
oldx , oldy 에 현재의 끝점을 대입해 놓았으므로 다음 마우스 이동시에 이 선을 지울 수 있다.
마우스 이동시에 보면 시작점과 끝점을 이어서 선을 만드는 작업을 두 번 한다.
첫 번째 작업은 이전의 선을 지워주는 것이다. ( 이전의 그림을 반전시키니까 흰색이 될 것이다 )
두 번째 작업은 실제 선을 긋는 것 이다. 바탕에는 아무 그림도 없을 것이므로 , 선이 그어진다.
SetROP2 문을 삭제 해보면 ,
한 번 출력한 선을 지우지 못하기 때문에 마우스가 움직이는 족족 새로운 선이 그려지게 된다.
이동중에 계속 선의 모양을 보여주기 위해서는 그리기 모드라는 것이 반드시 필요하다.
이 글을 공유하기