LCOV - code coverage report
Current view: top level - Core/Materials - OOMaterialConvenienceCreators.m (source / functions) Hit Total Coverage
Test: coverxygen.info Lines: 0 21 0.0 %
Date: 2025-05-28 07:50:54 Functions: 0 0 -

          Line data    Source code
       1           0 : /*
       2             : 
       3             : OOMaterialConvenienceCreators.m
       4             : 
       5             : 
       6             : Copyright (C) 2007-2013 Jens Ayton
       7             : 
       8             : Permission is hereby granted, free of charge, to any person obtaining a copy
       9             : of this software and associated documentation files (the "Software"), to deal
      10             : in the Software without restriction, including without limitation the rights
      11             : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      12             : copies of the Software, and to permit persons to whom the Software is
      13             : furnished to do so, subject to the following conditions:
      14             : 
      15             : The above copyright notice and this permission notice shall be included in all
      16             : copies or substantial portions of the Software.
      17             : 
      18             : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      19             : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      20             : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      21             : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      22             : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      23             : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
      24             : SOFTWARE.
      25             : 
      26             : */
      27             : 
      28             : #ifndef USE_NEW_SHADER_SYNTHESIZER
      29           0 : #define USE_NEW_SHADER_SYNTHESIZER      0
      30             : #endif
      31             : 
      32             : 
      33             : #import "OOMaterialConvenienceCreators.h"
      34             : #import "OOMaterialSpecifier.h"
      35             : 
      36             : #if USE_NEW_SHADER_SYNTHESIZER
      37             : #import "OODefaultShaderSynthesizer.h"
      38             : #import "ResourceManager.h"
      39             : #endif
      40             : 
      41             : #import "OOOpenGLExtensionManager.h"
      42             : #import "OOShaderMaterial.h"
      43             : #import "OOSingleTextureMaterial.h"
      44             : #import "OOMultiTextureMaterial.h"
      45             : #import "OOCollectionExtractors.h"
      46             : #import "Universe.h"
      47             : #import "OOCacheManager.h"
      48             : #import "OOTexture.h"
      49             : #import "OODebugFlags.h"
      50             : 
      51             : 
      52             : #if !USE_NEW_SHADER_SYNTHESIZER
      53           0 : typedef struct
      54             : {
      55           0 :         NSDictionary                    *inConfig;
      56           0 :         NSMutableDictionary             *outConfig;
      57           0 :         NSUInteger                              texturesUsed;
      58           0 :         NSUInteger                              maxTextures;
      59             :         
      60           0 :         NSMutableDictionary             *macros;
      61           0 :         NSMutableArray                  *textures;
      62           0 :         NSMutableDictionary             *uniforms;
      63             : } OOMaterialSynthContext;
      64             : 
      65             : 
      66             : static void SetUniform(NSMutableDictionary *uniforms, NSString *key, NSString *type, id value);
      67             : static void SetUniformFloat(OOMaterialSynthContext *context, NSString *key, float value);
      68             : 
      69             : /*      AddTexture(): add a texture to the configuration being synthesized.
      70             :         * specifier is added to the textures array.
      71             :         * uniformName is mapped to the appropriate texture unit in the uniforms dictionary.
      72             :         * If nonShaderKey is not nil, nonShaderKey (e.g. diffuse_map) is set to specifier.
      73             :         * If macroName is not nil, macroName is set to 1 in the macros dictionary.
      74             : */
      75             : static void AddTexture(OOMaterialSynthContext *context, NSString *uniformName, NSString *nonShaderKey, NSString *macroName, NSDictionary *specifier);
      76             : 
      77             : static void AddColorIfAppropriate(OOMaterialSynthContext *context, SEL selector, NSString *key, NSString *macroName);
      78             : static void AddMacroColorIfAppropriate(OOMaterialSynthContext *context, SEL selector, NSString *macroName);
      79             : 
      80             : static void SynthDiffuse(OOMaterialSynthContext *context, NSString *name);
      81             : static void SynthEmissionAndIllumination(OOMaterialSynthContext *context);
      82             : static void SynthNormalMap(OOMaterialSynthContext *context);
      83             : static void SynthSpecular(OOMaterialSynthContext *context);
      84             : 
      85             : #endif
      86             : 
      87             : 
      88             : @implementation OOMaterial (OOConvenienceCreators)
      89             : 
      90             : #if !USE_NEW_SHADER_SYNTHESIZER
      91             : 
      92           0 : + (NSDictionary *)synthesizeMaterialDictionaryWithName:(NSString *)name
      93             :                                                                                  configuration:(NSDictionary *)configuration
      94             :                                                                                                 macros:(NSDictionary *)macros
      95             : {
      96             :         if (configuration == nil)  configuration = [NSDictionary dictionary];
      97             :         OOMaterialSynthContext context =
      98             :         {
      99             :                 .inConfig = configuration,
     100             :                 .outConfig = [NSMutableDictionary dictionary],
     101             :                 .maxTextures = [[OOOpenGLExtensionManager sharedManager] textureImageUnitCount],
     102             :                 
     103             :                 .macros = [NSMutableDictionary dictionaryWithDictionary:macros],
     104             :                 .textures = [NSMutableArray array],
     105             :                 .uniforms = [NSMutableDictionary dictionary]
     106             :         };
     107             :         
     108             :         if ([UNIVERSE reducedDetail])
     109             :         {
     110             :                 context.maxTextures = 3;
     111             :         }
     112             :         
     113             :         //      Basic stuff.
     114             :         
     115             :         /*      Set up the various material attributes.
     116             :                 Order is significant here, because it determines the order in which
     117             :                 features will be dropped if we exceed the hardware's texture image
     118             :                 unit limit.
     119             :         */
     120             :         SynthDiffuse(&context, name);
     121             :         SynthEmissionAndIllumination(&context);
     122             :         SynthNormalMap(&context);
     123             :         SynthSpecular(&context);
     124             :         
     125             :         if ([UNIVERSE detailLevel] >= DETAIL_LEVEL_SHADERS)
     126             :         {
     127             :                 //      Add uniforms required for hull heat glow.
     128             :                 [context.uniforms setObject:@"hullHeatLevel" forKey:@"uHullHeatLevel"];
     129             :                 [context.uniforms setObject:@"timeElapsedSinceSpawn" forKey:@"uTime"];
     130             :                 [context.uniforms setObject:@"fogUniform" forKey:@"uFogColor"];
     131             :         }
     132             :         
     133             :         //      Stuff in the general properties.
     134             :         [context.outConfig setObject:@"true" forKey:@"_oo_is_synthesized_config"];
     135             :         [context.outConfig setObject:@"oolite-tangent-space-vertex.vertex" forKey:@"vertex_shader"];
     136             :         [context.outConfig setObject:@"oolite-default-shader.fragment" forKey:@"fragment_shader"];
     137             :         
     138             :         if ([context.textures count] != 0)  [context.outConfig setObject:context.textures forKey:@"textures"];
     139             :         if ([context.uniforms count] != 0)  [context.outConfig setObject:context.uniforms forKey:@"uniforms"];
     140             :         if ([context.macros count] != 0)  [context.outConfig setObject:context.macros forKey:@"_oo_synthesized_material_macros"];
     141             :         
     142             :         return context.outConfig;
     143             : }
     144             : 
     145             : 
     146           0 : + (OOMaterial *)defaultShaderMaterialWithName:(NSString *)name
     147             :                                                                          cacheKey:(NSString *)cacheKey
     148             :                                                                 configuration:(NSDictionary *)configuration
     149             :                                                                            macros:(NSDictionary *)macros
     150             :                                                                 bindingTarget:(id<OOWeakReferenceSupport>)target
     151             : {
     152             :         OOCacheManager                  *cache = nil;
     153             :         NSDictionary                    *synthesizedConfig = nil;
     154             :         OOMaterial                              *result = nil;
     155             :         
     156             :         // Avoid looping (can happen if shader fails to compile).
     157             :         if ([configuration objectForKey:@"_oo_is_synthesized_config"] != nil)
     158             :         {
     159             :                 OOLog(@"material.synthesize.loop", @"Synthesis loop for material %@.", name);
     160             :                 return nil;
     161             :         }
     162             :         
     163             :         if (cacheKey != nil)
     164             :         {
     165             :                 cache = [OOCacheManager sharedCache];
     166             :                 // configuration must be in cache key, as otherwise changes in
     167             :                 // non-diffuse map can end up miscached
     168             :                 cacheKey = [NSString stringWithFormat:@"%@/%@/%@", cacheKey, name, configuration];
     169             :                 synthesizedConfig = [cache objectForKey:cacheKey inCache:@"synthesized shader materials"];
     170             :         }
     171             :         
     172             :         if (synthesizedConfig == nil)
     173             :         {
     174             :                 synthesizedConfig = [self synthesizeMaterialDictionaryWithName:name
     175             :                                                                                                                  configuration:configuration
     176             :                                                                                                                                 macros:macros];
     177             :                 if (synthesizedConfig != nil && cacheKey != nil)
     178             :                 {
     179             :                         [cache setObject:synthesizedConfig
     180             :                                           forKey:cacheKey
     181             :                                          inCache:@"synthesized shader materials"];
     182             :                 }
     183             :         }
     184             :         
     185             :         if (synthesizedConfig != nil)
     186             :         {
     187             :                 result =  [self materialWithName:name
     188             :                                                                 cacheKey:cacheKey
     189             :                                                    configuration:synthesizedConfig
     190             :                                                                   macros:[synthesizedConfig objectForKey:@"_oo_synthesized_material_macros"]
     191             :                                                    bindingTarget:target
     192             :                                                  forSmoothedMesh:YES];
     193             :         }
     194             :         
     195             :         return result;
     196             : }
     197             : 
     198             : #else
     199             : 
     200             : #ifndef NDEBUG
     201             : static BOOL sDumpShaderSource = NO;
     202             : 
     203             : + (void) initialize
     204             : {
     205             :         sDumpShaderSource = [[NSUserDefaults standardUserDefaults] boolForKey:@"dump-synthesized-shaders"];
     206             : }
     207             : #endif
     208             : 
     209             : 
     210             : + (OOMaterial *) defaultShaderMaterialWithName:(NSString *)name
     211             :                                                                           cacheKey:(NSString *)cacheKey
     212             :                                                                  configuration:(NSDictionary *)configuration
     213             :                                                                                 macros:(NSDictionary *)macros
     214             :                                                                  bindingTarget:(id<OOWeakReferenceSupport>)target
     215             : {
     216             :         NSString                *vertexShader = nil;
     217             :         NSString                *fragmentShader = nil;
     218             :         NSArray                 *textureSpecs = nil;
     219             :         NSDictionary    *uniformSpecs = nil;
     220             :         
     221             :         if (!OOSynthesizeMaterialShader(configuration, name, cacheKey /* FIXME: entity name for error reporting */, &vertexShader, &fragmentShader, &textureSpecs, &uniformSpecs))
     222             :         {
     223             :                 return nil;
     224             :         }
     225             :         
     226             :         NSDictionary    *synthesizedConfig = [NSDictionary dictionaryWithObjectsAndKeys:
     227             :                                                                                   [NSNumber numberWithBool:YES], kOOIsSynthesizedMaterialConfigurationKey,
     228             :                                                                                   textureSpecs, kOOTexturesKey,
     229             :                                                                                   uniformSpecs, kOOUniformsKey,
     230             :                                                                                   vertexShader, kOOVertexShaderSourceKey,
     231             :                                                                                   fragmentShader, kOOFragmentShaderSourceKey,
     232             :                                                                                   nil];
     233             :         
     234             : #ifndef NDEBUG
     235             :         if (sDumpShaderSource)
     236             :         {
     237             :                 NSString *dumpPath = [NSString stringWithFormat:@"Synthesized Materials/%@/%@", cacheKey, name];
     238             :                 
     239             :                 [ResourceManager writeDiagnosticString:vertexShader toFileNamed:[dumpPath stringByAppendingPathExtension:@"vertex"]];
     240             :                 [ResourceManager writeDiagnosticString:fragmentShader toFileNamed:[dumpPath stringByAppendingPathExtension:@"fragment"]];
     241             :                 
     242             :                 // Hide internal keys in the synthesized config before writing it.
     243             :                 NSMutableDictionary *humanFriendlyConfig = [[synthesizedConfig mutableCopy] autorelease];
     244             :                 [humanFriendlyConfig removeObjectForKey:kOOVertexShaderSourceKey];
     245             :                 [humanFriendlyConfig removeObjectForKey:kOOFragmentShaderSourceKey];
     246             :                 [humanFriendlyConfig removeObjectForKey:kOOIsSynthesizedMaterialConfigurationKey];
     247             :                 [humanFriendlyConfig setObject:[NSString stringWithFormat:@"%@.vertex", name] forKey:kOOVertexShaderNameKey];
     248             :                 [humanFriendlyConfig setObject:[NSString stringWithFormat:@"%@.fragment", name] forKey:kOOFragmentShaderNameKey];
     249             :                 
     250             :                 [ResourceManager writeDiagnosticPList:humanFriendlyConfig toFileNamed:[dumpPath stringByAppendingPathExtension:@"plist"]];
     251             :                 
     252             :                 [ResourceManager writeDiagnosticPList:configuration toFileNamed:[[dumpPath stringByAppendingString:@"-original"] stringByAppendingPathExtension:@"plist"]];
     253             :         }
     254             : #endif
     255             :         
     256             :         return [self materialWithName:name
     257             :                                                  cacheKey:cacheKey
     258             :                                         configuration:synthesizedConfig
     259             :                                                    macros:nil
     260             :                                         bindingTarget:target
     261             :                                   forSmoothedMesh:YES];
     262             : }
     263             : 
     264             : #endif
     265             : 
     266             : 
     267             : + (OOMaterial *) materialWithName:(NSString *)name
     268             :                                                  cacheKey:(NSString *)cacheKey
     269             :                                         configuration:(NSDictionary *)configuration
     270             :                                                    macros:(NSDictionary *)macros
     271             :                                         bindingTarget:(id<OOWeakReferenceSupport>)object
     272             :                                   forSmoothedMesh:(BOOL)smooth  // Internally, this flg really means "force use of shaders".
     273             : {
     274             :         id result = nil;
     275             :         
     276             : #if OO_SHADERS
     277             : 
     278             :         if ([UNIVERSE useShaders])
     279             :         {
     280             :                 if ([OOShaderMaterial configurationDictionarySpecifiesShaderMaterial:configuration])
     281             :                 {
     282             :                         result = [OOShaderMaterial shaderMaterialWithName:name
     283             :                                                                                                 configuration:configuration
     284             :                                                                                                            macros:macros
     285             :                                                                                                 bindingTarget:object];
     286             :                 }
     287             :                 
     288             :                 // Use default shader if smoothing is on, or shader detail is full, DEBUG_NO_SHADER_FALLBACK is set, or material uses an effect map.
     289             :                 if (result == nil &&
     290             :                                 (smooth ||
     291             :                                  gDebugFlags & DEBUG_NO_SHADER_FALLBACK ||
     292             :                                  [UNIVERSE detailLevel] >= DETAIL_LEVEL_SHADERS ||
     293             :                                  [configuration oo_combinedSpecularMapSpecifier] != nil ||
     294             :                                  [configuration oo_normalMapSpecifier] != nil ||
     295             :                                  [configuration oo_parallaxMapSpecifier] != nil ||
     296             :                                  [configuration oo_normalAndParallaxMapSpecifier] != nil ||
     297             :                                  [configuration oo_emissionMapSpecifier] != nil ||
     298             :                                  [configuration oo_illuminationMapSpecifier] != nil ||
     299             :                                  [configuration oo_emissionAndIlluminationMapSpecifier] != nil
     300             :                                  ))
     301             :                 {
     302             :                         result = [self defaultShaderMaterialWithName:name
     303             :                                                                                                 cacheKey:cacheKey
     304             :                                                                                    configuration:configuration
     305             :                                                                                                   macros:macros
     306             :                                                                                    bindingTarget:(id<OOWeakReferenceSupport>)object];
     307             :                 }
     308             :         }
     309             : #endif
     310             :         
     311             : #if OO_MULTITEXTURE
     312             :         if (result == nil /*&& ![UNIVERSE reducedDetail]*/)
     313             :         {
     314             :                 if ([configuration oo_emissionMapSpecifier] != nil ||
     315             :                         [configuration oo_illuminationMapSpecifier] ||
     316             :                         [configuration oo_emissionAndIlluminationMapSpecifier] != nil)
     317             :                 {
     318             :                         result = [[OOMultiTextureMaterial alloc] initWithName:name configuration:configuration];
     319             :                         [result autorelease];
     320             :                 }
     321             :         }
     322             : #endif
     323             :         
     324             :         if (result == nil)
     325             :         {
     326             :                 if ([configuration oo_diffuseMapSpecifierWithDefaultName:name] == nil)
     327             :                 {
     328             :                         result = [[OOBasicMaterial alloc] initWithName:name configuration:configuration];
     329             :                 }
     330             :                 else
     331             :                 {
     332             :                         result = [[OOSingleTextureMaterial alloc] initWithName:name configuration:configuration];
     333             :                 }
     334             :                 if (result == nil)
     335             :                 {
     336             :                         result = [[OOBasicMaterial alloc] initWithName:name configuration:configuration];
     337             :                 }
     338             :                 [result autorelease];
     339             :         }
     340             :         return result;
     341             : }
     342             : 
     343             : 
     344             : + (OOMaterial *) materialWithName:(NSString *)name
     345             :                                                  cacheKey:(NSString *)cacheKey
     346             :                            materialDictionary:(NSDictionary *)materialDict
     347             :                                 shadersDictionary:(NSDictionary *)shadersDict
     348             :                                                    macros:(NSDictionary *)macros
     349             :                                         bindingTarget:(id<OOWeakReferenceSupport>)object
     350             :                                   forSmoothedMesh:(BOOL)smooth
     351             : {
     352             :         NSDictionary                    *configuration = nil;
     353             :         
     354             : #if OO_SHADERS
     355             : 
     356             :         if ([UNIVERSE useShaders])
     357             :         {
     358             :                 configuration = [shadersDict oo_dictionaryForKey:name];
     359             :         }
     360             : #endif
     361             :         
     362             :         if (configuration == nil)
     363             :         {
     364             :                 configuration = [materialDict oo_dictionaryForKey:name];
     365             :         }
     366             :         
     367             :         if (configuration == nil)
     368             :         {
     369             :                 // Use fallback material for non-existent simple texture.
     370             :                 // Texture caching means this won't be wasted in the general case.
     371             :                 OOTexture *texture = [OOTexture textureWithName:name inFolder:@"Textures"];
     372             :                 if (texture == nil)  return nil;
     373             :                 
     374             :                 configuration = [NSDictionary dictionary];
     375             :         }
     376             :         
     377             :         return [self materialWithName:name
     378             :                                                  cacheKey:cacheKey
     379             :                                         configuration:configuration
     380             :                                                    macros:macros
     381             :                                         bindingTarget:object
     382             :                                   forSmoothedMesh:smooth];
     383             : }
     384             : 
     385             : @end
     386             : 
     387             : 
     388             : #if !USE_NEW_SHADER_SYNTHESIZER
     389             : 
     390           0 : static void SetUniform(NSMutableDictionary *uniforms, NSString *key, NSString *type, id value)
     391             : {
     392             :         [uniforms setObject:[NSDictionary dictionaryWithObjectsAndKeys:type, @"type", value, @"value", nil] forKey:key];
     393             : }
     394             : 
     395             : 
     396           0 : static void SetUniformFloat(OOMaterialSynthContext *context, NSString *key, float value)
     397             : {
     398             :         SetUniform(context->uniforms, key, @"float", [NSNumber numberWithFloat:value]);
     399             : }
     400             : 
     401             : 
     402           0 : static void AddTexture(OOMaterialSynthContext *context, NSString *uniformName, NSString *nonShaderKey, NSString *macroName, NSDictionary *specifier)
     403             : {
     404             :         NSCParameterAssert(context->texturesUsed < context->maxTextures);
     405             :         
     406             :         context->texturesUsed++;
     407             :         SetUniform(context->uniforms, uniformName, @"texture", [NSNumber numberWithUnsignedInteger:[context->textures count]]);
     408             :         [context->textures addObject:specifier];
     409             :         if (nonShaderKey != nil)
     410             :         {
     411             :                 [context->outConfig setObject:specifier forKey:kOOMaterialDiffuseMapName];
     412             :         }
     413             :         if (macroName != nil)
     414             :         {
     415             :                 [context->macros setObject:@"1" forKey:macroName];
     416             :         }
     417             : }
     418             : 
     419             : 
     420           0 : static void AddColorIfAppropriate(OOMaterialSynthContext *context, SEL selector, NSString *key, NSString *macroName)
     421             : {
     422             :         OOColor *color = [context->inConfig performSelector:selector];
     423             :         
     424             :         if (color != nil)
     425             :         {
     426             :                 [context->outConfig setObject:[color normalizedArray] forKey:key];
     427             :                 if (macroName != nil)  [context->macros setObject:@"1" forKey:macroName];
     428             :         }
     429             : }
     430             : 
     431             : 
     432           0 : static void AddMacroColorIfAppropriate(OOMaterialSynthContext *context, SEL selector, NSString *macroName)
     433             : {
     434             :         OOColor *color = [context->inConfig performSelector:selector];
     435             :         
     436             :         if (color != nil)
     437             :         {
     438             :                 NSString *macroText = [NSString stringWithFormat:@"vec4(%g, %g, %g, %g)",
     439             :                                                            [color redComponent],
     440             :                                                            [color greenComponent],
     441             :                                                            [color blueComponent],
     442             :                                                            [color alphaComponent]];
     443             :                 [context->macros setObject:macroText forKey:macroName];
     444             :         }
     445             : }
     446             : 
     447             : 
     448           0 : static void SynthDiffuse(OOMaterialSynthContext *context, NSString *name)
     449             : {
     450             :         // Set up diffuse map if appropriate.
     451             :         NSDictionary *diffuseMapSpec = [context->inConfig oo_diffuseMapSpecifierWithDefaultName:name];
     452             :         if (diffuseMapSpec != nil && context->texturesUsed < context->maxTextures)
     453             :         {
     454             :                 AddTexture(context, @"uDiffuseMap", kOOMaterialDiffuseMapName, @"OOSTD_DIFFUSE_MAP", diffuseMapSpec);
     455             :                 
     456             :                 if ([diffuseMapSpec oo_boolForKey:@"cube_map"])
     457             :                 {
     458             :                         [context->macros setObject:@"1" forKey:@"OOSTD_DIFFUSE_MAP_IS_CUBE_MAP"];
     459             :                 }
     460             :         }
     461             :         else
     462             :         {
     463             :                 // No diffuse map must be specified explicitly.
     464             :                 [context->outConfig setObject:@"" forKey:kOOMaterialDiffuseMapName];
     465             :         }
     466             :         
     467             :         // Set up diffuse colour if any.
     468             :         AddColorIfAppropriate(context, @selector(oo_diffuseColor), kOOMaterialDiffuseColorName, nil);
     469             : }
     470             : 
     471             : 
     472           0 : static void SynthEmissionAndIllumination(OOMaterialSynthContext *context)
     473             : {
     474             :         // Read the various emission and illumination textures, and decide what to do with them.
     475             :         NSDictionary *emissionMapSpec = [context->inConfig oo_emissionMapSpecifier];
     476             :         NSDictionary *illuminationMapSpec = [context->inConfig oo_illuminationMapSpecifier];
     477             :         NSDictionary *emissionAndIlluminationSpec = [context->inConfig oo_emissionAndIlluminationMapSpecifier];
     478             :         BOOL isCombinedSpec = NO;
     479             :         BOOL haveIlluminationMap = NO;
     480             :         
     481             :         if (emissionMapSpec == nil && emissionAndIlluminationSpec != nil)
     482             :         {
     483             :                 emissionMapSpec = emissionAndIlluminationSpec;
     484             :                 if (illuminationMapSpec == nil)  isCombinedSpec = YES;  // Else use only emission part of emission_and_illumination_map, combined with full illumination_map.
     485             :         }
     486             :         
     487             :         if (emissionMapSpec != nil && context->texturesUsed < context->maxTextures)
     488             :         {
     489             :                 /*      FIXME: at this point, if there is an illumination map, we should
     490             :                         consider merging it into the emission map using
     491             :                         OOCombinedEmissionMapGenerator if the total number of texture
     492             :                         specifiers is greater than context->maxTextures. This will
     493             :                         require adding a new type of texture specifier - not a big deal.
     494             :                         -- Ahruman 2010-05-21
     495             :                 */
     496             :                 AddTexture(context, @"uEmissionMap", nil, isCombinedSpec ? @"OOSTD_EMISSION_AND_ILLUMINATION_MAP" : @"OOSTD_EMISSION_MAP", emissionMapSpec);
     497             :                 /*      Note that this sets emission_color, not emission_modulate_color.
     498             :                         This is because the emission colour value is sent through the
     499             :                         standard OpenGL emission colour attribute by OOBasicMaterial.
     500             :                 */
     501             :                 AddColorIfAppropriate(context, @selector(oo_emissionModulateColor), kOOMaterialEmissionColorName, @"OOSTD_EMISSION");
     502             :                 
     503             :                 haveIlluminationMap = isCombinedSpec;
     504             :         }
     505             :         else
     506             :         {
     507             :                 //      No emission map, use overall emission colour if specified.
     508             :                 AddColorIfAppropriate(context, @selector(oo_emissionColor), kOOMaterialEmissionColorName, @"OOSTD_EMISSION");
     509             :         }
     510             :         
     511             :         if (illuminationMapSpec != nil && context->texturesUsed < context->maxTextures)
     512             :         {
     513             :                 AddTexture(context, @"uIlluminationMap", nil, @"OOSTD_ILLUMINATION_MAP", illuminationMapSpec);
     514             :                 haveIlluminationMap = YES;
     515             :         }
     516             :         
     517             :         if (haveIlluminationMap)
     518             :         {
     519             :                 AddMacroColorIfAppropriate(context, @selector(oo_illuminationModulateColor), @"OOSTD_ILLUMINATION_COLOR");
     520             :         }
     521             : }
     522             : 
     523             : 
     524           0 : static void SynthNormalMap(OOMaterialSynthContext *context)
     525             : {
     526             :         if (context->texturesUsed < context->maxTextures)
     527             :         {
     528             :                 BOOL hasParallax = YES;
     529             :                 NSDictionary *normalMapSpec = [context->inConfig oo_normalAndParallaxMapSpecifier];
     530             :                 if (normalMapSpec == nil)
     531             :                 {
     532             :                         hasParallax = NO;
     533             :                         normalMapSpec = [context->inConfig oo_normalMapSpecifier];
     534             :                 }
     535             :                 
     536             :                 if (normalMapSpec != nil)
     537             :                 {
     538             :                         AddTexture(context, @"uNormalMap", nil, @"OOSTD_NORMAL_MAP", normalMapSpec);
     539             :                         
     540             :                         if (hasParallax)
     541             :                         {
     542             :                                 [context->macros setObject:@"1" forKey:@"OOSTD_NORMAL_AND_PARALLAX_MAP"];
     543             :                                 SetUniformFloat(context, @"uParallaxScale", [context->inConfig oo_parallaxScale]);
     544             :                                 SetUniformFloat(context, @"uParallaxBias", [context->inConfig oo_parallaxBias]);
     545             :                         }
     546             :                 }
     547             :         }
     548             : }
     549             : 
     550             : 
     551           0 : static void SynthSpecular(OOMaterialSynthContext *context)
     552             : {
     553             :         GLint shininess = [context->inConfig oo_specularExponent];
     554             :         if (shininess <= 0)  return;
     555             :         
     556             :         GLfloat gloss = [context->inConfig oo_gloss];
     557             :         if (gloss < 0.0f || gloss > 1.0f)  return;
     558             :         
     559             :         BOOL gammaCorrect = [context->inConfig oo_gammaCorrect];
     560             :         
     561             :         NSDictionary *specularMapSpec = nil;
     562             :         OOColor *specularColor = nil;
     563             :         
     564             :         if (context->texturesUsed < context->maxTextures)
     565             :         {
     566             :                 specularMapSpec = [context->inConfig oo_combinedSpecularMapSpecifier];
     567             :         }
     568             :         
     569             :         if (specularMapSpec != nil)  specularColor = [context->inConfig oo_specularModulateColor];
     570             :         else  specularColor = [context->inConfig oo_specularColor];
     571             :         if ([specularColor isBlack])  return;
     572             :         
     573             :         SetUniformFloat(context, @"uGloss", gloss);
     574             :         
     575             :         [context->outConfig setObject:[NSNumber numberWithUnsignedInt:shininess] forKey:kOOMaterialSpecularExponentLegacyName];
     576             :         
     577             :         if (specularMapSpec != nil)
     578             :         {
     579             :                 AddTexture(context, @"uSpecularMap", kOOMaterialDiffuseMapName, @"OOSTD_SPECULAR_MAP", specularMapSpec);
     580             :         }
     581             :         
     582             :         if (specularColor != nil)
     583             :         {
     584             :                 /*      As with emission colour, specular_modulate_color is transformed to
     585             :                  specular_color here because the shader reads it from the standard
     586             :                  material specular colour property set by OOBasicMaterial.
     587             :                  */
     588             :                 [context->outConfig setObject:[specularColor normalizedArray] forKey:kOOMaterialSpecularColorName];
     589             :         }
     590             :         [context->macros setObject:@"1" forKey:@"OOSTD_SPECULAR"];
     591             :         
     592             :         // setting a bool as a float uniform, to be used in the shader as a bool again
     593             :         // this is how hackish I can get... maybe a better way exists, but this is quick
     594             :         // and can be used also for the shader materials in a not too different way
     595             :         // - Nikos 20181001
     596             :         SetUniformFloat(context, @"uGammaCorrect", (float)gammaCorrect);
     597             : }
     598             : 
     599             : #endif

Generated by: LCOV version 1.14