Skip to content

Commit 1312f3b

Browse files
author
Thayer J Andrews
committed
CCEffectLighting - Support for changes to referenced lights after initialization
Based on the array of referenced lights, compute a key indicating the types of lights and their positions within the light array. If this key changes from one frame to the next, the shader must be regenerated.
1 parent 0908c6b commit 1312f3b

File tree

1 file changed

+66
-25
lines changed

1 file changed

+66
-25
lines changed

cocos2d/CCEffectLighting.m

Lines changed: 66 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,12 @@
1717
#import "CCEffect_Private.h"
1818
#import "CCSprite_Private.h"
1919

20+
static const NSUInteger CCEffectLightingMaxLightCount = 16;
21+
2022
@interface CCEffectLighting ()
2123

2224
@property (nonatomic, strong) NSMutableArray *lights;
25+
@property (nonatomic, assign) NSUInteger lightKey;
2326

2427
@end
2528

@@ -45,31 +48,7 @@ -(id)initWithLights:(NSArray *)lights
4548
{
4649
_lights = [[NSMutableArray alloc] init];
4750
}
48-
49-
50-
NSMutableArray *fragUniforms = [[NSMutableArray alloc] initWithArray:@[[CCEffectUniform uniform:@"vec4" name:@"u_globalAmbientColor" value:[NSValue valueWithGLKVector4:GLKVector4Make(1.0f, 1.0f, 1.0f, 1.0f)]]]];
51-
NSMutableArray *vertUniforms = [[NSMutableArray alloc] initWithArray:@[[CCEffectUniform uniform:@"mat4" name:@"u_ndcToTangentSpace" value:[NSValue valueWithGLKMatrix4:GLKMatrix4Identity]]]];
52-
NSMutableArray *varyings = [[NSMutableArray alloc] init];
53-
54-
for (NSUInteger lightIndex = 0; lightIndex < lights.count; lightIndex++)
55-
{
56-
CCLightNode *light = lights[lightIndex];
57-
58-
[vertUniforms addObject:[CCEffectUniform uniform:@"vec4" name:[NSString stringWithFormat:@"u_lightVector%lu", (unsigned long)lightIndex] value:[NSValue valueWithGLKVector4:GLKVector4Make(0.0f, 0.0f, 0.0f, 1.0f)]]];
59-
[fragUniforms addObject:[CCEffectUniform uniform:@"vec4" name:[NSString stringWithFormat:@"u_lightColor%lu", (unsigned long)lightIndex] value:[NSValue valueWithGLKVector4:GLKVector4Make(1.0f, 1.0f, 1.0f, 1.0f)]]];
60-
61-
if (light.type != CCLightDirectional)
62-
{
63-
[fragUniforms addObject:[CCEffectUniform uniform:@"float" name:[NSString stringWithFormat:@"u_lightFalloff%lu", (unsigned long)lightIndex] value:[NSNumber numberWithFloat:1.0f]]];
64-
}
65-
66-
[varyings addObject:[CCEffectVarying varying:@"vec4" name:[NSString stringWithFormat:@"v_tangentSpaceLightDir%lu", (unsigned long)lightIndex]]];
67-
}
68-
69-
NSMutableArray *fragFunctions = [CCEffectLighting buildFragmentFunctionsWithLights:lights];
70-
NSMutableArray *vertFunctions = [CCEffectLighting buildVertexFunctionsWithLights:lights];
71-
72-
[self buildEffectWithFragmentFunction:fragFunctions vertexFunctions:vertFunctions fragmentUniforms:fragUniforms vertexUniforms:vertUniforms varyings:varyings firstInStack:YES];
51+
_lightKey = 0;
7352
}
7453
return self;
7554
}
@@ -81,11 +60,14 @@ +(id)effectWithLights:(NSArray *)lights
8160

8261
-(void)addLight:(CCLightNode *)light
8362
{
63+
NSAssert(_lights.count < 16, @"CCEffectLighting only supports 16 lights.");
64+
NSAssert(![_lights containsObject:light], @"Adding a light to effect that is already here.");
8465
[_lights addObject:light];
8566
}
8667

8768
-(void)removeLight:(CCLightNode *)light
8869
{
70+
NSAssert([_lights containsObject:light], @"Removing a light from effect that is not here.");
8971
[_lights removeObject:light];
9072
}
9173

@@ -221,5 +203,64 @@ -(void)buildRenderPasses
221203
self.renderPasses = @[pass0];
222204
}
223205

206+
- (CCEffectPrepareStatus)prepareForRendering
207+
{
208+
CCEffectPrepareStatus result = CCEffectPrepareNothingToDo;
209+
210+
NSUInteger newLightKey = [CCEffectLighting computeLightKey:_lights];
211+
if (newLightKey != _lightKey)
212+
{
213+
_lightKey = newLightKey;
214+
215+
NSMutableArray *fragUniforms = [[NSMutableArray alloc] initWithArray:@[[CCEffectUniform uniform:@"vec4" name:@"u_globalAmbientColor" value:[NSValue valueWithGLKVector4:GLKVector4Make(1.0f, 1.0f, 1.0f, 1.0f)]]]];
216+
NSMutableArray *vertUniforms = [[NSMutableArray alloc] initWithArray:@[[CCEffectUniform uniform:@"mat4" name:@"u_ndcToTangentSpace" value:[NSValue valueWithGLKMatrix4:GLKMatrix4Identity]]]];
217+
NSMutableArray *varyings = [[NSMutableArray alloc] init];
218+
219+
for (NSUInteger lightIndex = 0; lightIndex < _lights.count; lightIndex++)
220+
{
221+
CCLightNode *light = _lights[lightIndex];
222+
223+
[vertUniforms addObject:[CCEffectUniform uniform:@"vec4" name:[NSString stringWithFormat:@"u_lightVector%lu", (unsigned long)lightIndex] value:[NSValue valueWithGLKVector4:GLKVector4Make(0.0f, 0.0f, 0.0f, 1.0f)]]];
224+
[fragUniforms addObject:[CCEffectUniform uniform:@"vec4" name:[NSString stringWithFormat:@"u_lightColor%lu", (unsigned long)lightIndex] value:[NSValue valueWithGLKVector4:GLKVector4Make(1.0f, 1.0f, 1.0f, 1.0f)]]];
225+
226+
if (light.type != CCLightDirectional)
227+
{
228+
[fragUniforms addObject:[CCEffectUniform uniform:@"float" name:[NSString stringWithFormat:@"u_lightFalloff%lu", (unsigned long)lightIndex] value:[NSNumber numberWithFloat:1.0f]]];
229+
}
230+
231+
[varyings addObject:[CCEffectVarying varying:@"vec4" name:[NSString stringWithFormat:@"v_tangentSpaceLightDir%lu", (unsigned long)lightIndex]]];
232+
}
233+
234+
NSMutableArray *fragFunctions = [CCEffectLighting buildFragmentFunctionsWithLights:_lights];
235+
NSMutableArray *vertFunctions = [CCEffectLighting buildVertexFunctionsWithLights:_lights];
236+
237+
[self buildEffectWithFragmentFunction:fragFunctions vertexFunctions:vertFunctions fragmentUniforms:fragUniforms vertexUniforms:vertUniforms varyings:varyings firstInStack:YES];
238+
239+
result = CCEffectPrepareSuccess;
240+
}
241+
return result;
242+
}
243+
244+
+(NSUInteger)computeLightKey:(NSArray*)lights
245+
{
246+
static const NSUInteger CCEffectLightingPointOffset = 0;
247+
static const NSUInteger CCEffectLightingDirectionalOffset = CCEffectLightingMaxLightCount;
248+
249+
NSUInteger lightKey = 0;
250+
for (NSUInteger lightIndex = 0; lightIndex < lights.count; lightIndex++)
251+
{
252+
CCLightNode *light = lights[lightIndex];
253+
if (light.type == CCLightPoint)
254+
{
255+
lightKey |= (1 << (lightIndex + CCEffectLightingPointOffset));
256+
}
257+
else if (light.type == CCLightDirectional)
258+
{
259+
lightKey |= (1 << (lightIndex + CCEffectLightingDirectionalOffset));
260+
}
261+
}
262+
return lightKey;
263+
}
264+
224265
@end
225266

0 commit comments

Comments
 (0)