Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

RedBook

.pdf
Скачиваний:
20
Добавлен:
11.06.2015
Размер:
7.43 Mб
Скачать

включенным и выключенным цветовым наложением, установите факторы наложения в GL_ONE и GL_ZERO вместо того, чтобы вызывать glDisable(GL_BLEND). (Это может потребоваться, например, если в некоторых кадрах анимации должно работать цветовое наложение, а в некоторых нет.) Альфа тестирование, тест трафарета, тест глубины и логические операции все это может быть заблокировано подобным образом.

Наконец, OpenGL требует, чтобы пофрагментая арифметика, такая как цветовое наложение и тест глубины, была инвариантна по отношению к (независима от) всех элементов состоянию OpenGL за исключением тех, которые непосредственно ее определяют. Например, единственные параметры OpenGL, влияющие на то, как производятся арифметические операции для цветового наложения это факторы источника и приемника, а также флаг активности цветового наложения. Цветовое наложение инвариантно по отношению ко всем остальным изменениям состояния. Такая инвариантность имеет место для теста отреза, альфа теста, теста глубины, теста трафарета, цветового наложения, цветового микширования, логических операций и масок записи.

Как результат всех этих требований инвариантности, OpenGL может гарантировать, что два изображения, одновременно или по очереди визуализированные в разных цветовых буферах с использованием одной и той же последовательности команд, являются попиксельно идентичными. Это касается всех цветовых буферов в буфере кадра, а также всех цветовых буферов во внеэкранном буфере, но это не относится к буферу кадра и внеэкранному буферу взятым вместе.

Приложение H. OpenGL и оконные системы

OpenGL доступна на множестве различных платформ и работает со множеством различных оконных систем. OpenGL разработана для дополнения оконных систем, а не для дублирования их функциональности. Вследствие этого OpenGL выполняет визуализацию геометрии и изображений в двумерном и трехмерном пространствах, но она не управляет окнами и не обрабатывает события пользовательского ввода.

Однако базовые определения большинства оконных систем не поддерживают такую сложную библиотеку, как OpenGL, с ее сложными и множественными форматами пикселей, буферами трафарета, глубины и аккумуляции, а также двойную буферизацию. Для большинства оконных систем были добавлены функции, расширяющие эти системы поддержкой OpenGL.

В этом приложении представлены расширения, определенные для нескольких оконных и операционных систем: X Windows System, Apple Mac OS, IBM OS/2 Warp и Microsoft Windows 95/98/NT. Для полного понимания приложения вам понадобятся некоторые знания об оконных системах.

GLX: Расширения OpenGL для X Window System

В системе X Window визуализация OpenGL реализована в качестве расширения к X в формальном понимании этого термина. GLX представляет собой расширение протокола X (и ассоциированного с ним API) для взаимодействия команд OpenGL с расширенным сервером X. Соединение и аутентификация производятся в соответствии с формальным механизмом X.

Как и в случае других расширений XX, команды OpenGL инкапсулируются внутри потока байт X согласно определенному сетевому протоколу для поддержки клиент серверной визуализации OpenGL. Поскольку быстродействие является критическим для трехмерной визуализации, расширение OpenGL для X позволяет OpenGL избегать вмешательства сервера X в кодирование, копирование и интерпретацию данных и вместо этого осуществлять визуализацию непосредственно на графический конвейер.

GLX версии 1.3 добавил несколько новшеств, например, новую структуру данных GLXFBConfig, описывающую конфигурацию буфера кадра GLX (включая глубину компонент цветового буфера, а также типы и размеры буферов глубины, трафарета, аккумуляции и дополнительных буферов). Структура GLXFBConfig описывает эти атрибуты для поверхности визуализации GLXDrawable. (В X, поверхность визуализации называется Drawable.)

GLX 1.3 поддерживает 3 типа поверхностей GLXDrawable: GLXWindow, GLXPixmap и GLXPbuffer. GLXWindow является экранным, а остальные внеэкранными. Поскольку поверхность GLXPixmap имеет ассоциированную с ней карту пикселей X, и OpenGL и X могут осуществлять визуализацию на этой поверхности. На поверхности GLXPbuffer может осуществлять визуализацию только OpenGL, такие поверхности предназначены для сохранения пиксельных данных в невидимой памяти буфера кадра. (Не гарантируется, что внеэкранная визуализация поддерживается непосредственными визуализаторами.)

X Visual является важной структурой данных для управления форматом пикселей окна OpenGL. Информация о формате пикселей отслеживается с помощью переменной типа XVisualInfo, включая тип пикселей (индексные или RGBA), однократная или двойная буферизация, разрешение цветов, а также наличие буферов глубины, трафарета и аккумуляции. Стандартные объекты X Visual (например, PseudoColor или TrueColor) не описывают деталей пиксельного формата, так что каждая реализация должна расширять число объектов X Visual.

В GLX 1.3 GLXWindow имеет X Visual, ассоциированный с его GLXFBConfig. Для

GLXPixmap и GLXPBuffer может быть, а может и не быть похожего ассоциированного X Visual. До GLX 1.3 все поверхности (окна или пиксельные карты) были ассоциированы с X Visual. (До версии 1.3 P – буферы не были частью GLX.)

Если вам требуется изучить внутренности GLX, его спецификацию можно найти по адресу: ftp://sgigate.sgi.com/pub/opengl/doc/opengl1.2.

Инициализация

Используйте функции glXQueryExtension() и glXQueryVersion() для установления того, присутствует ли расширение GLX для сервера X и, если да, то какой он версии. glXQueryExtensionString() возвращает информацию о клиент серверном соединении. glXGetClientString() возвращает информацию о клиентской библиотеке, включая расширения и номер версии. glXGetServerString() возвращает такую же информацию о сервере.

glXChooseFBConfig() возвращает указатель на массив структур GLXFBConfig, описывающих все возможные конфигурации буфера GLX, удовлетворяющие атрибутам, заданным клиентом. Вы можете использовать glXGetFBConfigAttrib() для установления того, поддерживает ли конфигурация буфера кадра конкретный атрибут GLX. Также вы можете вызвать glXGetVisualFromFBConfig() для получения X Visual, ассоциированного с GLXFBConfig.

Процесс создания областей визуализации несколько различается в зависимости от типа поверхности. Для GLXWindow сначала создайте X Window с X Visual, соответствующим GLXFBConfig. Затем используйте это X Window при вызове функции glXCreateWindow(), которая возвращает GLXWindow. Для GLXPixmap сначала создайте X Pixmap с глубиной пикселей, соответствующей GLXFBConfig. Затем используйте эту Pixmap при вызове функции glXCreatePixmap() для создания

GLXPixmap. GLXPbuffer не требует X Window или X Pixmap – просто вызовите glxCreatePbuffer() с соответствующей структурой GLXFBConfig.

Замечание: Если вы используете GLX 1.2 или меньше, у вас нет структуры GLXFBConfig. Вместо нее используйте функцию glXChooseVisual(), возвращающую указатель на структуру XVisualInfo, описывающую X Visual, соответствующий атрибутам, заданным клиентом. Вы можете опросить X Visual на предмет поддержки определенного атрибута OpenGL с помощью функции glXGetConfig(). Для визуализации на внеэкранную пиксельную карту, вы должны использовать функцию glXCreateGLXPixmap().

Управление визуализацией

GLX предоставляет несколько функций для создания и управления контекстом визуализации OpenGL. Также предоставляются функции для таких задач, как обработка событий GLX, синхронизация потоков исполнения X и OpenGL, переключение переднего и заднего буферов, а также использование X font.

Управление контекстом визуализации OpenGL

Контекст визуализации OpenGL создается функцией glXCreateNewContext(). Один из

аргументов этой функции позволяет вам запросить непосредственный контекст визуализации, который минует X Server, как было описано ранее. (Для осуществления непосредственной визуализации соединение с сервером X должно быть локальным и реализация OpenGL должна поддерживать непосредственную визуализацию.) glXCreateNewContext() также позволяет нескольким контекстам разделять списки отображения и текстурные объекты. Вы можете проверить, является ли контекст OpenGL непосредственным с помощью функции glXIsDirect().

glXMakeContextCurrent() привязывает контекст визуализации к текущему потому визуализации и устанавливает две текущие поверхности для рисования. Вы можете

рисовать на одной из текущих поверхностей для рисования и считывать пиксели с другой. Во многих ситуациях, обе этих поверхности являются одной и той же поверхностью GLXDrawable. glXGetCurrentContext() возвращает текущий контекст.

Вы можете получить текущую поверхность для рисования с помощью glXGetCurrentDrawable(), текущую поверхность для считывания с помощью функции glXGetCurrentReadDrawable(), а текущий X Display – с помощью glXGetCurrentDisplay(). Вы можете использовать glXQueryContext() для выяснения текущих значений атрибутов контекста.

В любое время для одного потока может существовать только один текущий контекст. Если у вас создано несколько контекстов, вы можете копировать группы переменных состояния OpenGL из одного в другой с помощью функции glXCopyContext(). Когда вы закончили работы с отдельным контекстом, уничтожьте его функцией glXDestroyContext().

Замечание: Если у вас GLX 1.2 или меньше, используйте glXCreateContext() для создания контекста визуализации и glXMakeCurrent() для установки его в качестве текущего. Вы не можете объявить поверхность в качестве отдельной поверхности для чтения, и у вас нет функции glXGetCurrentReadDrawable().

Обработка событий GLX

События появились в GLX 1.3. Они возвращаются в стандартном потоке событий X11. Обработка событий GLX была добавлена специально для разрешение проблемы неоднозначности содержимого GLXPbuffer. В GLX 1.3 вы можете использовать glXSelectEvent() для выбора только одного события – GLX_PBUFFER_CLOBBER_MASK. С помощью стандартного механизма обработки события X вы теперь можете засечь повреждение части GLXPbuffer и принять меры для восстановления, если это необходимо. (Вы также можете вызвать glXGetSelectedEvent() для выяснения того, проводите ли вы мониторинг этого события.)

Синхронизация исполнения

Во избежании запросов об исполнении X до того, как визуализация OpenGL закончится, вызовите glXWaitGL(). В этом случае гарантируется, что все вызванные команды OpenGL будут выполнены до того, как начнут исполняться функции визуализации X, вызванные после glXWaitGL(). Хотя тех же результатов можно достигнуть с помощью команды glFinish(), glXWaitGL() не требует дополнительного обращения к серверу и, таким образом, работает эффективнее в ситуациях, когда клиент и сервер OpenGL размещены на разных машинах.

Для предотвращения исполнения последовательностей команд OpenGL перед исполнением вызванных ранее функций визуализации X, используйте glXWaitX(). В этом случае гарантируется, что все вызванные функции X будут выполнены до того, как начнут исполняться команды визуализации OpenGL, вызванные после glXWaitX().

Переключение буферов

Для режима двойной буферизации передний и задний буферы можно переключить вызовом glXSwapBuffer(). glFlush() выполняется как часть этой функции.

Использование X Font

Короткий путь к использованию X Font в OpenGL предоставляется функцией glXUseXFont(). Эта функция строит списки отображения для каждого запрошенного шрифта и его размера, каждый из которых вызывает glBitmap().

Очистка поверхностей

После завершения визуализации, вы можете уничтожить поверхность для рисования с помощью функции glXDestroyWindow(), glXDestroyPixmap() или glXDestroyPbuffer(). (Эти функции отсутствуют в GLX версии 1.2 и ниже, хотя там есть функция glXDestroyGLXPixmap() по смыслу аналогичная glXDestroyPixmap().)

Прототипы GLX

Инициализация

Выяснить, определено ли расширение GLX для сервера X:

bool glXQueryExtension (Display *dpy, int *errorBase, int *eventBase);

Запросить версию и информацию о расширениях клиента и сервера: bool glXQueryVersion (Display *dpy, int *major, int *minor);

const char* glXGetClientString (Display *dpy, int name);

const char* glXQueryServerString (Display *dpy, int screen, int name); const char* glXQueryExtensionString (Display *dpy, int screen);

Получить доступные конфигурации буфера кадра:

GLXFBConfig* glXGetFBConfigs (Display *dpy, int screen, int* nelements);

GLXFBConfig* glXChooseFBConfig (Display *dpy, int screen, const int attribList, int *nelements);

Опросить буфер кадра на предмет атрибута GLX или информации X:

int glXGetFBConfigAttrib (Display *dpy, GLXFBConfig config, int attribute, int *value); XVisualInfo* glXGetVisualFromFB (Display *dpy, GLXFBConfig config);

Создать поверхности для поддержки визуализации (экранной или внеэкранной):

GLXWindow glXCreateWindow (Display *dpy, GLXFBConfig config, Window win, const int* attribList);

GLXPixmap glXCreatePixmap (Display *dpy, GLXFBConfig config, Pixmap pixmap, const int* attribList);

GLXPbuffer glXCreatePbuffer (Display *dpy, GLXFBConfig config, const int* attribList);

Управление визуализацией

Управление и опрос контекста визуализации OpenGL:

GLXContext glXCreateNewContext (Display *dpy, GLXBFConfig config, int renderType, GLXContext shareList, bool direct);

bool glXMakeContextCurrent (Display *dpy, GLXDrawable drawable, GLXDrawable read, GLXContext context);

void glXCopyContext (Display *dpy, GLXContext source, GLXContext dest, unsigned long mask);

bool glXIsDirect (Display *dpy, GLXContext context); GLXContext glXGetCurrentContext (void);

Display * glXGetCurrentDisplay (void);

GLXDrawable glXGetCurrentDrawable (void);

GLXDrawable glXGetCurrentReadDrawable (void);

int glXQueryContext (Display *dpy, GLXContext context, int attribute, int* value); void glXDestroyContext (Display *dpy, GLXContext context);

Запрос событий GLX:

int glXSelectEvent (Display *dpy, GLXDrawable drawable, unsigned long eventMask);

int glXGetSelectedEvent (Display *dpy, GLXDrawable drawable, unsigned long* eventMask);

Синхронизация исполнения:

void glXWaitGL (void);

void glXWaitX (void);

Поменять местами передний и задний буферы:

void glXSwapBuffers (Display *dpy, GLXDrawable drawable);

Использовать X Font:

void glXUseXFont (Font font, int first, int count, int listBase);

Очистить поверхности:

void glXDestroyWindow (Display *dpy, GLXWindow win); void glXDestroyPixmap (Display *dpy, GLXPixmap pixmap); void glXDestroyPbuffer (Display *dpy, GLXPbuffer pbuffer);

Устаревшие прототипы

Следующие функции являются устаревшими по отношению к GLX 1.3. Если вы используете GLX 1.2 или его предшественника, вам могут понадобиться некоторые из них.

Получить желаемый объект X Visual:

XVisualInfo* glXChooseVisual (Display *dpy, int screen, int* attribList); int glXGetConfig (Display *dpy, XVisualInfo* visual, int attrib, int* value);

Управление контекстом OpenGL:

GLXContext glXCreateContext (Display *dpy, XVisualInfo *visual, GLXContext shareList, bool direct);

bool glXMakeCurrent (Display *dpy, GLXDrawable drawable, GLXContext context);

Внеэкранная визуализация:

GLXPixmap glXCreateGLXPixmap (Display *dpy, XVisualInfo *visual, Pixmap pixmap); void glXDestroyGLXPixmap (Display *dpy, GLXPixmap pix);

AGL: Расширения OpenGL для Apple Macintosh

В этом разделе описаны функции, определенные в качестве расширений OpenGL для Apple Macintosh (AGL). Здесь требуется понимание того, как Macintosh производит графическую визуализацию (QuickDraw).

Для получения более подробной информации (включая способы получения программной библиотеки для Macintosh) вы можете получить на сайте Apple: http://www.apple.com/opengl.

Визуализация OpenGL для Macintosh реализуется через библиотеку, которая либо присоединяется к приложению, либо является резидентной для приложения, которое хочет ее использовать. Для систем, в которых отсутствует аппаратная поддержка,

OpenGL реализована на программном уровне. Если поддержка имеется, используются ее возможности, соответствующие требованиям конвейера OpenGL, а остальные реализуются программно.

Тип данных AGLPixelFormat (аналог AGL для XVisualInfo) хранит информацию о формате пикселей, включая тип пикселей (индексные или RGBA), тип буферизации (однократная или двойная), разрешение цветов, а также наличие буферов глубины, трафарета и аккумуляции.

В отличие от реализаций OpenGL для других систем (например, для X Window System) клиент серверная модель не используется. Однако вам все равно может понадобиться команда glFlush(), поскольку некоторая аппаратура может буферизовать команды OpenGL и требовать толчка, чтобы их выполнить.

Инициализация

Используйте функцию aglGetVersion() для определения присутствующей версии AGL

для Macintosh.

Соответствие возможностей нижележащих графических устройств и ваших требований к буферам визуализации устанавливается с помощью функции aglChoosePixelFormat(). Она возвращает структуру AGLPixelFormat или NULL в зависимости от того, могут ли быть выполнены ваши требования.

Визуализация и контексты

Для создания и управления контекстом OpenGL AGL предоставляет несколько функций.

Вы можете использовать контекст и для визуализации в окне и для внеэкранной визуализации. Также предоставляются функции для переключения переднего и заднего буферов, для использования шрифтов и для изменения настроек буфера в ответ на перемещение, изменение размера или событие от аппаратуры. Буферы для программной визуализации (и в некоторых случаях для аппаратной) создаются в системной памяти.

Управление контекстом визуализации OpenGL

Контекст OpenGL создается (должен быть как минимум один контекст на каждое окно, в которое осуществляется визуализация) с помощью функции aglCreateContext(). Она

принимает выбранный вами формат пикселей в качестве аргумента и использует его при инициализации буфера.

Используйте aglSetDrawable() для присоединения контекста к поверхности рисования и, далее, aglSetCurrentContext() для того, чтобы сделать контекст текущим. Только

один контекст может быть текущим для одного потока управления в каждый конкретный момент. Это определяет, на какую поверхность производится визуализация, и какой контекст следует использовать совместно с ней. Для

визуализации на одну и ту же поверхность может быть использовано более одного контекста (не одновременно). Определить текущий контекст визуализации и поверхность визуализации позволяют две функции: aglGetCurrentContext() и aglGetDrawable().

Если у вас создано несколько контекстов, вы можете копировать группы переменных состояния OpenGL из одного в другой с помощью функции aglCopyContext(). Когда вы закончили работы с отдельным контекстом, уничтожьте его функцией aglDestroyContext().

Экранная визуализация

Для экранной визуализации сначала создайте формат пикселей. Затем создайте

контекст на основании этого формата пикселей и присоедините его к окну с помощью функции aglSetDrawable(). Прямоугольник буфера может быть изменен с помощью вызова aglSetInteger(AGL_BUFFER_RECT, ...).

Внеэкранная визуализация

Для внеэкранной визуализации создайте формат пикселей с атрибутом AGL_OFFSCREEN. Затем создайте контекст на основании этого формата пикселей и свяжите его с экраном с помощью функции aglSetOffScreen().

Полноэкранная визуализация

Для полноэкранной визуализации создайте формат пикселей с атрибутом AGL_FULLSCREEN. Затем создайте контекст на основании этого формата пикселей и свяжите его с экраном с помощью функции aglSetFullScreen().

Переключение буферов

Для поверхностей с двойной буферизацией (для формата пикселей текущего контекста) используйте aglSwapBuffers() для переключения переднего и заднего буферов. Переключаемый прямоугольник может быть настроен с помощью вызова aglSetInteger(AGL_SWAP_RECT, ...). glFlush() выполняется как часть этой функции.

Обновление буферов визуализации

Apple Macintosh требует от вас производить собственную обработку событий и не позволяет библиотекам автоматически подключаться к потоку событий. Чтобы поверхности под управлением OpenGL могли изменяться в размере, положении и глубине пикселей, AGL представляет функцию aglUpdateContext().

Эта функция должна вызываться вашим кодом обработки событий, как только одно из этих событий произойдет на текущей поверхности. В идеале, стоит перерисовать сцену после обновления для учета изменений в буфере визуализации.

Использование шрифтов Apple Macintosh

Простой путь использования шрифтов Apple Macintosh предоставляется с помощью функции aglUseFont().Эта функция строит списки отображения для каждого запрошенного шрифта и его размера, каждый из которых вызывает glBitmap().

Обработка ошибок

Для расширения OpenGL в системе Apple Macintosh предоставляется механизм обработки ошибок. Когда ошибка произошла, вы можете вызвать функцию aglGetError() для более точного описания того, что вызвало эту ошибку.

Прототипы AGL

Инициализация

Получить информацию о версии:

void aglGetVersion (GLint* major, GLint* minor);

Получить доступные форматы пикселей:

AGLPixelFormat aglChoosePixelFormat (const AGLDevice* gdevs, GLint ndev, onst GLint *attribs);

void aglDestroyPixelFormat (AGLPixelFormat pix); AGLPixelFormat aglNextPixelFormat (AGLPixelFormat pix);

GLboolean aglDescribePixelFormat (AGLPixelFormat pix, GLint attrib, GLint *value); AGLDevice* aglDevicesOfPixelFormat (AGLPixelFormat pix, GLint *ndevs);

Информация о визуализаторе:

AGLRendererInfo aglQueryRendererInfo (const AGLDevice* gdevs, GLint ndev); void aglDestroyRendererInfo (AGLRendererInfo rend);

AGLRendererInfo aglNextRendererInfo ((AGLRendererInfo rend);

GLboolean aglDescribeRenderer (AGLRendererInfo rend, GLint prop, GLint *value);

Управление визуализацией

Управление контекстом визуализации OpenGL:

AGLContext aglCreateContext (AGLPixelFormat pix, AGLContext share); GLboolean aglDestroyContext (AGLContext ctx);

GLboolean aglCopyContext (AGLContext src, AGLContext dst, GLuint mask); GLboolean aglUpdateContext (AGLContext ctx);

Установка текущего состояния:

GLboolean aglSetCurrentContext (AGLContext ctx);

AGLContext aglGetCurrentContext (void);

Функции поверхностей:

GLboolean aglSetDrawable (AGLContext ctx, AGLDrawable draw);

GLboolean aglSetOffScreen (AGLContext ctx, GLsizei width, GLsizei height, GLsizei rowbytes, GLvoid *baseaddr);

GLboolean aglSetFullScreen (AGLContext ctx, GLsizei width, GLsizei height, GLsizei freq, GLint device);

AGLDrawable aglGetDrawable (AGLContext ctx);

Функции виртуального экрана:

GLboolean aglSetVirtualScreen (AGLContext ctx, GLint screen);

GLint aglGetVirtualScreen (AGLContext ctx);

Конфигурирование глобальных опций библиотеки: GLboolean aglConfigure (GLenum pname, GLuint param);

Функции переключения:

void aglSwapBuffers (AGLContext ctx);

Опции контекстов:

GLboolean aglEnable (AGLContext ctx, GLenum pname);

GLboolean aglDisable (AGLContext ctx, GLenum pname);

GLboolean aglIsEnabled (AGLContext ctx, GLenum pname);

GLboolean aglSetInteger (AGLContext ctx, GLenum pname, contst GLint *params); GLboolean aglGetInteger (AGLContext ctx, GLenum pname, contst GLint *params);

Шрифтовые функции:

GLboolean aglUseFont (AGLContext ctx, GLint fontID, Style face, GLint size, GLint first, GLint count, GLint base);

Функции работы с ошибками:

GLenum aglGetError (void);

const GLubyte *aglErrorString (GLenum code);

Функция сброса:

void aglResetLibrary (void);

PGL: Расширения OpenGL для IBM OS/2 Warp

Визуализация OpenGL для IBM OS/2 Warp осуществляется с помощью функций PGL, добавленных с целью интеграции OpenGL в стандартный Presentation Manager IBM. OpenGL совместно с PGL поддерживают и непосредственный контекст (который часто работает быстрее) и опосредованный контекст (который позволяет некоторую долю интеграции Интерфейса программирования графики (Graphics Programming Interface -- GPI) и визуализации OpenGL).

Тип данных VISUALCONFIG (аналог PGL для XVisualInfo) хранит информацию о формате пикселей, включая тип пикселей (индексные или RGBA), тип буферизации (однократная или двойная), разрешение цветов, а также наличие буферов глубины, трафарета и аккумуляции.

Для получения более подробной информации (включая способы получения программной библиотеки для IBM OS/2 Warp, Version 3.0) вы можете получить на сайте

IBM: http://www.austin.ibm.com/software/opengl.

Соседние файлы в предмете Компьютерная Графика