OpenGL이란 ?
OpenGL은 주로 그래픽과 이미지를 조작하는 데 사용할 수 있는 다양한 함수를 제공하는 API(응용 프로그램 인터페이스)로 간주됩니다. 그러나 OpenGL 자체는 API가 아니라 Khronos Group에서 개발하고 유지 관리하는 단순한 스펙(specification)입니다.
OpenGL 스펙은 각 함수의 결과/출력이 어떻게 실행되고 어떻게 작동해야 하는지를 정확히 명시합니다. 이 사양을 구현하는 개발자들은 이 함수가 어떻게 작동해야 하는지에 대한 해결책을 찾아내야 합니다. OpenGL 스펙은 따로 세부 사항을 제공하지 않기 때문에 실제 개발된 OpenGL 버전은 결과가 사양을 준수하는 한 다른 구현을 가질 수 있습니다.
실제 OpenGL 라이브러리를 개발하는 사람들은 보통 그래픽카드 제조업체들입니다.(엔비디아, AMD, Apple) 여러분이 구매하는 각 그래픽 카드는 해당 카드(시리즈)를 위해 특별히 개발된 특정 OpenGL 버전을 지원합니다. Apple 시스템을 사용할 때 OpenGL 라이브러리는 Apple 자체에서 유지 관리하며, Linux에서는 그래픽 공급업체 버전과 취미가들의 라이브러리 적응 조합이 존재합니다. 이는 OpenGL이 이상한 동작을 보일 때, 이는 대부분 그래픽 카드 제조업체(또는 라이브러리를 개발/유지 관리한 사람)의 잘못일 가능성이 높다는 것을 의미합니다.
대부분의 구현이 그래픽 카드 제조업체에 의해 만들어지기 때문에, 구현에 버그가 있을 때마다 이는 보통 비디오 카드 드라이버를 업데이트함으로써 해결됩니다. 이러한 드라이버에는 카드가 지원하는 최신 버전의 OpenGL이 포함되어 있습니다. 이것이 가끔 그래픽 드라이버를 업데이트하는 것이 항상 권장되는 이유 중 하나입니다.
Khronos는 모든 OpenGL 버전의 모든 스펙 문서를 공개적으로 호스팅합니다. 관심 있는 독자는 버전 3.3(우리가 사용할 버전)의 OpenGL 사양을 여기에서 찾을 수 있으며, OpenGL의 세부 사항을 파고들고 싶다면 좋은 읽을거리입니다(결과만 나옵니다.). 스펙은 또한 함수의 정확한 작동 방식을 찾는 데 훌륭한 참고자료를 제공합니다.
Core-profile vs Immeidate mode(즉시 모드)
옛날에는 OpenGL을 사용한다는 것은 Immeidate mode(fiexed function pipeple)에서 개발하는 것을 의미했으며, 이는 그래픽을 그리는 쉬운 방법이었습니다. OpenGL의 대부분 기능은 라이브러리 내부에 숨겨져 있었고 개발자들은 OpenGL이 계산을 수행하는 방식에 대해 커스텀이 불가능했습니다. 개발자들은 커스텀을 원하게 되었고,스펙은 커스텀이 가능하게 되었습니다. Immeidate mode는 쉽지만, 매우 비효율적이라 버전 3.2부터 즉시 모드 기능을 더 이상 사용하지 않기 시작했고, 개발자들에게 OpenGL의 Core-profile mode에서 개발하도록 권장했습니다. 코어 프로필은 모든 오래된 사용 중단 기능을 제거한 OpenGL 사양의 한 부분입니다.
OpenGL의 Core-profile mode를 사용할 때, OpenGL은 우리에게 현대적인 방식을 사용하도록 강요합니다. OpenGL의 사용 중단된 함수 중 하나를 사용하려고 할 때마다 OpenGL은 오류를 발생시키고 그리기를 중지합니다. 현대적인 접근 방식을 배우는 장점은 매우 유연하고 효율적이라는 것입니다. 그러나 배우기도 더 어렵습니다. Immeidate mode는 OpenGL이 실제로 수행하는 작업에서 꽤 많은 부분을 추상화했으며, 배우기는 쉬웠지만 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의 훌륭한 기능 중 하나는 extension 지원입니다. 그래픽 회사가 렌더링을 위한 새로운 기술이나 새로운 대규모 최적화를 개발할 때, 이는 종종 드라이버에 구현된 extension 기능에서 발견됩니다. 애플리케이션이 실행되는 하드웨어가 그러한 확장을 지원한다면, 개발자는 더 고급 또는 효율적인 그래픽을 위해 extension기능을 사용할 수 있습니다. 이런 방식으로 그래픽 개발자는 OpenGL이 이후 버전에 기능을 포함시킬 때까지 기다릴 필요 없이 그래픽 카드가 extension 지원 여부를 확인하는 것만으로 이러한 새로운 렌더링 기술을 계속 사용할 수 있습니다. 종종, extension 인기 있거나 유용할 때 해당 기능은 OpenGL 버전의 일부가 됩니다.
개발자는 이러한 extension 을 사용하기 전에 사용 가능한지 여부를 확인해야 합니다(또는 OpenGL extension라이브러리를 사용). 이를 통해 개발자는 확장 가능 여부에 따라 더 나은 방식이나 더 효율적인 방식으로 작업을 수행할 수 있습니다:
if(GL\_ARB\_extension\_name)
{
// 하드웨어가 지원하는 최신 extension기능 사용
}
else
{
// extension 지원 안됨: 예전 방식으로 하기
}
OpenGL 버전 3.3에서는 대부분의 기술에 확장이 거의 필요하지 않지만, 필요한 경우에는 적절한 지침이 제공됩니다.
상태 머신(State machine)
OpenGL은 그 자체로 하나의 큰 State machine입니다. State machine은 OpenGL이 현재 어떻게 작동해야 하는지 정의하는 변수 모음입니다. OpenGL의 상태는 일반적으로 OpenGL Context라고 합니다. OpenGL을 사용할 때, 우리는 종종 일부 옵션을 설정하고, 일부 버퍼(buffer)를 조작한 다음 현재 Context를 사용하여 렌더링함으로써 그 상태를 변경합니다.
예를 들어, 삼각형 대신 선을 그리고 싶다고 OpenGL에 알릴 때마다, 우리는 OpenGL이 어떻게 그려야 하는지 설정하는 일부 콘텍스트 변수(context var)를 변경함으로써 OpenGL의 상태를 변경합니다. OpenGL에게 선을 그려야 한다고 알려 context를 변경하는 순간, 다음 그리기 명령(drawing commands)은 삼각형(triangle) 대신 선(line)을 그립니다.
OpenGL에서 작업할 때, 우리는 context를 변경하는 여러 상태 변경(state-changing)함수와 OpenGL의 현재 상태를 기반으로 일부 작업을 수행하는 여러 상태 사용(state-using) 함수를 만나게 됩니다. OpenGL이 기본적으로 하나의 큰 상태 머신(State machine)이라는 점을 명심하면, 대부분의 기능이 더 이해하기 쉬워집니다.
객체(Objects)
OpenGL 라이브러리는 C로 작성되었으며 다른 언어에서 많은 파생을 허용하지만, 핵심적으로는 C 라이브러리로 남아 있습니다. C의 많은 언어 구성이 다른 고수준 언어로 잘 번역되지 않기 때문에, OpenGL은 몇 가지 추상화를 염두에 두고 개발되었습니다. 그 추상화 중 하나가 OpenGL Object입니다.
OpenGL의 객체는 OpenGL 상태의 하위 집합을 나타내는 옵션 모음입니다. 예를 들어, drawing window를 나타내는 객체가 있다면, size, 지원하는 color 수 등을 설정할 수 있습니다. 객체를 C와 유사한 구조체로 시각화할 수 있습니다:
struct object\_name {
float option1;
int option2;
char\[\] name;
};
객체를 사용하고 싶을 때는, 일반적으로 다음과 같은 모습입니다(OpenGL의 컨텍스트를 큰 구조체로 시각화):
// OpenGL의 상태
struct OpenGL\_Context {
...
object\_name\* object\_Window\_Target;
...
};
// Object 생성
unsigned int objectId = 0;
glGenObject(1, &objectId);
// 객체를 컨텍스트에 바인딩/할당
glBindObject(GL\_WINDOW\_TARGET, objectId);
// 현재 GL\_WINDOW\_TARGET에 바인딩된 객체의 옵션 설정
glSetObjectOption(GL\_WINDOW\_TARGET, GL\_OPTION\_WINDOW\_WIDTH, 800);
glSetObjectOption(GL\_WINDOW\_TARGET, GL\_OPTION\_WINDOW\_HEIGHT, 600);
// 컨텍스트 타겟을 기본으로 되돌림
glBindObject(GL\_WINDOW\_TARGET, 0);
위에 코드는 OpenGL로 작업할 때 자주 볼 수 있는 워크플로우(workflow)입니다. 먼저 객체를 생성하고 ID로 참조를 저장합니다(실제 객체의 데이터는 뒤에서 저장됨). 그런 다음 객체를 (ID를 사용) 컨텍스트의 대상 위치에 바인딩합니다(예제에서 window object의 target 위치는 GL_WINDOW_TARGET으로 정의됨). 다음으로 window을 설정하고 마지막으로 창 대상의 현재 객체 ID를 0으로 설정하여 객체를 언바인드합니다. 우리가 설정한 옵션은 objectId가 참조하는 객체에 저장되며 객체를 GL_WINDOW_TARGET에 다시 바인딩하는 즉시 복원됩니다.
이러한 객체를 사용하는 멋진 점은 애플리케이션에서 둘 이상의 객체를 정의하고, 옵션을 설정한 다음 OpenGL 상태를 사용하는 작업을 시작할 때마다 선호하는 설정이 있는 객체를 바인딩할 수 있다는 것입니다. 예를 들어 3D 모델 데이터(집이나 캐릭터)의 컨테이너 객체 역할을 하는 객체가 있으며, 그 중 하나를 그리고 싶을 때마다 그리려는 모델 데이터가 포함된 객체를 바인딩합니다(먼저 이러한 객체를 생성하고 옵션을 설정했습니다). 여러 객체를 가지면 많은 모델을 지정할 수 있으며, 특정 모델을 그리고 싶을 때마다 모든 옵션을 다시 설정하지 않고 그리기 전에 해당 객체를 바인딩하기만 하면 됩니다.
시작하기
OpenGL에서 스펙과 라이브러리가 대략 전체적으로 어떻게 작동하는지, 그리고 OpenGL이 사용하는 몇 가지 방식 대해 조금 배웠습니다. 모든 것을 이해하지 못했더라도 걱정하지 마세요. 책 전체에 걸쳐 각 단계를 함께 살펴보고 OpenGL을 실제로 이해하는 데 충분한 예제를 볼 수 있을 것입니다.
추가 자료
opengl.org: OpenGL의 공식 웹사이트.
OpenGL registry: 모든 OpenGL 버전에 대한 OpenGL 사양 및 확장을 호스팅합니다.
요약
OpenGL은 단지 API 사양일 뿐이고, 실제 라이브러리는 각 그래픽카드 제조업체들이 자사 하드웨어에 맞게 개발합니다. 따라서 드라이버 업데이트가 중요합니다.
과거에는 Immediate mode(고정 함수 파이프라인)를 사용했지만, OpenGL 3.3 이후부터는 Core-profile을 사용하도록 권장합니다. 이 방식은 비록 배우기는 어렵지만 더 유연하고 효율적이며 그래픽 프로그래밍을 더 깊이 이해할 수 있게 해줍니다.
현재 최신판은 OpenGL 4.6이지만, 3.3부터 핵심 개념과 메커니즘은 동일하기 때문에 3.3을 배워도 충분합니다. 4.6을 사용할 경우 낮은 사양의 그래픽카드에서는 호환성 문제가 발생할 수 있습니다.
OpenGL은 State machine(상태 기계)이며, 이 상태 모음을 Context(컨텍스트)라고 부릅니다. OpenGL을 사용할 때는 옵션을 설정하고, 버퍼를 조작한 다음 현재 컨텍스트를 사용하여 렌더링합니다.
OpenGL에서 일반적인 워크플로우는:
- 객체 생성(ID 할당)
- 객체를 컨텍스트에 바인딩
- 바인딩된 객체에 대한 옵션 설정
- 필요한 작업 수행
- 작업 완료 후 언바인딩(ID를 0으로 설정)
피드백 언제나 환영입니다.:)
날씨가 점점 풀려서 좋네요 !
'컴퓨터 공학 > OpenGL' 카테고리의 다른 글
[최신 OpenGL 시작하기 #1_4] 삼각형 만들기 (Hellow Triangle) (2) | 2025.03.04 |
---|---|
[최신OpenGL 시작하기 #1_3] Hellow Window (10) | 2025.02.28 |
[최신OpenGL 시작하기 #1_2] Window 창 만들기 (개발 환경 설정) (0) | 2025.02.26 |
[최신OpenGL 소개#0] 소개(Introduction) (2) | 2025.02.25 |
[최신OpenGL] 포스팅에 들어가기 앞서 (2) | 2025.02.25 |