17
17
#import " CCEffect_Private.h"
18
18
#import " CCSprite_Private.h"
19
19
20
+ static const NSUInteger CCEffectLightingMaxLightCount = 16 ;
21
+
20
22
@interface CCEffectLighting ()
21
23
22
24
@property (nonatomic , strong ) NSMutableArray *lights;
25
+ @property (nonatomic , assign ) NSUInteger lightKey;
23
26
24
27
@end
25
28
@@ -45,31 +48,7 @@ -(id)initWithLights:(NSArray *)lights
45
48
{
46
49
_lights = [[NSMutableArray alloc ] init ];
47
50
}
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 ;
73
52
}
74
53
return self;
75
54
}
@@ -81,11 +60,14 @@ +(id)effectWithLights:(NSArray *)lights
81
60
82
61
-(void )addLight : (CCLightNode *)light
83
62
{
63
+ NSAssert (_lights.count < 16 , @" CCEffectLighting only supports 16 lights." );
64
+ NSAssert (![_lights containsObject: light], @" Adding a light to effect that is already here." );
84
65
[_lights addObject: light];
85
66
}
86
67
87
68
-(void )removeLight : (CCLightNode *)light
88
69
{
70
+ NSAssert ([_lights containsObject: light], @" Removing a light from effect that is not here." );
89
71
[_lights removeObject: light];
90
72
}
91
73
@@ -221,5 +203,64 @@ -(void)buildRenderPasses
221
203
self.renderPasses = @[pass0];
222
204
}
223
205
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
+
224
265
@end
225
266
0 commit comments