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

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

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

Получение указателя функции к произвольной точке входа OpenGL

Получение указателя на функцию точки входа OpenGL является довольно прямым от Какао. Можно использовать Динамическую функцию Загрузчика NSLookupAndBindSymbol получить адрес точки входа OpenGL.

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

Перечисление c-1 показывает, как использовать NSLookupAndBindSymbol из функции MyNSGLGetProcAddress. Когда предоставленный имя символа, эта определенная с помощью приложения функция возвращает надлежащий указатель функции из глобальной таблицы символов. Подробное объяснение каждой пронумерованной строки кода появляется после перечисления.

Перечисление c-1  Используя NSLookupAndBindSymbol получить символ для имени символа

#import <mach-o/dyld.h>
#import <stdlib.h>
#import <string.h>
void * MyNSGLGetProcAddress (const char *name)
{
    NSSymbol symbol;
    char *symbolName;
    symbolName = malloc (strlen (name) + 2); // 1
    strcpy(symbolName + 1, name); // 2
    symbolName[0] = '_'; // 3
    symbol = NULL;
    if (NSIsSymbolNameDefined (symbolName)) // 4
        symbol = NSLookupAndBindSymbol (symbolName);
    free (symbolName); // 5
    return symbol ? NSAddressOfSymbol (symbol) : NULL; // 6
}

Вот то, что делает код:

  1. Выделяет хранение для имени символа плюс символ подчеркивания ('_'). Символ подчеркивания является частью UNIX C искажающее символ соглашение, поэтому удостоверьтесь, что Вы обеспечиваете хранение для него.

  2. Копирует имя символа в строковую переменную, запускающуюся во втором символе, для оставления комнаты для добавления префикса символа подчеркивания.

  3. Копирует символ подчеркивания в первый символ строки имени символа.

  4. Проверки, чтобы удостовериться, что имя символа определяется, и если это, ищут символ.

  5. Освобождает строку имени символа, потому что она больше не необходима.

  6. Возвращает надлежащий указатель в случае успеха, или NULL если не успешный. Перед использованием этого указателя необходимо удостовериться, что это - он допустимый.

Инициализация точек входа

Перечисление c-2 показывает, как использовать MyNSGLGetProcAddress функция от Перечисления c-1 для получения нескольких точек входа OpenGL. Подробное объяснение каждой пронумерованной строки кода появляется после перечисления.

Перечисление c-2  Используя NSGLGetProcAddress получить точку входа OpenGL

#import "MyNSGLGetProcAddress.h" // 1
static void InitEntryPoints (void);
static void DeallocEntryPoints (void);
 
// Function pointer type definitions
typedef void (*glBlendColorProcPtr)(GLclampf red,GLclampf green,
                        GLclampf blue,GLclampf alpha);
typedef void (*glBlendEquationProcPtr)(GLenum mode);
 typedef void (*glDrawRangeElementsProcPtr)(GLenum mode, GLuint start,
                GLuint end,GLsizei count,GLenum type,const GLvoid *indices);
 
glBlendColorProcPtr pfglBlendColor = NULL; // 2
glBlendEquationProcPtr pfglBlendEquation = NULL;
glDrawRangeElementsProcPtr pfglDrawRangeElements = NULL;
 
static void InitEntryPoints (void) // 3
{
    pfglBlendColor = (glBlendColorProcPtr) MyNSGLGetProcAddress
                                    ("glBlendColor");
    pfglBlendEquation = (glBlendEquationProcPtr)MyNSGLGetProcAddress
                                ("glBlendEquation");
    pfglDrawRangeElements = (glDrawRangeElementsProcPtr)MyNSGLGetProcAddress
                                ("glDrawRangeElements");
}
// -------------------------
static void DeallocEntryPoints (void) // 4
{
    pfglBlendColor = NULL;
    pfglBlendEquation = NULL;
    pfglDrawRangeElements = NULL;;
}

Вот то, что делает код:

  1. Импортирует заголовочный файл, содержащий MyNSGLProcAddress функция от Перечисления c-1.

  2. Объявляет указатели функции для функций интереса. Обратите внимание на то, что каждый указатель функции использует префикс pf для различения его от функции, это указывает на. Несмотря на то, что использование этого префикса не является требованием, лучше избегать использования точных имен функций.

  3. Инициализирует точки входа. Эта функция неоднократно вызывает MyNSGLProcAddress функция для получения указателей функции для каждой из функций интереса —glBlendColor, glBlendEquation, и glDrawRangeElements.

  4. Наборы каждый из указателей функции к NULL когда они больше не необходимы.