Skip to content

Commit b91b115

Browse files
committed
Automatic setters for texture size uniforms.
1 parent cb82e54 commit b91b115

File tree

3 files changed

+40
-14
lines changed

3 files changed

+40
-14
lines changed

cocos2d/CCRenderer.m

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -666,13 +666,14 @@ -(void)setRenderState:(CCRenderState *)renderState
666666

667667
// Set the shader's uniform state.
668668
__unsafe_unretained NSDictionary *shaderUniforms = renderState->_shaderUniforms;
669+
__unsafe_unretained NSDictionary *globalShaderUniforms = _globalShaderUniforms;
669670
if(shaderUniforms != _shaderUniforms){
670671
glInsertEventMarkerEXT(0, "Uniforms");
671672

672673
__unsafe_unretained NSDictionary *setters = shader->_uniformSetters;
673674
for(NSString *uniformName in setters){
674675
__unsafe_unretained CCUniformSetter setter = setters[uniformName];
675-
setter(self, shaderUniforms[uniformName] ?: _globalShaderUniforms[uniformName]);
676+
setter(self, shaderUniforms, globalShaderUniforms);
676677
}
677678
_shaderUniforms = shaderUniforms;
678679
}

cocos2d/CCShader.m

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -235,8 +235,8 @@ +(GLuint)createVAOforCCVertexBuffer:(GLuint)vbo elementBuffer:(GLuint)ebo
235235
static CCUniformSetter
236236
SetFloat(NSString *name, GLint location)
237237
{
238-
return ^(CCRenderer *renderer, NSNumber *value){
239-
value = value ?: @0;
238+
return ^(CCRenderer *renderer, NSDictionary *shaderUniforms, NSDictionary *globalShaderUniforms){
239+
NSNumber *value = shaderUniforms[name] ?: globalShaderUniforms[name] ?: @(0.0);
240240
NSCAssert([value isKindOfClass:[NSNumber class]], @"Shader uniform '%@' value must be wrapped in a NSNumber.", name);
241241

242242
glUniform1f(location, value.floatValue);
@@ -246,8 +246,29 @@ +(GLuint)createVAOforCCVertexBuffer:(GLuint)vbo elementBuffer:(GLuint)ebo
246246
static CCUniformSetter
247247
SetVec2(NSString *name, GLint location)
248248
{
249-
return ^(CCRenderer *renderer, NSValue *value){
250-
value = value ?: [NSValue valueWithGLKVector2:GLKVector2Make(0.0f, 0.0f)];
249+
NSString *textureName = nil;
250+
bool pixelSize = [name hasSuffix:@"PixelSize"];
251+
if(pixelSize){
252+
textureName = [name substringToIndex:name.length - @"PixelSize".length];
253+
} else if([name hasSuffix:@"Size"]){
254+
textureName = [name substringToIndex:name.length - @"Size".length];
255+
}
256+
257+
return ^(CCRenderer *renderer, NSDictionary *shaderUniforms, NSDictionary *globalShaderUniforms){
258+
NSValue *value = shaderUniforms[name] ?: globalShaderUniforms[name];
259+
260+
// Fall back on looking up the actual texture size if the name matches a texture.
261+
if(value == nil && textureName){
262+
CCTexture *texture = shaderUniforms[textureName] ?: globalShaderUniforms[textureName];
263+
GLKVector2 sizeInPixels = GLKVector2Make(texture.pixelWidth, texture.pixelHeight);
264+
265+
GLKVector2 size = GLKVector2MultiplyScalar(sizeInPixels, pixelSize ? 1.0 : 1.0/texture.contentScale);
266+
value = [NSValue valueWithGLKVector2:size];
267+
}
268+
269+
// Finally fall back on 0.
270+
if(value == nil) value = [NSValue valueWithGLKVector2:GLKVector2Make(0.0f, 0.0f)];
271+
251272
NSCAssert([value isKindOfClass:[NSValue class]], @"Shader uniform '%@' value must be wrapped in a NSValue.", name);
252273

253274
if(strcmp(value.objCType, @encode(GLKVector2)) == 0){
@@ -268,8 +289,8 @@ +(GLuint)createVAOforCCVertexBuffer:(GLuint)vbo elementBuffer:(GLuint)ebo
268289
static CCUniformSetter
269290
SetVec3(NSString *name, GLint location)
270291
{
271-
return ^(CCRenderer *renderer, NSValue *value){
272-
value = value ?: [NSValue valueWithGLKVector3:GLKVector3Make(0.0f, 0.0f, 0.0f)];
292+
return ^(CCRenderer *renderer, NSDictionary *shaderUniforms, NSDictionary *globalShaderUniforms){
293+
NSValue *value = shaderUniforms[name] ?: globalShaderUniforms[name] ?: [NSValue valueWithGLKVector3:GLKVector3Make(0.0f, 0.0f, 0.0f)];
273294
NSCAssert([value isKindOfClass:[NSValue class]], @"Shader uniform '%@' value must be wrapped in a NSValue.", name);
274295
NSCAssert(strcmp(value.objCType, @encode(GLKVector3)) == 0, @"Shader uniformm 'vec3 %@' value must be passed using [NSValue valueWithGLKVector3:]", name);
275296

@@ -281,8 +302,8 @@ +(GLuint)createVAOforCCVertexBuffer:(GLuint)vbo elementBuffer:(GLuint)ebo
281302
static CCUniformSetter
282303
SetVec4(NSString *name, GLint location)
283304
{
284-
return ^(CCRenderer *renderer, id value){
285-
value = value ?: [NSValue valueWithGLKVector4:GLKVector4Make(0.0f, 0.0f, 0.0f, 1.0f)];
305+
return ^(CCRenderer *renderer, NSDictionary *shaderUniforms, NSDictionary *globalShaderUniforms){
306+
NSValue *value = shaderUniforms[name] ?: globalShaderUniforms[name] ?: [NSValue valueWithGLKVector4:GLKVector4Make(0.0f, 0.0f, 0.0f, 1.0f)];
286307

287308
if([value isKindOfClass:[NSValue class]]){
288309
NSCAssert(strcmp([(NSValue *)value objCType], @encode(GLKVector4)) == 0, @"Shader uniformm 'vec4 %@' value must be passed using [NSValue valueWithGLKVector4:].", name);
@@ -301,8 +322,8 @@ +(GLuint)createVAOforCCVertexBuffer:(GLuint)vbo elementBuffer:(GLuint)ebo
301322
static CCUniformSetter
302323
SetMat4(NSString *name, GLint location)
303324
{
304-
return ^(CCRenderer *renderer, NSValue *value){
305-
value = value ?: [NSValue valueWithGLKMatrix4:GLKMatrix4Identity];
325+
return ^(CCRenderer *renderer, NSDictionary *shaderUniforms, NSDictionary *globalShaderUniforms){
326+
NSValue *value = shaderUniforms[name] ?: globalShaderUniforms[name] ?: [NSValue valueWithGLKMatrix4:GLKMatrix4Identity];
306327
NSCAssert([value isKindOfClass:[NSValue class]], @"Shader uniform '%@' value must be wrapped in a NSValue.", name);
307328
NSCAssert(strcmp(value.objCType, @encode(GLKMatrix4)) == 0, @"Shader uniformm 'mat4 %@' value must be passed using [NSValue valueWithGLKMatrix4:]", name);
308329

@@ -344,8 +365,8 @@ -(NSDictionary *)uniformSettersForProgram:(GLuint)program
344365
case GL_FLOAT_MAT4: uniformSetters[name] = SetMat4(name, location); break;
345366
case GL_SAMPLER_2D: {
346367
// Sampler setters are handled a differently since the real work is binding the texture and not setting the uniform value.
347-
uniformSetters[name] = ^(CCRenderer *renderer, CCTexture *texture){
348-
texture = texture ?: [CCTexture none];
368+
uniformSetters[name] = ^(CCRenderer *renderer, NSDictionary *shaderUniforms, NSDictionary *globalShaderUniforms){
369+
CCTexture *texture = shaderUniforms[name] ?: globalShaderUniforms[name] ?: [CCTexture none];
349370
NSAssert([texture isKindOfClass:[CCTexture class]], @"Shader uniform '%@' value must be a CCTexture object.", name);
350371

351372
// Bind the texture to the texture unit for the uniform.

cocos2d/CCShader_Private.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
#import "CCShader.h"
22

33
@class CCRenderer;
4-
typedef void (^CCUniformSetter)(__unsafe_unretained CCRenderer *renderer, __unsafe_unretained id value);
4+
typedef void (^CCUniformSetter)(
5+
__unsafe_unretained CCRenderer *renderer,
6+
__unsafe_unretained NSDictionary *shaderUniforms,
7+
__unsafe_unretained NSDictionary *globalShaderUniforms
8+
);
59

610
@interface CCShader() {
711
@public

0 commit comments

Comments
 (0)