41@interface OOShaderUniform (OOPrivate)
43- (id)initWithName:(NSString *)uniformName shaderProgram:(OOShaderProgram *)shaderProgram;
51@implementation OOShaderUniform
53- (id)initWithName:(NSString *)uniformName shaderProgram:(OOShaderProgram *)shaderProgram intValue:(GLint)constValue
55 self = [
self initWithName:uniformName shaderProgram:shaderProgram];
59 value.constInt = constValue;
66- (id)initWithName:(NSString *)uniformName shaderProgram:(OOShaderProgram *)shaderProgram floatValue:(GLfloat)constValue
68 self = [
self initWithName:uniformName shaderProgram:shaderProgram];
72 value.constFloat = constValue;
79- (id)initWithName:(NSString *)uniformName shaderProgram:(OOShaderProgram *)shaderProgram vectorValue:(GLfloat[4])constValue
81 self = [
self initWithName:uniformName shaderProgram:shaderProgram];
85 memcpy(value.constVector, constValue,
sizeof value.constVector);
92- (id)initWithName:(NSString *)uniformName shaderProgram:(OOShaderProgram *)shaderProgram colorValue:(
OOColor *)constValue
100 self = [
self initWithName:uniformName shaderProgram:shaderProgram];
114- (id)initWithName:(NSString *)uniformName shaderProgram:(OOShaderProgram *)shaderProgram quaternionValue:(Quaternion)constValue asMatrix:(BOOL)asMatrix
116 self = [
self initWithName:uniformName shaderProgram:shaderProgram];
127 value.constVector[0] = constValue.x;
128 value.constVector[1] = constValue.y;
129 value.constVector[2] = constValue.z;
130 value.constVector[3] = constValue.w;
138- (id)initWithName:(NSString *)uniformName shaderProgram:(OOShaderProgram *)shaderProgram matrixValue:(OOMatrix)constValue
140 self = [
self initWithName:uniformName shaderProgram:shaderProgram];
144 value.constMatrix = constValue;
151- (id)initWithName:(NSString *)uniformName
152 shaderProgram:(OOShaderProgram *)shaderProgram
153 boundToObject:(
id<OOWeakReferenceSupport>)target
154 property:(
SEL)selector
155 convertOptions:(OOUniformConvertOptions)options
159 if (
EXPECT_NOT(uniformName == NULL || shaderProgram == NULL || selector == NULL)) OK = NO;
164 if (
self ==
nil) OK = NO;
169 location = glGetUniformLocationARB([shaderProgram program], [uniformName UTF8String]);
173 OOLog(
@"shader.uniform.bind.failed",
@"Could not bind uniform \"%@\
" to -[%@ %@] (no uniform of that name could be found).", uniformName, [target
class], NSStringFromSelector(selector));
180 name = [uniformName retain];
182 value.binding.selector = selector;
184 convertClamp = (options & kOOUniformConvertClamp) != 0;
185 convertNormalize = (options & kOOUniformConvertNormalize) != 0;
186 convertToMatrix = (options & kOOUniformConvertToMatrix) != 0;
187 bindToSuper = (options & kOOUniformBindToSuperTarget) != 0;
189 if (target !=
nil) [
self setBindingTarget:target];
204 if (isBinding) [value.binding.object release];
210- (NSString *)description
212 NSString *valueDesc =
nil;
213 NSString *valueType =
nil;
218 object = [value.binding.object weakRefUnderlyingObject];
221 valueDesc = [NSString stringWithFormat:@"[<%@ %p> %@]", [object class], value.binding.object, NSStringFromSelector(value.binding.selector)];
233 valueDesc = [NSString stringWithFormat:@"%i", value.constInt];
237 valueDesc = [NSString stringWithFormat:@"%g", value.constFloat];
242 Vector v = { value.constVector[0], value.constVector[1], value.constVector[2] };
243 valueDesc = VectorDescription(v);
248 valueDesc = OOMatrixDescription(value.constMatrix);
268 valueType =
@"float";
277 valueType =
@"vec4 (quaternion)";
281 valueType =
@"matrix";
289 valueType =
@"object-binding";
293 if (valueType ==
nil) valueDesc =
@"INVALID";
294 if (valueDesc ==
nil) valueDesc =
@"INVALID";
300 return [NSString stringWithFormat:@"<%@ %p>{%i: %@ %@ = %@;}", [
self class], self, location, valueType, name, valueDesc];
309 if (isActiveBinding) [
self applyBinding];
311 else [
self applySimple];
315- (void)setBindingTarget:(
id<OOWeakReferenceSupport>)target
318 NSMethodSignature *signature =
nil;
320 NSString *methodProblem =
nil;
321 id<OOWeakReferenceSupport> superCandidate =
nil;
323 if (!isBinding)
return;
330 if (![target respondsToSelector:
@selector(superShaderBindingTarget)])
break;
332 superCandidate = [(id)target superShaderBindingTarget];
333 if (superCandidate ==
nil || superCandidate == target)
break;
334 target = superCandidate;
338 [value.binding.object release];
339 value.binding.object = [target weakRetain];
343 isActiveBinding = NO;
349 if (![target respondsToSelector:value.binding.selector])
351 methodProblem =
@"target does not respond to selector";
358 value.binding.method = [(id)target methodForSelector:value.binding.selector];
359 if (value.binding.method == NULL)
361 methodProblem =
@"could not retrieve method implementation";
368 signature = [(id)target methodSignatureForSelector:value.binding.selector];
369 if (signature ==
nil)
371 methodProblem =
@"could not retrieve method signature";
378 argCount = [signature numberOfArguments];
381 methodProblem =
@"only methods which do not require arguments may be bound to";
392 methodProblem = [NSString stringWithFormat:@"unsupported type \"%s\"", [signature methodReturnType]];
396 isActiveBinding = OK;
397 if (!OK)
OOLog(
@"shader.uniform.bind.failed",
@"Shader could not bind uniform \"%@\
" to -[%@ %@] (%@).", name, [target
class], NSStringFromSelector(value.binding.selector), methodProblem);
403@implementation OOShaderUniform (OOPrivate)
406- (id)initWithName:(NSString *)uniformName shaderProgram:(OOShaderProgram *)shaderProgram
410 if (
EXPECT_NOT(uniformName == NULL || shaderProgram == NULL)) OK = NO;
415 if (
self ==
nil) OK = NO;
420 location = glGetUniformLocationARB([shaderProgram program], [uniformName UTF8String]);
421 if (location == -1) OK = NO;
426 name = [uniformName copy];
442 OOGL(glUniform1iARB(location, value.constInt));
446 OOGL(glUniform1fARB(location, value.constFloat));
450 OOGL(glUniform4fvARB(location, 1, value.constVector));
454 GLUniformMatrix(location, value.constMatrix);
471 BOOL isInt = NO, isFloat = NO, isVector = NO, isMatrix = NO, isPoint = NO;
482 object = [value.binding.object weakRefUnderlyingObject];
483 if (
object ==
nil)
return;
495 iVal = (GLint)
OOCallIntegerMethod(
object, value.binding.selector, value.binding.method, type);
501 fVal =
OOCallFloatMethod(
object, value.binding.selector, value.binding.method, type);
507 if (convertNormalize) vVal = vector_normal(vVal);
517 if (convertNormalize) hpvVal = HPvector_normal(hpvVal);
518 expVVal[0] = (GLfloat)hpvVal.x;
519 expVVal[1] = (GLfloat)hpvVal.y;
520 expVVal[2] = (GLfloat)hpvVal.z;
554 if ([objVal isKindOfClass:[NSNumber
class]])
556 fVal = [objVal floatValue];
559 else if ([objVal isKindOfClass:[
OOColor class]])
573 if (convertClamp) fVal = OOClamp_0_1_f(fVal);
574 OOGL(glUniform1fARB(location, fVal));
578 if (convertClamp) iVal = iVal ? 1 : 0;
579 OOGL(glUniform1iARB(location, iVal));
583 GLfloat v2[2] = { pVal.x, pVal.y };
584 OOGL(glUniform2fvARB(location, 1, v2));
588 OOGL(glUniform4fvARB(location, 1, expVVal));
592 GLUniformMatrix(location, mVal);
#define OOLog(class, format,...)
OOMatrix OOMatrixForQuaternionRotation(Quaternion orientation)