API-그리기모드(흑백모드)

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 문을 삭제 해보면 ,

한 번 출력한 선을 지우지 못하기 때문에 마우스가 움직이는 족족 새로운 선이 그려지게 된다.

이동중에 계속 선의 모양을 보여주기 위해서는 그리기 모드라는 것이 반드시 필요하다.
 


이 글을 공유하기

댓글

Designed by JB FACTORY