Oolite 1.91.0.7604-240417-a536cbe
Loading...
Searching...
No Matches
Classes | Macros | Functions
OODefaultShaderSynthesizer.m File Reference
import "OODefaultShaderSynthesizer.h"
import "OOMesh.h"
import "OOTexture.h"
import "OOColor.h"
import "NSStringOOExtensions.h"
import "OOCollectionExtractors.h"
import "NSDictionaryOOExtensions.h"
import "OOMaterialSpecifier.h"
import "ResourceManager.h"
+ Include dependency graph for OODefaultShaderSynthesizer.m:

Go to the source code of this file.

Classes

class  OODefaultShaderSynthesizer
 

Macros

#define REQUIRE_STAGE(NAME)   if (!_completed_##NAME) { [self performStage:@selector(NAME)]; _completed_##NAME = YES; }
 

Functions

static NSDictionary * CanonicalizeMaterialSpecifier (NSDictionary *spec, NSString *materialKey)
 
static NSString * FormatFloat (double value)
 
static NSString * GetExtractMode (NSDictionary *textureSpecifier)
 
BOOL OOSynthesizeMaterialShader (NSDictionary *configuration, NSString *materialKey, NSString *entityName, NSString **outVertexShader, NSString **outFragmentShader, NSArray **outTextureSpecs, NSDictionary **outUniformSpecs)
 

Macro Definition Documentation

◆ REQUIRE_STAGE

#define REQUIRE_STAGE ( NAME)    if (!_completed_##NAME) { [self performStage:@selector(NAME)]; _completed_##NAME = YES; }

Definition at line 252 of file OODefaultShaderSynthesizer.m.

Function Documentation

◆ CanonicalizeMaterialSpecifier()

static NSDictionary * CanonicalizeMaterialSpecifier ( NSDictionary * spec,
NSString * materialKey )
static

Definition at line 1330 of file OODefaultShaderSynthesizer.m.

1331{
1332 NSMutableDictionary *result = [NSMutableDictionary dictionary];
1333 OOColor *col = nil;
1334 id texSpec = nil;
1335
1336 // Colours.
1337 col = [OOColor colorWithDescription:[spec objectForKey:kOOMaterialDiffuseColorName]];
1338 if (col == nil) col = [OOColor colorWithDescription:[spec objectForKey:kOOMaterialDiffuseColorLegacyName]];
1339 if (col != nil) [result setObject:[col normalizedArray] forKey:kOOMaterialDiffuseColorName];
1340
1341 col = [OOColor colorWithDescription:[spec objectForKey:kOOMaterialAmbientColorName]];
1342 if (col == nil) col = [OOColor colorWithDescription:[spec objectForKey:kOOMaterialAmbientColorLegacyName]];
1343 if (col != nil) [result setObject:[col normalizedArray] forKey:kOOMaterialAmbientColorName];
1344
1345 col = [OOColor colorWithDescription:[spec objectForKey:kOOMaterialSpecularColorName]];
1346 if (col == nil) col = [OOColor colorWithDescription:[spec objectForKey:kOOMaterialSpecularColorLegacyName]];
1347 if (col != nil) [result setObject:[col normalizedArray] forKey:kOOMaterialSpecularColorName];
1348
1349 col = [OOColor colorWithDescription:[spec objectForKey:kOOMaterialSpecularModulateColorName]];
1350 if (col != nil) [result setObject:[col normalizedArray] forKey:kOOMaterialSpecularModulateColorName];
1351
1352 col = [OOColor colorWithDescription:[spec objectForKey:kOOMaterialEmissionColorName]];
1353 if (col == nil) col = [OOColor colorWithDescription:[spec objectForKey:kOOMaterialEmissionColorLegacyName]];
1354 if (col != nil) [result setObject:[col normalizedArray] forKey:kOOMaterialEmissionColorName];
1355
1356 // Diffuse map.
1357 texSpec = [spec objectForKey:kOOMaterialDiffuseMapName];
1358 if ([texSpec isKindOfClass:[NSString class]])
1359 {
1360 if ([texSpec length] > 0)
1361 {
1362 texSpec = [NSDictionary dictionaryWithObject:texSpec forKey:kOOTextureSpecifierNameKey];
1363 }
1364 }
1365 else if ([texSpec isKindOfClass:[NSDictionary class]])
1366 {
1367 /* Special case for diffuse map: no name is changed to
1368 name = materialKey, while name = "" is changed to no name.
1369 */
1370 NSString *name = [texSpec objectForKey:kOOTextureSpecifierNameKey];
1371 if (name == nil) texSpec = [texSpec dictionaryByAddingObject:materialKey forKey:kOOTextureSpecifierNameKey];
1372 else if ([name length] == 0)
1373 {
1374 texSpec = [texSpec dictionaryByRemovingObjectForKey:kOOTextureSpecifierNameKey];
1375 }
1376 }
1377 else
1378 {
1379 // Special case for unspecified diffuse map.
1380 texSpec = [NSDictionary dictionaryWithObject:materialKey forKey:kOOTextureSpecifierNameKey];
1381 }
1382 [result setObject:texSpec forKey:kOOMaterialDiffuseMapName];
1383
1384 // Specular maps.
1385 {
1386 BOOL haveNewSpecular = NO;
1387 texSpec = [spec objectForKey:kOOMaterialSpecularColorMapName];
1388 if ([texSpec isKindOfClass:[NSString class]])
1389 {
1390 texSpec = [NSDictionary dictionaryWithObject:texSpec forKey:kOOTextureSpecifierNameKey];
1391 }
1392 else if (![texSpec isKindOfClass:[NSDictionary class]])
1393 {
1394 texSpec = nil;
1395 }
1396 if (texSpec != nil)
1397 {
1398 haveNewSpecular = YES;
1399 [result setObject:texSpec forKey:kOOMaterialSpecularColorMapName];
1400 }
1401
1402 texSpec = [spec objectForKey:kOOMaterialSpecularExponentMapName];
1403 if ([texSpec isKindOfClass:[NSString class]])
1404 {
1405 texSpec = [NSDictionary dictionaryWithObject:texSpec forKey:kOOTextureSpecifierNameKey];
1406 }
1407 else if (![texSpec isKindOfClass:[NSDictionary class]])
1408 {
1409 texSpec = nil;
1410 }
1411 if (texSpec != nil)
1412 {
1413 haveNewSpecular = YES;
1414 [result setObject:texSpec forKey:kOOMaterialSpecularExponentMapName];
1415 }
1416
1417 if (!haveNewSpecular)
1418 {
1419 // Fall back to legacy combined specular map if defined.
1420 texSpec = [spec objectForKey:kOOMaterialCombinedSpecularMapName];
1421 if ([texSpec isKindOfClass:[NSString class]])
1422 {
1423 texSpec = [NSDictionary dictionaryWithObject:texSpec forKey:kOOTextureSpecifierNameKey];
1424 }
1425 else if (![texSpec isKindOfClass:[NSDictionary class]])
1426 {
1427 texSpec = nil;
1428 }
1429 if (texSpec != nil)
1430 {
1431 [result setObject:texSpec forKey:kOOMaterialSpecularColorMapName];
1432 texSpec = [texSpec dictionaryByAddingObject:@"a" forKey:kOOTextureSpecifierSwizzleKey];
1433 [result setObject:texSpec forKey:kOOMaterialSpecularExponentMapName];
1434 }
1435 }
1436 }
1437
1438 // Normal and parallax maps.
1439 {
1440 BOOL haveParallax = NO;
1441 BOOL haveNewNormal = NO;
1442 texSpec = [spec objectForKey:kOOMaterialNormalMapName];
1443 if ([texSpec isKindOfClass:[NSString class]])
1444 {
1445 texSpec = [NSDictionary dictionaryWithObject:texSpec forKey:kOOTextureSpecifierNameKey];
1446 }
1447 else if (![texSpec isKindOfClass:[NSDictionary class]])
1448 {
1449 texSpec = nil;
1450 }
1451 if (texSpec != nil)
1452 {
1453 haveNewNormal = YES;
1454 [result setObject:texSpec forKey:kOOMaterialNormalMapName];
1455 }
1456
1457 texSpec = [spec objectForKey:kOOMaterialParallaxMapName];
1458 if ([texSpec isKindOfClass:[NSString class]])
1459 {
1460 texSpec = [NSDictionary dictionaryWithObject:texSpec forKey:kOOTextureSpecifierNameKey];
1461 }
1462 else if (![texSpec isKindOfClass:[NSDictionary class]])
1463 {
1464 texSpec = nil;
1465 }
1466 if (texSpec != nil)
1467 {
1468 haveNewNormal = YES;
1469 haveParallax = YES;
1470 [result setObject:texSpec forKey:kOOMaterialParallaxMapName];
1471 }
1472
1473 if (!haveNewNormal)
1474 {
1475 // Fall back to legacy combined normal and parallax map if defined.
1476 texSpec = [spec objectForKey:kOOMaterialNormalAndParallaxMapName];
1477 if ([texSpec isKindOfClass:[NSString class]])
1478 {
1479 texSpec = [NSDictionary dictionaryWithObject:texSpec forKey:kOOTextureSpecifierNameKey];
1480 }
1481 else if (![texSpec isKindOfClass:[NSDictionary class]])
1482 {
1483 texSpec = nil;
1484 }
1485 if (texSpec != nil)
1486 {
1487 haveParallax = YES;
1488 [result setObject:texSpec forKey:kOOMaterialNormalMapName];
1489 texSpec = [texSpec dictionaryByAddingObject:@"a" forKey:kOOTextureSpecifierSwizzleKey];
1490 [result setObject:texSpec forKey:kOOMaterialParallaxMapName];
1491 }
1492 }
1493
1494 // Additional parallax parameters.
1495 if (haveParallax)
1496 {
1497 float parallaxScale = [spec oo_floatForKey:kOOMaterialParallaxScaleName defaultValue:kOOMaterialDefaultParallaxScale];
1498 [result oo_setFloat:parallaxScale forKey:kOOMaterialParallaxScaleName];
1499
1500 float parallaxBias = [spec oo_floatForKey:kOOMaterialParallaxBiasName];
1501 [result oo_setFloat:parallaxBias forKey:kOOMaterialParallaxBiasName];
1502 }
1503 }
1504
1505 // Light maps.
1506 {
1507 NSMutableArray *lightMaps = [NSMutableArray array];
1508 id lightMapSpecs = [spec objectForKey:kOOMaterialLightMapsName];
1509 if (lightMapSpecs != nil && ![lightMapSpecs isKindOfClass:[NSArray class]])
1510 {
1511 lightMapSpecs = [NSArray arrayWithObject:lightMapSpecs];
1512 }
1513
1514 id lmSpec = nil;
1515 foreach (lmSpec, lightMapSpecs)
1516 {
1517 if ([lmSpec isKindOfClass:[NSString class]])
1518 {
1519 lmSpec = [NSMutableDictionary dictionaryWithObject:lmSpec forKey:kOOTextureSpecifierNameKey];
1520 }
1521 else if ([lmSpec isKindOfClass:[NSDictionary class]])
1522 {
1523 lmSpec = [[lmSpec mutableCopy] autorelease];
1524 }
1525 else
1526 {
1527 continue;
1528 }
1529
1530 id modulateColor = [lmSpec objectForKey:kOOTextureSpecifierModulateColorKey];
1531 if (modulateColor != nil && ![modulateColor isKindOfClass:[NSArray class]])
1532 {
1533 // Don't convert arrays here, because we specifically don't want the behaviour of treating numbers greater than 1 as 0..255 components.
1534 col = [OOColor colorWithDescription:modulateColor];
1535 [lmSpec setObject:[col normalizedArray] forKey:kOOTextureSpecifierModulateColorKey];
1536 }
1537
1538 id binding = [lmSpec objectForKey:kOOTextureSpecifierBindingKey];
1539 if (binding != nil)
1540 {
1541 if ([binding isKindOfClass:[NSString class]])
1542 {
1543 NSDictionary *expandedBinding = [NSDictionary dictionaryWithObjectsAndKeys:@"binding", @"type", binding, @"binding", nil];
1544 [lmSpec setObject:expandedBinding forKey:kOOTextureSpecifierBindingKey];
1545 }
1546 else if (![binding isKindOfClass:[NSDictionary class]] || [[binding oo_stringForKey:@"binding"] length] == 0)
1547 {
1548 [lmSpec removeObjectForKey:kOOTextureSpecifierBindingKey];
1549 }
1550 }
1551
1552 [lightMaps addObject:[[lmSpec copy] autorelease]];
1553 }
1554
1555 if ([lightMaps count] == 0)
1556 {
1557 // If light_map isn't use, handle legacy emission_map, illumination_map and emission_and_illumination_map.
1558 id emissionSpec = [spec objectForKey:kOOMaterialEmissionMapName];
1559 id illuminationSpec = [spec objectForKey:kOOMaterialIlluminationMapName];
1560
1561 if (emissionSpec == nil && illuminationSpec == nil)
1562 {
1563 emissionSpec = [spec objectForKey:kOOMaterialEmissionAndIlluminationMapName];
1564 if ([emissionSpec isKindOfClass:[NSString class]])
1565 {
1566 // Redundantish check required because we want to modify this as a dictionary to make illuminationSpec.
1567 emissionSpec = [NSDictionary dictionaryWithObject:emissionSpec forKey:kOOTextureSpecifierNameKey];
1568 }
1569 else if (![emissionSpec isKindOfClass:[NSDictionary class]])
1570 {
1571 emissionSpec = nil;
1572 }
1573
1574 if (emissionSpec != nil)
1575 {
1576 illuminationSpec = [emissionSpec dictionaryByAddingObject:@"a" forKey:kOOTextureSpecifierSwizzleKey];
1577 }
1578 }
1579
1580 if (emissionSpec != nil)
1581 {
1582 if ([emissionSpec isKindOfClass:[NSString class]])
1583 {
1584 emissionSpec = [NSDictionary dictionaryWithObject:emissionSpec forKey:kOOTextureSpecifierNameKey];
1585 }
1586 if ([emissionSpec isKindOfClass:[NSDictionary class]])
1587 {
1588 col = [OOColor colorWithDescription:[spec objectForKey:kOOMaterialEmissionModulateColorName]];
1589 if (col != nil) emissionSpec = [emissionSpec dictionaryByAddingObject:[col normalizedArray] forKey:kOOTextureSpecifierModulateColorKey];
1590
1591 [lightMaps addObject:emissionSpec];
1592 }
1593 }
1594
1595 if (illuminationSpec != nil)
1596 {
1597 if ([illuminationSpec isKindOfClass:[NSString class]])
1598 {
1599 illuminationSpec = [NSDictionary dictionaryWithObject:illuminationSpec forKey:kOOTextureSpecifierNameKey];
1600 }
1601 if ([illuminationSpec isKindOfClass:[NSDictionary class]])
1602 {
1603 col = [OOColor colorWithDescription:[spec objectForKey:kOOMaterialIlluminationModulateColorName]];
1604 if (col != nil) illuminationSpec = [illuminationSpec dictionaryByAddingObject:[col normalizedArray] forKey:kOOTextureSpecifierModulateColorKey];
1605
1606 illuminationSpec = [illuminationSpec dictionaryByAddingObject:[NSNumber numberWithBool:YES] forKey:kOOTextureSpecifierIlluminationModeKey];
1607
1608 [lightMaps addObject:illuminationSpec];
1609 }
1610 }
1611 }
1612
1613 [result setObject:lightMaps forKey:kOOMaterialLightMapsName];
1614 }
1615
1616 OOLog(@"material.canonicalForm", @"Canonicalized material %@:\nORIGINAL:\n%@\n\n@CANONICAL:\n%@", materialKey, spec, result);
1617
1618 return result;
1619}
#define OOLog(class, format,...)
Definition OOLogging.h:88
unsigned count
return nil
OOColor * colorWithDescription:(id description)
Definition OOColor.m:127
NSArray * normalizedArray()
Definition OOColor.m:511

References OOColor::colorWithDescription:, count, OODefaultShaderSynthesizer::materialKey, nil, OOColor::normalizedArray, and OOLog.

+ Here is the call graph for this function:

◆ FormatFloat()

static NSString * FormatFloat ( double value)
static

Definition at line 1622 of file OODefaultShaderSynthesizer.m.

1623{
1624 long long intValue = value;
1625 if (value == intValue)
1626 {
1627 return [NSString stringWithFormat:@"%lli.0", intValue];
1628 }
1629 else
1630 {
1631 return [NSString stringWithFormat:@"%g", value];
1632 }
1633}

◆ GetExtractMode()

static NSString * GetExtractMode ( NSDictionary * textureSpecifier)
static

◆ OOSynthesizeMaterialShader()

BOOL OOSynthesizeMaterialShader ( NSDictionary * configuration,
NSString * materialKey,
NSString * entityName,
NSString ** outVertexShader,
NSString ** outFragmentShader,
NSArray ** outTextureSpecs,
NSDictionary ** outUniformSpecs )

Definition at line 264 of file OODefaultShaderSynthesizer.m.

265{
266 NSCParameterAssert(configuration != nil && outVertexShader != NULL && outFragmentShader != NULL && outTextureSpecs != NULL && outUniformSpecs != NULL);
267
268 NSAutoreleasePool *pool = [NSAutoreleasePool new];
269
271 initWithMaterialConfiguration:configuration
272 materialKey:materialKey
273 entityName:entityName];
274 [synthesizer autorelease];
275
276 BOOL OK = [synthesizer run];
277 if (OK)
278 {
279 *outVertexShader = [[synthesizer vertexShader] retain];
280 *outFragmentShader = [[synthesizer fragmentShader] retain];
281 *outTextureSpecs = [[synthesizer textureSpecifications] retain];
282 *outUniformSpecs = [[synthesizer uniformSpecifications] retain];
283 }
284 else
285 {
286 *outVertexShader = nil;
287 *outFragmentShader = nil;
288 *outTextureSpecs = nil;
289 *outUniformSpecs = nil;
290 }
291
292 [pool release];
293
294 [*outVertexShader autorelease];
295 [*outFragmentShader autorelease];
296 [*outTextureSpecs autorelease];
297 [*outUniformSpecs autorelease];
298
299 return YES;
300}

References OODefaultShaderSynthesizer::fragmentShader, nil, OODefaultShaderSynthesizer::run, OODefaultShaderSynthesizer::textureSpecifications, OODefaultShaderSynthesizer::uniformSpecifications, and OODefaultShaderSynthesizer::vertexShader.

+ Here is the call graph for this function: