opengl 이란? opengl 개념 정리 [Learn OpenGL 쉬운 번역]

728x90
반응형
※ 본 포스팅은 learnopengl.com을 번역 및 가감한 포스팅이며, learnopengl에서는 번역 작업 참여를 적극 장려하고 있습니다!
아래 링크에서 원문을 확인할 수 있습니다.

 

OpenGL

opengl이라는 것은 뭘까요?

"그래픽과 이미지를 조작하기 위해 사용할 수 있는 많은 함수 집합을 제공하는 API(Application Porgram Interface)"

라고 하면 와닿으시나요?

 

핵심만 짚자면 "그래픽을 사용할 수 있는 함수의 집합" 인데,

opengl은 API라고 하기에도 애매하고 엄밀히는 크로노스라 그룹(Khronos Group)이라는 단체가 만든 명세서입니다.

 

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

명세서라는 것은 함수의 입출력과 동작 방식을 적어놓은 문서를 말하는데요. opengl이 그렇다는 겁니다.

opengl 개발자들은 이 명세서를 구현하는데, 명세서이기 때문에 어떻게 사용하는지에 대해서는 나와있지만 어떻게 구현되어있는지에 대해서는 제공하지 않습니다. 즉 버전이 달라지면 명세서가 같더라도 내부적인 구현 방식이 다를 수 있다는 거죠(그래도 사용자가 보는 결과는 똑같습니다).

 

실제로 opengl의 라이브러리를 개발하는 사람들은 그래픽 카드 제조업체입니다. 그래픽 카드의 종류별로 지원하는 opengl 버전이 다릅니다. Apple의 OS를 이용하면 opengl 라이브러리를 Apple이 관리하고, Linux에서는 공식적으로 제공된 버전과 달리 개발자들이 별도로 개발한 버전도 있습니다.

만약 opengl 라이브러리 동작이 이상하다면 라이브러리를 개발한 그래픽 카드 업체가 문제라는 말이겠죠.

따라서 버그가 생기면 그래픽 드라이버를 업데이트하면 해결되는 경우가 많습니다. 그래픽 드라이버를 업데이트해서 opengl의 최신 버전을 사용하는걸 권장드립니다.

 

khronos 사이트에서 opengl의 전 버전에 대한 명세서를 확인할 수 있습니다. 여기서는 opengl 3.3 을 사용하는데, 아래 링크에서 이 명세서를 볼 수 있습니다. 자세히 보고 싶으시다면요.

 

 

Core-profile vs Immediate mode

예전에는 opengl 개발을 immediate mode(즉시 모드)로 개발했다고 합니다. 이는 fixed funciton pipeline(고정 기능 파이프라인)이라고도 합니다.

 

이게 간편한 방법이었다고는 하는데, opengl 기능들이 라이브러리 내부에 숨어있어서 개발자들이 이 연산들을 잘 컨트롤하지 못했습니다.

 

개발자는 코드의 유연성을 요구하는 법이죠. opengl은 시간이 지나며 유연한 사양을 가졌고, 개발자들이 그래픽을 더 자유롭게 컨트롤하게 되었습니다.

 

이를테면 immediate mode는 쉽지만 효율적이지는 못했던 겁니다.

 

그러다보니 opengl의 사양은 3.2버전 이후로 immediate mode를 권장하지 않게 되었고, 오래된 것들은 deprecated (제거)된 core-profile mode로 개발하는게 위주가 되었습니다.

 

 

core-profile mode라는건 현대적인 방식을 고수하기 때문에, deprecated된 함수를 사용하면 에러가 뜹니다.

하지만 이 방식은 개발자들이 권장하는 만큼 유연하고 효율적입니다. 배우기가 어려울 수도 있다고는 하네요.
(하지만 한국어로 번역하는 입장에서는 이전 버전을 사용해보지 않아 알 턱이 없습니다)

 

그래서 보통 opengl을 사용한다고 하면 최근에는 3.3 버전 이상의 core-profile로 사용한답니다. learn opengl 사이트가 작성되면서도 4.6 버전이 있었다고 합니다. 그런데도 3.3버전을 기준으로 공부하는 이유는 뭘까요?

 

learn opengl은 단순한 답변을 줍니다. opengl 3.3 이후로는 핵심 매커니즘이 딱히 변경되지 않았기 때문이랍니다. 좀 더 유용한 함수가 나오긴 하지만 필수적이지는 않은 모양입니다.

 

opengl 최신 버전을 사용한다면, 그래픽 카드도 그에 따라 최신 것이어야한다는건 단점입니다. 
그래서 다양한 사람들이 함께 쓰기에는 공통되면서도 낮은 버전을 타겟으로하는게 좋은 것 같습니다.

최신 버전 기능들이 나오면 별도로 표시됩니다.

 

Extensions

opengl은 확장 기능을 지원하는데 장점이 있습니다. 그래픽 회사가 새로운 기술이나 대규모 렌더링 최적화 개발을 할 때 드라이버에 이러한 확장 기능을 많이 사용합니다.

 

확장 기능은 여러모로 고급스럽고 효율적인 그래픽을 하드웨어가 프로그램 상에서 실행할 수 있게 도와줍니다.

그래서 opengl 버전 업데이트 없이도, 확장 기능을 그래픽 카드가 사용할 수 있다면 충분히 새로운 기술을 도입할 수 있습니다.

 

다른 API처럼 보편적인 확장이라면 추후 버전에 포함되기도 하겠죠.

 

확장 기능을 사용하기 전에 사용 가능한지 확인해야합니다. 이걸 기술적으론 query(질문)한다고 표현합니다. 

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은 그 자체로 하나의 상태 머신이라고 볼 수 있습니다.

상태 머신이라는 것은 opengl이 어떻게 동작해야하는지 정의하는 변수들이 모여있는 구조을 말합니다. opengl에서 상태는 보통 opengl context라고 부릅니다. 

 

opengl을 사용하게 되면 몇 가지 옵션을 설정하고 버퍼를 조작하는데, 그 후 context를 사용하여 렌더링하면서 상태를 변경합니다.

 

만약 opengl에 삼각형이 아니라 선을 그리는 명령을 한다고 가정합시다. 개발자는 opengl에게 context 변수를 변경해서 상태를 변경하여 이 명령을 전달합니다. 이렇게 context를 통해 전달된 명령을 통해 opengl이 삼각형이 아니라 선을 그리게 할 수 있습니다.

 

작업을 하면서 다양한 state-changing(상태변경)함수와 state-using(상태사용)함수들을 보게 될 겁니다. 이렇게 opengl은 state machine 구조를 기반으로 동작한다는 것을 알아두시길 바랍니다. 

Objects

opengl 라이브러리는 C언어로 작성되어있기 때문에 다른 언어로 파생될 수도 있습니다. 기본적으로 core 라이브러리는 C언어 기반입니다.

 

C언어는 다른 고급언어로 변환되는게 쉽지는 않은데요. 때문에 opengl에서는 추상화 방법으로 objects라는 형태를 사용합니다.

 

objects에서는 opengl의 상태를 다나내는 옵션들이 있습니다. window 설정을 나타내는 객체를 통해 창의 크기, 지원 색상 등을 설정 가능합니다. 이 구조는 C언어의 struct(구조체)와 유사하게 볼 수 있습니다. 

 

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

 

objects는 위 코드와 같이 구성되어있습니다. opengl의 context 또한 이러한 구조체로 볼 수 있습니다.

 

// 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을 할 때 자주 보게 될 코드들인데요. object를 생성하고 해당 object에 대한 reference를 id로 저장합니다. object의 실제 데이터는 내부에서 관리됩니다.

 

그 다음, object id를 사용하여 context의 target 위치에 binding합니다.

여기서는 window object에 정의하기 위해 GL_WINDOW_TARGET에 하게 됩니다.

 

그리고 window 옵션을 설정하고, 마지막으로 window target의 현재 object id를 0으로 설정해서 binding을 해제시킵니다.

이 과정으로 설정한 옵션들은 reference한 object에 저장되었기에, object를 다시 GL_WINDOW_TARGET에 binding하면 옵션이 복원됩니다.

여기까지는 작동 방식에 대한 샘플들입니다.
다음 예제들을 통해 실제 코드를 배우게 됩니다.

object를 사용하는 것의 장점은

애플리케이션에서 여러 object를 정의해서 각각 옵션을 설정하면, opengl 의 특정 상태가 필요한 작업에서 원하는 설정을 가진 object를 binding하는 것으로 처리할 수 있게 됩니다.

 

예를 들면, 3D 모델을 담는 object가 있으면 이 모델을 그리고 싶을 때는 모델 object를 binding하면 됩니다. (물론 object 생성과 옵션 설정 과정을 모두 한 다음에요)

여러 object를 사용하면 모델도 여러 개 지정할 수 있겠죠. 각 상황에 따라 옵션을 제각기 설정할 필요가 없게 됩니다. 

 

Let's get started

이제 opengl이 무엇이고 어떻게 동작하는지 알았나요? 앞으로 예제를 통해 더 자세한 것들을 공부할 겁니다. 

Additional resources

다음 사이트들을 통해 추가적인 정보를 얻을 수 있어요.

 

 

OpenGL - The Industry Standard for High Performance Graphics

It has been a while in the making but we are very excited to launch the new Vulkan website to the community. Don’t worry, Vulkan is still maintained and owned by The Khronos Group; we just felt that it had outgrown its old website now that it has been fi

www.opengl.org

 

 

Khronos OpenGL® Registry - The Khronos Group Inc

Khronos OpenGL® Registry

registry.khronos.org

 

728x90
반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유