반응형


[컴퓨터그래픽스:OpenGL] glOrtho 함수  OpenGL / Language。 

2011/03/23 01:05

복사http://kimyongjun87.blog.me/50107809323

 

 

 

glOrtho 함수는 6개의 파라미터를 가지고 있다. left, right, bottom, top, near, far 가 바로 그것이다.

glOrtho() 함수는 viewport를 변경하게 되었을 때 물체가 왜곡되는 현상을 막는데 사용된다.

예를 들어 가로 300 세로 300의 viewport를 가로 600으로 크기를 수정하게 되면

물체는 가로의 길이가 2배 늘어 나게 된다.

이것을 막는 함수가 바로 glOrtho 함수이다. 예에서 말한 것처럼 만약 가로가 2배

커진다면 glOrtho(-1, 1, -1, 1, 1, 10)에서 glOrtho(-2, 2, -1, 1, 1, 10)으로 바꿔주면

물체가 원래의 모습을 유지합니다.

 

 

glOrtho, gluPerspective Studio

OpenGL에서 glOrtho와 gluPerpective의 인자인 near와 far의 값이 위치가 아닌 거리이다.
far의 방향은 z축 음의 방향이지만 거리를 표시하므로 far의 값이 양수가 된다.
glOrtho에서 near가 음수이면 관측자 뒤를 의미한다.
gluPerspective의 near 값은 0이 되면 안된다. (그래서 대부분 1로 처리)

반응형
반응형

http://www.gpgstudy.com/forum/viewtopic.php?t=731&sid=19239f4e54b2a269bb4656f30ef178b4

 

깊이에는 - 가 없으니 opengl 의 z값 또한 양의 값방향으로 나아간다가 맞는거 같네... 음








이전 주제 보기 :: 다음 주제 보기  
글쓴이메시지
[Q=kyu]



가입: 2002년 7월 11일
올린 글: 3

올리기openGL에서의 NDC의 z축 양의 방향이 어느쪽인지..올려짐: 2002-07-29 15:32
인용과 함께 답변 이 게시물을 del.icio.us에 추가

3D game Engine Design에서 사용한 방법으로, 
openGL 파이프라인 상의 프로젝션 행렬을 구하고 있습니다. 

그러다가 하나의 의문점이 생겼습니다. 
뷰 절두체를 투영행렬을 곱하여 [-1,1]^3 이 되는 
NDC를 얻게 되는데, 

이 NDC 역시 오른손 좌표계로 나타내어지는 지, 
즉, 
x축 양방향(오른쪽), 
y축 양방향(위쪽), 
z축 양방향(스크린에서 나오는 방향) 
인지가 궁금합니다. 

이것이 궁금한 이유는 
NDC에서 [-1,1]범위 내의 Z값을 비교해서 스크린에 투영 시 먼저 뿌려야 할 
것들을 판별한다고 생각하는데, 
glDepthFunc함수의 디폴트 옵션에서는 z값이 작을수록 화면 가까이에 있는 픽셀로 
판단하기 때문입니다. 이걸 보니 NDC의 z축 양의 방향은 화면 깊이 방향인지 
헥갈리네요. 

glDepthFunc의 옵션으로 사용되는 인자를 보면, 
GL_NEVER : 항상 거짓 
GL_LESS : 만일 source Z < drpth Z 라면 참 
GL_EQUAL : 만일 source Z = drpth Z 라면 참 
GL_LEQUAL : 만일 source Z <= drpth Z 라면 참 
GL_GREATER : 만일 source Z > drpth Z 라면 참 
GL_NOTEQUAL : 만일 source Z != drpth Z 라면 참 
GL_GEQUAL : 만일 source Z >= drpth Z 라면 참 
GL_ALWAYS : 항상 참 
GL_LESS가 default로 쓰이는 인자이고, 새로 체크되는 픽셀의 z값이 더 작으면, 
색상버퍼에 새로은 픽셀을 찍습니다.
위로
사용자 정보 보기 쪽지 보내기 MSN 메신저
류광



가입: 2001년 7월 25일
올린 글: 3569
소속: GPGstudy


타 사이트 ID(?):
docbook.kr::류광, indidev.net::류광
올리기올려짐: 2002-07-29 16:27
인용과 함께 답변 이 게시물을 del.icio.us에 추가

NDC가 normalized device coordinates 의 약자인가요?? 어쨌든 뷰포트 변환 단계까지 도달했다면 3D는 잊어버리고(즉 Z는 버리고) '2D + 깊이'로 생각하는 것이 혼란을 피할 수 있을 것 같습니다... 

OpenGL에서 깊이는 화면으로부터 화면 안쪽으로의 거리이고 범위는 [0,1]입니다. 음의 깊이에 있는 점은 그려지지 않으니까요.. 사실 깊이는 3차원 좌표계의 개념이라기보다는 은면 제거를 위한 일종의 참조 테이블이라고 보는 게 좋을 것 같아요...
위로
사용자 정보 보기 쪽지 보내기 글 올린이의 웹사이트 방문
toki



가입: 2002년 4월 13일
올린 글: 151
소속: 대한민국

올리기올려짐: 2002-07-29 16:34
인용과 함께 답변 이 게시물을 del.icio.us에 추가

저도 항상 헷갈려 왔는데 오른손 좌표계이면 Z축이 화면 밖으로 나오는 
방향인데...  
그런데 projection행렬은 무조건 왼손좌표계만 사용한다고 하네요. 당연한 
이야기이지만 처음에는 이 생각을 못해서, openGL이 화면 좌표계를 오른손 
좌표계를 사용하더라도 projection변환이 되기전에 왼손좌표계로 변환됩니 
다. 그러므로 projection에서 뽑아낸 절두체는 당연히 왼손좌표계이겠죠.
위로
사용자 정보 보기 쪽지 보내기 이메일 보내기
류광



가입: 2001년 7월 25일
올린 글: 3569
소속: GPGstudy


타 사이트 ID(?):
docbook.kr::류광, indidev.net::류광
올리기제가 이해하는 방식은...올려짐: 2002-07-29 16:40
인용과 함께 답변 이 게시물을 del.icio.us에 추가

깊이 값이 결정되는 단계가 오면 '손잡이(handness)'성은 문제가 되지 않는다고 봅니다... (간단히 말하면 깊이값의 결정은 3D 좌표계에서 벗어나는 단계라고 보는거죠) 

이 부분은 손잡이성의 문제라기보다는 그냥 화면 바깥이 양이냐 안쪽이 양이냐를 선택하는 것일 뿐이고 깊이라는 개념을 생각해 보면 당연히 화면 안쪽이 양이 되어야겠죠(수심 -10m라는 말은 없잖아요..) 화면 바깥이 양이라면 깊이 버퍼가 아니라 높이 버퍼라고 하지 않았을까 하는^^
위로
사용자 정보 보기 쪽지 보내기 글 올린이의 웹사이트 방문
toki



가입: 2002년 4월 13일
올린 글: 151
소속: 대한민국

올리기음 똑같은 이야기 같은데요!올려짐: 2002-07-29 16:57
인용과 함께 답변 이 게시물을 del.icio.us에 추가

projection에서는 왼손좌표계밖에 존재하지 않는다는 이야기가 깊이값이 
류광님 말대로 음이 될 수 없기때문에 당연한 것이라고 생각하기 때문에 
저는 별로 다를 것이 없다고 생각되어지는 데요. 
그리고 질문에서 좌표계에 대한 이야기가 나왔기때문에 좌표계에 대한 
것에 초점을 맞춘 대답일뿐 답하고자 한 내용자체가 다르다고는 생각하지 
않습니다. 

좀 오해의 소지가 있었나요 
위로
사용자 정보 보기 쪽지 보내기 이메일 보내기
류광



가입: 2001년 7월 25일
올린 글: 3569
소속: GPGstudy


타 사이트 ID(?):
docbook.kr::류광, indidev.net::류광
올리기올려짐: 2002-07-29 17:26
인용과 함께 답변 이 게시물을 del.icio.us에 추가

예 있다고 봅니다. 결과적으로는 같지만 강조하는 바가 좀 틀리지 않나 싶어서요... 

toki님은 변환 과정 중 한 부분에서 좌표계가 오른손에서 왼손으로 바뀐다는 관점에서 이야기하셨구요... 

제가 강조하고 싶었던 것은.... 최종 3D 변환 후 Z 좌표를 깊이로 바꾸는 과정은 좌표계 변환 차원의 문제라기보다는 참조테이블의 범위 조정 차원의 문제로 보는 게 더 이해하기 쉽지 않냐는 것이었구요... 다른 말로 하면 3D 좌표계의 손잡이성을 '2D + 깊이' 공간에 적용할 필요는 없지 않는가 하는 것이었습니다.
위로
사용자 정보 보기 쪽지 보내기 글 올린이의 웹사이트 방문
toki



가입: 2002년 4월 13일
올린 글: 151
소속: 대한민국

올리기올려짐: 2002-07-29 21:00
인용과 함께 답변 이 게시물을 del.icio.us에 추가

제가 왼손좌표계를 말했던 것은 어차피 절두체도 기하적인 모형이기때문에 z축의 방향이 있어야 하고 그것이 왼손좌표계를 사용해야만 된다는 이야기고 좌표계가 변환되어야 한다 는 것은 openGL이 오른손 좌표계를 modelview행렬에서 사용하기때문에 변환이야기를 한 것이죠. 좌표계를 바꾼다는 이야기가 제가 하고 싶은 말의 핵심은 아니였습니다. 질문이 NDC에서 z축의 방향은? 이였기에 
방향성을 정확하게 답변하고자 좌표계를 이야기했던 것이죠. 그냥 류광님 답변처럼 쉽게 깊이값이 음이 될 수 없다고 이야기를 했으면 좋았을 것 그랬네요. 
다시 한번 제 관점이 좌표계가 변환된다는 이야기가 아니였다는 것을 말씀드리고 싶네요. 그래서 똑같은 이야기같은데요 라고 주장을 했던 것입니다. 의도 전달이 정확하지 않았나 보네요. 죄송 
위로
사용자 정보 보기 쪽지 보내기 이메일 보내기
류광



가입: 2001년 7월 25일
올린 글: 3569
소속: GPGstudy


타 사이트 ID(?):
docbook.kr::류광, indidev.net::류광
올리기올려짐: 2002-07-29 21:22
인용과 함께 답변 이 게시물을 del.icio.us에 추가

예.. 아무래도 제가 원래의 질문을 너무 확대해석한 게 아닌가 싶네요.. 저는 원래의 질문에 "(엔진 개발에서 OpenGL을 참고하고 있는데) OpenGL 같은 널리 쓰이는 API에서 NDC의 Z 좌표값과 깊이 테스트에 쓰이는 깊이값의 방향이 서로 다른 것은 좀 이상한 것이 아닌가?" 라는 점이 내포되어 있다고 봤거든요... 그 부분에 너무 집중하다보니 toki님의 뜻을 오해한 것 같습니다... 저야말로 죄송 
위로
사용자 정보 보기 쪽지 보내기 글 올린이의 웹사이트 방문
Gamza



가입: 2001년 10월 11일
올린 글: 610

올리기결국은...올려짐: 2002-07-29 21:42
인용과 함께 답변 이 게시물을 del.icio.us에 추가

결국 NDC의 Z는 화면안쪽으로 들어가는 방향이 양(+)이라는....말씀.
_________________
HOME: http://www.Gamza.net
위로
사용자 정보 보기 쪽지 보내기 글 올린이의 웹사이트 방문 MSN 메신저
류광



가입: 2001년 7월 25일
올린 글: 3569
소속: GPGstudy


타 사이트 ID(?):
docbook.kr::류광, indidev.net::류광
올리기올려짐: 2002-07-29 21:53
인용과 함께 답변 이 게시물을 del.icio.us에 추가

예 어쨌든 제 뜻은 깊이값의 부호와 좌표계의 손잡이성 사이의 일치 여부가 중요하지 않다는 뜻으로 해석해 주시길... ^^;;;
위로
사용자 정보 보기 쪽지 보내기 글 올린이의 웹사이트 방문
[Q=kyu]



가입: 2002년 7월 11일
올린 글: 3

올리기올려짐: 2002-07-29 23:53
인용과 함께 답변 이 게시물을 del.icio.us에 추가

이렇게 많은 답글을 달아주셔서 감사합니다. ^^ 재밌네요. 글 올리는거. 
구글 검색하다가 첫방에 걸린 자료입니다. 

http://www.cs.unc.edu/~vogel/Equations/projection.doc 

이 문서에 openGL에서 사용하는 투영행렬에 관해 자세히 나와있군요. 
이 글을 살펴본 결과 NDC의 z좌표는 [-1,1] 구간으로 매핑되며, 
오른손 좌표계와는 반대로, 깊이방향이 z축 양의 방향이 되도록 뒤집힌다고 나옵니다. 

1. The view frustum defined by the parameters 
(left, right, bottom, top, near, far) is mapped to the canonical view volume in (-1, 1, -1, 1, -1, 1). 

2. The signs of the z-values are reversed. This is because in eyespace, the view is down the –z-axis, whereas in NDC, the view is down the +z-axis. 

깊이 값이 마이너스 값에도 대응하기 때문에 투영행렬식을 이끌어 내는데 
부호가 헥갈리는군요. DirectX처럼 [0,1]구간으로 대응시켰더라면, 
한결 생각하기 편했을텐데 말이죠.
위로
사용자 정보 보기 쪽지 보내기 MSN 메신저
manilee



가입: 2001년 12월 28일
올린 글: 67


타 사이트 ID(?):
156937058
올리기저두 한마디올려짐: 2002-07-30 09:43
인용과 함께 답변 이 게시물을 del.icio.us에 추가

일단 NDC에서의 z방향에 대해선 위에서 많이 언급되어 있는 거 같구. 

다 알고 계시겠지만, 앞에서 질문하신분은 depth buffer에서의 비교 또한 궁금해 하신것 같아서, 제가 아는데까지 말씀드리겠습니다. 

NDC에서 변환된 좌표는 x, y, z 모두 [-1,1] 범위를 가집니다. 
이것이 바로 그냥 frame buffer에 저장되는 것이 아니고, viewport transformation에 의해 window coordinate로 전화되어서 저장됩니다. 
x, y는 glViewport에 의해서 frame buffer의 좌표가 정해지고(물론 full screen이 아닌 window의 경우 윈도우 기준좌표이겠지요.), z 값의 경우 glDepthRange(default는 n=0, f=1입니다.)에 의해 NDC의 z좌표를 linear mapping이 되어서 변환됩니다. glDepthRange에서는 꼭 znear<zfar일 필요는 없습니다.(뒤집어지도록 mapping할 수도 있습니다.) 
식은 
zw=(f-n)/2*zd+(n+f)/2 


일단 변환되어진 z좌표는 [0,1]인 값으로 z-buffer에 저장됩니다.(이게 좀 애매하긴 합니다. 해서 제가 컴으로 test한 결과 f값이 1보다 크니까 변화가 없었습니다. 이런건 OpenGL spec 문서에도 언급되어 있지 않았는데, 말입니다. f가 1이하여야 한다든지 말입니다. 아니면, color값처럼 내부적으로 처리가 되든지 말입니다.) 
그러니까, 8bit의 경우 unsigned integer로 [0,255]이 [0,1], 
32bit의 경우 [0,65535]가 [0,1]..이런식으로 말입니다. 

한가지 주의할 점은 depth range 조절로 clipping이 달라지진 않습니다. 왜냐면 앞단계에서 clipping이 일어나기 때문입니다. 단지 z-buffer에 저장할 때, depth test에 의해서 보이는 것이 달라질 수는 있어도 말입니다. 
참고하시기를..
위로
사용자 정보 보기 쪽지 보내기 이메일 보내기
[Q=kyu]



가입: 2002년 7월 11일
올린 글: 3

올리기그렇군요.올려짐: 2002-07-30 11:54
인용과 함께 답변 이 게시물을 del.icio.us에 추가

NDC상에서 클리핑을 처리하고, 

깊이 값을 glDepthRange(default는 n=0, f=1)에서 정한 범위로 선형적으로 매핑 시키고, 

openGL에서 깊이버퍼의 해상도에 맞게 알아서 저장해 주고, 
(내부적으로 노멀라이즈를 한뒤에 깊이버퍼의 해상도를 곱해줄것 같군요.) 

화면에 뿌려줄 때에는 glDepthFunc(default는 GL_LESS)에서 깊이 값이 작은 것을 위에 뿌리는 것이군요. 

자세한 답변에 감사드립니다. glDepthRange라는 함수가 있었군요.
위로
사용자 정보 보기 쪽지 보내기 MSN 메신저
류광



가입: 2001년 7월 25일
올린 글: 3569
소속: GPGstudy


타 사이트 ID(?):
docbook.kr::류광, indidev.net::류광
올리기올려짐: 2002-07-30 12:08
인용과 함께 답변 이 게시물을 del.icio.us에 추가

[Q=kyu] 씀:

깊이 값이 마이너스 값에도 대응하기 때문에 투영행렬식을 이끌어 내는데 
부호가 헥갈리는군요. DirectX처럼 [0,1]구간으로 대응시켰더라면, 
한결 생각하기 편했을텐데 말이죠.


NDC의 Z 좌표와 깊이 버퍼의 깊이 값을 혼동하신 게 아닐지? manilee 님 지적에서도 알 수 있듯이 깊이 값 자체는 [0, 1]로 매핑됩니다... 구체적으로는 k / (2^m -1)로 매핑됩니다. m은 깊이 버퍼의 비트 수, k는 0 ~ (2^m-1) 이구요. 

앞에서도 말했듯이 모든 혼란의 원인은 깊이를 Z와 동일시 하는데 있다고 봅니다... 예를 들어 아직도 흔히 쓰이고 있는 Z 버퍼, Z 테스트라는 말은 뷰포트 변환 전과 후에 다행히 Z와 깊이의 방향이 같은 경우에만 안전하게 사용할 수 있을 뿐 그렇지 않을 경우 또는 좌표계를 의도적으로 뒤집을 수 있도록 허용하는 API의 경우에는 안전하지 못한 용어라고 봅니다. 

manilee 씀:

일단 변환되어진 z좌표는 [0,1]인 값으로 z-buffer에 저장됩니다.(이게 좀 애매하긴 합니다. 해서 제가 컴으로 test한 결과 f값이 1보다 크니까 변화가 없었습니다. 이런건 OpenGL spec 문서에도 언급되어 있지 않았는데, 말입니다. f가 1이하여야 한다든지 말입니다. 아니면, color값처럼 내부적으로 처리가 되든지 말입니다.) 
그러니까, 8bit의 경우 unsigned integer로 [0,255]이 [0,1], 
32bit의 경우 [0,65535]가 [0,1]..이런식으로 말입니다. 


n과 f가 0과 1이 아닐 때에 대해서는 OpenGL 명세서의 DepthRange 항목에 나와 있는 것 같네요((1.3, 1.4 모두 섹션 2.10.1) 

void DepthRange( clampd n, clampd f ); 

Each of n and f are clamped to lie within [0; 1], as are all arguments of type clampd or clampf. 

------- 

p.s 앗 Q=kyu 님 글을 남기셨네요.. 뒷북이 되었군요.. ^^
위로
사용자 정보 보기 쪽지 보내기 글 올린이의 웹사이트 방문
manilee



가입: 2001년 12월 28일
올린 글: 67


타 사이트 ID(?):
156937058
올리기앗 그렇군요.올려짐: 2002-07-30 12:14
인용과 함께 답변 이 게시물을 del.icio.us에 추가

제가 꼼꼼히 OpenGL spec을. 문서를 읽지 않았네요. 
한번 처음부터 끝까지 읽어 볼만한데... 시간이.. 
류광님 감사 
위로
사용자 정보 보기 쪽지 보내기 이메일 보내기
손님






올리기^^올려짐: 2002-07-30 16:51
인용과 함께 답변 이 게시물을 del.icio.us에 추가

와우!!! ^^ 멋지당.. 

1년전에 devpia에서 이 문제 나왔었는데 이제야..^^ 공론화 됐네여.. 
멋진 설명과 자세한 해설 .. 

그때두 이상했었는데..결국은..^^ 

대단하십니다..좋은설명 감사드립니다. 
꾸벅.^^
위로

반응형

'그래픽스(Graphics) > Opengl' 카테고리의 다른 글

OpenGL을 설치해보자.  (0) 2012.11.02
opengl - glortho  (0) 2012.11.02
OpenGL과 D3D의 파이프라인 비교  (0) 2012.11.02
OMT(Object Modeling Technique)  (0) 2012.11.02
vs2008 opengl 설치  (0) 2012.10.31
반응형

copyrightⓒ 김성완(kaswan) [2000년 1월 12일]

 

OpenGL과 Direct3D의 파이프라인은 기본적인 원리에서는 같지만... 
소프트웨어 엔진과 더불어 두 API도 동시에 지원할 경우 두 API의 렌더링 파이프라인의 차이점을 잘 알고 있어야 합니다.

3차원 엔진은 기본적으로 크게 세가지 모듈로 구성이 됩니다.
Transformation, Lighting, Rasterizer

이 중에서도 특히 Transformation 모듈의 Pipeline을 잘 이해해야 합니다.

OpenGL과 D3D의 파이프라인을 비교해 보죠.

OpenGL : ModelView ==> Projection ==> Viewport -> Perspective Division Direct3D : World -> View ==> Projection ==> Perspective Division -> Viewport

==> View coordinats 
==> Clipping coordinats

두 파이프라인을 비교해 보면 당장에 차이가 눈에 띠는데, 실질적으로 본다면 같은 겁니다.

* 먼저 Projection Transformation 이후 단계를 살펴보면 서로 순서가 다른데..

Homogeneous 좌표 w로 나누는 Perspective Division은 먼저 하던지 나중에 하던지 순서에 상관없이 최종 결과는 동일합니다.
그래서 실질적으로는 같은 겁니다.

D3DIM 의 예제중에 DrawPrim 이라는 예제가 있는데.. 
D3D의 세가지 버텍스 포맷을 모두 사용해서 Primitive를 렌더링하는 예입니다. 
그 중에 D3DTLVERTEX를 사용하는 Cube 모델의 경우 Transformation 을 직접하게 되는데, 소스를 살펴보면 D3D의 순서대로 하질 않고 OpenGL처럼 Perspevtive Division을 먼저하고 Viewport Transformation 을 합니다.
결국 순서에 상관이 없는 것이죠. 
(참고로 그 예제 소스에는 약간의 실수가 있더군요... 어차피 간단한 예제라 텍스츄어매핑없이 단순히 쉐이딩만 하는 거라서 실행중에 드러나지 않았지만, RHW 에다 1/w 를 대입해야하는데.. w를 바로 대입했더군요. 그리고 또 Projection Transformation후에 해야하는 3D Clipping이 생략되어 있습니다. 제대로 하려면 이것도 직접 해주어야죠.)

* 두번째 차이가 나는 곳은 Projection 변환하기 전인데...

살펴보면 OpenGL은 ModelView Transformation Matrix 하나만 설정하면 되는데...
D3D는 World 와 View 두가지로 나누어서 하게 되어 있죠.
D3D에서 두개로 나누어서 하더라도 내부적으로는 어차피 하나로 합쳐지게 되므로 결국 OpenGL처럼 한번에 설정하나 D3D처럼 따로 설정하나 같은 것이죠.
(D3D 매뉴얼에도 권고하기를 World TM과 View TM을 개별적으로 설정하기 보다는 하나는 항등행렬로 설정하고 하나에다 둘을 미리 곱해서 넣어주는게 속도상 유리하다고 되어있어요. 대개 3차원 엔진들은 행렬이 항등행렬인지 체크해서 아예 곱하는 계산에서 제외시키는 식으로 최적화 되어있기 때문이죠.)

결론적으로 OpenGL과 D3D의 Transformation 파이프라인은 동일하다고 보아도 별 문제가 없다는 것이죠.

물론 두API가 사용하는 좌표계가 서로 틀리고

OpenGL : 오른손 좌표계 
Direct3D : 왼손 좌표계

좌표값을 나타내는 행렬의 경우 OpenGL의 경우 열벡터를 사용하고 D3D의 경우 행백터를 사용하기 때문에 구체적인 행렬의 곱셈순서가 서로 반대이고, 행렬이 서로 행과 열이 바뀐(Transpose) 형태로 되어 있어 구체적인 행렬값은 틀리지요.

하지만 projection 변환까지 거치고 나면 두 API모두 좌표값이 사실상 같아집니다.
무슨 얘기인고 하니 둘다 결국은 3D 클리핑을 수행하기 위한 일종의 표준적인 정규 좌표계로 변환 되어서 같은 좌표가 된다는 것이죠. 
그래서 소프트웨어로 Transformation 을 처리할 경우 두 API 좌표계와 행렬 표시의 차이점을 개의치 않고. 적당한 하나의 공통 좌표계와 공통 행렬로 Projection 변환까지 수행한 후 두 API에 좌표값을 정규화된 좌표값으로 공급해주면 나머지는 동일하게 처리되는 것이죠.

OpenGL의 경우 ModelView 행렬과 Projection 행렬을 둘다 항등행렬로 설정하고 행렬연산을 직접하면 임의로 마음에 드는 좌표계를 사용하면서도 까다로운 3D 클리핑과 최종적인 ransterization을 API에게 맡길 수가 있습니다.

문제는 OpenGL의 경우 유연하게 이런식으로 하는게 먹히는데..
D3D의 경우 파이프라인의 어느 부분을 사용할 지를 Vertex 포멧으로 선택할 수 있는데.. 이 선택이 아래 세가지 밖에 없다는 것이죠.

D3DVERTEX : Transformation, Lighting, Rasterization 을 모두 D3D에게 맡김 D3DLVERTEX : Lighting, Rasterization 을 D3D에게 맡김 
D3DTLVERTEX : Rasterization 만 D3D에게 맡김

위에서 보다시피 OpenGL처럼 Transformation 파이프라인의 중간에 끼어 들거나 할 수 없다는 것이죠.

즉, D3D의 경우는 Transformation을 모두 직접하거나 아니면 모두 API에 맡기거나 하는 양단의 선택밖에 없다는 것이죠. 
(이런 걸 보아도 OpenGL이 얼마나 잘 만들어진 API인지 알 수 있죠.)

결국 이렇게되면 D3D의 경우 Transforamation을 직접 하려고 한다면, 까다로운 3D 클리핑까지 직접 해야 합니다.

물론 이미 소프트웨어 엔진이 제대로 구축되어 있다면 3D클리핑 도 직접 수행하므로 별문제가 없지만서도...

만약 소프트웨어 엔진없이 3D가속 카드 전용으로 만들면서 OpenGL과 D3D API를 동시에 지원하려고 한다면, 3D클리핑 처럼 힘든일은 3D API에게 맡기면서 가능한 공통의 코드를 공유할 수 있도록 하는 게 좋겠지요.

이런 경우 적당한 전략은 좌표계를 D3D에 맞추고 행렬도 D3D용을 공용으로 사용하고, 조명계산도 직접 공동으로 처리하고... 
OpenGL의 경우 Projection 변환까지는 직접 처리하고, 나머지는 OpenGL에 맡기고.. 
D3D의 경우 D3DLVERTEX를 사용해서 좌표변환 계산은 통째로 D3D에 맡기는 겁니다.
그럼 3D 클리핑도 알아서 해주겠지요...

반응형
반응형

크리에이티브 커먼즈 라이선스
Creative Commons License
럼버아저씨와 그의 동료들에 의해서 개발된 방법으로, 객체를 중심으로 기능보다는 구조에 중점을 두어
기술하는 방법이다.

객체 설계 방법으로 크게 객체모델, 동적모델, 기능적 모델로 구성된다.  

객체모델(Object model) : 정적인 구조로 시스템에서 객체간의 관계를 나타낸다. 
                                    클래스 다이어그램에 근간을 두고있다. 
동적 모델(dynamic model) : 시스템의 제어 측면을 기술하며, 객체의 행위와 이벤트를 기술해 준다. 
기능적 모델(functional model) : 함수적 의존관계를 보여주며, 객체 구조와 관계없이 입/출력 값의 
                                            흐름을 기술 해 준다. 




객체 상속 
 : 부모클래스에 연결하는 삼각형 (클래스다이어 그램과 동일)  
객체 집합관계 
 : 마름모 화살표 (클래스다이어그램과 동일)  
객체 참조 및 연관성
 : 직선(실선)으로 기술한다. 클래스의 결합은 객체 참조나 포인터로 존재하게 된다. 
   이를 표현하기 위해 직선으로 연결하며, 참조 하는쪽에 선위에 표기를 해 준다. 
   Drawing 은 Shape에 대해 알지만, Shape은 그것이 속해있는 Drawing에 대하여 모른다. 
객체 다른 객체 인스턴스 생성 
  : 점선 화살표로 기술한다. CreationTool 은 LineShape객체를 생성한다. 


또 다른  예로 팩토리 패턴을 그려 보았다. 




 클래스 다이어 그램에서 처럼 노트를 사용하여 의사코드를 설명 하기도 한다. 



 개인적으로, 클래스다이어 그램에서는 기술할 수 없었던 객체의 생성, 참조 관계에 대하여 표현 가능하며, 
 동적인 객체간의 흐름을 기술 할 수있어 OMT 기록법을 좋아하게 되었다.  


참고 자료 :
url - http://www.geocities.com/fozlul851/ooad/fozlul-lecture-12.doc
books - Design Patterns : Elements of Reusable Object-Priented Software 

반응형
반응형

http://blog.naver.com/vane77/30005554405


첨부파일 (1)

SwapChains을 이용한 다중 분할 창

 


 
 
 

swapchain을 사용할 개수 만큼 HWND인 윈도우 핸들을 선언 한다.
HWND g_hwnd = NULL;
HWND g_hwnd2 = NULL;
 
LPDIRECT3DSWAPCHAIN9 chain1 = NULL;
LPDIRECT3DSWAPCHAIN9 chain2 = NULL;
 

  
WinMain()
각각의 핸들은 CreateWindowEX 팝업창을 생성하고 등록 절차를 마친다.
g_hwnd  = CreateWindowEx( NULL,WINDOW_CLASSNAME, NULL,
                             WINDOW_STYLE2,   0,  10, 640, 480, NULL, NULL, hInstance, NULL);       
g_hwnd2 = CreateWindowEx( NULL,WINDOW_CLASSNAME, NULL,
                             WINDOW_STYLE2, 639,  10, 640, 480, NULL, NULL, hInstance, NULL);
 
ShowWindow(g_hwnd, SW_SHOW);  
UpdateWindow(g_hwnd);         
ShowWindow(g_hwnd2, SW_SHOW); 
UpdateWindow(g_hwnd2);

  
Init DirectX
DirectX객체 생성후 Device 생성 시점에 대표(?)가 되는 핸들을 이용하여 생성한다.
GetSwapChain으로 지정된 스왑체인을 CreateAdditionalSwapChain()으로 다른창 내용에
들어갈 chain2에 copy 한다.
 
Direct3D_Object->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hwnd,   
                              VertexProcessing,  &Present_Parameters, &D3D_Device)))
 
  // We create the first chain by simple calling GetSwapChain to get the default.
  // Then we call CreateAdditionalSwapChain to create the second window's chain.
  D3D_Device->GetSwapChain(0, &chain1);
  D3D_Device->CreateAdditionalSwapChain(&Present_Parameters, &chain2);
 
Render()를 호출 하기전에 각각의 분할창에 대해 스홥 체인을 바꿔가면서 렌더링을 걸어준다.  
  
  Render1()
    chain1->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer);
    D3D_Device->SetRenderTarget(0, pBackBuffer);
 
             BegineScene()
                      :
             EndScene()
 
    chain1->Present(NULL, NULL, g_hwnd, NULL, 0);
 
  Render2()
    chain2->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer);
    D3D_Device->SetRenderTarget(0, pBackBuffer);
 
             BegineScene()
                      :
             EndScene()
 
    chain2->Present(NULL, NULL, g_hwnd2, NULL, 0);
 
다중 분할창을 구현 하는 방법에 대해서 간단히 적어 보았습니다.
(참고로 제가 변경한 소스내용은 지저분합니다.)
아래 사이트 주소를 남겨 놓았으니 원본 소스를 참고하십시오.
DirectX Tutorial이 잘 되어 있습니다.
 
 
References
 
 



http://www.cyworld.com/mustx/417




 

맵툴 만들다가... 다이얼로그에 미니맵을 띄우면 좋을 것 같아서;;

 

처음에는 다이얼로그를 폼뷰로 만들어 보고, 그냥 폼뷰를 붙일 수 있을까도 생각해 봤는데...

;; 그럴 필요가 없더군요.

 

일단 스왑체인 포인터를 준비해 두고..

 

LPDIRECT3DSWAPCHAIN m_pSwapMain;

LPDIRECT3DSWAPCHAIN m_pSwapMini;

 

그런데 한가지, 같은 창 내의 것이라면 구지 스왑체인 (분할 윈도우...)을 쓰지 않아도 되는 듯 합니다. 정확히 기억 나지 않지만... 아니라면 테클 환영;;;

 

메인용 디바이스 생성 파라매터는 CDirect3D라는 클래스로 일단 초기화...

이제 스왑 채인을 생성?? 해야 겠습니다.

 

 D3DDISPLAYMODE d3ddm;

//일단 기본 정보를 CDirect3D클래스에서 뺴 돌립니다.
 if(FAILED(m_pDirect3d->m_pD3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm))) 
 {
        return false;
 }

//출력 파라메터에서 중요한 것이, 윈도우지정 부분입니다.

//첫번째 스왑 체인은 메인윈도우 디바이스에서 단순히 스왑체인을 얻어 오는 것이지만

//2번째는 생성? 개념으로 봐야 겠네요.. 그래서 출력할 다이얼로그의 윈도우 핸들 값을 넘겨 줍

//니다.
 D3DPRESENT_PARAMETERS d3dpp; 
 ZeroMemory(&d3dpp, sizeof(d3dpp));
 d3dpp.Windowed = true;
 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
 d3dpp.BackBufferFormat = d3ddm.Format;
 d3dpp.EnableAutoDepthStencil = true;
 d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
 d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
 d3dpp.hDeviceWindow = m_pDlgMini->GetSafeHwnd();

 

//그 다음으로 디바이스에서 매인 스왑체인을 얻어오고, 거기에 추가 스왑체인?? 을

//생성합니다. 이때 넘겨줄 첫번째 인자로 위에서 지정한 present parameter가 됩니다.

 m_pDirect3d->GetDevice()->GetSwapChain(0, &m_pSwap1);
 m_pDirect3d->GetDevice()->CreateAdditionalSwapChain(&d3dpp, &m_pSwap2);

 

이제 Render부분 입니다.

여기서 한가지, 메인이라고 해서 그냥 Device를 이용해서 그리기를 하려고 하면;; 안 그려 지더군요... 그래서 보통 스왑체인 포인터를 2개 선언한것도 메인용과, 그에 따른 애디션 스왑체인을 생성하기 위한 것 같습니다.

 

//첫번째로 최종 렌더된 이미지가 뿌려질 버퍼를 얻어 와야 합니다.

 LPDIRECT3DSURFACE9 pBackBuffer = NULL;       

//스왑 체인에서 해당 백 버퍼를 얻어 옵니다.
  m_pSwap1->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer );

//그리고 디바이스에서 최종적으로 뿌리게 될 타겟 버퍼를 아까 스왑 체인에서 얻어온 표면으로

//지정 합니다.
  m_pD3ddev->SetRenderTarget( 0, pBackBuffer );


  m_pD3ddev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xAAAAAAff, 1.0f, 0L);
  m_pD3ddev->BeginScene();

 // 드로우~~~!!

 m_pD3ddev->EndScene();
  

//그리기가 끝나면 최종적으로 해당 표면에 뿌리는데, 이때 일반 디바이스의 Present함수의

//인자와 틀린것이 최종적으로 뿌리게 될 윈도우를 지정 하여야 한 다는 것입니다.
  m_pSwap1->Present( NULL, NULL, m_mainWnd, NULL, 0 );

 

이제 미니맵으로 쓰이게 될 부분인데, 똑 같습니다;;;

m_pSwapMain을 m_pSwapMini로 바꿔주고, Present에서 타겟 윈도우(여기서는 다이얼로그)핸들을 지정해 주면 되는 것입니다.


 m_mainWnd = AfxGetMainWnd()->GetSafeHwnd();
 m_miniWnd = m_pDlgMini->GetSafeHwnd();

 

출처 블로그 > 별 헤는 밤 비는 내리고
원본 http://blog.naver.com/preknife/26829222

 

 




반응형
반응형

http://www.viper.pe.kr/cgi-bin/moin.cgi/MFC_%EB%A5%BC_%EC%9D%B4%EC%9A%A9%ED%95%9C_Direct3D_%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D#head-67b3c40633d83bbb112a1d972088a12b35a7fd35

 

1. 소개 [Bottom] [Top]

Direct3D 는 게임에서 주로 많이 사용되고 있으며 MFC 는 응용 프로그램 개발에 많이 사용되고 있다. 이렇게 사용 목적이 전혀 다른 두 가지를 게임 개발에 이용하는 것은 부적합하다. 하지만 게임 자체를 개발하는 것에는 부적합할지 모르나 개발에 필요한 보조 프로그램을 개발하는데는 가장 적합하지 않을까?

아직도 많은 사람들은 MFC 는 덩치가 크고 느리다고 한다. 그러나 그것은 펜티엄 100MHz 를 사용하던 과거의 이야기일뿐, 지금과 같이 거의 모든 CPU 가 GHz 를 넘어가는 경우엔 전혀 다르다. 메모리나 저장매체 또한 GByte 단위를 넘어가고 있는 현시점에서 전혀 영향을 줄 수 없는 것들이다. 그리고 WINAPI 보다 편리한 인터페이스와 프레임워크를 제공하고 있으므로 프로그래밍 속도 또한 빠르다.

MFC 를 이용한 Direct3D 프로그래밍은 게임 프로그램 보다는 보조 프로그램을 개발하는 것이 목적이다. 그리고 Direct3D 프로그래밍을 처음 시작할 때도 유용하다. 우선 Direct3D 를 구동하기 위한 프레임워크 개발이 필요 없으며 여러가지 데이터를 입력하거나 테스트할 경우에는 손쉽게 인터페이스를 만들고 수정할 수 있다. MFC 를 이용한 Direct3D 프로그래밍를 시작하게 된 이유도 편리한 인터페이스 프로그래밍 때문이다.

참고로 Microsoft Visual Studio 2005 를 기준으로 정리한다.

2. 참고도서 [Bottom] [Top]

  • IT EXPERT : 3D 게임 프로그래밍
    • 김용준 저, 한빛 미디어
    • ISBN: 8979142536

    • Direct3D 의 Framework 에 대하여 간략히 소개하고 있음 ( p.142 ~ 158 )

3. 참고링크 [Bottom] [Top]

4. MFC 프로젝트 만들기 [Bottom] [Top]

MFC 프레임워크는 다양한 형태를 제공한다. 기본적으로는 다중 문서 (MDI) 와 문서/뷰 (Doc/View) 구조가 선택되어 있지만, Direct3D 프로그래밍에서는 단일 문서 (SDI) 구조를 사용할 것이다. 그리고 문서/뷰 (Doc/View) 구조는 불필요하기 때문에 단일 뷰 구조만 사용한다. 문서/뷰 구조를 사용하고 싶다면 참고링크 에 소개된 글들을 참고한다.

4.1. 새 프로젝트 만들기 [Bottom] [Top]

  1. Visual Studio 의 새 프로젝트 마법사를 열고, 아래 그림과 같이 MFC 응용 프로그램 을 선택한 후 프로젝트 이름을 입력하고 확인을 클릭한다.

    • 예) 프로젝트 이름: MFC4Direct3D

  2. MFC 응용 프로그램 마법사 가 열리면 다음과 같이 선택한다.

    • 단일 문서 를 선택한다.

    • 문서/뷰 아키텍처 지원 은 체크하지 않는다(단일 뷰 구조).

    • 참고> 유니코드를 사용하지 않는 경우, 유니코드 라이브러리 사용 을 체크하지 않는다.

  3. MFC 응용 프로그램 마법사 의 나머지 과정은 기본값을 사용한다.

  4. 새 프로젝트 만들기 끝나면 다음과 같이 구조가 될 것이다.

4.2. 라이브러리 링크 시키기 [Bottom] [Top]

새로운 프로젝트가 만들어졌다면, Direct3D 를 사용할 수 있도록 Direct3D 라이브러리를 추가한다. 라이브러리 추가는 프로젝트 속성에서 추가하거나 컴파일 지시어를 사용한다.

  • D3D9.lib

  • D3DX9.lib
  • Winmm.lib

4.2.1. 방법1: 프로젝트 속성에서 라이브러리 추가 [Bottom] [Top]

4.2.2. 방법2: 컴파일 지시어를 사용하여 라이브러리 추가 [Bottom] [Top]

MFC 응용 프로그램 프로젝트는 미리 컴파일된 헤더 (Precompiled Header) 를 사용하므로 StdAfx.h 헤더 파일에 다음과 같이 추가하면 된다.

  • function isnumbered(obj) { return obj.childNodes.length && obj.firstChild.childNodes.length && obj.firstChild.firstChild.className == 'LineNumber'; } function nformat(num,chrs,add) { var nlen = Math.max(0,chrs-(''+num).length), res = ''; while (nlen>0) { res += ' '; nlen-- } return res+num+add; } function addnumber(did, nstart, nstep) { var c = document.getElementById(did), l = c.firstChild, n = 1; if (!isnumbered(c)) if (typeof nstart == 'undefined') nstart = 1; if (typeof nstep == 'undefined') nstep = 1; n = nstart; while (l != null) { if (l.tagName == 'SPAN') { var s = document.createElement('SPAN'); s.className = 'LineNumber' s.appendChild(document.createTextNode(nformat(n,4,' '))); n += nstep; if (l.childNodes.length) l.insertBefore(s, l.firstChild) else l.appendChild(s) } l = l.nextSibling; } return false; } function remnumber(did) { var c = document.getElementById(did), l = c.firstChild; if (isnumbered(c)) while (l != null) { if (l.tagName == 'SPAN' && l.firstChild.className == 'LineNumber') l.removeChild(l.firstChild); l = l.nextSibling; } return false; } function togglenumber(did, nstart, nstep) { var c = document.getElementById(did); if (isnumbered(c)) { remnumber(did); } else { addnumber(did,nstart,nstep); } return false; } document.write('줄 번호 보이기/숨기기<\/a>'); 줄 번호 보이기/숨기기
    #pragma comment( lib, "D3D9" )
    #pragma comment( lib, "D3DX9" )
    #pragma comment( lib, "Winmm" )
    

5. 프로그램 구조 이해하기 [Bottom] [Top]

기본적인 프로젝트 설정이 끝났다면 구현에 앞서 다음의 그림을 보면서 앞으로 만들게 프로그램에 대하여 대략적인 구조를 파악해 보자.

여러개의 추가적인 클래스와 더 많은 멤버 함수들이 있지만 여기서는 프로그램 초기화, 렌더링, 마무리 작업의 주축을 이루는 부분에 대해서만 정리하였다.

아래에서 설명하겠지만 CChildView 클래스는 C3DBase 클래스를 상속 받은 클래스로 UpdateFrame() 과 Render() 함수는 C3DBase 클래스에 정의된 가상 함수 (Virtual Function) 를 재정의 (Overriding) 한 것이다.

그럼, 프로그램 초기화, 렌더링, 마무리 작업에 대하여 시퀸스 다이어그램을 보면서 처리 과정을 이해해 보자.

5.1. 초기화 과정 [Bottom] [Top]

일반적인 MFC 응용 프로그램 초기화 과정에 3D 장치 초기화/설정 및 3D 객체 생성 과정을 추가한 것으로 CChildView::InitStartup() 함수에서 필요한 초기화 과정을 추가하면 된다.

예를 들어 카메라 및 조명을 초기화 하거나, 격자 (Grid) 객체를 생성한다.

5.2. 렌더링 과정 [Bottom] [Top]

  • 기본 렌더링 과정
    • 루프를 통한 렌더링 과정 수행

  • 화면 갱신에 의한 렌더링 과정
    • 창의 전환이나 크기 조절, 이동 시 발생하는 화면 갱신에 대하여 렌더링 과정 수행

5.3. 마무리 과정 [Bottom] [Top]

프로그램 종료 시 3D 장치 해제와 3D 객체 제거 과정을 수행한다. CChildView::FinalCleanup() 함수에서 필요한 마무리 과정을 추가하면 된다.

예를 들어 CChildView::InitStartup() 함수에서 생성된 객체를 제거한다.

6. Direct3D 에 맞게 MFC 프로그래밍하기 [Bottom] [Top]

먼저, 앞서 그림에서 CMFC4Direct3DAppCMainFrameCChildView 그리고 C3DBase 로 4개의 주요 클래스를 볼 수 있다. 이 중에서 CMFC4Direct3DApp 클래스는 프로젝트에 따라 다른 이름으로 생성될 수도 있으며, 각 클래스는 개조하는 과정에서 자세히 설명할 것이다.

6.1. C3DBase 클래스 만들기 [Bottom] [Top]

C3DBase 클래스는 CChildView 클래스가 상속하게 될 Base 클래스로 주요 기능은 다음과 같다.

  • Direct3D 인터페이스와 장치를 얻어서 Direct3D 를 사용할 수 있도록 초기화 한다.
  • Direct3D 인터페이스와 장치를 해제하여 Direct3D 를 종료한다.
  • 3D 렌더링 과정을 수행한다.

6.1.1. 멤버 함수 [Bottom] [Top]

  • document.write('줄 번호 보이기/숨기기<\/a>'); 줄 번호 보이기/숨기기
    HRESULT CreateDirect3D( HWND hWnd, UINT nPresentationInterval );
    void    ReleaseDirect3D();
    void    ResetDirect3D( int nWidth, int nHeight );
    void    RenderDirect3D();
    
    virtual void    UpdateFrame() = 0;
    virtual void    Render() = 0;
    
    void    Pause( BOOL bPause=TRUE );
    
  • CreateDirect3D() 함수
    • Direct3D 장치를 생성한다.

  • ReleaseDirect3D() 함수
    • Direct3D 장치를 해제한다.

  • ResetDirect3D() 함수
    • 화면 (View) 의 크기가 바뀔때 Direct3D 장치를 재설정한다.

  • RenderDirect3D() 함수
    • 렌더링 과정을 수행한다. 내부에서 UpdateFrame() 과 Render() 함수를 호출한다.

  • UpdateFrame() 함수 (가상 함수)

    • 상속 받은 클래스에서 재정의 해야하며 프레임 갱신 처리를 한다.

  • Render() 함수 (가상 함수)

    • 상속 받은 클래스에서 재정의 해야하며 렌더링 처리를 한다.

  • Pause() 함수
    • 다른 창으로 포커스가 이동 시 CPU 점유율을 떨어뜨리기 위해서 사용한다.

6.2. CChildView 클래스 개조하기 [Bottom] [Top]

CChildView 클래스는 C3DBase 클래스를 상속받은 클래스로 실제 3D 렌더링을 수행한다. 또한 Direct3D 의 초기화 및 해제가 실제로 처리되는 곳이다. 즉, 3D 렌더링의 핵심 클래스가 된다.

  • PreCreateWindow() 함수 수정

    • 아래의 코드 중 AfxRegisterWndClass() 함수의 3번째 매개변수 값을 NULL 로 설정한다.

    document.write('줄 번호 보이기/숨기기<\/a>'); 줄 번호 보이기/숨기기
       1 BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs)
       2 {
       3         if (!CWnd::PreCreateWindow(cs))
       4                 return FALSE;
       5 
       6         cs.dwExStyle |= WS_EX_CLIENTEDGE;
       7         cs.style &= ~WS_BORDER;
       8         cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS,
       9                 ::LoadCursor(NULL, IDC_ARROW), NULL, NULL);
      10 
      11         return TRUE;
      12 }
    
    • 참고> AfxRegisterWndClass() 함수의 3번째 매개변수는 Background Brush 를 설정하는 곳으로 NULL 로 설정하게 되면 프레임마다 화면이 지워지지 않는다. 즉, 화면이 깜박거리는 현상 (Flicker 현상) 을 방지한다.

  • OnPaint() 함수 수정

    • 위에서 설명했듯이 창 변화에 따른 화면 갱신 과정으로 렌더링 과정을 수행한다.
    • WM_PAINT 메세지 핸들러.
    document.write('줄 번호 보이기/숨기기<\/a>'); 줄 번호 보이기/숨기기
       1 void CChildView::OnPaint()
       2 {
       3         CPaintDC dc(this);      // 삭제하면 안됨.
       4 
       5         if( IS_NOT_NULL( g_pD3DDevice ) )
       6         {
       7                 // 렌더링 수행
       8                 RenderDirect3D();
       9         }
      10 }
    
    • 참고> CPaintDC dc(this); 코드는 삭제하지 말것. 삭제하게 되면 화면 갱신 시 창의 프레임 갱신이 느려지게 된다.

  • InitStartup() 함수 추가

    • 초기화 과정에 필요한 작업을 여기에 추가한다.

    document.write('줄 번호 보이기/숨기기<\/a>'); 줄 번호 보이기/숨기기
       1 HRESULT CChildView::InitStartup()
       2 {
       3         //----------------------------------------------------------------------
       4         // TODO: 초기화 처리를 수행한다.
       5         //      * 배경색 설정
       6         //      * 카메라 설정
       7         //      * 조명 설정
       8         //      * 렌더링 객체 생성 등
       9         //
      10 
      11         // 배경색 설정
      12         SetBackColor( 0x40, 0x40, 0x40 );
      13 
      14         // 카메라 설정
      15         m_pCamera = new CCamera();
      16         InitCamera();
      17 
      18         // 조명 설정
      19         InitLight();
      20         LightEnable( FALSE );           // 조명 비활성화
      21 
      22         // 격자 생성
      23         m_grid.Create( 20, 4, 20 );
      24 
      25         return S_OK;
      26 }
    
  • FinalCleanup() 추가

    • 초기화 과정이나 실행 과정에서 생성된 3D 객체를 여기서 제거한다.

    document.write('줄 번호 보이기/숨기기<\/a>'); 줄 번호 보이기/숨기기
       1 void CChildView::FinalCleanup()
       2 {
       3         //----------------------------------------------------------------------
       4         // TODO: 마무리 처리를 수행한다.
       5         //      * 초기화 또는 수행 중 생성된 3D 객체 해제 등
       6 
       7         // 격자 제거
       8         m_grid.Release();
       9 
      10         // 카메라 제거
      11         SAFE_DELETE( m_pCamera );
      12 
      13         // Direct 3D 해제
      14         ReleaseDirect3D();
      15 }
    
  • UpdateFrame() 함수 재정의 (C3DBase 가상 함수)

    • 실제 프레임 갱신 작업을 여기에 추가한다.

    document.write('줄 번호 보이기/숨기기<\/a>'); 줄 번호 보이기/숨기기
       1 void CChildView::UpdateFrame()
       2 {
       3         if( IS_NOT_NULL( m_pCamera ) )
       4         {
       5                 // 카메라 설정
       6                 m_pCamera->SetCamera();
       7         }
       8 
       9         //--------------------------------------------------------------------------
      10         // TODO: 프레임 갱신 처리를 수행한다.
      11         //
      12 }
    
  • Render() 함수 재정의 (C3DBase 가상 함수)
    • 실제 렌더링 작업을 여기에 추가한다.

    document.write('줄 번호 보이기/숨기기<\/a>'); 줄 번호 보이기/숨기기
       1 void CChildView::Render()
       2 {
       3         // 격자 렌더링
       4         m_grid.Render();
       5 
       6         //--------------------------------------------------------------------------
       7         // TODO: 3D 오브젝트를 렌더링한다.
       8         //
       9 }
    
  • WM_SIZE 메세지 핸들러 추가
    • 창의 크기가 바뀔 때 Direct3D 장치를 재설정한다.
    • 이 과정이 생략되면 창의 크기가 바뀔 시 3D 화면이 찌그러지거나 도트가 뭉게지는 현상이 발생한다.
    document.write('줄 번호 보이기/숨기기<\/a>'); 줄 번호 보이기/숨기기
       1 void CChildView::OnSize(UINT nType, int cx, int cy)
       2 {
       3         __super::OnSize(nType, cx, cy);
       4 
       5         if( IS_NOT_NULL( g_pD3DDevice ) )
       6         {
       7                 // Direct3D 재설정
       8                 ResetDirect3D( cx, cy );
       9 
      10                 // 조명 설정
      11                 InitLight();
      12                 LightEnable( FALSE );           // 조명 비활성화
      13         }
      14 }
    

6.3. CMainFrame 클래스 개조하기 [Bottom] [Top]

CMainFrame 클래스는 MFC 프레임워크에서 창의 기본 골격을 이루는 클래스로 창을 열거나 닫기, 메뉴, 툴바, 상태바 등을 관리하며 주로 사용자와의 인터페이스 처리를 담당하게 된다. 따라서 3D 렌더링에는 별로 중요하지 않다.

  • InitDirect3D() 함수 추가
    • 프로그램 시작 시 3D 초기화 과정을 수행한다.
    document.write('줄 번호 보이기/숨기기<\/a>'); 줄 번호 보이기/숨기기
       1 HRESULT CMainFrame::InitDirect3D()
       2 {
       3         // View 영역 크기 설정
       4         SetSize( 800, 600 );
       5 
       6         // Direct 3D 초기화
       7         m_wndView.CreateDirect3D( m_wndView.m_hWnd, D3DPRESENT_INTERVAL_IMMEDIATE );
       8 
       9         // 사용자 초기화 수행
      10         m_wndView.InitStartup();
      11 
      12         return S_OK;
      13 }
    
  • SetSize() 함수 추가

    • 프로그램 시작 시 3D 화면의 크기를 설정하는 곳으로 3D 화면에 맞게 창의 프레임 크기를 재계산하고 창 크기를 변경한다.
    • 매개변수는 실제 3D 화면의 크기를 설정한다.
    document.write('줄 번호 보이기/숨기기<\/a>'); 줄 번호 보이기/숨기기
       1 void CMainFrame::SetSize( int nWidth, int nHeight )
       2 {
       3         RECT client, frame;
       4 
       5         GetWindowRect( &frame );
       6         m_wndView.GetClientRect( &client );
       7 
       8         // View 영역 크기에 맞게 창크기 변경
       9         frame.right  = nWidth  + frame.right  - client.right;
      10         frame.bottom = nHeight + frame.bottom - client.bottom;
      11 
      12         MoveWindow( &frame );
      13 }
    
  • DestroyWindow() 함수 재정의 (CWnd 가상 함수)

    • 프로그램 종료 과정의 시작점으로 마무리 과정을 수행한다.
    document.write('줄 번호 보이기/숨기기<\/a>'); 줄 번호 보이기/숨기기
       1 BOOL CMainFrame::DestroyWindow()
       2 {
       3         // 마무리 작업
       4         m_wndView.FinalCleanup();
       5 
       6         return CFrameWnd::DestroyWindow();
       7 }
    
  • WM_ACTIVATE 메세지 핸들러 추가
    • 창의 포커스 이동 유무에 따라 3D 렌더링 속도를 조절한다. 즉, CPU 점유율을 조절한다.
    document.write('줄 번호 보이기/숨기기<\/a>'); 줄 번호 보이기/숨기기
       1 void CMainFrame::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
       2 {
       3         CFrameWnd::OnActivate(nState, pWndOther, bMinimized);
       4 
       5         m_wndView.Pause( nState == WA_INACTIVE );
       6 }
    

6.4. CMFC4Direct3DApp 클래스 개조하기 [Bottom] [Top]

CMFC4Direct3DApp 클래스는 가장 먼저 실행되므로 실행 순서상으로 본다면 최상위에 위치한다고 볼 수 있다. 주요 기능은 다른 객체들을 생성하고 실행시키는 역활을 한다. 그리고 가장 중요한 기능은 CChildView 클래스에게 3D 렌더링하도록 RenderDirect3D() 함수를 호출한다.

  • InitInstance() 함수 수정

    • 프로그램 초기화 과정으로 MFC 응용 프로그램 마법사 에서 생성된 코드에 3D 초기화 과정만 추가한다.

    document.write('줄 번호 보이기/숨기기<\/a>'); 줄 번호 보이기/숨기기
       1 BOOL CMFC4Direct3DApp::InitInstance()
       2 {
       3         ...     // 생략
       4 
       5         // 창 하나만 초기화되었으므로 이를 표시하고 업데이트합니다.
       6         pFrame->ShowWindow(SW_SHOW);
       7         pFrame->UpdateWindow();
       8         // 접미사가 있을 경우에만 DragAcceptFiles를 호출합니다.
       9         // SDI 응용 프로그램에서는 ProcessShellCommand 후에 이러한 호출이 발생해야 합니다.
      10 
      11         // 초기화 수행
      12         pFrame->InitDirect3D();
      13 
      14         return TRUE;
      15 }
    
  • OnIdle() 함수 재정의 (CWinApp 가상 함수)

    • 반복 루프로 CChildView::RenderDirect3D() 함수를 호출한다.

    document.write('줄 번호 보이기/숨기기<\/a>'); 줄 번호 보이기/숨기기
       1 BOOL CMFC4Direct3DApp::OnIdle(LONG lCount)
       2 {
       3         CWinApp::OnIdle(lCount);
       4 
       5         // 렌더링 수행
       6         static_cast< CMainFrame * >( m_pMainWnd )->m_wndView.RenderDirect3D();
       7 
       8         return TRUE;
       9 }
    

7. 다운로드 (준비중) [Bottom] [Top]

  • 다운로드: /!\ 코드는 준비중 - <!> 준비되면 업로드 예정


MFC

 

반응형
반응형

http://blog.naver.com/humanist23/90027831935




오버클럭은 말 그대로 CPU나 램 등 반도체의 작동 속도를 강제로 빠르게 하는 것으로 돈을 들이지 않고 성능 높이는 하나의 방법이다.

그래픽카드는 PC게임이 3D그래픽(영화, 기타등등)으로 나오는 요즘. PC전체의 성능을 좌우하는 중요한 부품이 그래픽카드 이다.

 

그래픽카드 오버클럭 방법은 두가지가 있으며, 다음과 같다.

1.GPU(그래픽 프로세서)클럭의 오버클럭

2.메모리 클럭의 오버클럭

 

이 두 부품의 클럭이 그래픽카드의 성능을 대변하므로 이를 높여 성능을 향상시킬 수 있다.

출시되는 대부분의 그래픽카드는 GPU와 메모리 클럭이 다르다.

 

메모리는 대부분 DDR SD램을 사용하고 있어 실제 표시 클럭의 2배로 작동한다.

이건 그래픽카드 구조상 GPU보다는 메모리쪽에 더 많은 부하가 걸리기 때문이다.

오버클럭 효과를 높이기 위해서는 GPU보다는 메모리클럭을 올리는 것이 더 확실하다.

 

그래픽카드 오버클럭이 가능한 것은 프로세서와 마찬가지로 GPU와 메모리에 마진율이 적용되기 때문이다.

반도체를 설계할 때는 목표동작 주파수(클럭)를 정하고 설계한다.

그러나 실제 제조 공정을 거쳐 실리콘 웨어퍼 상에 칩을 만들면 정확히 목표한 클럭대로 칩이 만들어지는 것은 아니다.

따라서 그래픽카드 제조사에서는 이 칩을 테스트해 일정한 마진을 두고 안정적으로 동작하는 클럭으로 마킹해 출시한다.

이 과정에서 발생하는 마진으로 인해 오버클럭이 가능한 것이다.

 

여기서 설명하는 엔디비아 그래픽카드의 오버클럭 방법은 엔디비아에서 제공하는 nTune 라는 유틸리티를 사용하는 것으로, ForceWare 1xx.xx 대 버전의  그래픽카드 드라이버에서 할 수 있는 방법이다.

 

참고로 nTune 는 엔디비아 메인보드용 유틸리티로서 엔디비아 메인보드를 사용하고 있다면, 시스템에 대한 좀더 폭넓은 정보(메인보드 온도 등등) 및 CPU 오버클럭 그리고 안정성 검사 등을 할수 있는 유틸리티이다.

 

 

아래 링크를 클릭하여 nTune 를 다운받는다.

  2007년 9월 19일 NVIDIA 홈페이지에 업데이트된 NVIDIA nTune v5.05.54.00 정식 버전

  WinXP/WinXP 64Bit/WinVista/WinVista 64Bit OS용

  다운로드   (파일서버가 미국에 있는것이라 다운받는데 시간이 좀 걸린다.)

 

 

프로그램을 설치하고 바탕화면 -> 마우스 오른클릭 -> NVIDIA 제어판 선택

혹은 시작 -> 제어판 ->  NVIDIA 제어판 

 

 

유틸리티가 정상적으로 설치 되었다면 아래의 이미지와 같이 성능 이라는 탭이 생성된다.

 

 

왼쪽창에서 "최종 사용자 라이센스 계약 동의"를 선택하고 오른쪽 창의 "동의" 버튼을 클릭한다.

 

 

성능 탭아래 안보이던 메뉴가 몇개 추가된 것을 확인할 수 있으며, GPU 설정 조정 메뉴를 선택한다.

엔디비아 메인보드를 사용하고 있다면, GPU 설정 조정 아래 나열되어 있는 메뉴에서 시스템 정보를 얻거나 시스템 설정, 시스템 안정성 테스트 등을 할 수 있다.

오른쪽 창의 GPU 클럭 설정 에서 오버클럭을 할 수 있으며, 그 아래 GPU 팬 설정이 보인다. 

아쉽게도 필자의 그래픽카드에는 GPU 팬 컨트롤러가 없는 제품이다. 따라서 GPU 팬 설정 항목이 활성화 되지 않는다.

(GPU팬 전원이 2핀이라면 GPU 팬 컨트롤러가 없다고 보면 된다.)

 

 

 

오른쪽 창에서 사용자 정의 클럭 주파수 선택

 

 

마우스로 Core클럭바와 Memory클럭바를 오른쪽으로 이동시켜 오버클럭을 설정하며, 정밀조정은 키보드의 왼쪽 혹은 오른쪽 방향키 를 사용한다.

(참고. 안정적인 오버클럭율은 기본클럭의 10% ~ 20% 이며, 과도한 오버클럭은 오히려 시스템성능을 저하 시키기도 한다.)

 

 

오버클럭값을 정했다면, 테스트 버튼 클릭


 

 

테스트가 끝날때 까지 기다리자.

 

 

테스트를 통과 했다면 다음과 같은 메시지 창을 볼수가 있다.

확인 하고 시스템에 적용 시키자.

 

 

 

오버클럭후 평소에 자주하던 3D 게임을 최소 3~5번 정도 실행해 보고 이상이 없어야 한다.

 

 




반응형

'그래픽스(Graphics) > Shader' 카테고리의 다른 글

[소스] 해칭(Hatching) HLSL 소스  (0) 2013.01.05
VS에서 HLSL 편집하기 InteliShade  (0) 2013.01.05
쉐이더 기법  (0) 2012.11.02
셰이더 내장함수  (0) 2012.11.02
smoothstep  (0) 2012.11.02
반응형

블렌더, 무료라네

http://cafe.naver.com/blender3d/

오랫동안 여러가지 3D 소프트웨어의 기능을 학습하고 사용해온 카페지기의 경험에 비추어볼 때 블렌더(www.blender.org)의 기능은 참으로 놀라웠습니다. 간단히 정리하자면 블렌더는 3D 애니메이션을 만들기에 완전한 All-IN-ONE 패키지입니다. 모델링과 쉐이딩, 애니메이션, 다이나믹스, 렌더링은 물론이고 정교한 컴포지팅까지 포함하고 있으며 간단한 사운드 작업까지 가능합니다. 이런 패키지가 용량이 15M라는 것이 놀라우며 거기에 무료라는 것이 더욱 놀랍습니다. 2000년 말에 전 세계적으로 공식 홈페이지에 등록한 사용자가 25만명이 넘었으니 대단한 반응이라고 할 수 있습니다(등록하지 않고도 얼마든지 합법적으로 사용할 수 있고 그런 사용자가 얼마인지는 추산되지 않는다). 이러한 장점에도 불구하고 카페지기에게 가장 큰 매력으로 다가온 것은 다른데 있습니다. 그것은 블렌더에 매우 훌륭한 게임엔진이 탑재되있다는 것입니다. 블렌더의 게임엔진은 노드 기반으로 이루어져 있어서 아티스트들 조차도 쉽게 학습하여 3D 게임을 제작할 수 있게 되어 있으며 물리엔진까지 포함하고 있습니다. 그리고 파이썬 스크립트를 지원하여 얼마든지 기능을 확장할 수 있습니다. 이 모든 것이 무료이니 얼마나 놀랍습니까!

블렌더는 매우 다양한 포맷의 데이터를 입출력할 수 있습니다. 썬-마이크로 시스템즈는 2008년에 인터넷을 활용하는 자사의 네트워킹 기술과 블렌더를 활용하여 Big Buck Bunny라는 HD 버전의 애니메이션을 발표한 바 있습니다. 이 프로젝트는 PC만 가지고 있으면 이제 소프트웨어 비용에 대한 걱정없이 극장용 포맷의 3D 애니메이션을 제작할 수 있음을 증명하였습니다.

이런 자유소프트웨어에 대한 가장 잦은 질문 중에 하나는 "이런 프로그램을 이용하여 만든 애니메이션이나 게임을 돈을 주고 팔거나 저작권을 내 것으로 주장하는데 어떤 제약이 있느냐?"는 것입니다. 답은 "전혀! 전혀! 없다."입니다. 이 질문을 벗어난 한 가지 제약이 있다면 블렌더라는 프로그램 자체를 개선하여 돈을 주고 팔려고 공개했을 때 다른 사람이 프로그램 소스를 보고 싶다고 말할 경우 그 사람에게 공개해야 한다는 것입니다. 그러나 이 글을 읽는 독자 중에 블렌더를 굳이 개선하여 팔려고 마음 먹는 분은 거의 없을 것입니다. 왜냐하면 블렌더는 매년 수 차례에 걸쳐 공식 협회를 통해 가장 훌륭하게 업그레이드 되고 있기 때문입니다.^^ 우리의 관심사는 만들어진 컨텐츠의 소유권입니다. 그것은 100% 만든 사람의 것입니다.

자유소프트웨어의 소유권에 대해 법적으로 정확한 내용을 알고 싶다면 http://www.gnu.org/licenses/gpl-faq.ko.html의 "[영어]"부분을 참고하기 바랍니다. 결론으로 필자는 소프트웨어 비용의 부담없이 애니메이션과 게임을 만들고 싶은 개인이나 기업이 있다면 블렌더를 적극 추천합니다. 또한 애니메이션과 게임을 만드는 커리큘럼을 개설하고자 하나 소프트웨어 구매비용 때문에 부담을 느끼는 교육기관이나 대학이 있다면 블렌더를 사용하라고 적극 추천하고 싶습니다. 해피 블렌딩~^^

<카페지기 소개>

1993년부터 3D Graphic분야에서 일해오고 있다. 그동안 애니메이션, 영화특수효과, 드라마 특수효과, 건축 CG, 시뮬레이션 영상, 입체영상 등 다양한 분야의 경험을 쌓았으며 세 권의 Maya 학습서를 집필하였다. 더불어 2000년부터 교육분야에서 학생들을 가르치는 일을 겸해오고 있다. 2004년부터 3D게임의 Rendering분야 프로그래밍에 관심을 가지고 연구해오고 있으며 Z-Brush2.0 버전부터 많은 학습을 하였고 Z-Brush3.0 런칭 세미나에서 신기술 분야 강사로 초청되었다. 최근에는 오픈소스 진영의 자유소프트웨어 활용에 많은 노력을 기울이고 있다. E-mail : blender3d.co.kr@gmail.com

반응형
반응형

the direct3d device has a non-zero reference count meaning some objects were not released

이 에러는 DXUT를 이용한 Application을 종료할때 나오는 Error Message 이다.

정확한 뜻은 D3D객체가 모두 릴리즈되지 않았다 이다. 

그래서 OnD3D9DestroyDevice()에서 릴리즈 시켜준다면 에러가 없어질 것이다.


만약 모든 객체가 릴리즈 된 상태에서도 이 Error가 난다면 레퍼런스 카운터를 증가하지 않아서 생긴 문제이다.

AddRef()를 추가해서 한번 호출해주고 가져다 쓴 부분은 Release() 해준다.

몇가지의 함수들의 경우 호출시 자동으로 AddRef()를 호출해서 카운트가 증가하는 함수가 있지만

반응형

'그래픽스(Graphics) > DirectX9~12' 카테고리의 다른 글

정점 압축[Vertex Component Packing 처리]  (0) 2012.11.02
MFC & Directx 에서 스왑체인 멀티뷰구현  (0) 2012.11.01
MFC와 Directx 연동  (0) 2012.11.01
블렌더 무료  (0) 2012.10.31
Directx 11 설명  (0) 2012.10.31
반응형

첨부파일 :  DX11.pptx

반응형
반응형

2008 opengl 설치후

그리고 헤더파일부분에 #include <gl.h> 이렇게 해줘야 합니다

http://robotstory.tistory.com/184

반응형
반응형

[CUDA 포함파일 환경설정]


CUDA 4.1 visual studio 2010 설정 (윈도우 7)  Parallel 

2012/02/28 19:18

복사http://blog.naver.com/sks12345/20152136920


2시간 삽질하면서 찾은 cuda 4.1 설정 방법입니다. 

 

간단하게 설정 할 수 있는데 역시 모르니 완전 헤멥니다. 아는게 힘이라능

 

다운 받는건 http://blog.naver.com/toses3/40140926000 요기로 가셔서 보시고...

 

4.0버전으로 설명되어있는데, bug fix는 현재 사라졌으니 무시하시고

 

1. CUDA Tool kit 4.1

2. GPU Computing SDK

3. 개발자용 그래픽 드라이버

 

이렇게 3개가 필요합니다.

 

각각 설치하시고 난뒤

 

 visual studio 2010을 실행시키고 프로젝트를 하나 만듭니다. 이 과정도 위 링크에 다 있습니다.

 

프로젝트 속성에서 라이브러리 폴더와 include 폴더, 라이브러리를 추가해주어야 합니다.

 

아래 그림과 같이 VC++ 디렉터리에서 설정하시면 됩니다.

 

 





 

포함 디렉터리는 헤더파일용입니다. 그자리에 다음과 같이 넣으시면 됩니다.

 

C:\ProgramData\NVIDIA Corporation\NVIDIA GPU Computing SDK 4.1\C\common\inc

C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v4.1\include

 

SDK의 include 폴더와 GPU Tool kit의 include 폴더 이렇게 2개가 한 쌍으로 있어야합니다. 하나라도 빠지면 링크 에러 납니당..;;

 

라이브러리 디렉터리에는 다음과 같이 넣습니다.

 

C:\ProgramData\NVIDIA Corporation\NVIDIA GPU Computing SDK 4.1\C\common\lib\Win32

C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v4.1\lib\Win32

 

저는 32비트로 설치했으므로 위와 같이 하였고, 64비트로 설치하신분은 끝에 Win32를 x64로 하시면 될겁니다.

 

그리고 *.cu로 생성한 파일의 속성에서 cuda 컴파일러를 설정해줍니다.

 

 

파일의 속성입니다. 프로젝트 속성이 아닙니다. 헷갈리지 마시구요. 처음에는 빌드에 참여안함 이라고 되어있는데 그것을 위의 그림처럼 설정 해줍니다.

 

이제 설정이 다되었구요. CUDA의 세계로 빠지시면 됩니다.

 

반응형
반응형

http://gpuray.blogspot.com/2009/06/cudathreadsynchronize.html

THURSDAY, JUNE 25, 2009

cudaThreadSynchronize

This function is important for anyone who is launching a kernel many times (example: from a for loop). This is because a CUDA kernel launch is asynchronous, and returns immediately. This means that your CPU side for loop will finish in an instant and try to launch everything at once.

Calling cudaThreadSynchronize() will make the CPU wait till all previously launched kernels terminate.
대강 정리하면.. CPU가 GPU 의 커널이 모두 처리 될때까지 CPU 를 기다리게 한다는것 => CPU 와 GPU 같의 동기화를 수행한다



이하원문


Rays of hope

This Blog
Linked From Here
This Blog
Linked From Here

Thursday, June 25, 2009

cudaThreadSynchronize

This function is important for anyone who is launching a kernel many times (example: from a for loop). This is because a CUDA kernel launch is asynchronous, and returns immediately. This means that your CPU side for loop will finish in an instant and try to launch everything at once.

Calling cudaThreadSynchronize() will make the CPU wait till all previously launched kernels terminate.

No comments:

Post a Comment

반응형
반응형

http://fineav.tistory.com/232


PCI 버스(Peripheral Component Interconnect Bus)
컴퓨터 메인보드에 주변 장치를 장착하는 데 쓰이는 컴퓨터 버스의 일종이다.
오늘날 개인용 컴퓨터에서 가장 많이 볼 수 있는 버스이다.
표준적인 확장 버스 역할 분야에서는 한때 쓰였던 ISA 버스, VESA 로컬 버스 등을 PCI 버스가 대체해 버렸다.
PCI는 1990년 즈음에 인텔의 아키텍처 개발 연구소에서 비롯하였다.
2004년에 PCI 익스프레스로 대체되기 시작했다.

▲ 32비트 PCI 버스

PCI 익스프레스(PCI Express)
2002년 PCI SIG가 책정한 입출력을 위한 직렬 구조의 인터페이스이며 인텔 주도하에 만들어졌다.
서적이나 문서에서는 PCIe로 표기하는 경우도 많다. 이 표기는 PCI SIG 웹 사이트에서도 쓰이고 있다.
PCI-X와는 다른 규격이며 오랫동안 3D 그래픽 카드를 군림했던 AGP를 대체한다.

2004년부터 본격적으로 쓰이기 시작했으며, 1초에 8기가바이트 정도의 데이터를 전송할 수 있다.
이에 대한 규격으로 PCI 익스프레스 2.0과 PCI 익스프레스 3.0으로 잘 알려져 있다.

PCI Express 2.0
2007년 1월에 PCI-SIG가 책정한, 컴퓨터용의 시리얼 전송 인터페이스. PCI 대신에 보급된 PCI Express 1.1의 차기 버젼.

최소구성 전송로('레인'으로 불림)는 PCI Experss 1.1로는 한방향2.5Gbps(양방향 5.0Gbps)였던 것이, 단방향 5.0Gbps, 양방향10Gbps로 확장되었다. PCI Express 1.1와 마찬가지로 8비트 데이터를 보내는 클럭의 신호등에 2비트를 추가한 10비트를 쓰기 때문에, 실제 데이터 속도는 단방향 4Gbps(500MB/s), 양방향 8Gbps(1GB/s)가 된다. 10랜을 이용한 경우의 전송속도는 16GB/s가 된다.

PCI Express 2.0은 PCI Express 1.1의 상위호환이 되어 있어 PCI Express 1.1용의 기기를 그대로 접속시킬 수 있다. 또한 소프트웨어로부터 동적으로 전송속도를 변경할 수가 있어, 최고속도가 필요하지 않은 경우에는 소비전력을 절약할 수 있다. 기존의 확장슬롯에 카드를 꼽는 접속방법뿐만 아니라, 10m까지의 길이의 메탈 케이블로 기기간을 접속시킬 수 있는 'PCI Experss Cable'이라는 사양도 정해져 있다.

아래글 출처 : 보드나라 Q&A 게시판
PCI Express 1.1의 전송속도는 Lane당 250MB/s 입니다. (31Mhz x 8Bit = 250MB/s)
따라서 16Lane을 사용하는 PCI Express 1.1 16x는 250MB/s x 16 = 4GB/s 의 전송속도가 나지요.
AGP 8X와 비교해보면, 33Mhz x 8Bit x 8배속 = 2.1GB/s 였습니다.
PCI Express 2.0은 PCI Express 1.1에 비해 2배의 전송속도가 나는 인터페이스 규격으로, Lane당 500MB/s를 갖습니다.
따라서 PCI Express 2.0 16x의 경우, 8GB/s의 전송속도를 갖습니다.
이론적으로 인터페이스가 작동하려면 수신/송신측 모두 동일한 인터페이스를 가지고있어야 합니다. 즉, PCI Express 2.0이 작동하려면 메인보드와 그래픽카드 모두가 PCI-Express 2.0을 지원해야 하며, 둘중에 하나라도 1.1 규격을 지원한다면, PCI-Express 1.1로 작동합니다.
현재 PCI-Express 2.0 을 채택한 그래픽카드가 많이 나오고있지요. 실제 장착하여보면 1.1 메인보드에 장착해도 큰 성능차이가 나지 않습니다. 즉, 역으로 2.0의 대역폭을 다 사용하지 못하고 있다고 보면 됩니다.



PCI 32Q비트 66MHz 266MB/s

PCI ExpressX1 2.5GHz 512MB/s

PCI ExpressX4 2.5GHz 2GB/s (Duplex)

PCI ExpressX8 2.5GHz 4GB/s (Duplex)

PCI ExpressX16 2.5GHz 8GB/s (Duplex)





관련 게시물
PCIe 2.0의 최대속도를 뽑아 내려면 P67을 쓸것

반응형
반응형

http://forums.nvidia.com/index.php?showtopic=198586

EDIT : Okay, on VS2010 :

Quote

Project->Properties->Configuration Properties->CUDA C/C++->Device
Then under "Code Generation"
Change "compute_10,sm_10" to "compute_20,sm_20".
And don't put "compute_20,sm_20;%CodeGeneration;" as I did !

반응형
반응형



쿠다 변수 특성 

http://blog.naver.com/lithium81/80145123334 

 

이 포스트는 "CUDA By Example", "대규모 병렬 프로세서 프로그래밍", "CUDA 병렬 프로그래밍"을 스터디하면서 익힌 내용을 까먹지 않게 정리한 것임.

※ 로그인 안 하고도 내가 언제든지 볼 수 있도록 공개한 것일 뿐, 맘대로 퍼가고 수정하라고 만든 자료 아님. 불펌 금지








CUDA 병렬프로그래밍에 대한 이해...  Cuda / 개발 및 연구 

2012/01/27 15:02

복사http://blog.naver.com/rmagus101/90134660153

전용뷰어

//---------------------------------------------------

아~ for문으로 10번 돌것을 하나의 block 이 하나의 배열을

맡아서 계산해서 넘겨주는 거구나

즉 커널을 통해 "나(CPU) 10번 돌거 GPU 니내 10명이서 나눠서

한개씩 맡고 나에게 주렴" 이라는 거구나... 어렵다...

//--------------------------------------------------

#include <stdio.h>
#include <malloc.h>
#include <cuda_runtime.h>
#include <cutil.h>

#define blksize  8
#define grdsize  8
#define N   10

__global__ void test(int *a, int *b, int *c)
{
 int tid = blockIdx.x;

 c[tid] = a[tid] + b[tid];
}

int main()
{
 //cudaSetDevice (int device );
 //property출력을 위한 구조체 생성
 cudaDeviceProp prop;
 
 //디바이스 장치의 숫자를 획득
 int count;
 cudaGetDeviceCount(&count);
 
 //각 디바이스 장치의 property들을 출력
 for(int i=0;i<count;i++){
  cudaGetDeviceProperties(&prop,i);
  
  printf("--%d번째 디바이스의 정보를 출력합니다--\n",i+1);
  printf("  (1) 장치 이름: %s\n", prop.name);
  printf("  (2) Clock Rate: %d\n", prop.clockRate);
  printf("  (3) 전역 메모리 용량: %ld\n",prop.totalGlobalMem); 
  printf("  (4) 상수 메모리 용량: %ld\n",prop.totalConstMem);
  printf("  (5) 통합형인가??: %ld\n",prop.integrated);
 }

 int a[N], b[N], c[N];
 int *dev_a, *dev_b, *dev_c;

 cudaMalloc( (void**) &dev_a, sizeof(int) * N);
 cudaMalloc( (void**) &dev_b, sizeof(int) * N);
 cudaMalloc( (void**) &dev_c, sizeof(int) * N);

 for(int i=0; i<N; i++) {
  a[i] = i;
  b[i] = i;
 }

 cudaMemcpy( dev_a, a, sizeof(int) * N, cudaMemcpyHostToDevice );
 cudaMemcpy( dev_b, b, sizeof(int) * N, cudaMemcpyHostToDevice );

 test<<<N, 1>>>(dev_a, dev_b, dev_c);

 cudaMemcpy( c, dev_c, sizeof(int) * N, cudaMemcpyDeviceToHost );

 for(int i=0; i<N; i++) {
  printf("%d + %d = %d\n", a[i], b[i], c[i]);
 }

 cudaFree(dev_a);
 cudaFree(dev_b);
 cudaFree(dev_c);

 return 0;
}




반응형
반응형

http://goparallel.egloos.com/1969596

CUDA Event로 시간측정 CUDA 프로그래밍 Tips

이번은 호스트 프로그램으로 Kernel나 CUDA API의 실행 시간을 측정하는 방법에 대해 설명합니다. Kernel 내부에서의 시간측정에 관해서는 CUDA 프로그램의 시간을 측정하는 - clock()을 참고하세요.

시간측정의 주의점!

CUDA API는 그 실행 문맥 중에서 제일 처음에 불린 API는 매우 시간이 걸리는 특징이 있습니다.이것은 CUDA의 초기화 작업을 하고 있기 때문입니다. 그러므로, cudaSetDevice등의 다른 초기화 함수를 부르는지와 최초의 API는 시간에 필요한 시간을 잘 살펴봐야 합니다.

시간측정을 통일합니다.

CUDA로 프로그램을 구현하여 프로그램의 성능을 측정할 필요가 있을 때 시간을 측정하는 방법으로 고민하는 일이 있습니다. OS에 의한 시간측정방법과 완전히 다르기 때문에 portability 코드를 쓰는 것은 상당히 귀찮습니다. 잘못된 시간측정을 실시하면 결과는 터무니없는 값이 되겠지만, 계측 시간이 msec 단위인 경우 그것이 작성된 쓴 원시 코드 때문인지 아니면 정말로 그 시간 걸렸는지 알 수 없습니다.

이번에는 CUDA의 Event를 사용하여 어떤 환경에도 이용할 수 있고 단순하고 올바른 측정 시간을 얻을 수 있습니다.

사용예제

#include <stdio.h>

#define VEC_NUM (512)

__global__ void dummy(float *dA)

{

int id = blockDim.x * blockIdx.x + threadIdx.x;

dA[id] = dA[id] + dA[VEC_NUM-1-id];

}

int main(int argc, char** argv)

{

float A[VEC_NUM];

float *dA;

size_t size = VEC_NUM * sizeof(float);

int i;

for( i=0; i<VEC_NUM; i++ ) {

A[i] = (float) i;

}

cudaMalloc( (void **) &dA, size );

cudaMemcpy( dA, A, size, cudaMemcpyHostToDevice );

float elapsed_time_ms=0.0f;

cudaEvent_t start, stop;

cudaEventCreate( &start );

cudaEventCreate( &stop );

cudaEventRecord( start, 0 );

dummy<<<VEC_NUM/128, 128>>>(dA);

cudaEventRecord( stop, 0 );

cudaEventSynchronize( stop );

cudaEventElapsedTime( &elapsed_time_ms, start, stop );

cudaMemcpy( A, dA, size, cudaMemcpyDeviceToHost );

printf( "time: %8.2f ms\n", elapsed_time_ms );

cudaEventDestroy( start );

cudaEventDestroy( stop );

cudaFree( dA );

return 0;

}

프로그램의 내용에 큰 의미는 없습니다. 중요한 것은 다음 부분입니다.

float elapsed_time_ms=0.0f;

cudaEvent_t start, stop;

cudaEventCreate( &start );

cudaEventCreate( &stop );

cudaEventRecord( start, 0 );

dummy<<<VEC_NUM/128, 128>>>(dA);

cudaEventRecord( stop, 0 );

cudaEventSynchronize( stop );

cudaEventElapsedTime( &elapsed_time_ms, start, stop );

CUDA Event를 사용하여 CUDA API에서 비동기화로 실행되고 있는 여러가지 명령(호스트·디바이스 사이의 데이터 전송이나, kernel의 실행등)의 진행 상황을 체크 포인트(이벤트) 마다 모니터 할 수 있습니다.

1.cudaEvent_t형의 변수를 기록하고 싶은 이벤트의 수 만큼 선언 한다

2.cudaEventCreate를 이용해 이벤트를 생성한다

3.cudaEventRecord를 이용해 이벤트를 기록한다

4.cudaEventSynchronize로 이벤트를 동기화 한다

5.cudaEventElapsedTime로 이벤트간의 시간측정을 한다

6.cudaEventDestroy로 이벤트를 파기한다

cudaEventRecord는 다음과 같은 동작을 합니다.

이 함수가 불리기 직전까지 호출된 CUDA API의 동작이 모두 끝난 직후에 이벤트를 기록한다.

덧붙여 이 함수는 비동기화에 동작하기 때문에 경과시간을 계측하기 전에 이벤트를 기록하고 있는지를 보증할 필요가 있습니다. 이를 위한 것이 cudaEventSynchronize입니다. 함수 인수의 이벤트가 종료 할 때까지 cudaEventSynchronize는 실행을 블록합니다.

마지막으로, cudaEventElapsedTime로 시간을 측정합니다. 단위는 밀리 세컨드입니다.

반응형
반응형

http://istqb.tistory.com/350

지금부터는
.cu파일을 열어보면 int float #include 등에 상관없이 모두 검정색 글씨로 되어있는데
이걸 일반C++파일을 열었을 때처럼 파란색/갈색으로 하이라이팅 하는 법입니다.
아래 사진처럼 SDK-C--doc-syntax_highlighting-visual_studio_8 안쪽에 있는 usertype.dat를
비주얼스튜디오가 설치된 폴더의 Common7-IDE에 복사합니다. (비주얼스튜디오버전에 맞는 폴더를 찾아가시면됩니다.)





설치후에 보면~~ 푸른색과 갈색?으로 하이라이팅 된 것을 확인하실 수 있습니다~





이번에는 Visual Assist X (비주얼 어시스트 X)설정 법입니다.
Visual Assist X\AutoText\Latest\Cpp.tpl을 하나 복사해서 이름을 Cu.tpl로 바꿉니다.






시작-실행-regedit 하신다음에 HKEY_CURRENT_USER\Software\Whole Tomato\Visual Assist X\VANet7.0
(자신의 VS버전폴더를찾으시면됩니다.) 에 들어가셔서 ExtHeader와 ExtSource에 각각 .cuh와 .cu를 추가해줍니다.





비주얼 스튜디오를 다시 실행시켜보시면 우왕ㅋ굳ㅋ




http://sigttou.com/category/adventures-in-graphicsland

STEP 5: CONFIGURE VISUAL ASSIST X TO KNOW ABOUT CUDA.

To get full syntax highlighting and include support, we need to tell VAX about our CUDA libraries as well as the fact that it should treat CUDA files as C/C++ files.

Launch VS 2010 and open the Options screen (Tools > Options). Under Projects and Solutions > VC++ Project Settings add the following entries to the Extensions to Include item:

  • .cu
  • .cu.h (or whatever you use for your CUDA headers)

It should look something like this:

Extensions to Include

Now close VS 2010 and open up the registry editor (Start > regedit.exe). Browse to the following folder:

  • HKEY_CURRENT_USER\Software\Whole Tomato\Visual Assist X\VANet10

Now look for the ExtHeader key and add .cu.h to the list. Make sure the whole line ends with a semicolon. It should look something like this:

Regedit ExtHeader

Look a little further down and you should see the ExtSource key. Add .cu to the list in the same way. Again, make sure the line ends with a semicolon.

Regedit Source

Now relaunch VS 2010 and open the VAX options (VAssistX > Visual Assist X Options). Open the Projects group on the left and select C/C++ Directories. Under Platform select Custom. Then, select Stable Include Files from the drop down on the right and add the paths to your CUDA toolkit includes and GPU Computing SDK includes. If you used the default installation directories, these are:

  • C:\Program Files (x86)\NVIDIA GPU Computing Toolkit\CUDA\v3.2\include
  • C:\ProgramData\NVIDIA Corporation\NVIDIA GPU Computing SDK 3.2\C\common\inc

In other words, your screen should look something like this:

Stable Includes

Now switch the drop down to Source files and add the following paths:

  • C:\Program Files (x86)\NVIDIA GPU Computing Toolkit\CUDA\v3.2\src
  • C:\ProgramData\NVIDIA Corporation\NVIDIA GPU Computing SDK 3.2\C\common\src

Source Files

Lastly, select the Performance item from the left and click the Rebuild Symbol Databases button.

Rebuild Symbol Databases

You should be good to go now with Visual Assist X and CUDA.

반응형
반응형

순서대로 따라하면 됨.


http://blog.naver.com/PostView.nhn?blogId=toses3&logNo=40140926000

-개발자버전 드라이버를 설치해야 한다, 그냥 드라이버가 아닌..

-쿠다툴킷 설치

-비주얼스튜디오 설치

요약

1. win32 Console application 으로 생성

2. 사용자 지정빌드(프로젝트에 마우스 대로오른쪽 버튼 누르면 나옴) 에서 CUDA 4.1(Targets, .props) 를 선택

하면 빌드할 것들을 알아서 목록포함

(4.1 툴킷 부터는 프로퍼티가 안뜨는 버그는 안보이는듯)

옵션에서 텍스트 에디터 -> 파일 확장자 에서 cu. cuh 확장자를 Visual C++ 에티터로 등록

.cu 코드 작성후 속성에서

.cu 의 속성->일반->아이템 타입 이 CUDA C/C++ 이 되도록 변경

프로젝트속성 -> 입력 에서 추가 종속성에 cudart.lib 추가


반응형

+ Recent posts