그리기 모드란 도형이 그려질 때 원래 그려져 있던 그림과 새로 그려지는 그림과의 관계를 말한다.
간단하게 그림을 만들어봤다.
참고로 간단하게 흑백의 그래픽 환경을 가정해서 만들었더.
OR
0 | 1 | 0 | 1 |
0 | 1 | 1 | 0 |
0 | 1 | 1 | 1 |
0 | 1 | 0 | 1 |
0 | 1 | 1 | 0 |
0 | 1 | 0 | 0 |
0 | 0 | 0 | 1 |
0 | 0 | 1 | 0 |
0 | 0 | 1 | 0 |
같은 이야기니까 편한걸로 이해하길 바란다.
그리기 모드의 종류
윈도우에서 사용하는 디폴트 그리기 모드는 R2_COPYPEN 모드이다. 그래서 그려지는 그림이 기존 그림을 덮어 버런다.
그리기 모드에 대한 함수는
int SetROP2(HDC,int fnDrawMode);
int GetROP2(HDC,hdc);
첫 번째 인수는 설정하거나 정보를 얻고자 하는 dc를 말한다.
두 번째 인수는 설정하고자하는 모드를 말한다. 그리모드는 다음표와 같다.
R2_BLACK | 항상 검정색이다 |
R2_WHITE | 항상 흰색이다 |
R2_NOP | 아무런 그리기도 하지 않는다. |
R2_NOT | 원래의 그림을 반전시킨다. |
R2_COPYPEN | 원래의 그림을 덮어버리고 새 그림을 그린다. |
R2_NOTCOPYPEN | 새 그림을 반전시켜 그린다. |
R2_NOTXORPEN | XOR한 결과의 반대값을 써 넣는다 |
R2_MERGENPEN | OR연산으로 두 그림을 합친다. |
R2_MASKPEN | AND.연산으로 겹치는 부분만 그린다. |
R2_XORPEN | XOR연산으로 겹치는 부부만 반전시킨다. |
그 외에 몇가지 그리모드가 더있는데. 거의 안써서 설명에서 제외!
자 그럼 실습을 해보자.
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam){
static int xpos,ypos;
static int xposSave, yposSave;
static BOOL buttonFlag=false;
HDC hdc;
switch(iMessage){
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_LBUTTONDOWN:
xpos=LOWORD(lParam);
ypos=HIWORD(lParam);
xposSave=xpos;
yposSave=ypos;
buttonFlag=true;
return 0;
case WM_LBUTTONUP:
buttonFlag=false;
hdc=GetDC(hWnd);
MoveToEx(hdc,xpos,ypos,NULL);
LineTo(hdc,xposSave,yposSave);
ReleaseDC(hWnd,hdc);
return 0;
case WM_MOUSEMOVE:
if(buttonFlag){
hdc=GetDC(hWnd);
SetROP2(hdc,R2_NOT);
MoveToEx(hdc,xpos,ypos,NULL);
LineTo(hdc,xposSave,yposSave);
xposSave=LOWORD(lParam);
yposSave=HIWORD(lParam);
MoveToEx(hdc,xpos,ypos,NULL);
LineTo(hdc,xposSave,yposSave);
ReleaseDC(hWnd,hdc);
}
return 0;
}
return (DefWindowProc(hWnd,iMessage,wParam,lParam));
}
자 궁금증이 생기지 않은가? 왜 반전을 시켰는가.
그렇다면 SetROP2(hdc,R2_NOT);
부분을 주석처리해서 프로그램을 돌려보자!.
간단하게 프로그램 분석을 해보자.
마우스 왼쪽 버튼을 누르는 순간 좌표가 변수에 저장되며 save변수에도 좌표를 저장한다.
왜냐하면 시작점과 끝점이 같기 때문이다.
그리고 플래그를 올려둔다.
마우스가 움직이면 플래그가 올라갔다면 마우스가
왼쪽버튼을 누른상태에서 움직이면 선이 그어지는데 왜냐하면 기본 좌표 xpos와 ypos는 고정되어있고 입력을받아 그어지는것은 끝점인
xposSave와 yposSave가 이동 좌표가 되는것이다.
첫번째 Lineto함수는 기존에 선과 똑같은위치에 선을 그린다 반전모드이기때문에 선이 삭제 되겠죠.
그리고 다시 마우스 좌표를 받아
선을 그리는것이다.
마우스 버튼을 놓게 되면 마지막에 move에서 마지막에 그어졌던 선 위치 그위치에 똑같이 선을 그린다.
그렇다면 흰색팬으로 지운 후 검은색 펜으로 다시 그리는 방식을 사용하면 어떨까?
if(buttonFlag){
hdc=GetDC(hWnd);
SelectObject(hdc,GetStockObject(WHITE_PEN));
MoveToEx(hdc,xpos,ypos,NULL);
LineTo(hdc,xposSave,yposSave);
xposSave=LOWORD(lParam);
yposSave=HIWORD(lParam);
SelectObject(hdc,GetStockObject(BLACK_PEN));
MoveToEx(hdc,xpos,ypos,NULL);
LineTo(hdc,xposSave,yposSave);
ReleaseDC(hWnd,hdc);
}
이렇게 바꾸면 어떨까?
잘되는것 같지만.. 그건 위에 보이는 선만 그렇다 왜 저 코드가 안되는것일까?
간단하다 마지막에 그려진 선은 잘 처리가 되지만 지운걸 다시 그리기 때문에 지워지는 부분에서 다 원상복구 시켜주지 않기 때문에
깔려있는 선은 죽어나가는것이다.
이해가 안되면 돌려보도록.
'Computer > Win API' 카테고리의 다른 글
WinApi 그래픽 [비트맵 bitmap] (0) | 2010.07.22 |
---|---|
WinApi RopMode2 [확장] (0) | 2010.07.22 |
WinApi 그래픽 [투명 오브젝트] (0) | 2010.07.22 |
WinApi 그래픽 [변수를 두개 두는 이유] (0) | 2010.07.21 |
WinApi 그래픽 [색상][펜][브러쉬] (0) | 2010.07.21 |