diff --git a/Examples/Tests/Layer.js b/Examples/Tests/Layer.js index ddf77b3ce65228f39dd8d01327e5b4f01c5e4257..5904ceb43aa9d07c932e716aae44c78dbd15cf2a 100644 --- a/Examples/Tests/Layer.js +++ b/Examples/Tests/Layer.js @@ -13,7 +13,7 @@ uniform sampler2D t2; void main () { vec4 c1 = texture2D(t1, uv); vec4 c2 = texture2D(t2, uv); - gl_FragColor = vec4(mix(c1.rgb, c2.rgb, c2.a), 1.0); + gl_FragColor = mix(c1, c2, c2.a); } ` } @@ -21,14 +21,12 @@ void main () { class Layer extends GL.Component { render () { - const { width, height, children, ...rest } = this.props; + const { children, ...rest } = this.props; if (!children || children.length !== 2) throw new Error("You must provide 2 children to Layer"); const [t1, t2] = children; return ; } diff --git a/Examples/Tests/Premultiply.js b/Examples/Tests/Premultiply.js new file mode 100644 index 0000000000000000000000000000000000000000..08bfcbd10aec5584ce104d393f88cd918ea465bf --- /dev/null +++ b/Examples/Tests/Premultiply.js @@ -0,0 +1,33 @@ +const React = require("react-native"); +const GL = require("gl-react-native"); + +const shaders = GL.Shaders.create({ + Premultiply: { + frag: ` +precision highp float; + +varying vec2 uv; +uniform sampler2D t; + +void main () { + vec4 c = texture2D(t, uv); + c.rgb *= c.a; + gl_FragColor = c; +} +` + } +}); + +class Premultiply extends GL.Component { + render () { + const { children: t, ...rest } = this.props; + return ; + } +} + +module.exports = Premultiply; diff --git a/Examples/Tests/TransparentNonPremultiplied.js b/Examples/Tests/TransparentNonPremultiplied.js new file mode 100644 index 0000000000000000000000000000000000000000..0951ff778779e4b299b03e7a0273e7b3fd18f001 --- /dev/null +++ b/Examples/Tests/TransparentNonPremultiplied.js @@ -0,0 +1,31 @@ +const React = require("react-native"); +const GL = require("gl-react-native"); + +const shaders = GL.Shaders.create({ + TransparentNonPremultiplied: { + frag: ` +precision highp float; + +varying vec2 uv; +uniform sampler2D t; + +void main () { + gl_FragColor = vec4(texture2D(t, uv).rgb, 0.0); +} +` + } +}); + +class TransparentNonPremultiplied extends GL.Component { + render () { + const { children: t, ...rest } = this.props; + return ; + } +} + +module.exports = TransparentNonPremultiplied; diff --git a/Examples/Tests/index.ios.js b/Examples/Tests/index.ios.js index 783379e0689a3ad2497761c93155ecfffda41902..11721a7ba53432c3cca0b0b5fb81dbf71e00c0dd 100644 --- a/Examples/Tests/index.ios.js +++ b/Examples/Tests/index.ios.js @@ -15,6 +15,7 @@ const NativeLayer = require("./NativeLayer"); const HelloGL = require("./HelloGL"); const Display2 = require("./Display2"); const Copy = require("./Copy"); +const TransparentNonPremultiplied = require("./TransparentNonPremultiplied"); const { width: viewportW, height: viewportH } = require("Dimensions").get("window"); class Tests extends React.Component { @@ -145,6 +146,71 @@ class Tests extends React.Component { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + http://i.imgur.com/S22HNaU.png + + + + + + + + + + + http://i.imgur.com/mp79p5T.png + + + + + + + + + + http://i.imgur.com/mp79p5T.png + + + + + http://i.imgur.com/S22HNaU.png + + + + + + + ; diff --git a/RNGL/GLCanvas.m b/RNGL/GLCanvas.m index 2d187932eb5ead5093ad6fe171c57ab728b4a865..874ea411482faa8a2ae56c57e66c1444a70a47b4 100644 --- a/RNGL/GLCanvas.m +++ b/RNGL/GLCanvas.m @@ -160,6 +160,7 @@ RCT_NOT_IMPLEMENTED(-init) weak_traverseTree = traverseTree = ^GLRenderData *(GLData *data) { NSNumber *width = data.width; NSNumber *height = data.height; + BOOL premultipliedAlpha = data.premultipliedAlpha; int fboId = [data.fboId intValue]; NSMutableArray *contextChildren = [[NSMutableArray alloc] init]; @@ -254,7 +255,8 @@ RCT_NOT_IMPLEMENTED(-init) withHeight:height withFboId:fboId withContextChildren:contextChildren - withChildren:children]; + withChildren:children + withPremultipliedAlpha:premultipliedAlpha]; }; _renderData = traverseTree(_data); @@ -352,7 +354,10 @@ RCT_NOT_IMPLEMENTED(-init) glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + if (renderData.premultipliedAlpha) + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + else + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glDrawArrays(GL_TRIANGLES, 0, 6); }; diff --git a/RNGL/GLData.h b/RNGL/GLData.h index 610261f101d699a562ee315a5f0e20cf19050280..376528e47ed77081f2374c197ce17ac67c91e79a 100644 --- a/RNGL/GLData.h +++ b/RNGL/GLData.h @@ -11,6 +11,7 @@ @property (nonatomic) NSNumber *fboId; @property (nonatomic) NSArray *contextChildren; @property (nonatomic) NSArray *children; +@property (nonatomic) BOOL premultipliedAlpha; -(instancetype)initWithShader: (NSNumber *)shader withUniforms: (NSDictionary *)uniforms @@ -18,6 +19,7 @@ withHeight: (NSNumber *)height withFboId: (NSNumber *)fboId withContextChildren: (NSArray *)contextChildren - withChildren: (NSArray *)children; + withChildren: (NSArray *)children + withPremultipliedAlpha: (BOOL)premultipliedAlpha; @end diff --git a/RNGL/GLData.m b/RNGL/GLData.m index 246685431b6c4b4b8181950600ab8f28282ac212..c1db168a6a992d4879f82cbf81d4921c887443ca 100644 --- a/RNGL/GLData.m +++ b/RNGL/GLData.m @@ -9,6 +9,7 @@ withFboId: (NSNumber *)fboId withContextChildren: (NSArray *)contextChildren withChildren: (NSArray *)children + withPremultipliedAlpha: (BOOL)premultipliedAlpha { if ((self = [super init])) { self.shader = shader; @@ -18,6 +19,7 @@ self.fboId = fboId; self.contextChildren = contextChildren; self.children = children; + self.premultipliedAlpha = premultipliedAlpha; } return self; } diff --git a/RNGL/GLRenderData.h b/RNGL/GLRenderData.h index 44ecf9d2fe03aa86509f21c650e658791bcde221..80cab9c02af05186505b4d73d70306319f3147a5 100644 --- a/RNGL/GLRenderData.h +++ b/RNGL/GLRenderData.h @@ -12,6 +12,7 @@ @property (nonatomic) int fboId; @property (nonatomic) NSArray *contextChildren; @property (nonatomic) NSArray *children; +@property (nonatomic) BOOL premultipliedAlpha; -(instancetype) initWithShader: (GLShader *)shader withUniforms:(NSDictionary *)uniforms @@ -20,6 +21,7 @@ withHeight: (NSNumber *)height withFboId: (int)fboId withContextChildren: (NSArray *)contextChildren - withChildren: (NSArray *)children; + withChildren: (NSArray *)children + withPremultipliedAlpha: (BOOL)premultipliedAlpha; @end diff --git a/RNGL/GLRenderData.m b/RNGL/GLRenderData.m index f4b6721c6ec01c8eeecf037813ed5a5f8e02633f..2d6698468721805b29e085a276c61daf8bbab6cb 100644 --- a/RNGL/GLRenderData.m +++ b/RNGL/GLRenderData.m @@ -11,6 +11,7 @@ withFboId: (int)fboId withContextChildren: (NSArray *)contextChildren withChildren: (NSArray *)children + withPremultipliedAlpha: (BOOL)premultipliedAlpha { if ((self = [super init])) { @@ -22,6 +23,7 @@ self.fboId = fboId; self.contextChildren = contextChildren; self.children = children; + self.premultipliedAlpha = premultipliedAlpha; } return self; } diff --git a/RNGL/GLShadersRegistry.m b/RNGL/GLShadersRegistry.m index 101899011d67308ceccb7884abfb5839274992dd..04eb31175a322caa1e080ebded2f9897928d11fd 100644 --- a/RNGL/GLShadersRegistry.m +++ b/RNGL/GLShadersRegistry.m @@ -40,6 +40,7 @@ RCT_EXPORT_MODULE(); self = [super init]; if (self) { _context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + if (!_context) { RCTLogError(@"Failed to initialize OpenGLES 2.0 context"); } diff --git a/RNGL/RCTConvert+GLData.m b/RNGL/RCTConvert+GLData.m index e65f49cd84f828339c39663fbdfffb8900124148..82996555bf8e76bff2ad500753817d089ba6377d 100644 --- a/RNGL/RCTConvert+GLData.m +++ b/RNGL/RCTConvert+GLData.m @@ -25,6 +25,8 @@ GLData *child = [self GLData:childJSON]; [contextChildren addObject:child]; } + + BOOL premultipliedAlpha = [self BOOL:json[@"premultipliedAlpha"]]; return [[GLData alloc] initWithShader: shader withUniforms: uniforms @@ -32,7 +34,8 @@ withHeight: height withFboId: fboId withContextChildren: contextChildren - withChildren: children]; + withChildren: children + withPremultipliedAlpha: premultipliedAlpha]; } @end