프로그래밍 측면과 구성 요소가 서로 대화하는 방법에 대해 약간 작성하기로 결정했습니다. 어쩌면 특정 지역에서 약간의 빛을 비출 것입니다.
프레젠테이션
질문에 게시 한 단일 이미지를 화면에 표시하려면 어떻게해야합니까?
화면에 삼각형을 그리는 방법에는 여러 가지가 있습니다. 간단하게하기 위해 정점 버퍼가 사용되지 않았다고 가정 해 봅시다. ( 정점 버퍼 는 좌표를 저장하는 메모리 영역입니다.) 프로그램이 단순히 그래픽 처리 파이프 라인에 모든 단일 정점 (정점은 공간의 좌표)에 대해 연속적으로 지시했다고 가정 해 봅시다.
그러나 무언가를 그리기 전에 먼저 비계를 실행해야합니다. 나중에 이유를 살펴 보겠습니다 .
// Clear The Screen And The Depth Buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Reset The Current Modelview Matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Drawing Using Triangles
glBegin(GL_TRIANGLES);
// Red
glColor3f(1.0f,0.0f,0.0f);
// Top Of Triangle (Front)
glVertex3f( 0.0f, 1.0f, 0.0f);
// Green
glColor3f(0.0f,1.0f,0.0f);
// Left Of Triangle (Front)
glVertex3f(-1.0f,-1.0f, 1.0f);
// Blue
glColor3f(0.0f,0.0f,1.0f);
// Right Of Triangle (Front)
glVertex3f( 1.0f,-1.0f, 1.0f);
// Done Drawing
glEnd();
그래서 그것은 무엇을 했습니까?
그래픽 카드를 사용하려는 프로그램을 작성할 때 일반적으로 드라이버에 대한 인터페이스를 선택합니다. 드라이버에 대한 잘 알려진 인터페이스는 다음과 같습니다.
이 예제에서는 OpenGL을 사용하겠습니다. 지금, 당신의 드라이버에 대한 인터페이스는 당신이 프로그램을 만들기 위해 필요한 모든 도구를 제공 무엇인가 이야기를 그래픽 카드에 (또는 드라이버를 한 후 협상 카드로).
이 인터페이스는 특정 도구 를 제공합니다 . 이 도구는 프로그램에서 호출 할 수 있는 API 형태를 취합니다 .
이 API는 위 예제에서 사용 된 것으로 보입니다. 좀 더 자세히 살펴 보자.
비계
실제로 실제 그림을 그리기 전에 설정 을 수행해야합니다 . 뷰포트 (실제로 렌더링 될 영역), 투시도 ( 세계에 카메라 ), 사용할 앤티 앨리어싱 (삼각형의 가장자리를 매끄럽게하기)을 정의해야합니다 ...
그러나 우리는 그 어떤 것도 보지 않을 것입니다. 우리는 모든 프레임 에서해야 할 일을 들여다 볼 것 입니다. 처럼:
화면 지우기
그래픽 파이프 라인은 모든 프레임에서 화면을 지우지 않습니다. 당신은 그것을 말해야 할 것입니다. 왜? 이는 이유:
화면을 지우지 않으면 매 프레임마다 화면 을 그 립니다 . 우리 glClear
가 GL_COLOR_BUFFER_BIT
세트로 전화 하는 이유 입니다. 다른 비트 ( GL_DEPTH_BUFFER_BIT
)는 OpenGL에 깊이 버퍼 를 지우도록 지시합니다 . 이 버퍼는 어떤 픽셀이 다른 픽셀 앞에 있는지 (또는 뒤에 있는지)를 결정하는 데 사용됩니다.
변환
이미지 소스
변환은 모든 입력 좌표 (삼각형의 꼭짓점)를 가져와 ModelView 행렬을 적용하는 부분입니다. 이것은 모델 (정점)이 어떻게 회전, 축척 및 변환 (이동) 되는지 설명 하는 매트릭스입니다 .
다음으로 투영 행렬을 적용합니다. 모든 좌표를 움직여 카메라를 올바르게 향하게합니다.
이제 뷰포트 매트릭스를 사용하여 한 번 더 변형합니다. 모델 을 모니터 크기에 맞게 조정하기 위해이 작업을 수행합니다 . 이제 렌더링 준비가 된 정점 세트가 있습니다!
잠시 후에 다시 변환으로 돌아갑니다.
그림
삼각형을 그리려면 상수 를 호출 하여 OpenGL에 새 삼각형 목록 을 시작하도록 지시 glBegin
하면 GL_TRIANGLES
됩니다.
그릴 수있는 다른 양식들도 있습니다. 삼각 스트립 이나 삼각 팬 처럼 . 동일한 양의 삼각형을 그리려면 CPU와 GPU 간의 통신이 덜 필요하기 때문에 주로 최적화입니다.
그런 다음 각 삼각형을 구성해야하는 3 개의 정점 세트 목록을 제공 할 수 있습니다. 모든 삼각형은 3 차원 좌표를 사용합니다 (3D 공간에서와 같이). 또한 을 호출 하기 전에 호출 하여 각 정점에 색상 을 제공합니다 .glColor3f
glVertex3f
3 개의 정점 (삼각형의 3 개의 모서리) 사이의 음영은 OpenGL에 의해 자동으로 계산 됩니다 . 다각형의 전체면에 걸쳐 색상을 보간합니다.
상호 작용
이제 창을 클릭하면 응용 프로그램 은 클릭을 알리는 창 메시지 만 캡처하면 됩니다. 그런 다음 원하는 프로그램에서 모든 작업을 실행할 수 있습니다.
이것은 도착 많은 당신이 당신의 3D 장면과 상호 작용 시작하고 싶어 한 번 더 어렵습니다.
먼저 사용자가 창을 클릭 한 픽셀을 명확하게 알아야합니다. 그런 다음 원근 을 고려하여 마우스 클릭 지점에서 장면으로 광선의 방향을 계산할 수 있습니다. 그런 다음 장면의 객체 가 해당 광선과 교차 하는지 계산할 수 있습니다 . 이제 사용자가 객체를 클릭했는지 알 수 있습니다.
그렇다면 어떻게 회전 시키나요?
변환
일반적으로 적용되는 두 가지 유형의 변환에 대해 알고 있습니다.
차이점은 뼈 가 단일 정점에 영향을 미친다 는 것입니다 . 행렬은 항상 같은 방식으로 그려진 모든 정점에 영향을줍니다. 예를 봅시다.
예
앞서 삼각형을 그리기 전에 항등 행렬 을로드했습니다 . 항등 행렬은 단순히 변환 을 전혀 제공 하지 않는 행렬입니다 . 따라서 내가 그리는 것은 내 관점에만 영향을받습니다. 따라서 삼각형이 전혀 회전하지 않습니다.
나는 지금 회전 할 경우, I합니다 (CPU)에 수학 자신을 단순히 호출 할 수 있습니다 중 하나 glVertex3f
와 함께 다른 (회전) 좌표. 또는 glRotatef
그리기 전에 호출하여 GPU가 모든 작업을 수행하도록 할 수 있습니다 .
// Rotate The Triangle On The Y axis
glRotatef(amount,0.0f,1.0f,0.0f);
amount
물론 고정 된 값입니다. 애니메이션 하려면 애니메이션 을 추적 amount
하고 매 프레임마다 늘려야합니다.
잠깐, 모든 매트릭스 토크는 어떻게 되었습니까?
이 간단한 예제에서는 행렬을 신경 쓸 필요가 없습니다. 우리는 단순히 전화 glRotatef
해서 우리 를 위해 모든 것을 처리합니다.
glRotate
angle
벡터 xyz 주위 의 각도 회전을 생성합니다 . 현재 행렬 ( glMatrixMode 참조 )에 glMultMatrix 가 다음 행렬을 인수로 호출 한 것처럼 현재 행렬을 대체하는 곱으로 회전 행렬을 곱합니다 .
x 2 1-c + cx y 1-c-z sx z 1-c + y s 0 y x 1-c + z sy 2 1-c + cy z 1-c-x s 0 x z 1-c-y sy z 1-c + x sz 2 1-c + c 000 00 1
고마워요!
결론
명백한 것은 OpenGL 과 많은 대화가 있다는 것 입니다. 그러나 그것은 우리에게 아무것도 말하지 않습니다 . 커뮤니케이션은 어디에 있습니까?
이 예제에서 OpenGL이 우리에게 알려주는 것은 완료되었을 때 입니다. 모든 작업에는 일정 시간이 걸립니다. 어떤 작업은 엄청나게 오래 걸리고 다른 작업은 엄청나게 빠릅니다.
GPU에 꼭짓점 을 보내는 것은 너무 빠를 것입니다. 표현 방법조차 모르겠습니다. CPU에서 GPU로 수천 개의 정점을 보내는 것은 매 프레임마다 전혀 문제가되지 않습니다.
뷰포트의 크기에 따라 화면을 지우는 데 1 밀리 초 이상이 걸릴 수 있습니다 (일반적으로 각 프레임을 그리는 데 약 16 밀리 초의 시간이 소요됩니다). 이를 정리하기 위해 OpenGL은 제거하려는 색상의 모든 단일 픽셀을 그려야합니다. 수백만 픽셀이 될 수 있습니다.
그 외에는 그래픽 어댑터의 기능 (최대 해상도, 최대 앤티 앨리어싱, 최대 색상 깊이 등)에 대해서만 OpenGL에 요청할 수 있습니다.
그러나 특정 색상의 픽셀로 텍스처를 채울 수도 있습니다. 따라서 각 픽셀은 값을 가지며 텍스처는 데이터로 채워진 거대한 "파일"입니다. 텍스처 버퍼를 생성하여 그래픽 카드에로드 한 다음 셰이더 를로드 하고이 셰이더에 텍스처를 입력으로 사용하도록 지시하고 "파일"에 대해 매우 무거운 계산을 실행하도록 지시 할 수 있습니다.
그런 다음 계산 결과 (새로운 색상의 형태)를 새로운 텍스처로 "렌더링"할 수 있습니다.
그것이 다른 방식으로 GPU를 작동시키는 방법입니다. 나는 CUDA가 그 측면과 비슷하게 작동한다고 가정하지만 그와 함께 일할 기회는 없었습니다.
우리는 실제로 전체 주제를 약간만 만졌습니다. 3D 그래픽스 프로그래밍은 야수입니다.
이미지 소스