튜토리얼이 OpenGL 렌더링에 다른 접근법을 사용하는 이유는 무엇입니까?


43

http://www.sdltutorials.com/sdl-opengl-tutorial-basics

http://www.opengl-tutorial.org/beginners-tutorials/tutorial-2-the-first-triangle/

이 두 튜토리얼은 완전히 다른 접근법을 사용하여 거의 동일한 결과를 얻습니다. 첫 번째는와 같은 것을 사용합니다 glBegin(GL_QUADS). 두 번째는 vertexBufferObjectsGLEW 기반의 쉐이더 와 같은 것을 사용합니다 . 그러나 결과는 동일합니다. 기본 도형을 얻습니다.

이러한 차이점이 존재하는 이유는 무엇입니까?

첫 번째 방법은 이해하기 훨씬 쉬운 것 같습니다. 복잡한 두 번째 접근 방식의 장점은 무엇입니까?


4
고양이를 피부에 바르는 방법은 없습니다.
Philipp

4
@Philipp 그렇습니다. 그러나 올바른 방법과 잘못된 방법, 오래된 방법과 새로운 방법이 있습니다 (아래 답변에서 알 수 있듯이 기존 방법과 새로운 방법은 모든 상황에서 호환되지 않을 수 있습니다)
Andrew Hill

3
없습니다 잘 방법과 잘못된 방법으로, 악화 방법과 (여러 다른 차원에서) 더 나은 방법.
user253751

glBegin그리고 glEnd그들이 현재 그래픽 아키텍처를위한 매우 비효율적이기 때문에 사용되지 않습니다
알렉스

답변:


77

OpenGL에는 모바일 장치 및 임베디드 시스템 (OpenGL | ES) 및 JavaScript (WebGL)를 통한 웹 버전을 포함하지 않는 4 가지 주요 버전이 있습니다. Direct3D 11이 Direct3D 8과 다른 방식으로 작업하는 것과 마찬가지로 OpenGL 3도 OpenGL 1과 다른 방식으로 작업을 수행합니다. OpenGL 버전은 대부분 이전 버전의 애드온이라는 점만 다릅니다. 전적으로).

OpenGL의 여러 버전과 버전 외에도 기본 OpenGL은 프로파일 개념을 추가했습니다. 즉 호환성 프로파일 (이전 버전의 API를 지원할 수 있음)과 코어 프로파일 (이전 API를 사용하지 않도록 설정 함)입니다. 같은 것들 glBegin당신은 코어 프로필을 사용하면 간단하게 작업을하지 않습니다하지만 당신은 (기본값) 호환성 프로필을 사용하는 경우.

또 하나의 주요 합병증으로, Apple과 같은 OpenGL의 일부 구현은 코어 프로파일을 사용할 때 최신 OpenGL 기능 만 활성화합니다. 따라서 최신 API를 사용하려면 이전 API 사용을 중지 해야합니다 .

그런 다음 튜토리얼에 대한 몇 가지 매우 혼란스러운 시나리오가 생깁니다.

  1. 이 튜토리얼은 오래되었으며 더 이상 사용되지 않는 API 만 사용합니다.
  2. 이 튜토리얼은 새롭고 잘 작성되었으며 코어 호환 API 만 사용합니다.
  3. 이 튜토리얼은 새로운 것이지만 호환성 모드에서 모든 API를 활성화하고 새로운 API와 기존 API를 자유롭게 혼합하는 드라이버로 작업하고 있다고 가정하는 실수를합니다.
  4. 이 자습서는 이전 버전의 API를 전혀 지원하지 않는 OpenGL | ES와 같은 다른 버전의 OpenGL을 대상으로합니다.

이와 같은 glBegin것은 때때로 직접 모드 API라고하는 것의 일부입니다. OpenGL에는 유지 모드와 같은 것이 없으며 "즉시 모드"는 이미 그래픽에서 다른 정의를 가지고 있기 때문에 이것은 매우 혼란 스럽습니다. OpenGL 2.1 이후로 사용되지 않았으므로 OpenGL 1.x API로 참조하는 것이 훨씬 좋습니다.

OpenGL의 1.x API는 예전에는 그래픽 파이프 라인에 정점을 즉시 제출했습니다. 이것은 정점을 렌더링 한 하드웨어의 속도가 정점 데이터를 생성하는 CPU의 속도와 거의 비슷했을 때 잘 작동했습니다. 그런 다음 OpenGL은 삼각형 래스터 화를 오프로드했으며 그다지 많지 않았습니다.

요즘 GPU는 고급 버텍스 및 픽셀 변환을 수행하면서 대량의 버텍스를 매우 빠른 속도로 씹을 수 있으며 CPU는 단순히 원격 유지조차 할 수 없습니다. 또한 CPU와 GPU 간의 인터페이스는이 속도 차이를 중심으로 설계되어 더 이상 한 번에 하나씩 정점을 GPU에 제출할 수 없습니다.

모든 GL 드라이버는 glBegin내부적으로 정점 버퍼를 할당하고 제출 된 정점 glVertex을이 버퍼에 넣은 다음 호출 될 때 단일 버퍼에서 전체 버퍼를 제출하여 에뮬레이션해야합니다 glEnd. 이러한 함수의 오버 헤드는 버텍스 버퍼를 직접 업데이트 한 경우보다 훨씬 큽니다. 따라서 일부 문서에서 (매우 실수로!) 버텍스 버퍼를 "최적화"(최적화가 아님 : 실제로는 유일한 방법 임) GPU와 대화하십시오).

수년 동안 OpenGL에서 더 이상 사용되지 않거나 폐기 된 다양한 다른 API가 있습니다. 소위 고정 기능 파이프 라인은 또 다른 그런 부분입니다. 일부 문서는 여전히이 파이프 라인을 사용하거나 프로그래밍 가능한 파이프 라인과 혼합 될 수 있습니다. 고정 기능 파이프 라인은 그래픽 카드가 3D 장면을 렌더링하는 데 사용 된 모든 수학을 하드 코딩하고 OpenGL API가 해당 수학에 대한 일부 구성 값을 설정하는 것으로 제한되었던 옛날부터 시작되었습니다. 요즘 하드웨어에는 하드 코딩 된 수학이 거의 없으며 (CPU와 마찬가지로) 대신 사용자 제공 프로그램 (종종 셰이더라고 함)을 실행합니다.

고정 기능 기능이 더 이상 하드웨어에 존재하지 않기 때문에 드라이버는 이전 API를 다시 한 번 모방해야합니다. 즉, 드라이버에는 자체 셰이더를 제공하지 않을 때 사용되는 고정 함수 시절의 오래된 수학을 실행하는 호환성 셰이더가 포함되어 있습니다. 이전 OpenGL 조명 API와 같이 이전 고정 함수 상태를 수정하는 이전 OpenGL 함수는 실제로 이러한 값을 드라이버의 호환성 셰이더에 제공하기 위해 균일 버퍼와 같은 최신 OpenGL 기능을 사용하고 있습니다.

호환성을 지원하는 드라이버는 이러한 구식 기능을 사용할 때를 파악하고 최신 기능과 원활하게 결합하여 오버 헤드를 추가하고 드라이버를 크게 복잡하게 만들 수 있도록 많은 비하인드 작업을 수행해야합니다. 이것이 일부 드라이버가 코어 프로파일이 새로운 기능을 갖도록하는 이유 중 하나입니다. 이전 및 새로운 API를 동시에 사용할 필요가 없으므로 드라이버 내부를 크게 단순화합니다.

시작하기가 쉽기 때문에 이전 API로 시작하는 것이 좋습니다. Direct3D 는 더 간단한 그리기 API와 사전 작성된 쉐이더를 제공하는 컴패니언 라이브러리 ( DirectX Tool Kit )를 제공 하여 초보자가이 문제를 해결했습니다.이 라이브러리 는 전문 지식이 커짐에 따라 원시 Direct3D 11 사용법과 자유롭게 혼합 할 수 있습니다. 더 넓은 OpenGL 커뮤니티는 불행히도 초보자를위한 호환성 프로파일을 사용하고 있습니다. 불행히도 이전 OpenGL API와 새로운 OpenGL API를 혼합 할 수없는 시스템이 있기 때문에 문제가됩니다. 다양한 레벨의 기능과 대상 사용 사례 및 언어 ( MonoGame)를 사용하여 새로운 OpenGL에서 간단한 렌더링을위한 비공식 라이브러리 및 도구가 있습니다. 예를 들어 .NET 사용자의 경우) 그러나 공식적으로 승인하거나 널리 동의 한 것은 없습니다.

찾은 문서는 OpenGL 용이 아니라 다른 유사한 API 중 하나 일 수 있습니다. OpenGL | ES 1.x에는 고정 함수 렌더링이 있었지만 정점 제출을위한 OpenGL 1.x API는 없었습니다. OpenGL | ES 2.x + 및 WebGL 1+에는 고정 기능 기능이 전혀 없으며 해당 API에 대한 하위 호환성 모드가 없습니다.

이 API는 기본 OpenGL과 매우 유사합니다. 그것들은 완벽하게 호환되지는 않지만, OpenGL에 대한 공식 확장이 있습니다 (일부는 아님) 일부 드라이버는 OpenGL | ES (WebGL 기반)와 호환되도록 지원합니다. 전에는 충분히 혼란스럽지 않았기 때문입니다.


4
+1 환상적인 답변! 새로운 OpenGL에서 간단한 렌더링을위한 비공식 라이브러리 및 도구를 언급 할 수 있다면 좋을 것입니다.)
Mehrdad

2
훌륭한 답변. 나는 OpenGL보다 훨씬 간단하게 DirectX와 같은 문제를 겪었지만 유지 / 즉시 모드에서 셰이더로의 도약은 엄청났습니다. 다행스럽게도 문서는 많은 도움이되었지만 (OpenGL과는 달리 저에게는 최소한), "어떻게 밝게 표시합니까?"의 시작은 미쳤습니다. : D
Luaan

나는 opengl-tutorial.org의 저자이며 Sean의 의견에 동의합니다. API는 주로 성능상의 이유로 이러한 방식으로 발전했습니다.
Calvin1602

주제에 대한 아주 좋은 정보 ..
reynmar

1
@Mehrdad : 나는 내 머리 꼭대기를 떠올리지 않습니다. 단순화 된 2D 렌더링, 다양한 장면 그래프 라이브러리, MonoGame for C # 등을 추가하는 SDL2 또는 SFML과 같은 라이브러리가 있지만 실제로는 생각하기 때문에 Direct TK와 직접적으로 동등한 것을 알지 못합니다. "많은"이라고 말한 이후 게시물을 편집하면 큰 뚱뚱한 거짓말이 될 수 있습니다. :)
Sean Middleditch

9

주요 차이점은 전략의 최신 상태입니다. 첫 번째 튜토리얼에서 사용 된 즉시 모드 :

glBegin(GL_QUADS);
    glColor3f(1, 0, 0); glVertex3f(0, 0, 0);
    glColor3f(1, 1, 0); glVertex3f(100, 0, 0);
    glColor3f(1, 0, 1); glVertex3f(100, 100, 0);
    glColor3f(1, 1, 1); glVertex3f(0, 100, 0);
glEnd();

최신 버전이며 최신 버전에서 지원되지 않습니다.

버텍스 버퍼와 쉐이더를 사용하는 것이 현재 OpenGL로 렌더링하는 방법입니다. 더 복잡해 보일 수 있지만 성능이 훨씬 뛰어납니다. 또한 OpenGL을 마무리하는 지원 코드가 있으면 차이점이 대부분 추상화됩니다.


2

다른 훌륭한 답변에 더 많은 컨텍스트를 추가하십시오.

첫 번째 링크에 설명 된 즉시 모드는 다른 사람들이 말했듯이 초기 버전의 OpenGL (1.1)의 레거시 코드입니다. GPU가 삼각형 래스터 라이저에 지나지 않았고 프로그램 가능한 파이프 라인에 대한 아이디어가 없었을 때 사용되었습니다. 예를 들어 GLQuake 및 Quake 2와 같은 초기 하드웨어 가속 게임의 소스 코드를 보면 즉시 사용중인 모드가 표시됩니다. 간단히 말해 CPU는 한 번에 하나씩 정점에 대한 명령을 GPU에 보내 화면에 삼각형을 그리기 시작합니다. 기록적으로 GL_QUADS는 GL_TRIANGLES와 동일한 결과를 가져옵니다. 단, GPU는 쿼드를 삼각형 자체로 즉시 전환해야합니다.

최신 (3.2+) OpenGL은 다른 접근법을 취합니다. 정점 데이터를 GPU 메모리에 버퍼링하여 빠르게 액세스 한 다음 glDrawArrays 또는 glDrawElements를 사용하여 그리기 지침을 보낼 수 있습니다. 또한 GPU가 정점의 위치와 색상을 지정하는 방법을 사용자 지정할 수있는 프로그래밍 가능한 파이프 라인 (glUseProgram)이 있습니다.

즉각적인 모드가 더 이상 사용되지 않는 데는 몇 가지 이유가 있습니다. 주된 이유는 성능입니다. Sean이 그의 답변에서 말했듯이, 오늘날 GPU는 CPU가 데이터를 업로드 할 수있는 속도보다 빠르게 데이터를 처리 할 수 ​​있으므로 GPU 성능에 병목 현상이 발생합니다. OpenGL을 호출 할 때마다 약간의 오버 헤드가 발생합니다. 아주 작지만 매 프레임마다 수만 건의 호출을하면 쌓이기 시작합니다. 간단히 말해 즉시 모드를 사용하여 텍스처 모델을 그리려면 프레임 당 최소 2 개의 호출 (glTexCoord2f 및 glVertex3f)이 필요합니다. 최신 OpenGL을 사용하면 처음에 데이터를 버퍼링하기 위해 몇 번의 호출을 사용하고, 몇 개의 호출만으로 정점 배열 객체를 바인딩하고 일부 속성 포인터를 활성화하고 포함하는 정점 수에 관계없이 전체 모델을 그릴 수 있습니다. 그런 다음 glDrawElements 또는 glDrawArrays에 대한 단일 호출.

어떤 기술이 옳습니까? 그것은 당신이하려는 일에 달려 있습니다. 멋진 포스트 프로세싱 기술이나 셰이더가 필요없는 간단한 2D 게임은 즉각적인 모드를 사용하면 잘 작동하며 코드를 작성하는 것이 더 쉬울 것입니다. 그러나보다 현대적인 3D 게임은 실제로 어려움을 겪고 GLSL (셰이더 언어) 학습을 계획하고 있다면 현대 기술을 확실히 배우십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.