=================================
=================================
=================================
출처: http://3dprog.tistory.com/entry/Etc-2D-%ED%81%B4%EB%A6%AC%ED%95%91
2d 그래픽 처리중에서 일정영역 밖으로 나가는 부분을 제외하는 기술을
클리핑
이라고 합니다
이를 처리하기 위해 필요한 인자는 3개
코드:
-------------------------------------------------------------
클리핑영역(입력:const)
대상영역(입력&출력)
원본영역(출력)
-------------------------------------------------------------
이 필요합니다.
간단히 알고리즘을 알아보면
코드:
-------------------------------------------------------------
if
대상영역이 클리핑 영역을 완전히 벗어나는가?:
return
; # 출력 안함
else
: # 그렇지 않다면 클리핑영역에 걸쳐있거나 안에 있는것이다
if
대상영역오른쪽이 클리핑영역오른쪽에 걸치는가?:
원본영역오른쪽=클리핑영역오른쪽-대상영역왼쪽
else
:
원본영역오른쪽=대상영역오른쪽-대상영역왼쪽
if
대상영역왼쪽이 클리핑 왼쪽영역에 걸치는가?
원본왼쪽=클리핑왼쪽-대상왼쪽;
대상왼쪽=클리핑왼쪽
else
:
원본왼쪽=0;
-------------------------------------------------------------
위아래쪽도 같은 왼쪽오른쪽처리와 같다
실제 예를 들어 상황에 대입해보면
코드:
예) clip(0~600)
if
dst
(100~500):
src.right=500-100=400;
->
dst
(100, 500), src(0, 400)
if
dst
(100~700):
src.right=600-100=500
dst.right=clip.right=600;
->
dst
(100, 600), src(0, 500)
if
dst
(-100, 300):
src.right=300-(-100)=400
src.left=0-(-100)=100
dst.left=0
->
dst
(0, 300), src(100, 400)
if
dst
(-200, 800):
src.right=600-(-200)=800;
dst.right=600;
src.left=0-(-200)=200;
dst.left=0;
->
dst
(0, 600), src(200, 800)
이런식이 된다
코드:
bool
IsClipRange
(
long
leftClip,
long
rightClip, long leftDst,
long
rightDst)
{
if
(leftDst > rightClip)
return false;
if
(rightDst < leftClip)
return false;
return
true;
}
bool
GetClipSourceRange
(
long
leftClip,
long
rightClip,
long
& rLeftDst,
long
& rRightDst,
long
* pRetLeftSrc,
long
* pRetRightSrc)
{
if
(!
IsClipRange
(leftClip, rightClip, rLeftDst, rRightDst))
return
false;
if
(rRightDst > rightClip)
{
*pRetRightSrc = rightClip - rLeftDst;
rRightDst = rightClip;
}
else
{
*pRetRightSrc = rRightDst - rLeftDst;
}
if
(rLeftDst < leftClip)
{
*pRetLeftSrc = leftClip - rLeftDst;
rLeftDst = leftClip;
}
else
{
*pRetLeftSrc = 0;
}
return
true;
}
bool
GetClipSourceRect
(
const RECT
& c_rrcClip,
RECT
& rrcDst,
RECT
* prcRetSrc)
{
if
(!
GetClipSourceRange
(c_rrcClip.left, c_rrcClip.right, rrcDst.left, rrcDst.right, &prcRetSrc->left, &prcRetSrc->right))
return false
;
if
(!
GetClipSourceRange
(c_rrcClip.top, c_rrcClip.bottom, rrcDst.top, rrcDst.bottom, &prcRetSrc->top, &prcRetSrc->bottom))
return
false;
return true
;
}
출처: http://3dprog.tistory.com/entry/Etc-2D-클리핑 [3D 프로그래밍]
=================================
=================================
=================================
출처: http://sugame.tistory.com/203
소프트웨어 렌더링 - 3. 직선 클리핑
직선을 이루는 2점이 화면 바깥에 있는경우에는 화면끝에서 잘라줘야됩니다. 직선 클리핑은 대부분 많이 사용하는 코헨-수더랜드(Cohen-Sutherland) 알고리즘에 대해서 설명하겠습니다.이 알고리즘은 직선을 이루는 2점의 위치를 파악하여 그 점이 화면 바깥에 있을경우 직선의 기울기를 구하여 직선과 화면영역과의 교점을 구하여 화면 안쪽으로 점을 바꿔주는것입니다.
그림에서 점p1은 0x1000위치에 있고 점p2는0x0010위치에 있습니다.
점p1의 y값에 대한 화면역역의 교점은 0입니다. x값은 직선의 기울기를 구하여 화면영역의 교점을 찾습니다new_x = p1.x + -p1.y * (p2.x - p1.x) / (p2.y - p1.y ) + 0.5f현재 x위치에 x값이 교점까지 진행한 길이 만큼 더해준 것 입니다. -p1.y는 0x1000위치는 y값이 음수이기때문에 양수로 바꾼것이고 0.5를 더 한것은 new_x가 정수형이기때문에 반올림을 하기 위한 것입니다.p2도 위와 같은방법으로 구하여 주면됩니다.그리고 각각 위치에 따라 특성이 다르기때문에 switch문으로 각각의 위치에 따라 다르게 코딩을 해야합니다.
알고리즘 정리
1. 점p1, p2의 위치를 찾는다.
2. 점p1과 p2의 위치가 둘다 0x0000 이면 화면영역안에 점이 있는것이기때문에 클리핑할필요없이 함수를 빠져나간다.
3. 두 점이 둘다 화면바깥에 있고 직선이 화면영역을 걸치지 않는경우는 그릴필요가 없기때문에 함수를 빠져나간다.
4. 점p1부터 클리핑을 해준다. switch문으로 0x0001, 0x0002, 0x0004, ... 0x1010의 경우를 따로따로 구현한다.
5. 클리핑된 점을 점p1, p2에 대입한다.소스가 약간 길기 때문에 첨부된 소스를 참고하시기 바랍니다.
출처: http://sugame.tistory.com/203 [프로그래밍 저장소]
=================================
=================================
=================================
출처: http://gpgstudy.com/forum/viewtopic.php?t=19541
=================================
=================================
=================================
'프로그래밍 관련 > 3D,2D DRAW 관련' 카테고리의 다른 글
OpenGL 렌더링 속도 높히기(glDrawElements, VBO) (0) | 2020.09.10 |
---|---|
DirectX, OpenGL 텍스처 필터링 ( Texture Filtering ) 관련 (0) | 2020.09.10 |
Z-order in top-down 2d games (0) | 2017.11.08 |
OpenGL Shader를 이용해 YUV 420 포맷 색상을 RGB로 변경하기 (0) | 2017.08.18 |
OpenGL Stencil Buffer의 사용법 (0) | 2017.08.18 |
댓글 영역