Shader synthesizer: light maps can now be controlled by bindings.

git-svn-id: http://svn.berlios.de/svnroot/repos/oolite-linux/trunk@4793 127b21dd-08f5-0310-b4b7-95ae10353056
This commit is contained in:
Jens Ayton 2012-02-26 17:08:49 +00:00
parent cedebad520
commit a106f4055f
9 changed files with 279 additions and 25 deletions

View File

@ -490,6 +490,7 @@
1A7B967F0E620C9E00322821 /* OOSoundInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A7B967E0E620C9E00322821 /* OOSoundInternal.h */; };
1A7BA8830D843485003C6CA3 /* ShipEntityScriptMethods.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A7BA80B0D84231A003C6CA3 /* ShipEntityScriptMethods.h */; };
1A7BA8840D843485003C6CA3 /* ShipEntityScriptMethods.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A7BA80C0D84231A003C6CA3 /* ShipEntityScriptMethods.m */; };
1A7C27CA14FA70A500F2D2A8 /* shader-uniform-bindings.plist in Copy Config */ = {isa = PBXBuildFile; fileRef = 1A7C27C814FA709500F2D2A8 /* shader-uniform-bindings.plist */; };
1A7C75C30CC39EC3005D0AA2 /* OOJSSun.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A7C75980CC39D11005D0AA2 /* OOJSSun.m */; };
1A7C75C50CC39EC9005D0AA2 /* OOJSSun.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A7C75990CC39D11005D0AA2 /* OOJSSun.h */; };
1A7D3A180C4F6162008EDC33 /* OOCheckRequiresPListVerifierStage.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A7D3A160C4F6162008EDC33 /* OOCheckRequiresPListVerifierStage.h */; };
@ -923,6 +924,7 @@
1A2316FB0B9CFAD700EF0852 /* shipdata.plist in Copy Config */,
1A2316FC0B9CFAD800EF0852 /* shipyard.plist in Copy Config */,
1A2316FD0B9CFAD800EF0852 /* speech_pronunciation_guide.plist in Copy Config */,
1A7C27CA14FA70A500F2D2A8 /* shader-uniform-bindings.plist in Copy Config */,
1AAF565A0F1A27EA00A2F2E6 /* whitelist.plist in Copy Config */,
);
name = "Copy Config";
@ -1730,6 +1732,7 @@
1A7B967E0E620C9E00322821 /* OOSoundInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOSoundInternal.h; sourceTree = "<group>"; };
1A7BA80B0D84231A003C6CA3 /* ShipEntityScriptMethods.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShipEntityScriptMethods.h; sourceTree = "<group>"; };
1A7BA80C0D84231A003C6CA3 /* ShipEntityScriptMethods.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ShipEntityScriptMethods.m; sourceTree = "<group>"; };
1A7C27C814FA709500F2D2A8 /* shader-uniform-bindings.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = "shader-uniform-bindings.plist"; sourceTree = "<group>"; };
1A7C75980CC39D11005D0AA2 /* OOJSSun.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOJSSun.m; sourceTree = "<group>"; };
1A7C75990CC39D11005D0AA2 /* OOJSSun.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOJSSun.h; sourceTree = "<group>"; };
1A7CBF6D10937DD6005B7797 /* OOPointMaths.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOPointMaths.h; sourceTree = "<group>"; };
@ -2127,6 +2130,7 @@
1AC5452C0D4D298E00C90E5B /* oolite-font.plist */,
1AC973F90C9847850010C42B /* pirate-victim-roles.plist */,
1A95338A0C02089E004EBB58 /* planetinfo.plist */,
1A7C27C814FA709500F2D2A8 /* shader-uniform-bindings.plist */,
1A2316EB0B9CFAD700EF0852 /* shipdata.plist */,
1A2123261051892500530CDE /* shipdata-overrides.plist */,
1A2316EC0B9CFAD700EF0852 /* shipyard.plist */,
@ -3943,7 +3947,6 @@
COPY_PHASE_STRIP = NO;
COPY_SCHEMATA = 1;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = dwarf;
DEPS_INCLUDE_PATH = "$(SYMROOT)/$(CONFIGURATION)/include";
FRAMEWORK_SEARCH_PATHS = (
"\"$(SRCROOT)/deps/Cocoa-deps/\"",
@ -3970,7 +3973,6 @@
HEADER_SEARCH_PATHS_QUOTED_4 = "\"$(SRCROOT)/src/Core/Materials/\"";
INFOPLIST_EXPAND_BUILD_SETTINGS = YES;
INFOPLIST_FILE = "src/Cocoa/Info-Oolite.plist";
INSTALL_PATH = "$(HOME)/Applications";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"\"$(SRCROOT)/deps/Cocoa-deps/Ogg Vorbis\"",
@ -3996,7 +3998,6 @@
buildSettings = {
COPY_PHASE_STRIP = NO;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = dwarf;
DEPS_INCLUDE_PATH = "$(SYMROOT)/$(CONFIGURATION)/include";
EXPORTED_SYMBOLS_FILE = "src/Cocoa/exports-release.exp";
"EXPORTED_SYMBOLS_FILE[arch=x86_64]" = "src/Cocoa/exports-release.exp";
@ -4021,7 +4022,6 @@
HEADER_SEARCH_PATHS_QUOTED_3 = "\"$(SRCROOT)/src/Core/Entites/\"";
HEADER_SEARCH_PATHS_QUOTED_4 = "\"$(SRCROOT)/src/Core/Materials/\"";
INFOPLIST_FILE = "src/Cocoa/Info-Oolite.plist";
INSTALL_PATH = "$(HOME)/Applications";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"\"$(SRCROOT)/deps/Cocoa-deps/Ogg Vorbis\"",
@ -4067,7 +4067,6 @@
COPY_PHASE_STRIP = NO;
COPY_SCHEMATA = 1;
COPY_SCR_SHIM = 1;
DEBUG_INFORMATION_FORMAT = dwarf;
DEPS_INCLUDE_PATH = "$(SYMROOT)/$(CONFIGURATION)/include";
FRAMEWORK_SEARCH_PATHS = (
"\"$(SRCROOT)/deps/Cocoa-deps/\"",
@ -4088,7 +4087,6 @@
HEADER_SEARCH_PATHS_QUOTED_3 = "\"$(SRCROOT)/src/Core/Entites/\"";
HEADER_SEARCH_PATHS_QUOTED_4 = "\"$(SRCROOT)/src/Core/Materials/\"";
INFOPLIST_FILE = "src/Cocoa/Info-Oolite.plist";
INSTALL_PATH = "$(HOME)/Applications";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"\"$(SRCROOT)/deps/Cocoa-deps/Ogg Vorbis\"",

View File

@ -55,11 +55,11 @@
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.GDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
ignoresPersistentStateOnLaunch = "YES"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<BuildableProductRunnable>

View File

@ -0,0 +1,82 @@
{
entity =
{
"position" = "vector";
"orientation" = "quaternion";
"relativePosition" = "vector";
"viewpointOffset" = "vector";
"collisionRadius" = "float";
"mass" = "float";
"energy" = "float";
"maxEnergy" = "float";
"universalTime" = "float";
"spawnTime" = "float";
"timeElapsedSinceSpawn" = "float";
"throwingSparks" = "boolean";
"clock" = "float";
"pseudoFixedD100" = "float";
"pseudoFixedD256" = "integer";
"systemGovernment" = "integer";
"systemEconomy" = "integer";
"systemTechLevel" = "integer";
"systemPopulation" = "integer";
"systemProductivity" = "integer";
};
ship =
{
"$inherit" = "entity";
"isBeacon" = "boolean";
"isFrangible" = "boolean";
"isCloaked" = "boolean";
"isJammingScanning" = "boolean";
"hasMilitaryScannerFilter" = "boolean";
"messageTime" = "float";
"escortCount" = "integer";
"hasHostileTarget" = "boolean";
"weaponRange" = "float";
"scannerRange" = "float";
"withinStationAegis" = "boolean";
"fuel" = "float";
"flightPitch" = "float";
"flightRoll" = "float";
"flightYaw" = "float";
"flightSpeed" = "float";
"maxFlightSpeed" = "float";
"speedFactor" = "float";
"damage" = "float";
"laserHeatLevel" = "float";
"hullHeatLevel" = "float";
"entityPersonality" = "float";
"entityPersonalityInt" = "integer";
"numberOfScannedShips" = "integer";
"destination" = "vector";
"rangeToDestination" = "float";
"rangeToPrimaryTarget" = "float";
"laserColor" = "color";
"isHulk" = "boolean";
"lightsActive" = "boolean";
"legalStatus" = "integer";
"fuel" = "integer"; // Tenths of a light year
"velocity" = "vector";
"missileCapacity" = "integer";
"missileCount" = "integer";
};
player =
{
"$inherit" = "ship";
"fuelLeakRate" = "float";
"massLocked" = "boolean";
"atHyperspeed" = "boolean";
"dialForwardShield" = "float";
"dialAftShield" = "float";
"dialMissileStatus" = "integer"; // 0 = safe, 1 = armed, 2 = target locked
"dialFuelScoopStatus" = "integer"; // 0 = not intalled, 1 = full hold, 2 = OK/idle, 3 = active
"compassMode" = "integer"; // 0 = basic, 1 = planet, 3 = station, 4 = sun, 5 = target, 6 = beacon (2 unused)
"dialIdentEngaged" = "boolean";
"alertCondition" = "integer"; // 0 = docked, 1 = green, 2 = yellow, 3 = red
"trumbleCount" = "integer";
};
}

View File

@ -34,6 +34,7 @@ SOFTWARE.
#import "OOCollectionExtractors.h"
#import "NSDictionaryOOExtensions.h"
#import "OOMaterialSpecifier.h"
#import "ResourceManager.h"
/*
* GNUstep 1.20.1 does not support NSIntegerHashCallBacks but uses
@ -82,6 +83,8 @@ static NSString *FormatFloat(double value);
// _sampledTextures: hash of integer texture IDs for which weve set up a sample.
NSHashTable *_sampledTextures;
NSMutableDictionary *_uniformBindingNames;
NSUInteger _usesNormalMap: 1,
_usesDiffuseTerm: 1,
_constZNormal: 1,
@ -96,7 +99,7 @@ static NSString *FormatFloat(double value);
_completed_writeDiffuseColorTermIfNeeded: 1,
_completed_writeVertexPosition: 1,
_completed_writeNormalIfNeeded: 1,
_completed_writeNormal: 1,
_completedwriteNormal: 1,
_completed_writeLightVector: 1,
_completed_writeEyeVector: 1,
_completed_writeTotalColor: 1,
@ -119,16 +122,32 @@ static NSString *FormatFloat(double value);
- (NSArray *) textureSpecifications;
- (NSDictionary *) uniformSpecifications;
- (NSString *) materialKey;
- (NSString *) entityName;
- (void) createTemporaries;
- (void) destroyTemporaries;
- (void) composeVertexShader;
- (void) composeFragmentShader;
- (NSString *) materialKey;
- (NSString *) entityName;
// Write various types of declarations.
- (void) appendVariable:(NSString *)name ofType:(NSString *)type withPrefix:(NSString *)prefix to:(NSMutableString *)buffer;
- (void) addAttribute:(NSString *)name ofType:(NSString *)type;
- (void) addVarying:(NSString *)name ofType:(NSString *)type;
- (void) addVertexUniform:(NSString *)name ofType:(NSString *)type;
- (void) addFragmentUniform:(NSString *)name ofType:(NSString *)type;
// Create or retrieve a uniform variable name for a given binding.
- (NSString *) defineBindingUniform:(NSDictionary *)binding ofType:(NSString *)type;
- (NSString *) readRGBForTextureSpec:(NSDictionary *)textureSpec mapName:(NSString *)mapName; // Generate a read for an RGB value, or a single channel splatted across RGB.
- (NSString *) readOneChannelForTextureSpec:(NSDictionary *)textureSpec mapName:(NSString *)mapName; // Generate a read for a single channel.
// Details of texture setup; generally use -read*ForTextureSpec:mapName: instead.
- (NSUInteger) textureIDForSpec:(NSDictionary *)textureSpec;
- (void) setUpOneTexture:(NSDictionary *)textureSpec;
- (void) getSampleName:(NSString **)outSampleName andSwizzleOp:(NSString **)outSwizzleOp forTextureSpec:(NSDictionary *)textureSpec;
/* Stages. These should only be called through the REQUIRE_STAGE macro to
@ -222,6 +241,13 @@ static NSString *FormatFloat(double value);
- (void) writeFinalColorComposite;
/*
REQUIRE_STAGE(): pull in the required stage. A stage must have a
zero-parameter method and a matching _completed_stage instance variable.
In debug/testrelease builds, this dispatches through performStage: which
checks for recursive calls.
*/
#ifndef NDEBUG
#define REQUIRE_STAGE(NAME) if (!_completed_##NAME) { [self performStage:@selector(NAME)]; _completed_##NAME = YES; }
- (void) performStage:(SEL)stage;
@ -262,6 +288,7 @@ BOOL OOSynthesizeMaterialShader(NSDictionary *configuration, NSString *materialK
*outTextureSpecs = nil;
*outUniformSpecs = nil;
}
[pool release];
[*outVertexShader autorelease];
@ -447,6 +474,39 @@ static NSString *GetExtractMode(NSDictionary *textureSpecifier)
}
- (NSString *) defineBindingUniform:(NSDictionary *)binding ofType:(NSString *)type
{
NSString *name = [binding oo_stringForKey:@"binding"];
NSParameterAssert([name length] > 0);
NSMutableDictionary *bindingSpec = [[binding mutableCopy] autorelease];
if ([bindingSpec oo_stringForKey:@"type"] == nil) [bindingSpec setObject:@"binding" forKey:@"type"];
// Use existing uniform if one is defined.
NSString *uniformName = [_uniformBindingNames objectForKey:bindingSpec];
if (uniformName != nil) return uniformName;
// Capitalize first char of name, and prepend u.
unichar firstChar = toupper([name characterAtIndex:0]);
NSString *baseName = [NSString stringWithFormat:@"u%C%@", firstChar, [name substringFromIndex:1]];
// Ensure name is unique.
name = baseName;
unsigned idx = 1;
while ([_uniforms objectForKey:name] != nil)
{
name = [NSString stringWithFormat:@"%@%u", ++idx];
}
[self addFragmentUniform:name ofType:type];
[_uniforms setObject:bindingSpec forKey:name];
[_uniformBindingNames setObject:name forKey:bindingSpec];
return name;
}
- (void) composeVertexShader
{
while ([_vertexBody hasSuffix:@"\t\n"])
@ -537,7 +597,10 @@ static NSString *KeyFromTextureSpec(NSDictionary *spec)
NSParameterAssert(spec != nil);
// extract_channel doesn't affect uniqueness, and we don't want OOTexture to do actual extraction.
spec = [spec dictionaryByRemovingObjectForKey:kOOTextureSpecifierSwizzleKey];
if ([spec objectForKey:kOOTextureSpecifierSwizzleKey] != nil)
{
spec = [spec dictionaryByRemovingObjectForKey:kOOTextureSpecifierSwizzleKey];
}
NSString *texName = nil;
OOTextureFlags texOptions;
@ -620,7 +683,6 @@ static NSString *KeyFromTextureSpec(NSDictionary *spec)
}
// Generate a read for an RGB value, or a single channel splatted across RGB.
- (NSString *) readRGBForTextureSpec:(NSDictionary *)textureSpec mapName:(NSString *)mapName
{
NSString *sample, *swizzle;
@ -647,7 +709,6 @@ static NSString *KeyFromTextureSpec(NSDictionary *spec)
}
// Generate a read for a single channel.
- (NSString *) readOneChannelForTextureSpec:(NSDictionary *)textureSpec mapName:(NSString *)mapName
{
NSString *sample, *swizzle;
@ -707,6 +768,8 @@ static NSString *KeyFromTextureSpec(NSDictionary *spec)
_textureIDs = [[NSMutableDictionary alloc] init];
_sampledTextures = NSCreateHashTable(NSIntegerHashCallBacks, 0);
_uniformBindingNames = [[NSMutableDictionary alloc] init];
#ifndef NDEBUG
_stagesInProgress = NSCreateHashTable(NSNonOwnedPointerHashCallBacks, 0);
#endif
@ -734,6 +797,8 @@ static NSString *KeyFromTextureSpec(NSDictionary *spec)
_sampledTextures = NULL;
}
DESTROY(_uniformBindingNames);
#ifndef NDEBUG
if (_stagesInProgress != NULL)
{
@ -1170,6 +1235,48 @@ static NSString *KeyFromTextureSpec(NSDictionary *spec)
[_fragmentBody appendFormat:@"\tlightMapColor = vec3(%@, %@, %@);\n", FormatFloat(rgba[0]), FormatFloat(rgba[1]), FormatFloat(rgba[2])];
}
NSDictionary *binding = [textureSpec oo_dictionaryForKey:kOOTextureSpecifierBindingKey];
if (binding != nil)
{
NSString *bindingName = [binding oo_stringForKey:@"binding"];
NSDictionary *typeDict = [[ResourceManager shaderBindingTypesDictionary] oo_dictionaryForKey:@"player"]; // FIXME: select appropriate binding subset.
NSString *bindingType = [typeDict oo_stringForKey:bindingName];
NSString *glslType = nil;
NSString *swizzle = @"";
if ([bindingType isEqualToString:@"float"])
{
glslType = @"float";
}
else if ([bindingType isEqualToString:@"vector"])
{
glslType = @"vec3";
}
else if ([bindingType isEqualToString:@"color"])
{
glslType = @"vec4";
swizzle = @".rgb";
}
if (glslType != nil)
{
NSString *uniformName = [self defineBindingUniform:binding ofType:bindingType];
[_fragmentBody appendFormat:@"\tlightMapColor *= %@%@;\n", uniformName, swizzle];
}
else
{
if (bindingType == nil)
{
OOLogERR(@"material.binding.error.unknown", @"Cannot bind light map to unknown attribute \"%@\".", bindingName);
}
else
{
OOLogERR(@"material.binding.error.badType", @"Cannot bind light map to attribute \"%@\" of type %@.", bindingName, bindingType);
}
[_fragmentBody appendString:@"\tlightMapColor = vec3(0.0); // Bad binding, see log.\n"];
}
}
if (!isIllumination)
{
[_fragmentBody appendString:@"\ttotalColor += lightMapColor;\n\t\n"];
@ -1409,9 +1516,13 @@ static NSDictionary *CanonicalizeMaterialSpecifier(NSDictionary *spec, NSString
{
if ([lmSpec isKindOfClass:[NSString class]])
{
lmSpec = [NSDictionary dictionaryWithObject:lmSpec forKey:kOOTextureSpecifierNameKey];
lmSpec = [NSMutableDictionary dictionaryWithObject:lmSpec forKey:kOOTextureSpecifierNameKey];
}
else if (![lmSpec isKindOfClass:[NSDictionary class]])
else if ([lmSpec isKindOfClass:[NSDictionary class]])
{
lmSpec = [[lmSpec mutableCopy] autorelease];
}
else
{
continue;
}
@ -1421,10 +1532,24 @@ static NSDictionary *CanonicalizeMaterialSpecifier(NSDictionary *spec, NSString
{
// Don't convert arrays here, because we specifically don't want the behaviour of treating numbers greater than 1 as 0..255 components.
col = [OOColor colorWithDescription:modulateColor];
lmSpec = [lmSpec dictionaryByAddingObject:[col normalizedArray] forKey:kOOTextureSpecifierModulateColorKey];
[lmSpec setObject:[col normalizedArray] forKey:kOOTextureSpecifierModulateColorKey];
}
[lightMaps addObject:lmSpec];
id binding = [lmSpec objectForKey:kOOTextureSpecifierBindingKey];
if (binding != nil)
{
if ([binding isKindOfClass:[NSString class]])
{
NSDictionary *expandedBinding = [NSDictionary dictionaryWithObjectsAndKeys:@"binding", @"type", binding, @"binding", nil];
[lmSpec setObject:expandedBinding forKey:kOOTextureSpecifierBindingKey];
}
else if (![binding isKindOfClass:[NSDictionary class]] || [[binding oo_stringForKey:@"binding"] length] == 0)
{
[lmSpec removeObjectForKey:kOOTextureSpecifierBindingKey];
}
}
[lightMaps addObject:[[lmSpec copy] autorelease]];
}
if ([lightMaps count] == 0)

View File

@ -316,3 +316,4 @@ extern NSString * const kOOTextureSpecifierModulateColorKey;
extern NSString * const kOOTextureSpecifierIlluminationModeKey;
extern NSString * const kOOTextureSpecifierSelfColorKey;
extern NSString * const kOOTextureSpecifierScaleFactorKey;
extern NSString * const kOOTextureSpecifierBindingKey;

View File

@ -57,6 +57,7 @@ NSString * const kOOTextureSpecifierModulateColorKey = @"color";
NSString * const kOOTextureSpecifierIlluminationModeKey = @"illumination_mode";
NSString * const kOOTextureSpecifierSelfColorKey = @"self_color";
NSString * const kOOTextureSpecifierScaleFactorKey = @"scale_factor";
NSString * const kOOTextureSpecifierBindingKey = @"binding";
// Used only by "internal" specifiers from OOMakeTextureSpecifier.
static NSString * const kOOTextureSpecifierFlagValueInternalKey = @"_oo_internal_flags";

View File

@ -35,7 +35,7 @@ SOFTWARE.
// Note: object lifetime issues aside, we need to copy and autorelease so that the right thing happens for mutable dictionaries.
if (object == nil || key == nil) return [[self copy] autorelease];
NSMutableDictionary *temp = [[NSMutableDictionary alloc] initWithDictionary:self];
NSMutableDictionary *temp = [self mutableCopy];
[temp setObject:object forKey:key];
NSDictionary *result = [[temp copy] autorelease];
[temp release];
@ -49,7 +49,7 @@ SOFTWARE.
// Note: object lifetime issues aside, we need to copy and autorelease so that the right thing happens for mutable dictionaries.
if (key == nil) return [[self copy] autorelease];
NSMutableDictionary *temp = [[NSMutableDictionary alloc] initWithDictionary:self];
NSMutableDictionary *temp = [self mutableCopy];
[temp removeObjectForKey:key];
NSDictionary *result = [[temp copy] autorelease];
[temp release];
@ -63,7 +63,7 @@ SOFTWARE.
// Note: object lifetime issues aside, we need to copy and autorelease so that the right thing happens for mutable dictionaries.
if (dictionary == nil) return [[self copy] autorelease];
NSMutableDictionary *temp = [[NSMutableDictionary alloc] initWithDictionary:self];
NSMutableDictionary *temp = [self mutableCopy];
[temp addEntriesFromDictionary:dictionary];
NSDictionary *result = [[temp copy] autorelease];
[temp release];

View File

@ -75,7 +75,9 @@ typedef enum
andMerge:(BOOL) mergeFiles
cache:(BOOL)useCache;
+ (NSDictionary *) whitelistDictionary; // method-whitelist.plist, explicitly not merged like normal plists.
// These are deliberately not merged like normal plists for security reasons.
+ (NSDictionary *) whitelistDictionary;
+ (NSDictionary *) shaderBindingTypesDictionary;
+ (OOSound *)ooSoundNamed:(NSString *)fileName inFolder:(NSString *)folderName;
+ (OOMusic *)ooMusicNamed:(NSString *)fileName inFolder:(NSString *)folderName;

View File

@ -737,12 +737,11 @@ static NSMutableDictionary *sStringCache;
+ (NSDictionary *) whitelistDictionary
{
static id whitelistDictionary = nil;
NSString *path = nil;
static id whitelistDictionary = nil;
if (whitelistDictionary == nil)
{
path = [[[ResourceManager builtInPath] stringByAppendingPathComponent:@"Config"] stringByAppendingPathComponent:@"whitelist.plist"];
NSString *path = [[[ResourceManager builtInPath] stringByAppendingPathComponent:@"Config"] stringByAppendingPathComponent:@"whitelist.plist"];
whitelistDictionary = [NSDictionary dictionaryWithContentsOfFile:path];
if (whitelistDictionary == nil) whitelistDictionary = [NSNull null];
@ -754,6 +753,52 @@ static NSMutableDictionary *sStringCache;
}
+ (NSDictionary *) shaderBindingTypesDictionary
{
static id shaderBindingTypesDictionary = nil;
if (shaderBindingTypesDictionary == nil)
{
NSAutoreleasePool *pool = [NSAutoreleasePool new];
NSString *path = [[[ResourceManager builtInPath] stringByAppendingPathComponent:@"Config"] stringByAppendingPathComponent:@"shader-uniform-bindings.plist"];
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithContentsOfFile:path];
NSArray *keys = [dict allKeys];
// Resolve all $inherit keys.
unsigned changeCount = 0;
do {
changeCount = 0;
NSString *key = nil;
foreach (key, keys)
{
NSDictionary *value = [dict oo_dictionaryForKey:key];
NSString *inheritKey = [value oo_stringForKey:@"$inherit"];
if (inheritKey != nil)
{
changeCount++;
NSMutableDictionary *mutableValue = [[value mutableCopy] autorelease];
[mutableValue removeObjectForKey:@"$inherit"];
NSDictionary *inherited = [dict oo_dictionaryForKey:inheritKey];
if (inherited != nil)
{
[mutableValue addEntriesFromDictionary:inherited];
}
[dict setObject:[[mutableValue copy] autorelease] forKey:key];
}
}
} while (changeCount != 0);
shaderBindingTypesDictionary = [dict copy];
[pool release];
}
return shaderBindingTypesDictionary;
}
+ (NSString *) pathForFileNamed:(NSString *)fileName inFolder:(NSString *)folderName
{
return [self pathForFileNamed:fileName inFolder:folderName cache:YES];