5 minute read

1. Getting Started


여정을 시작하기 전에 먼저 OpenGL이 실제로 무엇인지 정의해야 합니다. OpenGL은 주로 그래픽과 이미지를 조작하는 데 사용할 수 있는 많은 기능을 제공하는 API(응용 프로그래밍 인터페이스)로 간주됩니다. 그러나 OpenGL 자체는 API가 아니라 Khronos Group에서 개발 및 유지 관리하는 사양일 뿐입니다.

OpenGL 사양은 각 함수의 결과/출력이 어떠해야 하고 어떻게 수행되어야 하는지를 정확히 지정합니다. 그런 다음 이 기능이 어떻게 작동해야 하는지에 대한 솔루션을 마련하는 것은 이 사양을 구현하는 개발자에게 달려 있습니다. OpenGL 사양은 구현 세부 사항을 제공하지 않기 때문에 결과가 사양을 준수하는 한(따라서 사용자에게 동일한) OpenGL의 실제 개발 버전은 다른 구현을 가질 수 있습니다.

실제 OpenGL 라이브러리를 개발하는 사람들은 일반적으로 그래픽 카드 제조업체입니다. 구입하는 각 그래픽 카드는 해당 카드(시리즈)용으로 특별히 개발된 OpenGL 버전인 OpenGL의 특정 버전을 지원합니다. Apple 시스템을 사용할 때 OpenGL 라이브러리는 Apple 자체에서 유지 관리하며 Linux에서는 이러한 라이브러리에 대한 그래픽 공급업체의 버전과 애호가의 적응이 결합되어 있습니다. 이것은 또한 OpenGL이 해서는 안 되는 이상한 동작을 보일 때마다 이것이 그래픽 카드 제조업체(또는 라이브러리를 개발/유지 관리한 사람)의 잘못일 가능성이 높다는 것을 의미합니다.

=> 아 사양이라는 것이 각 그래픽카드용으로 특별히 개발된 OpenGL버전을 지원하는데, 이 때문에 그래픽카드 제조업체마다 OpenGL버전이 다르고, 구현된 내용이 다를 수 있다.그렇기 때문에 사양이라고 논하는 것 같다.

대부분의 구현은 그래픽 카드 제조업체에서 구축하기 때문에 구현에 버그가 있을 때마다 일반적으로 비디오 카드 드라이버를 업데이트하여 해결합니다. 이러한 드라이버에는 카드가 지원하는 최신 버전의 OpenGL이 포함되어 있습니다. 이것이 항상 그래픽 드라이버를 가끔 업데이트하도록 권장되는 이유 중 하나입니다.

Khronos는 모든 OpenGL 버전에 대한 모든 사양 문서를 공개적으로 호스팅합니다. 관심 있는 독자는 여기에서 버전 3.3(우리가 사용할 것)의 OpenGL 사양을 찾을 수 있습니다. 이 사양은 OpenGL의 세부 사항을 탐구하려는 경우에 좋습니다. 사양은 또한 해당 기능의 정확한 작동을 찾기 위한 훌륭한 참조를 제공합니다.

Core-profile vs Immediate mode

예전에 OpenGL을 사용한다는 것은 그래픽을 그리는 데 사용하기 쉬운 방법인 즉시 모드(종종 고정 함수 파이프라인이라고도 함)에서 개발하는 것을 의미했습니다. OpenGL의 대부분의 기능은 라이브러리 내부에 숨겨져 있었고 개발자는 OpenGL이 계산을 수행하는 방법을 많이 제어할 수 없었습니다. 개발자들은 결국 더 많은 유연성에 굶주렸고 시간이 지남에 따라 사양은 결과적으로 더 유연해졌습니다. 개발자는 그래픽을 더 많이 제어할 수 있습니다. 즉시 모드는 사용과 이해가 정말 쉽지만 매우 비효율적입니다. 이러한 이유로 사양은 버전 3.2부터 즉시 모드 기능을 더 이상 사용하지 않기 시작했으며 개발자가 사용되지 않는 이전 기능을 모두 제거한 OpenGL 사양의 한 부분인 OpenGL의 코어 프로필 모드에서 개발하도록 동기를 부여하기 시작했습니다.

이것이 이 책이 핵심 프로필 OpenGL 버전 3.3에 맞춰져 있는 이유이기도 합니다. 더 어렵지만 노력할 가치가 있습니다.

오늘부터 OpenGL의 상위 버전을 선택할 수 있습니다(4.6 작성 당시). 그러면 OpenGL 4.6이 출시될 때 왜 OpenGL 3.3을 배우고 싶습니까? 그 질문에 대한 답은 비교적 간단합니다. 3.3부터 OpenGL의 모든 향후 버전은 OpenGL의 핵심 메커니즘을 변경하지 않고 OpenGL에 유용한 기능을 추가합니다. 최신 버전은 동일한 작업을 수행하는 데 약간 더 효율적이거나 더 유용한 방법을 소개합니다. 결과는 모든 개념과 기술이 최신 OpenGL 버전에서 동일하게 유지되므로 OpenGL 3.3을 배우는 것이 완벽하게 유효합니다. 준비가 되거나 경험이 많을 때마다 최신 OpenGL 버전의 특정 기능을 쉽게 사용할 수 있습니다.

중요 최신 버전의 OpenGL 기능을 사용할 때 최신 그래픽 카드만 응용 프로그램을 실행할 수 있습니다. 이것이 대부분의 개발자가 일반적으로 OpenGL의 낮은 버전을 대상으로 하고 선택적으로 더 높은 버전의 기능을 활성화하는 이유입니다.

일부 장에서는 이와 같이 기록된 보다 현대적인 기능을 찾을 수 있습니다.

Extensions

OpenGL의 가장 큰 특징은 확장 기능을 지원한다는 것입니다. 그래픽 회사가 렌더링을 위한 새로운 기술이나 대규모 최적화를 제시할 때마다 드라이버안에서 확장 구현된 것이 발견됩니다. 응용 프로그램이 실행되는 하드웨어가 이러한 확장을 지원하는 경우 개발자는 확장에서 제공하는 기능을 사용하여 고급 그래픽이나 효율적인 그래픽을 사용할 수 있습니다. 이런 식으로 그래픽 개발자는 확장이 그래픽 카드에서 지원되는지 확인하는 것만으로 OpenGL이 향후 버전에 기능을 포함할 때까지 기다릴 필요 없이 이러한 새로운 렌더링 기술을 계속 사용할 수 있습니다. 종종 확장 기능이 대중적이거나 매우 유용하면 결국 향후 OpenGL 버전의 일부가 됩니다. (대충 드라이버에서 확장 구현된 기능들이 발견되니 그래픽 카드 지원만 확인하면 새로운 렌더링 기술을 계속 사용할 수 있도록 하면 됨. 이런 뜻인가?)

개발자는 이러한 확장을 사용하기 전에(또는 OpenGL 확장 라이브러리를 사용하여) 사용할 수 있는지 여부를 쿼리해야 합니다. 이를 통해 개발자는 확장 기능을 사용할 수 있는지 여부에 따라 작업을 더 잘하거나 더 효율적으로 수행할 수 있습니다.

if(GL_ARB_extension_name)
{
    // Do cool new and modern stuff supported by hardware
}
else
{
    // Extension not supported: do it the old way
}

OpenGL 버전 3.3을 사용하면 대부분의 기술에 대한 확장이 거의 필요하지 않지만 필요한 경우 적절한 지침이 제공됩니다.

State Machine(스테이트 머신)

OpenGL은 그 자체로 큰 State Machine( : OpenGL이 현재 작동해야 하는 방식을 정의하는 변수 모음입니다.)입니다. OpenGL의 상태는 일반적으로 OpenGL 컨텍스트라고 합니다. OpenGL을 사용할 때 일부 옵션을 설정하고 일부 버퍼를 조작한 다음 현재 컨텍스트를 사용하여 렌더링하여 상태를 변경하는 경우가 많습니다.

/내해석 OpenGL을 사용할 때, 일부 옵션을 세팅할 때 우리는 그것의(OpenGL을 뜻하는건가?) state를 종종 바꾼다. 일부 버퍼들을 조작하고 현재 컨텍스트를 사용하여 렌더링한다.

예를 들어 이제 삼각형 대신 선을 그리고 싶다고 OpenGL에 말할 때마다 OpenGL이 그리는 방법을 설정하는 일부 컨텍스트 변수를 변경하여 OpenGL의 상태를 변경합니다. OpenGL에 선을 그려야 한다고 말하여 컨텍스트를 변경하자마자 다음 그리기 명령은 이제 삼각형 대신 선을 그립니다.

OpenGL에서 작업할 때 컨텍스트를 변경하는 여러 상태 변경 함수와 OpenGL의 현재 상태를 기반으로 일부 작업을 수행하는 여러 상태 사용 함수를 접하게 됩니다. OpenGL이 기본적으로 하나의 대형 상태 머신이라는 점을 염두에 두는 한 해당 기능의 대부분이 더 이해가 될 것입니다.

Objects

OpenGL 라이브러리는 C로 작성되었으며 다른 언어로 많은 파생을 허용하지만 핵심은 C 라이브러리로 남아 있습니다. C의 많은 언어 구조가 다른 higher-level 언어로 잘 번역되지 않기 때문에 OpenGL은 몇 가지 추상화를 염두에 두고 개발되었습니다. 이러한 추상화 중 하나는 OpenGL의 객체입니다.

OpenGL의 객체는 OpenGL 상태(state)의 하위 집합을 나타내는 옵션의 모음입니다. 예를 들어 그리기 창의 설정을 나타내는 객체가 있을 수 있습니다. 그런 다음 크기, 지원하는 색상 수 등을 설정할 수 있습니다. 객체를 C와 같은 구조체로 시각화할 수 있습니다.

struct object_name {
    float  option1;
    int    option2;
    char[] name;
};


객체를 사용하려고 할 때마다 일반적으로 다음과 같이 보입니다(OpenGL의 컨텍스트가 큰 구조체로 시각화됨).

// The State of OpenGL
struct OpenGL_Context {
  	...
  	object_name* object_Window_Target;
  	...  	
};
// create object
unsigned int objectId = 0;
glGenObject(1, &objectId);
// bind/assign object to context
glBindObject(GL_WINDOW_TARGET, objectId);
// set options of object currently bound to GL_WINDOW_TARGET
glSetObjectOption(GL_WINDOW_TARGET, GL_OPTION_WINDOW_WIDTH,  800);
glSetObjectOption(GL_WINDOW_TARGET, GL_OPTION_WINDOW_HEIGHT, 600);
// set context target back to default
glBindObject(GL_WINDOW_TARGET, 0);

이 작은 코드 조각은 OpenGL로 작업할 때 자주 보게 될 워크플로우입니다. 먼저 객체를 생성한 다음 id에 객체에 대한 참조를 저장합니다(실제 객체의 데이터는 배후에서 저장됨). 그런 다음 해당 id를 사용하여 객체를 컨텍스트의 대상 위치에 바인딩합니다(예제 창 개체 대상의 위치는 GL_WINDOW_TARGET으로 정의됨). 다음으로 창 옵션을 설정하고 마지막으로 창 대상의 현재 객체 ID를 0으로 설정하여 객체를 바인딩 해제합니다. 우리가 설정한 옵션은 objectId가 참조하는 객체에 저장됩니다. 그리고 객체를 GL_WINDOW_TARGET로 다시 바인딩 하는 순간 바로 복원됩니다.

Let’s get started

really get a grasp of OpenGL. 이제 사양 및 라이브러리로서의 OpenGL, OpenGL이 내부적으로 대략적으로 작동하는 방식 및 OpenGL이 사용하는 몇 가지 사용자 정의 트릭에 대해 조금 배웠습니다. 모두 이해 못했다고 걱정하지 마십시오. 책 전체에서 우리는 각 단계를 살펴보고 OpenGL을 실제로 이해하기에 충분한 예제를 보게 될 것입니다.

출처 : https://learnopengl.com/Getting-started/OpenGL