1

While trying to translate this in Swift, I see that my code cannot compile

let movementShader = SKShader(fileNamed: "reflection.fsh")
movementShader.addUniform(SKUniform(name: "size", SCNVector3: SCNVector3Make(0.0, 0.0, 0.0)))

Saying that I have an extra argument in my call.

Quite new here, any ideas ?

Thanks

mohit
  • 4,968
  • 1
  • 22
  • 39
Disco Fever
  • 147
  • 10
  • possible duplicate of [Using GLKMath from GLKit in Swift](http://stackoverflow.com/questions/24622475/using-glkmath-from-glkit-in-swift) – rintaro Nov 09 '14 at 15:45
  • `SKUniform` doesn't have an `init(name:SCNVector3:)` initializer. And you can't call the vector initializers it does have (like [`init(name:floatVector3:)`](https://developer.apple.com/library/ios/documentation/SpriteKit/Reference/SKUniform_Ref/index.html#//apple_ref/occ/instm/SKUniform/initWithName:floatVector3:)) from Swift because those use GLKit types. Those are C union types, which Swift doesn't support, so it doesn't import any API that uses them. – rickster Nov 09 '14 at 18:01
  • `SCNVector3` is usable from Swift, so if you define `initWithSCNVector3:` in an ObjC category on `SKUniform` that might be a good workaround. – rickster Nov 09 '14 at 18:04
  • Thanks, can you provide a starting point ? – Disco Fever Nov 09 '14 at 18:28
  • my answer has a full solution, did you try it? – Wladek Surala Dec 08 '14 at 16:30

1 Answers1

2

Here is a sample implementation. Create an Objective-C category on SKShader, I called it Unions. Declare a method in .h file:

#import <SpriteKit/SpriteKit.h>

@interface SKShader (Unions)

+(SKShader*)shaderForX:(float)x y:(float)y z:(float)z;
@end

Then go to .m file and implement:

#import "SKShader+Unions.h"

@implementation SKShader (Unions)

+(SKShader*)shaderForX:(float)x y:(float)y z:(float)z
{
    SKShader *shader = [SKShader shaderWithFileNamed:@"shader.fsh"];
    SKUniform *texture = [SKUniform uniformWithName:@"customTexture" texture:[SKTexture textureWithImageNamed:@"shade"]];
    SKUniform *uniformSCNVector = [SKUniform uniformWithName:@"size" floatVector3:GLKVector3Make(x, y, z)];

    [shader setUniforms:@[texture,uniformSCNVector]];
    return shader;
}
@end

Don't forget to create a bridging header for your project. It's a .h file called "YourProjectName-Bridging-Header.h" and contains #import "SKShader-Unions.h" directive.

Now you can call from Swift file:

let shader = SKShader(forX: x, y: y, z: y)
Wladek Surala
  • 2,590
  • 1
  • 26
  • 31