From 45122c2250e6f64e71a7a8bf54ba741eda5e727a Mon Sep 17 00:00:00 2001 From: Jens Ayton Date: Wed, 27 Jun 2007 17:43:37 +0000 Subject: [PATCH] Fix for shader uniform bindings under GNU Objective-C runtime. git-svn-id: http://svn.berlios.de/svnroot/repos/oolite-linux/trunk@1046 127b21dd-08f5-0310-b4b7-95ae10353056 --- GNUmakefile | 2 +- src/Core/Materials/OOShaderUniform.h | 2 +- src/Core/Materials/OOShaderUniform.m | 59 ++--- .../Materials/OOShaderUniformMethodType.h | 82 ++++++ .../Materials/OOShaderUniformMethodType.m | 236 ++++++++++++++++++ 5 files changed, 336 insertions(+), 45 deletions(-) create mode 100644 src/Core/Materials/OOShaderUniformMethodType.h create mode 100644 src/Core/Materials/OOShaderUniformMethodType.m diff --git a/GNUmakefile b/GNUmakefile index eab3b963..a5b18a5b 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -26,7 +26,7 @@ endif OBJC_PROGRAM_NAME = oolite oolite_C_FILES = legacy_random.c strlcpy.c -oolite_OBJC_FILES = Comparison.m AI.m DustEntity.m Entity.m GameController.m GuiDisplayGen.m HeadUpDisplay.m main.m MyOpenGLView.m OpenGLSprite.m ParticleEntity.m PlanetEntity.m PlayerEntityLegacyScriptEngine.m PlayerEntityContracts.m PlayerEntityControls.m PlayerEntityLoadSave.m PlayerEntitySound.m PlayerEntity.m ResourceManager.m RingEntity.m ShipEntityAI.m ShipEntity.m SkyEntity.m StationEntity.m TextureStore.m Universe.m OOSound.m SDLMusic.m NSFileManagerOOExtensions.m JoystickHandler.m PlayerEntityStickMapper.m OOBasicSoundReferencePoint.m OOBasicSoundSource.m OOCharacter.m OOTrumble.m WormholeEntity.m NSScannerOOExtensions.m OOXMLExtensions.m NSMutableDictionaryOOExtensions.m Geometry.m Octree.m CollisionRegion.m OOColor.m OOLogging.m OOCacheManager.m OOCache.m OOStringParsing.m OOCollectionExtractors.m OOVector.m OOMatrix.m OOQuaternion.m OOVoxel.m OOTriangle.m OOPListParsing.m OOFastArithmetic.m OOTextureScaling.m OOConstToString.m OOScript.m OOJSScript.m OOJavaScriptEngine.m OOPListScript.m OOSCompiler.m OOSTokenizer.m NSStringOOExtensions.m PlayerEntityScriptMethods.m OOWeakReference.m OOJSEntity.m EntityOOJavaScriptExtensions.m OOJSQuaternion.m OOMaterial.m OOShaderMaterial.m OOShaderProgram.m OOShaderUniform.m OOTexture.m OOTextureLoader.m OOPNGTextureLoader.m OOOpenGLExtensionManager.m OOBasicMaterial.m OOSingleTextureMaterial.m OOCPUInfo.m OOSelfDrawingEntity.m OOEntityWithDrawable.m OODrawable.m OOJSVector.m OOMesh.m OOOpenGL.m OOGraphicsResetManager.m OOSkyDrawable.m OOProbabilisticTextureManager.m OODebugGLDrawing.m +oolite_OBJC_FILES = Comparison.m AI.m DustEntity.m Entity.m GameController.m GuiDisplayGen.m HeadUpDisplay.m main.m MyOpenGLView.m OpenGLSprite.m ParticleEntity.m PlanetEntity.m PlayerEntityLegacyScriptEngine.m PlayerEntityContracts.m PlayerEntityControls.m PlayerEntityLoadSave.m PlayerEntitySound.m PlayerEntity.m ResourceManager.m RingEntity.m ShipEntityAI.m ShipEntity.m SkyEntity.m StationEntity.m TextureStore.m Universe.m OOSound.m SDLMusic.m NSFileManagerOOExtensions.m JoystickHandler.m PlayerEntityStickMapper.m OOBasicSoundReferencePoint.m OOBasicSoundSource.m OOCharacter.m OOTrumble.m WormholeEntity.m NSScannerOOExtensions.m OOXMLExtensions.m NSMutableDictionaryOOExtensions.m Geometry.m Octree.m CollisionRegion.m OOColor.m OOLogging.m OOCacheManager.m OOCache.m OOStringParsing.m OOCollectionExtractors.m OOVector.m OOMatrix.m OOQuaternion.m OOVoxel.m OOTriangle.m OOPListParsing.m OOFastArithmetic.m OOTextureScaling.m OOConstToString.m OOScript.m OOJSScript.m OOJavaScriptEngine.m OOPListScript.m OOSCompiler.m OOSTokenizer.m NSStringOOExtensions.m PlayerEntityScriptMethods.m OOWeakReference.m OOJSEntity.m EntityOOJavaScriptExtensions.m OOJSQuaternion.m OOMaterial.m OOShaderMaterial.m OOShaderProgram.m OOShaderUniform.m OOTexture.m OOTextureLoader.m OOPNGTextureLoader.m OOOpenGLExtensionManager.m OOBasicMaterial.m OOSingleTextureMaterial.m OOCPUInfo.m OOSelfDrawingEntity.m OOEntityWithDrawable.m OODrawable.m OOJSVector.m OOMesh.m OOOpenGL.m OOGraphicsResetManager.m OOSkyDrawable.m OOProbabilisticTextureManager.m OODebugGLDrawing.m OOShaderUniformMethodType.m include $(GNUSTEP_MAKEFILES)/objc.make include GNUmakefile.postamble diff --git a/src/Core/Materials/OOShaderUniform.h b/src/Core/Materials/OOShaderUniform.h index f57ee0a1..71555693 100644 --- a/src/Core/Materials/OOShaderUniform.h +++ b/src/Core/Materials/OOShaderUniform.h @@ -86,7 +86,7 @@ SOFTWARE. - (id)initWithName:(NSString *)uniformName shaderProgram:(OOShaderProgram *)shaderProgram vectorValue:(Vector)constValue; - (id)initWithName:(NSString *)uniformName shaderProgram:(OOShaderProgram *)shaderProgram colorValue:(OOColor *)constValue; // Converted to vector - (id)initWithName:(NSString *)uniformName shaderProgram:(OOShaderProgram *)shaderProgram quaternionValue:(Quaternion)constValue asMatrix:(BOOL)asMatrix; // Converted to vector (in xyzw order, not wxyz!) or rotation matrix. -- (id)initWithName:(NSString *)uniformName shaderProgram:(OOShaderProgram *)shaderProgram matrixValue:(Matrix)constValue; +// - (id)initWithName:(NSString *)uniformName shaderProgram:(OOShaderProgram *)shaderProgram matrixValue:(Matrix)constValue; /* "Convert" has different meanings for different types. For float and int types, it clamps to the range [0, 1]. diff --git a/src/Core/Materials/OOShaderUniform.m b/src/Core/Materials/OOShaderUniform.m index 3fb8e90d..8ca9c825 100644 --- a/src/Core/Materials/OOShaderUniform.m +++ b/src/Core/Materials/OOShaderUniform.m @@ -53,23 +53,7 @@ SOFTWARE. #import #import "OOMaths.h" #import "OOOpenGLExtensionManager.h" - - -typedef enum -{ - kOOShaderUniformTypeInvalid, - kOOShaderUniformTypeChar, // Binding only - kOOShaderUniformTypeShort, // Binding only - kOOShaderUniformTypeInt, - kOOShaderUniformTypeLong, // Binding only - kOOShaderUniformTypeFloat, - kOOShaderUniformTypeDouble, // Binding only - kOOShaderUniformTypeVector, - kOOShaderUniformTypeQuaternion, // Binding only - kOOShaderUniformTypeMatrix, - kOOShaderUniformTypePoint, // Binding only - kOOShaderUniformTypeObject // Binding only -} OOShaderUniformType; +#import "OOShaderUniformMethodType.h" typedef char (*CharReturnMsgSend)(id, SEL); @@ -296,9 +280,13 @@ OOINLINE BOOL ValidBindingType(OOShaderUniformType type) switch (type) { case kOOShaderUniformTypeChar: + case kOOShaderUniformTypeUnsignedChar: case kOOShaderUniformTypeShort: + case kOOShaderUniformTypeUnsignedShort: case kOOShaderUniformTypeInt: + case kOOShaderUniformTypeUnsignedInt: case kOOShaderUniformTypeLong: + case kOOShaderUniformTypeUnsignedLong: valueType = @"int"; break; @@ -332,10 +320,9 @@ OOINLINE BOOL ValidBindingType(OOShaderUniformType type) - (void)setBindingTarget:(id)target { BOOL OK = YES; - NSMethodSignature *sig = nil; + NSMethodSignature *signature = nil; unsigned argCount; NSString *methodProblem = nil; - const char *typeCode = NULL; if (!isBinding) return; if (EXPECT_NOT([value.binding.object weakRefUnderlyingObject] == target)) return; @@ -369,8 +356,8 @@ OOINLINE BOOL ValidBindingType(OOShaderUniformType type) if (OK) { - sig = [(id)target methodSignatureForSelector:value.binding.selector]; - if (sig == nil) + signature = [(id)target methodSignatureForSelector:value.binding.selector]; + if (signature == nil) { methodProblem = @"could not retrieve method signature"; OK = NO; @@ -379,7 +366,7 @@ OOINLINE BOOL ValidBindingType(OOShaderUniformType type) if (OK) { - argCount = [sig numberOfArguments]; + argCount = [signature numberOfArguments]; if (argCount != 2) // "no-arguments" methods actually take two arguments, self and _msg. { methodProblem = @"only methods which do not require arguments may be bound to"; @@ -389,29 +376,11 @@ OOINLINE BOOL ValidBindingType(OOShaderUniformType type) if (OK) { - typeCode = [sig methodReturnType]; - - #define TYPE_MATCH(T, TC) (0 == strcmp(@encode(T), TC)) - - if (TYPE_MATCH(float, typeCode)) type = kOOShaderUniformTypeFloat; - else if (TYPE_MATCH(double, typeCode)) type = kOOShaderUniformTypeDouble; - else if (TYPE_MATCH(signed char, typeCode)) type = kOOShaderUniformTypeChar; - else if (TYPE_MATCH(unsigned char, typeCode)) type = kOOShaderUniformTypeChar; - else if (TYPE_MATCH(signed short, typeCode)) type = kOOShaderUniformTypeShort; - else if (TYPE_MATCH(unsigned short, typeCode)) type = kOOShaderUniformTypeShort; - else if (TYPE_MATCH(signed int, typeCode)) type = kOOShaderUniformTypeInt; - else if (TYPE_MATCH(unsigned int, typeCode)) type = kOOShaderUniformTypeInt; - else if (TYPE_MATCH(signed long, typeCode)) type = kOOShaderUniformTypeLong; - else if (TYPE_MATCH(unsigned long, typeCode)) type = kOOShaderUniformTypeLong; - else if (TYPE_MATCH(Vector, typeCode)) type = kOOShaderUniformTypeVector; - else if (TYPE_MATCH(Quaternion, typeCode)) type = kOOShaderUniformTypeQuaternion; - else if (TYPE_MATCH(Matrix, typeCode)) type = kOOShaderUniformTypeMatrix; - else if (TYPE_MATCH(NSPoint, typeCode)) type = kOOShaderUniformTypePoint; - else if (TYPE_MATCH(id, typeCode)) type = kOOShaderUniformTypeObject; - else + type = OOShaderUniformTypeFromMethodSignature(signature); + if (type == kOOShaderUniformTypeInvalid) { OK = NO; - methodProblem = [NSString stringWithFormat:@"unsupported type \"%s\"", typeCode]; + methodProblem = [NSString stringWithFormat:@"unsupported type \"%s\"", [signature methodReturnType]]; } } @@ -506,21 +475,25 @@ OOINLINE BOOL ValidBindingType(OOShaderUniformType type) switch (type) { case kOOShaderUniformTypeChar: + case kOOShaderUniformTypeUnsignedChar: iVal = ((CharReturnMsgSend)value.binding.method)(object, value.binding.selector); isInt = YES; break; case kOOShaderUniformTypeShort: + case kOOShaderUniformTypeUnsignedShort: iVal = ((ShortReturnMsgSend)value.binding.method)(object, value.binding.selector); isInt = YES; break; case kOOShaderUniformTypeInt: + case kOOShaderUniformTypeUnsignedInt: iVal = ((IntReturnMsgSend)value.binding.method)(object, value.binding.selector); isInt = YES; break; case kOOShaderUniformTypeLong: + case kOOShaderUniformTypeUnsignedLong: iVal = ((LongReturnMsgSend)value.binding.method)(object, value.binding.selector); isInt = YES; break; diff --git a/src/Core/Materials/OOShaderUniformMethodType.h b/src/Core/Materials/OOShaderUniformMethodType.h new file mode 100644 index 00000000..26f13231 --- /dev/null +++ b/src/Core/Materials/OOShaderUniformMethodType.h @@ -0,0 +1,82 @@ +/* + +OOShaderUniformMethodType.h + +Type code declarations and OpenStep implementation agnostic method type +matching for uniform bindings. + +Oolite +Copyright (C) 2004-2007 Giles C Williams and contributors + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +MA 02110-1301, USA. + + +This file may also be distributed under the MIT/X11 license: + +Copyright (C) 2007 Jens Ayton + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +*/ + +#ifndef NO_SHADERS + +#import "OOCocoa.h" + + +typedef enum +{ + kOOShaderUniformTypeInvalid, // Not valid for bindings or constants + + kOOShaderUniformTypeChar, // Binding only + kOOShaderUniformTypeUnsignedChar, // Binding only + kOOShaderUniformTypeShort, // Binding only + kOOShaderUniformTypeUnsignedShort, // Binding only + kOOShaderUniformTypeInt, // Binding or constant + kOOShaderUniformTypeUnsignedInt, // Binding only + kOOShaderUniformTypeLong, // Binding only + kOOShaderUniformTypeUnsignedLong, // Binding only + kOOShaderUniformTypeFloat, // Binding or constant + kOOShaderUniformTypeDouble, // Binding only + kOOShaderUniformTypeVector, // Binding or constant + kOOShaderUniformTypeQuaternion, // Binding only + kOOShaderUniformTypeMatrix, // Binding only + kOOShaderUniformTypePoint, // Binding only + kOOShaderUniformTypeObject, // Binding only + + kOOShaderUniformTypeCount // Not valid for bindings or constants +} OOShaderUniformType; + + +OOShaderUniformType OOShaderUniformTypeFromMethodSignature(NSMethodSignature *signature); + +#endif // NO_SHADERS diff --git a/src/Core/Materials/OOShaderUniformMethodType.m b/src/Core/Materials/OOShaderUniformMethodType.m new file mode 100644 index 00000000..4cc244eb --- /dev/null +++ b/src/Core/Materials/OOShaderUniformMethodType.m @@ -0,0 +1,236 @@ +/* + +OOShaderUniformMethodType.m + +Oolite +Copyright (C) 2004-2007 Giles C Williams and contributors + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +MA 02110-1301, USA. + + +This file may also be distributed under the MIT/X11 license: + +Copyright (C) 2007 Jens Ayton + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +*/ + +#ifndef NO_SHADERS + +#import "OOShaderUniformMethodType.h" +#import "OOMaths.h" + +static BOOL sInited = NO; +static const char *sTemplates[kOOShaderUniformTypeCount]; + +static void InitTemplates(void); +static const char *CopyTemplateForSelector(SEL selector); + + +OOShaderUniformType OOShaderUniformTypeFromMethodSignature(NSMethodSignature *signature) +{ + unsigned i; + const char *typeCode = NULL; + + if (EXPECT_NOT(sInited == NO)) InitTemplates(); + + typeCode = [signature methodReturnType]; + if (EXPECT_NOT(typeCode == NULL)) return kOOShaderUniformTypeInvalid; + + for (i = kOOShaderUniformTypeInvalid + 1; i != kOOShaderUniformTypeCount; ++i) + { + if (sTemplates[i] != NULL && strcmp(sTemplates[i], typeCode) == 0) return i; + } + + return kOOShaderUniformTypeInvalid; +} + + +@interface OOShaderUniformTypeMethodSignatureTemplateClass: NSObject + +- (float)floatMethod; +- (double)doubleMethod; +- (signed char)signedCharMethod; +- (unsigned char)unsignedCharMethod; +- (signed short)signedShortMethod; +- (unsigned short)unsignedShortMethod; +- (signed int)signedIntMethod; +- (unsigned int)unsignedIntMethod; +- (signed long)signedLongMethod; +- (unsigned long)unsignedLongMethod; +- (Vector)vectorMethod; +- (Quaternion)quaternionMethod; +- (Matrix)matrixMethod; +- (NSPoint)pointMethod; +- (id)idMethod; + +@end + + +static void InitTemplates(void) +{ + #define GET_TEMPLATE(enumValue, sel) do { \ + sTemplates[enumValue] = CopyTemplateForSelector(@selector(sel)); \ + } while (0) + + GET_TEMPLATE(kOOShaderUniformTypeChar, signedCharMethod); + GET_TEMPLATE(kOOShaderUniformTypeUnsignedChar, unsignedCharMethod); + GET_TEMPLATE(kOOShaderUniformTypeShort, signedShortMethod); + GET_TEMPLATE(kOOShaderUniformTypeUnsignedShort, unsignedShortMethod); + GET_TEMPLATE(kOOShaderUniformTypeInt, signedIntMethod); + GET_TEMPLATE(kOOShaderUniformTypeUnsignedInt, unsignedIntMethod); + GET_TEMPLATE(kOOShaderUniformTypeLong, signedLongMethod); + GET_TEMPLATE(kOOShaderUniformTypeUnsignedLong, unsignedLongMethod); + GET_TEMPLATE(kOOShaderUniformTypeFloat, floatMethod); + GET_TEMPLATE(kOOShaderUniformTypeDouble, doubleMethod); + GET_TEMPLATE(kOOShaderUniformTypeVector, vectorMethod); + GET_TEMPLATE(kOOShaderUniformTypeQuaternion, quaternionMethod); + GET_TEMPLATE(kOOShaderUniformTypeMatrix, matrixMethod); + GET_TEMPLATE(kOOShaderUniformTypePoint, pointMethod); + GET_TEMPLATE(kOOShaderUniformTypeObject, idMethod); + + sInited = YES; +} + + +static const char *CopyTemplateForSelector(SEL selector) +{ + NSMethodSignature *signature = nil; + const char *typeCode = NULL; + + signature = [OOShaderUniformTypeMethodSignatureTemplateClass instanceMethodSignatureForSelector:selector]; + typeCode = [signature methodReturnType]; + + /* typeCode is *probably* a constant, but this isn't formally guaranteed + as far as I'm aware, so we make a copy of it. + */ + return typeCode ? strdup(typeCode) : NULL; +} + + +@implementation OOShaderUniformTypeMethodSignatureTemplateClass: NSObject + +- (signed char)signedCharMethod +{ + return 0; +} + + +- (unsigned char)unsignedCharMethod +{ + return 0; +} + + +- (signed short)signedShortMethod +{ + return 0; +} + + +- (unsigned short)unsignedShortMethod +{ + return 0; +} + + +- (signed int)signedIntMethod +{ + return 0; +} + + +- (unsigned int)unsignedIntMethod +{ + return 0; +} + + +- (signed long)signedLongMethod +{ + return 0; +} + + +- (unsigned long)unsignedLongMethod +{ + return 0; +} + + +- (float)floatMethod +{ + return 0.0f; +} + + +- (double)doubleMethod +{ + return 0.0; +} + + +- (Vector)vectorMethod +{ + Vector v = {0}; + return v; +} + + +- (Quaternion)quaternionMethod +{ + Quaternion q = {0}; + return q; +} + + +- (Matrix)matrixMethod +{ + return kZeroMatrix; +} + + +- (NSPoint)pointMethod +{ + return NSZeroPoint; +} + + +- (id)idMethod +{ + return nil; +} + +@end + +#endif // NO_SHADERS