Запись потребительских патчей
Потребительский патч вытягивает (или использует), данные от процессора и патчей провайдера, воздействует на данные и представляет результат месту назначения, обычно экран, но это может быть другое место назначения. В этой главе рассматриваются некоторые методы наиболее успешной практики для использования OpenGL в Кварцевом Композиторе пользовательский патч и затем показывает, как создать пользовательский потребительский патч, представляющий текстуру OpenGL к четверке.
Необходимо знать, что программирование OpenGL понимает эту главу. Если Вы не знаете OpenGL, но хотите учиться, эти книги обеспечивают хорошую начальную точку:
Руководство по программированию OpenGL, Наблюдательным советом Архитектуры OpenGL; иначе известный как «Redbook”.
Справочник OpenGL, Наблюдательным советом Архитектуры OpenGL; иначе известный как «Синяя книга”.
Несмотря на то, что эти книги обеспечивают прочную основу в OpenGL, необходимо будет также считать Руководство по программированию OpenGL для Mac для подробных данных о том, как получить лучшую производительность на платформе Macintosh с помощью новых расширений OpenGL и OS X платформы OpenGL.
Используя OpenGL в пользовательском патче
Используя OpenGL в пользовательском патче требует немного большего количества работы установки, чем, что необходимо для патчей, не использующих OpenGL, но не очень. Необходимо установить контекст OpenGL в контекст выполнения пользовательского патча. Установка требует двух шагов:
Включайте
CGLMacro.h
файл.Установите контекст OpenGL в контекст выполнения пользовательского патча с помощью этой строки кода:
CGLContextObj cgl_ctx = [context CGLContextObj];
Первый шаг выполнен для Вас при использовании шаблона проекта XCode для Кварцевых плагинов Композитора. При включении макро-заголовочного файла CGL можно тогда использовать локальную переменную контекста для кэширования текущего средства рендеринга. Локальный кэш избавляет от необходимости OpenGL выполнять глобальный контекст и поиск средства рендеринга для каждой команды, которую это выполняет, таким образом сокращая наверху и улучшая производительность.
CGLContextObj
метод QCPlugInContext
протокол получает контекст OpenGL, к которому можно нарисовать из метода выполнения пользовательского патча. (См. Ссылку на протокол QCPlugInContext.) После установки контекста OpenGL (cgl_ctx
), Кварцевый Композитор отправляет все команды OpenGL в контекст выполнения OpenGL пользовательского патча.
Код OpenGL в Вашем пользовательском патче получает преимущества от любых методов программирования, улучшающих производительность любого кода OpenGL. Другими словами, нет никаких особых требований для кода OpenGL, это - часть пользовательского патча. Однако Вы захотите сохранить и восстановить все изменения состояния кроме тех, которые являются частью GL_CURRENT_BIT
(Цвет RGBA, индекс цвета, вектор нормали, координаты текстуры, и т.д). Можно также хотеть смотреть на главу “Улучшающаяся Производительность” в Руководстве по программированию OpenGL для Mac.
Вращение квадрата: рендеринг текстуры к четверке
Вращающийся Квадратный пользовательский патч представляет текстуру к четверке OpenGL, которую можно анимировать. Это имеет восемь входных параметров:
Enable
порт, который Кварцевый Композитор автоматически создает для потребительского патча.Следующие три —
X Position
,Y Position
, иZ Position
— управляйте расположением центра квадрата.Rotation Angle
определяет угол вращения четверки.Color
цвет фона для четверки.Image
преобразовывается в текстуру и масштабируется для адаптации четверке. Посмотрите Получение Изображений От Входного порта.
Получающийся патч показан на рисунке 4-2.
Выполните эти шаги для создания Вращающегося Квадратного пользовательского патча:
Откройте Xcode и выберите File> New Project.
В окне New Project выберите Standard Apple Plug-ins> Quartz Composer Plug-in и нажмите Далее.
Войти
RotatingSquare
в текстовом поле Project Name и нажимают Далее.Откройтесь
RotatingSquarePlugin.h
файл.Измените интерфейсный файл так, чтобы он имел четыре динамических свойства Objective-C: значения x и y, цвет и входное изображение.
#import <Quartz/Quartz.h>
@interface RotatingSquarePlugIn : QCPlugIn
{
}
// Declare four property input ports of type Number with the
// keys inputX, inputY, inputZ, and inputAngle
@property double inputX;
@property double inputY;
@property double inputZ;
@property double inputAngle;
// Declare a property input port of type Color with the key inputColor
@property(assign) CGColorRef inputColor;
// Declare a property input port of type Image with the key inputImage
@property(assign) id<QCPlugInInputImageSource> inputImage;
@end
Сохраните и закройтесь
RotatingSquarePlugIn.h
файл.Откройтесь
RotatingPlugin.m
файл. Для обеспечения лучшей производительности OpenGL удостоверьтесь, что файл содержит следующее утверждение:#import <OpenGL/CGLMacro.h>
Вы установите контекст OpenGL позже в выполнить методе.
Сразу после оператора реализации, добавьте эту директиву так, чтобы Кварцевый Композитор обработал реализацию свойств:
@dynamic inputX, inputY, inputZ, inputAngle, inputColor, inputImage;
Добавьте пространство для разделения слов на имя. Тогда измените описание для пользовательского патча.
Когда Вы сделаны, два
#define
операторы для взгляда следующим образом:#define kQCPlugIn_Name @"Rotating Square"
#define kQCPlugIn_Description @"Renders a colored square that you can animate."
Затем Вы запишете, что методы должны были реализовать
RotatingSquarePlugIn
подкласс.attributes
метод, предоставленный в шаблоне, должен уже быть похожим на это:+ (NSDictionary*) attributes
{
return [NSDictionary dictionaryWithObjectsAndKeys:
kQCPlugIn_Name,QCPlugInAttributeNameKey,
kQCPlugIn_Description,QCPlugInAttributeDescriptionKey,
nil];
}
Измените
attributesForPropertyPortWithKey:
метод так, чтобы это возвратило словарь для каждого входного параметра. Ключевое имя атрибута порта - то, что появляется в Кварцевом Композиторе как метка для пользовательского порта патча.Метод должен посмотреть следующим образом:
+ (NSDictionary*) attributesForPropertyPortWithKey:(NSString*)key
{
if([key isEqualToString:@"inputX"])
return [NSDictionary dictionaryWithObjectsAndKeys:
@"X Position", QCPortAttributeNameKey,
nil];
if([key isEqualToString:@"inputY"])
return [NSDictionary dictionaryWithObjectsAndKeys:
@"Y Position", QCPortAttributeNameKey,
nil];
if([key isEqualToString:@"inputZ"])
return [NSDictionary dictionaryWithObjectsAndKeys:
@"Z Position", QCPortAttributeNameKey,
nil];
if([key isEqualToString:@"inputAngle"])
return [NSDictionary dictionaryWithObjectsAndKeys:
@"Rotation Angle", QCPortAttributeNameKey,
nil];
if([key isEqualToString:@"inputColor"])
return [NSDictionary dictionaryWithObjectsAndKeys:
@"Color", QCPortAttributeNameKey,
nil];
if([key isEqualToString:@"inputImage"])
return [NSDictionary dictionaryWithObjectsAndKeys:
@"Image", QCPortAttributeNameKey, nil];
return nil;
}
Удостоверьтесь
executionMode
возвраты методаkQCPlugInExecutionModeConsumer
указать, что пользовательский патч является потребителем. Среди прочего это заставляет Кварцевого Композитора добавлять Разрешать входной порт к получающемуся патчу.+ (QCPlugInExecutionMode) executionMode
{
return kQCPlugInExecutionModeConsumer;
}
Удостоверьтесь что
timeMode
возвратыkQCPlugInTimeModeNone
.Это - значение по умолчанию, таким образом, Вы не должны должны быть вносить любые изменения в предоставленный код.
Этот пользовательский патч выполняется только, когда изменяются входные значения.
+ (QCPlugInTimeMode) timeMode
{
return kQCPlugInTimeModeNone;
}
Реализуйте метод выполнения для контекста выполнения. Это - то, где определяется поток команды OpenGL. Необходимо определить контекст CGL здесь.
- (BOOL) execute:(id<QCPlugInContext>)context
atTime:(NSTimeInterval)time
withArguments:(NSDictionary*)arguments
{
// Define a context and set it. This line causes OpenGL to use macros.
CGLContextObj cgl_ctx = [context CGLContextObj];
id<QCPlugInInputImageSource> image;
GLuint textureName;
GLint saveMode;
const CGFloat* colorComponents;
GLenum error;
if(cgl_ctx == NULL)
return NO;
// Copy the image on the input port to a local variable.
image = self.inputImage;
// Get a texture from the image in the context color space
if(image && [image lockTextureRepresentationWithColorSpace:([image shouldColorMatch] ? [context colorSpace] :
[image imageColorSpace])
forBounds:[image imageBounds]])
textureName = [image textureName];
else
textureName = 0;
// Save and set the modelview matrix.
glGetIntegerv(GL_MATRIX_MODE, &saveMode);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
// Translate the matrix
glTranslatef(self.inputX, self.inputY, self.inputZ);
// Rotate the matrix
glRotatef(self.inputAngle, 0.0, 1.0, 0.0);
// Bind the texture to a texture unit
if(textureName) {
[image bindTextureRepresentationToCGLContext:cgl_ctx
textureUnit:GL_TEXTURE0
normalizeCoordinates:YES];
}
// Get the color components (RGBA) from the input color port.
colorComponents = CGColorGetComponents(self.inputColor);
// Set the color.
glColor4f(colorComponents[0], colorComponents[1], colorComponents[2], colorComponents[3]);
// Render the textured quad by mapping the texture coordinates to the vertices
glBegin(GL_QUADS);
glTexCoord2f(1.0, 1.0);
glVertex3f(0.5, 0.5, 0); // upper right
glTexCoord2f(0.0, 1.0);
glVertex3f(-0.5, 0.5, 0); // upper left
glTexCoord2f(0.0, 0.0);
glVertex3f(-0.5, -0.5, 0); // lower left
glTexCoord2f(1.0, 0.0);
glVertex3f(0.5, -0.5, 0); // lower right
glEnd();
// Unbind the texture from the texture unit.
if(textureName)
[image unbindTextureRepresentationFromCGLContext:cgl_ctx
textureUnit: GL_TEXTURE0];
// Restore the modelview matrix.
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(saveMode);
// Check for OpenGL errors and log them if there are errors.
if(error = glGetError())
[context logMessage:@"OpenGL error %04X", error];
// Release the texture.
if(textureName)
[image unlockTextureRepresentation];
return (error ? NO : YES);
}
Откройтесь
Info.plist
файл и удостоверяется, что следующий ключ является записью в словаре:<key>QCPlugInClasses</key>
<array>
<string>RotatingSquarePlugIn</string>
</array>
Если Вы хотите, настраиваете идентификатор пакета. Тогда сохраните и закройте файл.
Под Целями выберите Build и Copy. Затем нажмите Build Build и Copy от всплывающего меню Действия.
При создании использования этой опции XCode копирует успешно созданный плагин в
~/Library/Graphics/Quartz Composer Plug-Ins
.Откройте Quartz Composer и ищите Вращающийся Квадратный пользовательский патч в Создателе Патча.
Создайте состав для тестирования пользовательского патча. Попытайтесь выбрать цвет и позиции. Добавьте патч интерполяции для анимации квадрата. Для проверки ввода изображения можно перетащить изображение непосредственно редактору и затем подключить изображение к патчу, как показано ниже.
Следует иметь в виду, что, если изображение не является квадратным, Вращающийся Квадратный патч отображает координаты для приспосабливания изображения в квадрате, искажая изображение при необходимости.