OpenGLES Programming Guide for iOS 번역 - 2장. OpenGL ES 컨텍스트 설정

OpenGL ES/iOS 2011. 9. 21. 11:20

본 번역은 얼마든지 정확하지 않을 수 있습니다. 참고용으로만 보시길... ^^;;;


OpenGL ES의 모든 구현은 OpenGL ES 사양에서 요구되는 상태를 관리하기 위한 렌더링 컨텍스트를 생성하는 수단을 제공합니다. 이 상태를 컨텍스트에 배치하여 다른 응용 프로그램 상태에 간섭하지 않고 여러 응용 프로그램에서 그래픽 하드웨어를 쉽게 공유할 수 있습니다.

이 장에서는 iOS 에서 컨텍스트를 만들고 설정하는 방법을 설명합니다.

EAGL 컨텍스트는 OpenGL ES 렌더링 컨텍스트 iOS 의 구현

응용프로그램이 OpenGL ES 함수를 호출할 수 있도록 하려면 응용프로그램이 EAGLContext 개체를 초기화하고 이 개체를 현재 컨텍스트로 설정해야 합니다. EAGLContext 클래스는 응용프로그램이 OpenGL ES 콘텐츠 Core Animation에 통합하는 데 사용하는 수단을 제공합니다. 이러한 수단이 없으면 응용프로그램은 오프 스크린 이미지 작업 밖에 할 수 없습니다.

현재 컨텍스트는 스레드에서 생성한 OpenGL ES 함수 호출의 대상

iOS 응용 프로그램의 모든 스레드가 현재 컨텍스트를 보유하고 있습니다. 응용 프로그램이 OpenGL ES 함수를 호출할 때 해당 스레드의 컨텍스트 함수 호출에 의해 변경됩니다.

현재 컨텍스트를 설정하려면 EAGLContext 클래스 메소드인 setCurrentContext : 을 호출합니다.

[EAGLContext setCurrentContext : myContext];

응용프로그램은 EAGLContext 클래스 메서드 currentContext 를 호출하여 스레드의 현재 컨텍스트를 얻을 수 있습니다.
응용프로그램에서 새 컨텍스트를 설정하면 EAGL 이전 컨텍스트를 해제(이전 컨텍스트가있는 경우)하고 새로운 컨텍스트를 유지합니다.

참고 : 응용프로그램이 동일한 스레드에서 2개 이상의 컨텍스트를 활성화 전환 경우 새 컨텍스트를 현재 컨텍스트에 설정하기 전에 glFlush 함수를 호출합니다. 그러면 사전에 전송되지 명령은 적절한 타이밍에 그래픽 하드웨어에 전달됩니다.

OpenGL ES의 모든 컨텍스트 대상 특정 버전

EAGLContext 개체는 OpenGL ES 1.1 또는 OpenGL ES 2.0 중 하나를 지원하지만 모두 지원하는 것은 아닙니다.
그 이유는 OpenGL ES 2.0 의 디자인에 있습니다. OpenGL ES 2.0 은 OpenGL ES 1.1 에 존재하는 고정 기능 그래픽 파이프라인을 다루는 모든 함수를 제거하고 쉐이더 기반 깨끗한 인터페이스를 제공하는 많은 새로운 기능을 추가했습니다.
응용프로그램이 OpenGL ES 1.1 의 컨텍스트에서 OpenGL ES 2.0 의 함수를 호출하려고하는 경우 (또는 그 반대로 할 경우)의 결과는 정의되지 않습니다.
응용프로그램은 EAGLContext 개체를 만들고 초기화할 때 어떤 버전의 OpenGL ES 를 지원하는지 여부를 결정합니다. OpenGL ES 2.0 컨텍스트를 만들려면 다음과 같이 응용 프로그램이 EAGLContext 개체를 초기화합니다

EAGLContext * myContext = [[EAGLContext alloc] initWithAPI : kEAGLRenderingAPIOpenGLES2];

응용 프로그램에서 OpenGL ES 1.1 을 사용하려면 다른 상수를 사용하여 초기화합니다.

EAGLContext * myContext = [[EAGLContext alloc] initWithAPI : kEAGLRenderingAPIOpenGLES1];

요청된 버전의 OpenGL ES 장치가 지원하지 않는 경우 initWithAPI : 메소드는 nil 을 반환합니다. 응용 프로그램은 컨텍스트가 올바르게 초기화되었는지 확인하기 위해 컨텍스트를 사용하기 전에 반드시 확인하십시오. OpenGL ES 2.0 및 OpenGL ES 1.1 모두 렌더링 옵션을 지원하려면 응용 프로그램을 처음 OpenGL ES 2.0 렌더링 컨텍스트 초기화를 시도할 필요가 있습니다. 반환되는 객체가 nil 이면 OpenGL ES 1.1 컨텍스트를 초기화합니다. 목록 2-1 에서는이 방법을 소개하고 있습니다.

목록 2-1 같은 응용프로그램에서 OpenGL ES 1.1 및 OpenGL ES 2.0 지원

EAGLContext * CreateBestEAGLContext ()
{
    EAGLContext * context;
    context = [EAGLContext alloc] initWithAPI : kEAGLRenderingAPIOpenGLES2];
    if (context == nil)
    {
         context = [EAGLContext alloc] initWithAPI : kEAGLRenderingAPIOpenGLES1];
    }
    return context;
}

컨텍스트 API 속성은 컨텍스트가 지원하는 OpenGL ES 버전을 나타냅니다. 응용 프로그램 컨텍스트 API 속성을 테스트하고 그 속성을 사용하여 올바른 렌더링 경로를 선택합니다. 이것을 구현하는 일반적인 패턴은 각 렌더링 경로에 대해 클래스를 만드는 것입니다. 응용프로그램이 초기화될 때 컨텍스트를 테스트하고 한 번 렌더러를 만듭니다.

EAGL Sharegroup는 Context의 OpenGL ES 개체를 관리한다.

컨텍스트는 OpenGL ES 의 상태를 유지하지만, OpenGL ES 개체를 직접 관리하는 것은 없습니다. OpenGL ES 개체는 EAGLSharegroup 객체에 의해 생성되고 유지됩니다. 어떤 컨텍스트에 개체를 만들 위임 EAGLSharegroup 개체가 포함됩니다.

sharegroup 의 장점은 2 개 이상의 문맥이 같은 sharegroup 를 참조하는 경우에 밝혀져있다 (그림 2-1 참조).
복수의 문맥이 공통 sharegroup 에 연결되어있는 경우 어떤 컨텍스트에서 만든 OpenGL ES 객체는 모든 컨텍스트에서 사용할 수 있습니다. 개체를 만든 컨텍스트가 아닌 다른 컨텍스트에서 동일한 객체 식별자에 바인딩하면 같은 OpenGL ES 개체를 참조합니다. 리소스는 모바일 장치에서 희귀한 경우가 적지 않습니다. 여러 컨텍스트에서 동일한 내용의 여러 복사본을 작성하는 것은 비효율적입니다. 공통 자원을 공유하여 장치의 그래픽 리소스 공간을보다 효과적으로 사용할 수 있습니다.

응용프로그램은 sharegroup 을 불투명 개체로 취급할 수 있습니다. sharegroup 응용프로그램이 호출할 수있는 메소드와 속성이 아니라 소스의 컨텍스트에 따라 자동으로 유지되고, 풀어 놓이고합니다.

그림 2-1. 2개 컨텍스트의 OpenGL ES 개체 공유



sharegroup 은 다음 2 가지 구체적인 시나리오에서 가장 유용합니다.

● 컨텍스트간에 공유되는 리소스의 대부분이 변경되지 않는 경우.

● 렌더 러의 주 스레드 이외의 스레드에서 응용 프로그램이 새로운 OpenGL ES 개체를 만들 수 있도록하려는 경우. 이 경우 2 번째 컨텍스트는 별도의 스레드에서 실행되고 데이터의 인출과 리소스를 만드는 데 충당됩니다. 리소스가 로드된 후 첫 컨텍스트는 개체에 바인딩하여 즉시 사용할 수 있습니다.

같은 sharegroup 를 참조하는 여러 컨텍스트를 만들려면 먼저 컨텍스트를 initWithAPI : 을 호출하여 초기화합니다. sharegroup 는 컨텍스트에 대해 자동으로 생성됩니다. 2 번째 이후의 컨텍스트는 initWithAPI : sharegroup : 메서드를 호출하여 첫 번째 컨텍스트 sharegroup 를 사용하도록 초기화됩니다. 목록 2-2 에서는이 이론을 설명하고 있습니다 처음 컨텍스트는 목록 2-1 ( 24 페이지)로 정의되는 간단한 함수를 사용하여 작성됩니다. 2 번째 컨텍스트 먼저 컨텍스트에서 API 버전과 sharegroup 을 추출하여 만들어집니다.

중요 : 동일한 sharegroup 에 관련된 모든 컨텍스트는 초기 컨텍스트와 동일한 버전의 OpenGL ES API 를 사용해야합니다.

목록 2-2  공통 sharegroup 있는 2 개의 문맥의 작성

EAGLContext * firstContext = CreateBestEAGLContext ();
EAGLContext * secondContext =
    [[EAGLContext alloc] initWithAPI : [firstContext API]
sharegroup : [firstContext sharegroup]];

sharegroup 여러 컨텍스트에서 공유되고있는 경우 OpenGL ES 개체 발생 상태의 변화 관리 응용 프로그램의 책임입니다. 변화 관리에 대한 규칙은 다음과 같습니다.

● 개체 수정 중이 아닐 경우 여러 컨텍스트에 걸쳐 동시에 그 개체에 액세스할 수 있다.

● 컨텍스트에 전송된 명령에 의해 객체가 수정되는 동안 개체를 읽거나 다른 컨텍스트에서 개체를 수정하거나 하지한다.

● 객체가 수정되면 모든 컨텍스트에서 개체를 다시 바인딩하고 변경을 인식할 필요가있다. 개체의 내용은 컨텍스트 바인딩하기 전에 개체를 참조하는 경우 정의되지 않는다.

OpenGL ES 개체를 업데이트하기 위해 응용 프로그램이 따르는 절차는 다음과 같습니다.

1. 오브젝트를 사용할 수 있는 컨텍스트마다 glFlush 를 호출한다.
2. 오브젝트를 수정하는 문맥에서 1 개 이상의 OpenGL ES 함수를 호출하여 개체를 변경.
3. 상태 변경 명령을 수신하는 문맥에서 glFlush 를 호출한다.
4. 다른 각 컨텍스트에서 개체 식별자를 다시 바인딩합니다

참고 : 개체를 공유하는 1 개의 방법은 단일 렌더링 컨텍스트가 아닌 여러 렌더링 대상 프레임 버퍼를 ​​사용하는 것입니다. 렌더링 시에 응용프로그램은 적절한 프레임 버퍼를 ​​바인딩하고 필요에 따라 프레임을 렌더링합니다. 모든 OpenGL ES 객체는 하나의 컨텍스트에서 참조되므로 OpenGL ES 객체는 동일한 OpenGL ES 데이터를 인식하고 있습니다. 이 방법은 적은 리소스를 사용하지만, 컨텍스트의 상태를 신중하게 제어할 수 있는 단일 스레드 응용 프로그램에서만 유용합니다.

: