Commit 5669c7e1 authored by Gaëtan Renaudeau's avatar Gaëtan Renaudeau

Merge pull request #56 from ProjectSeptemberInc/2.18.0

2.18.0-rc
parents d5c628c9 0c589f77
...@@ -74,7 +74,7 @@ android { ...@@ -74,7 +74,7 @@ android {
dependencies { dependencies {
compile fileTree(dir: "libs", include: ["*.jar"]) compile fileTree(dir: "libs", include: ["*.jar"])
compile "com.android.support:appcompat-v7:23.0.1" compile "com.android.support:appcompat-v7:23.0.1"
compile "com.facebook.react:react-native:0.17.+" compile "com.facebook.react:react-native:0.18.+"
compile project(':RNGL') compile project(':RNGL')
} }
...@@ -3,12 +3,14 @@ ...@@ -3,12 +3,14 @@
"version": "0.0.1", "version": "0.0.1",
"private": true, "private": true,
"scripts": { "scripts": {
"start": "react-native start" "start": "node node_modules/react-native/local-cli/cli.js start"
}, },
"dependencies": { "dependencies": {
"gl-react": "^2.0.2", "fbjs": "^0.6.0",
"gl-react": "^2.1.0",
"gl-react-native": "file:../..", "gl-react-native": "file:../..",
"glsl-transitions": "^2015.11.8", "glsl-transitions": "^2015.11.8",
"react-native": "^0.17.0" "react": "^0.14.5",
"react-native": "0.18.0-rc"
} }
} }
require("gl-react/react-native");
const React = require("react-native"); const React = require("react-native");
const { const {
StyleSheet, StyleSheet,
......
...@@ -74,6 +74,6 @@ android { ...@@ -74,6 +74,6 @@ android {
dependencies { dependencies {
compile fileTree(dir: "libs", include: ["*.jar"]) compile fileTree(dir: "libs", include: ["*.jar"])
compile "com.android.support:appcompat-v7:23.0.1" compile "com.android.support:appcompat-v7:23.0.1"
compile "com.facebook.react:react-native:0.17.+" compile "com.facebook.react:react-native:0.18.+"
compile project(":RNGL") compile project(":RNGL")
} }
...@@ -3,13 +3,15 @@ ...@@ -3,13 +3,15 @@
"version": "0.0.1", "version": "0.0.1",
"private": true, "private": true,
"scripts": { "scripts": {
"start": "react-native start" "start": "node node_modules/react-native/local-cli/cli.js start"
}, },
"dependencies": { "dependencies": {
"crypto": "0.0.3", "crypto": "0.0.3",
"gl-react": "^2.0.6", "fbjs": "^0.6.0",
"gl-react": "^2.1.0",
"gl-react-native": "file:../..", "gl-react-native": "file:../..",
"react-native": "^0.17.0", "react": "^0.14.5",
"react-native": "0.18.0-rc",
"seedrandom": "gre/seedrandom#released" "seedrandom": "gre/seedrandom#released"
} }
} }
import GL from "gl-react"; import GL from "gl-react";
const {React} = GL; import React from "react";
const {PropTypes} = React; const {PropTypes} = React;
const shaders = GL.Shaders.create({ const shaders = GL.Shaders.create({
......
require("gl-react/react-native");
const React = require("react-native"); const React = require("react-native");
const { const {
StyleSheet, StyleSheet,
......
...@@ -77,7 +77,7 @@ ...@@ -77,7 +77,7 @@
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.facebook.fresco/fresco/0.8.1/jars" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.facebook.fresco/fresco/0.8.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.facebook.fresco/imagepipeline-okhttp/0.8.1/jars" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.facebook.fresco/imagepipeline-okhttp/0.8.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.facebook.fresco/imagepipeline/0.8.1/jars" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.facebook.fresco/imagepipeline/0.8.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.facebook.react/react-native/0.17.1/jars" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.facebook.react/react-native/0.18.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/org.webkit/android-jsc/r174650/jars" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/org.webkit/android-jsc/r174650/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
...@@ -96,14 +96,14 @@ ...@@ -96,14 +96,14 @@
<orderEntry type="library" exported="" name="okio-1.6.0" level="project" /> <orderEntry type="library" exported="" name="okio-1.6.0" level="project" />
<orderEntry type="library" exported="" name="stetho-okhttp-1.2.0" level="project" /> <orderEntry type="library" exported="" name="stetho-okhttp-1.2.0" level="project" />
<orderEntry type="library" exported="" name="okhttp-2.5.0" level="project" /> <orderEntry type="library" exported="" name="okhttp-2.5.0" level="project" />
<orderEntry type="library" exported="" name="jsr305-3.0.0" level="project" />
<orderEntry type="library" exported="" name="stetho-1.2.0" level="project" /> <orderEntry type="library" exported="" name="stetho-1.2.0" level="project" />
<orderEntry type="library" exported="" name="jsr305-3.0.0" level="project" />
<orderEntry type="library" exported="" name="jackson-core-2.2.3" level="project" /> <orderEntry type="library" exported="" name="jackson-core-2.2.3" level="project" />
<orderEntry type="library" exported="" name="fbcore-0.8.1" level="project" /> <orderEntry type="library" exported="" name="fbcore-0.8.1" level="project" />
<orderEntry type="library" exported="" name="commons-cli-1.2" level="project" /> <orderEntry type="library" exported="" name="commons-cli-1.2" level="project" />
<orderEntry type="library" exported="" name="recyclerview-v7-23.0.1" level="project" /> <orderEntry type="library" exported="" name="recyclerview-v7-23.0.1" level="project" />
<orderEntry type="library" exported="" name="imagepipeline-0.8.1" level="project" /> <orderEntry type="library" exported="" name="imagepipeline-0.8.1" level="project" />
<orderEntry type="library" exported="" name="react-native-0.17.1" level="project" /> <orderEntry type="library" exported="" name="react-native-0.18.0" level="project" />
<orderEntry type="library" exported="" name="android-jsc-r174650" level="project" /> <orderEntry type="library" exported="" name="android-jsc-r174650" level="project" />
<orderEntry type="library" exported="" name="fresco-0.8.1" level="project" /> <orderEntry type="library" exported="" name="fresco-0.8.1" level="project" />
<orderEntry type="library" exported="" name="imagepipeline-okhttp-0.8.1" level="project" /> <orderEntry type="library" exported="" name="imagepipeline-okhttp-0.8.1" level="project" />
...@@ -112,6 +112,7 @@ ...@@ -112,6 +112,7 @@
<orderEntry type="library" exported="" name="drawee-0.8.1" level="project" /> <orderEntry type="library" exported="" name="drawee-0.8.1" level="project" />
<orderEntry type="library" exported="" name="appcompat-v7-23.0.1" level="project" /> <orderEntry type="library" exported="" name="appcompat-v7-23.0.1" level="project" />
<orderEntry type="library" exported="" name="support-annotations-23.0.1" level="project" /> <orderEntry type="library" exported="" name="support-annotations-23.0.1" level="project" />
<orderEntry type="module" module-name="react-native-fs" exported="" />
<orderEntry type="module" module-name="RNMaterialKit" exported="" /> <orderEntry type="module" module-name="RNMaterialKit" exported="" />
<orderEntry type="module" module-name="RNGL" exported="" /> <orderEntry type="module" module-name="RNGL" exported="" />
</component> </component>
......
...@@ -74,8 +74,10 @@ android { ...@@ -74,8 +74,10 @@ android {
dependencies { dependencies {
compile fileTree(dir: "libs", include: ["*.jar"]) compile fileTree(dir: "libs", include: ["*.jar"])
compile "com.android.support:appcompat-v7:23.0.1" compile "com.android.support:appcompat-v7:23.0.1"
compile "com.facebook.react:react-native:0.17.+" compile "com.facebook.react:react-native:0.18.+"
compile project(":RNMaterialKit") compile project(":RNMaterialKit")
compile project(":RNGL") compile project(":RNGL")
compile project(':react-native-fs')
} }
...@@ -11,6 +11,7 @@ import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler; ...@@ -11,6 +11,7 @@ import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
import com.facebook.react.shell.MainReactPackage; import com.facebook.react.shell.MainReactPackage;
import com.github.xinthink.rnmk.ReactMaterialKitPackage; import com.github.xinthink.rnmk.ReactMaterialKitPackage;
import com.projectseptember.RNGL.RNGLPackage; import com.projectseptember.RNGL.RNGLPackage;
import com.rnfs.RNFSPackage;
public class MainActivity extends Activity implements DefaultHardwareBackBtnHandler { public class MainActivity extends Activity implements DefaultHardwareBackBtnHandler {
...@@ -28,6 +29,7 @@ public class MainActivity extends Activity implements DefaultHardwareBackBtnHand ...@@ -28,6 +29,7 @@ public class MainActivity extends Activity implements DefaultHardwareBackBtnHand
.setJSMainModuleName("index.android") .setJSMainModuleName("index.android")
.addPackage(new MainReactPackage()) .addPackage(new MainReactPackage())
.addPackage(new RNGLPackage()) .addPackage(new RNGLPackage())
.addPackage(new RNFSPackage())
.addPackage(new ReactMaterialKitPackage()) .addPackage(new ReactMaterialKitPackage())
.setUseDeveloperSupport(BuildConfig.DEBUG) .setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED) .setInitialLifecycleState(LifecycleState.RESUMED)
......
...@@ -6,4 +6,7 @@ include ':RNMaterialKit' ...@@ -6,4 +6,7 @@ include ':RNMaterialKit'
project(':RNMaterialKit').projectDir = file('../node_modules/react-native-material-kit/android') project(':RNMaterialKit').projectDir = file('../node_modules/react-native-material-kit/android')
include ':RNGL' include ':RNGL'
project(':RNGL').projectDir = file('../../../android') project(':RNGL').projectDir = file('../../../android')
\ No newline at end of file
include ':react-native-fs'
project(':react-native-fs').projectDir = new File(settingsDir, '../node_modules/react-native-fs/android')
\ No newline at end of file
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; }; 146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; };
34607B601C132B22009203B1 /* libRCTMaterialKit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34607B581C132B1C009203B1 /* libRCTMaterialKit.a */; }; 34607B601C132B22009203B1 /* libRCTMaterialKit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34607B581C132B1C009203B1 /* libRCTMaterialKit.a */; };
3461EB4B1C132AEC0003E4A2 /* libRNGL.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3461EB4A1C132AD30003E4A2 /* libRNGL.a */; }; 3461EB4B1C132AEC0003E4A2 /* libRNGL.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3461EB4A1C132AD30003E4A2 /* libRNGL.a */; };
34C9905A1C3530D6002F49FC /* libRNFS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34C990581C3530CE002F49FC /* libRNFS.a */; };
832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; }; 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
...@@ -104,6 +105,13 @@ ...@@ -104,6 +105,13 @@
remoteGlobalIDString = 4107012F1ACB723B00C6AA39; remoteGlobalIDString = 4107012F1ACB723B00C6AA39;
remoteInfo = RNGL; remoteInfo = RNGL;
}; };
34C990571C3530CE002F49FC /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 34C990481C3530CE002F49FC /* RNFS.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = F12AFB9B1ADAF8F800E0535D;
remoteInfo = RNFS;
};
78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */ = { 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy; isa = PBXContainerItemProxy;
containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */; containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */;
...@@ -142,6 +150,7 @@ ...@@ -142,6 +150,7 @@
146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = "<group>"; }; 146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = "<group>"; };
34607B4F1C132B1C009203B1 /* RCTMaterialKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTMaterialKit.xcodeproj; path = "../node_modules/react-native-material-kit/iOS/RCTMaterialKit.xcodeproj"; sourceTree = "<group>"; }; 34607B4F1C132B1C009203B1 /* RCTMaterialKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTMaterialKit.xcodeproj; path = "../node_modules/react-native-material-kit/iOS/RCTMaterialKit.xcodeproj"; sourceTree = "<group>"; };
3461EB3B1C132AD30003E4A2 /* RNGL.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RNGL.xcodeproj; path = "../node_modules/gl-react-native/ios/RNGL.xcodeproj"; sourceTree = "<group>"; }; 3461EB3B1C132AD30003E4A2 /* RNGL.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RNGL.xcodeproj; path = "../node_modules/gl-react-native/ios/RNGL.xcodeproj"; sourceTree = "<group>"; };
34C990481C3530CE002F49FC /* RNFS.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RNFS.xcodeproj; path = "../node_modules/react-native-fs/RNFS.xcodeproj"; sourceTree = "<group>"; };
78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = "<group>"; }; 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = "<group>"; };
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = "<group>"; }; 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
...@@ -158,6 +167,7 @@ ...@@ -158,6 +167,7 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
34C9905A1C3530D6002F49FC /* libRNFS.a in Frameworks */,
34607B601C132B22009203B1 /* libRCTMaterialKit.a in Frameworks */, 34607B601C132B22009203B1 /* libRCTMaterialKit.a in Frameworks */,
3461EB4B1C132AEC0003E4A2 /* libRNGL.a in Frameworks */, 3461EB4B1C132AEC0003E4A2 /* libRNGL.a in Frameworks */,
146834051AC3E58100842450 /* libReact.a in Frameworks */, 146834051AC3E58100842450 /* libReact.a in Frameworks */,
...@@ -287,6 +297,14 @@ ...@@ -287,6 +297,14 @@
name = Products; name = Products;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
34C990491C3530CE002F49FC /* Products */ = {
isa = PBXGroup;
children = (
34C990581C3530CE002F49FC /* libRNFS.a */,
);
name = Products;
sourceTree = "<group>";
};
78C398B11ACF4ADC00677621 /* Products */ = { 78C398B11ACF4ADC00677621 /* Products */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
...@@ -298,6 +316,7 @@ ...@@ -298,6 +316,7 @@
832341AE1AAA6A7D00B99B32 /* Libraries */ = { 832341AE1AAA6A7D00B99B32 /* Libraries */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
34C990481C3530CE002F49FC /* RNFS.xcodeproj */,
34607B4F1C132B1C009203B1 /* RCTMaterialKit.xcodeproj */, 34607B4F1C132B1C009203B1 /* RCTMaterialKit.xcodeproj */,
3461EB3B1C132AD30003E4A2 /* RNGL.xcodeproj */, 3461EB3B1C132AD30003E4A2 /* RNGL.xcodeproj */,
146833FF1AC3E56700842450 /* React.xcodeproj */, 146833FF1AC3E56700842450 /* React.xcodeproj */,
...@@ -453,6 +472,10 @@ ...@@ -453,6 +472,10 @@
ProductGroup = 146834001AC3E56700842450 /* Products */; ProductGroup = 146834001AC3E56700842450 /* Products */;
ProjectRef = 146833FF1AC3E56700842450 /* React.xcodeproj */; ProjectRef = 146833FF1AC3E56700842450 /* React.xcodeproj */;
}, },
{
ProductGroup = 34C990491C3530CE002F49FC /* Products */;
ProjectRef = 34C990481C3530CE002F49FC /* RNFS.xcodeproj */;
},
{ {
ProductGroup = 3461EB3C1C132AD30003E4A2 /* Products */; ProductGroup = 3461EB3C1C132AD30003E4A2 /* Products */;
ProjectRef = 3461EB3B1C132AD30003E4A2 /* RNGL.xcodeproj */; ProjectRef = 3461EB3B1C132AD30003E4A2 /* RNGL.xcodeproj */;
...@@ -537,6 +560,13 @@ ...@@ -537,6 +560,13 @@
remoteRef = 3461EB491C132AD30003E4A2 /* PBXContainerItemProxy */; remoteRef = 3461EB491C132AD30003E4A2 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR; sourceTree = BUILT_PRODUCTS_DIR;
}; };
34C990581C3530CE002F49FC /* libRNFS.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libRNFS.a;
remoteRef = 34C990571C3530CE002F49FC /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
78C398B91ACF4ADC00677621 /* libRCTLinking.a */ = { 78C398B91ACF4ADC00677621 /* libRCTLinking.a */ = {
isa = PBXReferenceProxy; isa = PBXReferenceProxy;
fileType = archive.ar; fileType = archive.ar;
......
...@@ -3,12 +3,15 @@ ...@@ -3,12 +3,15 @@
"version": "0.0.1", "version": "0.0.1",
"private": true, "private": true,
"scripts": { "scripts": {
"start": "react-native start" "start": "node node_modules/react-native/local-cli/cli.js start"
}, },
"dependencies": { "dependencies": {
"fbjs": "^0.6.0",
"gl-react": "^2.1.0",
"gl-react-native": "file:../..", "gl-react-native": "file:../..",
"gl-react": "^2.0.8", "react": "^0.14.5",
"react-native": "^0.17.0", "react-native": "0.18.0-rc",
"react-native-material-kit": "^0.2.4" "react-native-fs": "^1.1.0",
"react-native-material-kit": "gre/react-native-material-kit#no-peerDependencies"
} }
} }
const GL = require("gl-react"); const GL = require("gl-react");
const React = GL.React; const React = require("react");
const Blur1D = require("./Blur1D"); const Blur1D = require("./Blur1D");
module.exports = GL.createComponent(({ width, height, factor, children }) => module.exports = GL.createComponent(({ width, height, factor, children }) =>
......
const GL = require("gl-react"); const GL = require("gl-react");
const React = GL.React; const React = require("react");
const shaders = GL.Shaders.create({ const shaders = GL.Shaders.create({
blur1D: { blur1D: {
......
const GL = require("gl-react"); const GL = require("gl-react");
const React = GL.React; const React = require("react");
const shaders = GL.Shaders.create({ const shaders = GL.Shaders.create({
helloGL: { helloGL: {
......
const GL = require("gl-react"); const GL = require("gl-react");
const React = GL.React; const React = require("react");
const shaders = GL.Shaders.create({ const shaders = GL.Shaders.create({
hueRotate: { hueRotate: {
......
const GL = require("gl-react"); const GL = require("gl-react");
const React = GL.React; const React = require("react");
const shaders = GL.Shaders.create({ const shaders = GL.Shaders.create({
pieProgress: { pieProgress: {
......
const GL = require("gl-react"); const GL = require("gl-react");
const React = GL.React; const React = require("react");
const shaders = GL.Shaders.create({ const shaders = GL.Shaders.create({
saturation: { saturation: {
......
require("gl-react/react-native");
const React = require("react-native"); const React = require("react-native");
const { const {
StyleSheet, StyleSheet,
...@@ -22,6 +20,8 @@ const { ...@@ -22,6 +20,8 @@ const {
MKButton, MKButton,
} = require("react-native-material-kit"); } = require("react-native-material-kit");
const RNFS = require("react-native-fs");
const HelloGL = require("./HelloGL"); const HelloGL = require("./HelloGL");
const Saturation = require("./Saturation"); const Saturation = require("./Saturation");
const HueRotate = require("./HueRotate"); const HueRotate = require("./HueRotate");
...@@ -82,7 +82,8 @@ class Simple extends Component { ...@@ -82,7 +82,8 @@ class Simple extends Component {
switch1: false, switch1: false,
switch2: false, switch2: false,
switch3: false, switch3: false,
captured: null captured: null,
captureConfig: null
}; };
this.onCapture1 = this.onCapture1.bind(this); this.onCapture1 = this.onCapture1.bind(this);
...@@ -97,9 +98,17 @@ class Simple extends Component { ...@@ -97,9 +98,17 @@ class Simple extends Component {
} }
onCapture1 () { onCapture1 () {
this.refs.helloGL.captureFrame().then(data64 => { const captureConfig = {
this.setState({ captured: data64 }); quality: Math.round((Math.random() * 100))/100,
}); type: Math.random() < 0.5 ? "jpg": "png",
format: Math.random() < 0.5 ? "base64" : "file"
};
if (captureConfig.format === "file") {
captureConfig.filePath = RNFS.DocumentDirectoryPath+"/hellogl_capture.png";
}
this.refs.helloGL
.captureFrame(captureConfig)
.then(captured => this.setState({ captured, captureConfig }));
} }
render () { render () {
...@@ -113,7 +122,8 @@ class Simple extends Component { ...@@ -113,7 +122,8 @@ class Simple extends Component {
switch1, switch1,
switch2, switch2,
switch3, switch3,
captured captured,
captureConfig
} = this.state; } = this.state;
return <View style={styles.container}> return <View style={styles.container}>
...@@ -128,9 +138,28 @@ class Simple extends Component { ...@@ -128,9 +138,28 @@ class Simple extends Component {
</Surface> </Surface>
<View style={{ paddingTop: 20, alignItems: "center", flexDirection: "row" }}> <View style={{ paddingTop: 20, alignItems: "center", flexDirection: "row" }}>
<Button onPress={this.onCapture1}>captureFrame()</Button> <Button onPress={this.onCapture1}>captureFrame()</Button>
{captured && <Image source={{ uri: captured }} style={{ marginLeft: 20, width: 51, height: 34 }} />} {captured &&
<Image source={{ uri: captured }}
style={{ marginLeft: 20, width: 51, height: 34 }}
/> }
</View> </View>
{captured && <Text style={{ marginTop: 10, fontSize: 10, fontFamily: "Cochin" }} numberOfLines={1}>{captured.slice(0, 100)}</Text>} {captureConfig &&
<View style={{ paddingTop: 20, alignItems: "center", flexDirection: "row", justifyContent: "space-between" }}>
<Text style={{ fontSize: 10 }}>
format={captureConfig.format}
</Text>
<Text style={{ fontSize: 10 }}>
type={captureConfig.type}
</Text>
<Text style={{ fontSize: 10 }}>
quality={captureConfig.quality+""}
</Text>
</View>
}
{captured &&
<Text numberOfLines={1} style={{ marginTop: 10, fontSize: 10, color: "#aaa" }}>
{captured.slice(0, 100)}
</Text> }
</Demo> </Demo>
<Demo id={2} title="2. Saturate an Image"> <Demo id={2} title="2. Saturate an Image">
......
...@@ -74,7 +74,7 @@ android { ...@@ -74,7 +74,7 @@ android {
dependencies { dependencies {
compile fileTree(dir: "libs", include: ["*.jar"]) compile fileTree(dir: "libs", include: ["*.jar"])
compile "com.android.support:appcompat-v7:23.0.1" compile "com.android.support:appcompat-v7:23.0.1"
compile "com.facebook.react:react-native:0.17.+" compile "com.facebook.react:react-native:0.18.+"
compile project(":RNGL") compile project(":RNGL")
} }
...@@ -3,11 +3,13 @@ ...@@ -3,11 +3,13 @@
"version": "0.0.1", "version": "0.0.1",
"private": true, "private": true,
"scripts": { "scripts": {
"start": "react-native start" "start": "node node_modules/react-native/local-cli/cli.js start"
}, },
"dependencies": { "dependencies": {
"fbjs": "^0.6.0",
"gl-react": "^2.1.0",
"gl-react-native": "file:../..", "gl-react-native": "file:../..",
"gl-react": "^2.0.2", "react": "^0.14.5",
"react-native": "^0.17.0" "react-native": "0.18.0-rc"
} }
} }
const GL = require("gl-react"); const GL = require("gl-react");
const React = GL.React; const React = require("react");
const shaders = GL.Shaders.create({ const shaders = GL.Shaders.create({
add: { add: {
......
const GL = require("gl-react"); const GL = require("gl-react");
const React = GL.React; const React = require("react");
const { const {
PropTypes PropTypes
} = React; } = React;
......
const GL = require("gl-react"); const GL = require("gl-react");
const React = GL.React; const React = require("react");
const { const {
PropTypes PropTypes
} = React; } = React;
......
const GL = require("gl-react"); const GL = require("gl-react");
const React = GL.React; const React = require("react");
const shaders = GL.Shaders.create({ const shaders = GL.Shaders.create({
Copy: { Copy: {
......
const GL = require("gl-react"); const GL = require("gl-react");
const React = GL.React; const React = require("react");
const shaders = GL.Shaders.create({ const shaders = GL.Shaders.create({
display2: { display2: {
......
const GL = require("gl-react"); const GL = require("gl-react");
const React = GL.React; const React = require("react");
const shaders = GL.Shaders.create({ const shaders = GL.Shaders.create({
helloGL: { helloGL: {
......
const GL = require("gl-react"); const GL = require("gl-react");
const React = GL.React; const React = require("react");
const shaders = GL.Shaders.create({ const shaders = GL.Shaders.create({
layer: { layer: {
......
const GL = require("gl-react"); const GL = require("gl-react");
const React = GL.React; const React = require("react");
const shaders = GL.Shaders.create({ const shaders = GL.Shaders.create({
multiply: { multiply: {
......
const GL = require("gl-react"); const GL = require("gl-react");
const React = GL.React; const React = require("react");
const shaders = GL.Shaders.create({ const shaders = GL.Shaders.create({
TransparentNonPremultiplied: { TransparentNonPremultiplied: {
......
require("gl-react/react-native");
const React = require("react-native"); const React = require("react-native");
const { const {
Text, Text,
......
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id=":RNGL" external.linked.project.path="$MODULE_DIR$/../../android" external.root.project.path="$MODULE_DIR$/../AdvancedEffects/android" external.system.id="GRADLE" external.system.module.group="AdvancedEffects" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="android-gradle" name="Android-Gradle">
<configuration>
<option name="GRADLE_PROJECT_PATH" value=":RNGL" />
</configuration>
</facet>
<facet type="android" name="Android">
<configuration>
<option name="SELECTED_BUILD_VARIANT" value="debug" />
<option name="SELECTED_TEST_ARTIFACT" value="_android_test_" />
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
<option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugAndroidTest" />
<option name="COMPILE_JAVA_TEST_TASK_NAME" value="compileDebugAndroidTestSources" />
<afterSyncTasks>
<task>generateDebugAndroidTestSources</task>
<task>generateDebugSources</task>
</afterSyncTasks>
<option name="ALLOW_USER_CONFIGURATION" value="false" />
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
<option name="RES_FOLDERS_RELATIVE_PATH" value="" />
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
<option name="LIBRARY_PROJECT" value="true" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="false">
<output url="file://$MODULE_DIR$/../../android/build/intermediates/classes/debug" />
<output-test url="file://$MODULE_DIR$/../../android/build/intermediates/classes/androidTest/debug" />
<exclude-output />
<content url="file://$MODULE_DIR$/../../android">
<sourceFolder url="file://$MODULE_DIR$/../../android/build/generated/source/r/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/../../android/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/../../android/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/../../android/build/generated/source/rs/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/../../android/build/generated/res/rs/debug" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/../../android/build/generated/res/resValues/debug" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/../../android/build/generated/source/r/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/../../android/build/generated/source/aidl/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/../../android/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/../../android/build/generated/source/rs/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/../../android/build/generated/res/rs/androidTest/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/../../android/build/generated/res/resValues/androidTest/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/../../android/src/debug/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/../../android/src/debug/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/../../android/src/debug/assets" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/../../android/src/debug/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../android/src/debug/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../android/src/debug/jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../android/src/debug/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../android/src/main/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/../../android/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/../../android/src/main/assets" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/../../android/src/main/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../android/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../android/src/main/jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../android/src/main/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../android/src/androidTest/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/../../android/src/androidTest/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/../../android/src/androidTest/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/../../android/src/androidTest/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/../../android/src/androidTest/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/../../android/src/androidTest/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/../../android/src/androidTest/rs" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/../../android/build/intermediates/annotations" />
<excludeFolder url="file://$MODULE_DIR$/../../android/build/intermediates/assets" />
<excludeFolder url="file://$MODULE_DIR$/../../android/build/intermediates/bundles" />
<excludeFolder url="file://$MODULE_DIR$/../../android/build/intermediates/classes" />
<excludeFolder url="file://$MODULE_DIR$/../../android/build/intermediates/dependency-cache" />
<excludeFolder url="file://$MODULE_DIR$/../../android/build/intermediates/incremental" />
<excludeFolder url="file://$MODULE_DIR$/../../android/build/intermediates/lint" />
<excludeFolder url="file://$MODULE_DIR$/../../android/build/intermediates/res" />
<excludeFolder url="file://$MODULE_DIR$/../../android/build/intermediates/rs" />
<excludeFolder url="file://$MODULE_DIR$/../../android/build/intermediates/symbols" />
<excludeFolder url="file://$MODULE_DIR$/../../android/build/outputs" />
<excludeFolder url="file://$MODULE_DIR$/../../android/build/tmp" />
</content>
<orderEntry type="jdk" jdkName="Android API 23 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" exported="" name="okhttp-ws-2.5.0" level="project" />
<orderEntry type="library" exported="" name="library-2.4.0" level="project" />
<orderEntry type="library" exported="" name="okio-1.6.0" level="project" />
<orderEntry type="library" exported="" name="stetho-okhttp-1.2.0" level="project" />
<orderEntry type="library" exported="" name="okhttp-2.5.0" level="project" />
<orderEntry type="library" exported="" name="stetho-1.2.0" level="project" />
<orderEntry type="library" exported="" name="jsr305-3.0.0" level="project" />
<orderEntry type="library" exported="" name="jackson-core-2.2.3" level="project" />
<orderEntry type="library" exported="" name="fbcore-0.8.1" level="project" />
<orderEntry type="library" exported="" name="commons-cli-1.2" level="project" />
<orderEntry type="library" exported="" name="recyclerview-v7-23.0.1" level="project" />
<orderEntry type="library" exported="" name="imagepipeline-0.8.1" level="project" />
<orderEntry type="library" exported="" name="react-native-0.17.1" level="project" />
<orderEntry type="library" exported="" name="android-jsc-r174650" level="project" />
<orderEntry type="library" exported="" name="fresco-0.8.1" level="project" />
<orderEntry type="library" exported="" name="imagepipeline-okhttp-0.8.1" level="project" />
<orderEntry type="library" exported="" name="bolts-android-1.1.4" level="project" />
<orderEntry type="library" exported="" name="support-v4-23.0.1" level="project" />
<orderEntry type="library" exported="" name="drawee-0.8.1" level="project" />
<orderEntry type="library" exported="" name="appcompat-v7-23.0.1" level="project" />
<orderEntry type="library" exported="" name="support-annotations-23.0.1" level="project" />
</component>
</module>
\ No newline at end of file
**[Gitbook documentation](http://projectseptemberinc.gitbooks.io/gl-react/content/) / [Github](https://github.com/ProjectSeptemberInc/gl-react-native/) / [gl-react](https://github.com/ProjectSeptemberInc/gl-react/)** / [#gl-react on reactiflux](https://discordapp.com/channels/102860784329052160/106102146109325312) **[Gitbook documentation](http://projectseptemberinc.gitbooks.io/gl-react/content/) / [Github](https://github.com/ProjectSeptemberInc/gl-react-native/) / [gl-react](https://github.com/ProjectSeptemberInc/gl-react/)** / [#gl-react on reactiflux](https://discordapp.com/channels/102860784329052160/106102146109325312)
# <img width="32" alt="icon" src="https://cloud.githubusercontent.com/assets/211411/9813786/eacfcc24-5888-11e5-8f9b-5a907a2cbb21.png"> gl-react-native ![](https://img.shields.io/badge/react--native-%200.17.x-05F561.svg) # <img width="32" alt="icon" src="https://cloud.githubusercontent.com/assets/211411/9813786/eacfcc24-5888-11e5-8f9b-5a907a2cbb21.png"> gl-react-native ![](https://img.shields.io/badge/react--native-%200.18.x-05F561.svg) ![](https://img.shields.io/badge/gl--react-%202.1.x-05F561.svg)
OpenGL bindings for React Native to implement complex effects over images and components, in the descriptive VDOM paradigm. OpenGL bindings for React Native to implement complex effects over images and components, in the descriptive VDOM paradigm.
......
...@@ -30,5 +30,5 @@ repositories { ...@@ -30,5 +30,5 @@ repositories {
} }
dependencies { dependencies {
compile 'com.facebook.react:react-native:0.17.+' compile 'com.facebook.react:react-native:0.18.+'
} }
package com.projectseptember.RNGL;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
public class CaptureConfig {
String format;
String type;
String filePath;
Double quality;
public CaptureConfig(String format, String type, String filePath, Double quality) {
this.format = format;
this.type = type;
this.filePath = filePath;
this.quality = quality;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CaptureConfig that = (CaptureConfig) o;
if (format != null ? !format.equals(that.format) : that.format != null) return false;
if (type != null ? !type.equals(that.type) : that.type != null) return false;
if (filePath != null ? !filePath.equals(that.filePath) : that.filePath != null)
return false;
return !(quality != null ? !quality.equals(that.quality) : that.quality != null);
}
@Override
public int hashCode() {
int result = format != null ? format.hashCode() : 0;
result = 31 * result + (type != null ? type.hashCode() : 0);
result = 31 * result + (filePath != null ? filePath.hashCode() : 0);
result = 31 * result + (quality != null ? quality.hashCode() : 0);
return result;
}
public static CaptureConfig fromMap (ReadableMap map) {
return new CaptureConfig(
map.getString("format"),
map.getString("type"),
map.getString("filePath"),
map.getDouble("quality")
);
}
public WritableMap toMap () {
WritableMap map = Arguments.createMap();
map.putString("format", format);
map.putString("type", type);
map.putString("filePath", filePath);
map.putDouble("quality", quality);
return map;
}
}
...@@ -27,6 +27,11 @@ public class GLCanvasManager extends SimpleViewManager<GLCanvas> { ...@@ -27,6 +27,11 @@ public class GLCanvasManager extends SimpleViewManager<GLCanvas> {
private ExecutorSupplier executorSupplier; private ExecutorSupplier executorSupplier;
@ReactProp(name="pixelRatio")
public void setPixelRatio (GLCanvas view, float pixelRatio) {
view.setPixelRatio(pixelRatio);
}
@ReactProp(name="nbContentTextures") @ReactProp(name="nbContentTextures")
public void setNbContentTextures (GLCanvas view, int nbContentTextures) { public void setNbContentTextures (GLCanvas view, int nbContentTextures) {
view.setNbContentTextures(nbContentTextures); view.setNbContentTextures(nbContentTextures);
...@@ -89,7 +94,7 @@ public class GLCanvasManager extends SimpleViewManager<GLCanvas> { ...@@ -89,7 +94,7 @@ public class GLCanvasManager extends SimpleViewManager<GLCanvas> {
Assertions.assertNotNull(args); Assertions.assertNotNull(args);
switch (commandType) { switch (commandType) {
case COMMAND_CAPTURE_FRAME: { case COMMAND_CAPTURE_FRAME: {
canvas.requestCaptureFrame(); canvas.requestCaptureFrame(CaptureConfig.fromMap(args.getMap(0)));
return; return;
} }
default: default:
......
...@@ -10,17 +10,19 @@ public class GLData { ...@@ -10,17 +10,19 @@ public class GLData {
final Integer shader; final Integer shader;
final ReadableMap uniforms; final ReadableMap uniforms;
final Integer width; final Double width;
final Integer height; final Double height;
final Double pixelRatio;
final Integer fboId; final Integer fboId;
final List<GLData> contextChildren; final List<GLData> contextChildren;
final List<GLData> children; final List<GLData> children;
public GLData(Integer shader, ReadableMap uniforms, Integer width, Integer height, Integer fboId, List<GLData> contextChildren, List<GLData> children) { public GLData(Integer shader, ReadableMap uniforms, Double width, Double height, Double pixelRatio, Integer fboId, List<GLData> contextChildren, List<GLData> children) {
this.shader = shader; this.shader = shader;
this.uniforms = uniforms; this.uniforms = uniforms;
this.width = width; this.width = width;
this.height = height; this.height = height;
this.pixelRatio = pixelRatio;
this.fboId = fboId; this.fboId = fboId;
this.contextChildren = contextChildren; this.contextChildren = contextChildren;
this.children = children; this.children = children;
...@@ -37,11 +39,12 @@ public class GLData { ...@@ -37,11 +39,12 @@ public class GLData {
public static GLData fromMap (ReadableMap map) { public static GLData fromMap (ReadableMap map) {
Integer shader = map.getInt("shader"); Integer shader = map.getInt("shader");
ReadableMap uniforms = map.getMap("uniforms"); ReadableMap uniforms = map.getMap("uniforms");
Integer width = (int) map.getDouble("width"); Double width = map.getDouble("width");
Integer height = (int) map.getDouble("height"); Double height = map.getDouble("height");
Double pixelRatio = map.getDouble("pixelRatio");
Integer fboId = map.getInt("fboId"); Integer fboId = map.getInt("fboId");
List<GLData> children = fromArray(map.getArray("children")); List<GLData> children = fromArray(map.getArray("children"));
List<GLData> contextChildren = fromArray(map.getArray("contextChildren")); List<GLData> contextChildren = fromArray(map.getArray("contextChildren"));
return new GLData(shader, uniforms, width, height, fboId, contextChildren, children); return new GLData(shader, uniforms, width, height, pixelRatio, fboId, contextChildren, children);
} }
} }
...@@ -21,29 +21,30 @@ public class GLShader { ...@@ -21,29 +21,30 @@ public class GLShader {
private int pointerLoc; // The "pointer" attribute is used to iterate over vertex private int pointerLoc; // The "pointer" attribute is used to iterate over vertex
private Map<String, Integer> uniformLocations; // The uniform locations cache private Map<String, Integer> uniformLocations; // The uniform locations cache
public GLShader(String name, String vert, String frag) { private Integer id;
this.name = name; private RNGLContext rnglContext;
this.vert = vert; private GLShaderCompilationFailed compilationFailed;
this.frag = frag;
}
public GLShader(GLShaderData data) { public GLShader(GLShaderData data, Integer id, RNGLContext rnglContext) {
this.name = data.name; this.name = data.name;
this.vert = data.vert; this.vert = data.vert;
this.frag = data.frag; this.frag = data.frag;
this.id = id;
this.rnglContext = rnglContext;
} }
@Override @Override
protected void finalize() throws Throwable { protected void finalize() throws Throwable {
super.finalize(); super.finalize();
if (buffer != null) { if (buffer != null) {
// TODO: need to check if this works properly
glDeleteProgram(program); glDeleteProgram(program);
glDeleteBuffers(1, buffer, 0); glDeleteBuffers(1, buffer, 0);
} }
} }
public void runtimeException (String msg) { public void runtimeException (String msg) {
throw new RuntimeException("Shader '"+name+"': "+msg); throw new GLShaderCompilationFailed(name, msg);
} }
public void bind () { public void bind () {
...@@ -64,7 +65,7 @@ public class GLShader { ...@@ -64,7 +65,7 @@ public class GLShader {
glGetProgramiv(program, GL_VALIDATE_STATUS, validSuccess, 0); glGetProgramiv(program, GL_VALIDATE_STATUS, validSuccess, 0);
if (validSuccess[0] == GL_FALSE) { if (validSuccess[0] == GL_FALSE) {
glGetProgramInfoLog(program); glGetProgramInfoLog(program);
runtimeException("Validation failed " + glGetProgramInfoLog(program)); runtimeException(glGetProgramInfoLog(program));
} }
} }
...@@ -133,7 +134,7 @@ public class GLShader { ...@@ -133,7 +134,7 @@ public class GLShader {
int compileSuccess[] = new int[1]; int compileSuccess[] = new int[1];
glGetShaderiv(shaderHandle, GL_COMPILE_STATUS, compileSuccess, 0); glGetShaderiv(shaderHandle, GL_COMPILE_STATUS, compileSuccess, 0);
if (compileSuccess[0] == GL_FALSE) { if (compileSuccess[0] == GL_FALSE) {
runtimeException("failed to compile: " + glGetShaderInfoLog(shaderHandle)); runtimeException(glGetShaderInfoLog(shaderHandle));
return -1; return -1;
} }
return shaderHandle; return shaderHandle;
...@@ -157,7 +158,7 @@ public class GLShader { ...@@ -157,7 +158,7 @@ public class GLShader {
this.uniformLocations = locations; this.uniformLocations = locations;
} }
private void makeProgram () { private void makeProgram () throws GLShaderCompilationFailed {
int vertex = compileShader(vert, GL_VERTEX_SHADER); int vertex = compileShader(vert, GL_VERTEX_SHADER);
if (vertex == -1) return; if (vertex == -1) return;
...@@ -172,7 +173,7 @@ public class GLShader { ...@@ -172,7 +173,7 @@ public class GLShader {
int[] linkSuccess = new int[1]; int[] linkSuccess = new int[1];
glGetProgramiv(program, GL_LINK_STATUS, linkSuccess, 0); glGetProgramiv(program, GL_LINK_STATUS, linkSuccess, 0);
if (linkSuccess[0] == GL_FALSE) { if (linkSuccess[0] == GL_FALSE) {
runtimeException("Linking failed "+glGetProgramInfoLog(program)); runtimeException(glGetProgramInfoLog(program));
} }
glUseProgram(program); glUseProgram(program);
...@@ -208,7 +209,18 @@ public class GLShader { ...@@ -208,7 +209,18 @@ public class GLShader {
} }
public boolean ensureCompile() { public boolean ensureCompile() {
if (!isReady()) makeProgram(); if (!isReady()) {
if (compilationFailed != null) throw compilationFailed;
try {
makeProgram();
rnglContext.shaderSucceedToCompile(id, uniformTypes);
}
catch (GLShaderCompilationFailed e) {
compilationFailed = e;
rnglContext.shaderFailedToCompile(id, e);
throw e;
}
}
return isReady(); return isReady();
} }
} }
package com.projectseptember.RNGL;
public class GLShaderCompilationFailed extends RuntimeException {
public final String shaderName;
public final String compileError;
public GLShaderCompilationFailed(String shaderName, String compileError) {
super("Shader '"+shaderName+"': "+compileError);
this.compileError = compileError;
this.shaderName = shaderName;
}
}
package com.projectseptember.RNGL; package com.projectseptember.RNGL;
import android.util.Log;
import static android.opengl.GLES20.*;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod; import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap; import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
...@@ -20,6 +26,7 @@ public class RNGLContext extends ReactContextBaseJavaModule { ...@@ -20,6 +26,7 @@ public class RNGLContext extends ReactContextBaseJavaModule {
private Map<Integer, GLShaderData> shaders = new HashMap<>(); private Map<Integer, GLShaderData> shaders = new HashMap<>();
private Map<Integer, GLFBO> fbos = new HashMap<>(); private Map<Integer, GLFBO> fbos = new HashMap<>();
private Map<Integer, Callback> onCompileCallbacks = new HashMap<>();
public RNGLContext (ReactApplicationContext reactContext) { public RNGLContext (ReactApplicationContext reactContext) {
super(reactContext); super(reactContext);
...@@ -35,9 +42,67 @@ public class RNGLContext extends ReactContextBaseJavaModule { ...@@ -35,9 +42,67 @@ public class RNGLContext extends ReactContextBaseJavaModule {
} }
@ReactMethod @ReactMethod
public void addShader (final Integer id, final ReadableMap config) { public void addShader (final Integer id, final ReadableMap config, final Callback onCompile) {
final String frag = config.getString("frag"); final String frag = config.getString("frag");
final String name = config.getString("name"); final String name = config.getString("name");
shaders.put(id, new GLShaderData(name, STATIC_VERT, frag)); shaders.put(id, new GLShaderData(name, STATIC_VERT, frag));
if (onCompile != null) {
onCompileCallbacks.put(id, onCompile);
}
}
@ReactMethod
public void removeShader (final Integer id) {
GLShaderData shader = shaders.remove(id);
if (shader == null) {
throw new Error("removeShader("+id+"): shader does not exist");
}
}
public void shaderFailedToCompile(Integer id, GLShaderCompilationFailed e) {
Callback onCompile = onCompileCallbacks.get(id);
if (onCompile == null) {
Log.e("RNGLContext", e.getMessage());
}
else {
onCompile.invoke(e.compileError);
}
}
public void shaderSucceedToCompile(Integer id, Map<String, Integer> uniformTypes) {
Callback onCompile = onCompileCallbacks.get(id);
onCompileCallbacks.remove(id);
if (onCompile != null) {
WritableMap res = Arguments.createMap();
WritableMap uniforms = Arguments.createMap();
for (String key : uniformTypes.keySet()) {
uniforms.putString(key, glTypeString(uniformTypes.get(key)));
}
res.putMap("uniforms", uniforms);
onCompile.invoke(null, res);
}
}
static String glTypeString (int type) {
switch (type) {
case GL_FLOAT: return "float";
case GL_FLOAT_VEC2: return "vec2";
case GL_FLOAT_VEC3: return "vec3";
case GL_FLOAT_VEC4: return "vec4";
case GL_INT: return "int";
case GL_INT_VEC2: return "ivec2";
case GL_INT_VEC3: return "ivec3";
case GL_INT_VEC4: return "ivec4";
case GL_BOOL: return "bool";
case GL_BOOL_VEC2: return "bvec2";
case GL_BOOL_VEC3: return "bvec3";
case GL_BOOL_VEC4: return "bvec4";
case GL_FLOAT_MAT2: return "mat2";
case GL_FLOAT_MAT3: return "mat3";
case GL_FLOAT_MAT4: return "mat4";
case GL_SAMPLER_2D: return "sampler2D";
case GL_SAMPLER_CUBE: return "samplerCube";
}
return "";
} }
} }
#import <Foundation/Foundation.h>
@interface CaptureConfig: NSObject
@property (nonatomic, copy) NSString *format;
@property (nonatomic, copy) NSString *type;
@property (nonatomic, copy) NSString *filePath;
@property (nonatomic, copy) NSNumber *quality;
-(instancetype)initWithFormat: (NSString *)format
withType: (NSString *)type
withQuality: (NSNumber *)quality
withFilePath: (NSString *)filePath;
- (bool) isEqualToCaptureConfig: (CaptureConfig *)other;
- (NSDictionary *) dictionary;
@end
#import "CaptureConfig.h"
@implementation CaptureConfig
-(instancetype)initWithFormat: (NSString *)format
withType: (NSString *)type
withQuality: (NSNumber *)quality
withFilePath: (NSString *)filePath
{
if ((self = [super init])) {
self.format = format;
self.type = type;
self.quality = quality;
self.filePath = filePath;
}
return self;
}
- (bool) isEqualToCaptureConfig: (CaptureConfig *)other
{
return [self.format isEqualToString:other.format] &&
[self.type isEqualToString:other.type] &&
[self.quality isEqualToNumber:other.quality] &&
[self.filePath isEqualToString:other.filePath];
}
- (NSDictionary *) dictionary
{
return @{
@"format": self.format,
@"type": self.type,
@"quality": self.quality,
@"filePath": self.filePath
};
}
@end
#import <GLKit/GLKit.h> #import <GLKit/GLKit.h>
#import "GLData.h" #import "GLData.h"
#import "CaptureConfig.h"
#import "RCTComponent.h" #import "RCTComponent.h"
@interface GLCanvas: GLKView @interface GLCanvas: GLKView
...@@ -11,6 +12,7 @@ ...@@ -11,6 +12,7 @@
@property (nonatomic) BOOL visibleContent; @property (nonatomic) BOOL visibleContent;
@property (nonatomic) NSNumber *nbContentTextures; @property (nonatomic) NSNumber *nbContentTextures;
@property (nonatomic) NSNumber *renderId; @property (nonatomic) NSNumber *renderId;
@property (nonatomic) NSNumber *pixelRatio;
@property (nonatomic) NSArray *imagesToPreload; @property (nonatomic) NSArray *imagesToPreload;
@property (nonatomic, copy) RCTBubblingEventBlock onGLProgress; @property (nonatomic, copy) RCTBubblingEventBlock onGLProgress;
@property (nonatomic, copy) RCTBubblingEventBlock onGLLoad; @property (nonatomic, copy) RCTBubblingEventBlock onGLLoad;
...@@ -18,6 +20,6 @@ ...@@ -18,6 +20,6 @@
- (instancetype)initWithBridge:(RCTBridge *)bridge; - (instancetype)initWithBridge:(RCTBridge *)bridge;
- (void) requestCaptureFrame; - (void) requestCaptureFrame:(CaptureConfig *)config;
@end @end
This diff is collapsed.
#import "GLCanvasManager.h" #import "GLCanvasManager.h"
#import "GLCanvas.h" #import "GLCanvas.h"
#import "RCTConvert+GLData.h" #import "RCTConvert+GLData.h"
#import "RCTConvert+CaptureConfig.h"
#import "RCTUIManager.h" #import "RCTUIManager.h"
#import "RCTLog.h" #import "RCTLog.h"
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
...@@ -17,17 +18,23 @@ RCT_EXPORT_MODULE(); ...@@ -17,17 +18,23 @@ RCT_EXPORT_MODULE();
return self; return self;
} }
- (dispatch_queue_t)methodQueue
{
return self.bridge.uiManager.methodQueue;
}
RCT_EXPORT_VIEW_PROPERTY(nbContentTextures, NSNumber); RCT_EXPORT_VIEW_PROPERTY(nbContentTextures, NSNumber);
RCT_EXPORT_VIEW_PROPERTY(opaque, BOOL); RCT_EXPORT_VIEW_PROPERTY(opaque, BOOL);
RCT_EXPORT_VIEW_PROPERTY(autoRedraw, BOOL); RCT_EXPORT_VIEW_PROPERTY(autoRedraw, BOOL);
RCT_EXPORT_VIEW_PROPERTY(data, GLData); RCT_EXPORT_VIEW_PROPERTY(data, GLData);
RCT_EXPORT_VIEW_PROPERTY(renderId, NSNumber); RCT_EXPORT_VIEW_PROPERTY(renderId, NSNumber);
RCT_EXPORT_VIEW_PROPERTY(pixelRatio, NSNumber);
RCT_EXPORT_VIEW_PROPERTY(imagesToPreload, NSArray); RCT_EXPORT_VIEW_PROPERTY(imagesToPreload, NSArray);
RCT_EXPORT_VIEW_PROPERTY(onGLLoad, RCTBubblingEventBlock); RCT_EXPORT_VIEW_PROPERTY(onGLLoad, RCTBubblingEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onGLProgress, RCTBubblingEventBlock); RCT_EXPORT_VIEW_PROPERTY(onGLProgress, RCTBubblingEventBlock);
RCT_EXPORT_VIEW_PROPERTY(onGLCaptureFrame, RCTBubblingEventBlock); RCT_EXPORT_VIEW_PROPERTY(onGLCaptureFrame, RCTBubblingEventBlock);
RCT_EXPORT_METHOD(capture: (nonnull NSNumber *)reactTag) RCT_EXPORT_METHOD(capture: (nonnull NSNumber *)reactTag withConfig:(id)config)
{ {
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) { [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
UIView *view = viewRegistry[reactTag]; UIView *view = viewRegistry[reactTag];
...@@ -36,7 +43,7 @@ RCT_EXPORT_METHOD(capture: (nonnull NSNumber *)reactTag) ...@@ -36,7 +43,7 @@ RCT_EXPORT_METHOD(capture: (nonnull NSNumber *)reactTag)
} }
else { else {
GLCanvas *glCanvas = (GLCanvas *)view; GLCanvas *glCanvas = (GLCanvas *)view;
[glCanvas requestCaptureFrame]; [glCanvas requestCaptureFrame:[RCTConvert CaptureConfig:config]];
} }
}]; }];
} }
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
@property (nonatomic) NSDictionary *uniforms; @property (nonatomic) NSDictionary *uniforms;
@property (nonatomic) NSNumber *width; @property (nonatomic) NSNumber *width;
@property (nonatomic) NSNumber *height; @property (nonatomic) NSNumber *height;
@property (nonatomic) NSNumber *pixelRatio;
@property (nonatomic) NSNumber *fboId; @property (nonatomic) NSNumber *fboId;
@property (nonatomic) NSArray *contextChildren; @property (nonatomic) NSArray *contextChildren;
@property (nonatomic) NSArray *children; @property (nonatomic) NSArray *children;
...@@ -16,6 +17,7 @@ ...@@ -16,6 +17,7 @@
withUniforms: (NSDictionary *)uniforms withUniforms: (NSDictionary *)uniforms
withWidth: (NSNumber *)width withWidth: (NSNumber *)width
withHeight: (NSNumber *)height withHeight: (NSNumber *)height
withPixelRatio: (NSNumber *)pixelRatio
withFboId: (NSNumber *)fboId withFboId: (NSNumber *)fboId
withContextChildren: (NSArray *)contextChildren withContextChildren: (NSArray *)contextChildren
withChildren: (NSArray *)children; withChildren: (NSArray *)children;
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
withUniforms: (NSDictionary *)uniforms withUniforms: (NSDictionary *)uniforms
withWidth: (NSNumber *)width withWidth: (NSNumber *)width
withHeight: (NSNumber *)height withHeight: (NSNumber *)height
withPixelRatio: (NSNumber *)pixelRatio
withFboId: (NSNumber *)fboId withFboId: (NSNumber *)fboId
withContextChildren: (NSArray *)contextChildren withContextChildren: (NSArray *)contextChildren
withChildren: (NSArray *)children withChildren: (NSArray *)children
...@@ -15,6 +16,7 @@ ...@@ -15,6 +16,7 @@
self.uniforms = uniforms; self.uniforms = uniforms;
self.width = width; self.width = width;
self.height = height; self.height = height;
self.pixelRatio = pixelRatio;
self.fboId = fboId; self.fboId = fboId;
self.contextChildren = contextChildren; self.contextChildren = contextChildren;
self.children = children; self.children = children;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
+ (GLImageData*) empty; + (GLImageData*) empty;
+ (GLImageData*) genPixelsWithImage: (UIImage *)image; + (GLImageData*) genPixelsWithImage: (UIImage *)image;
+ (GLImageData*) genPixelsWithView: (UIView *)view; + (GLImageData*) genPixelsWithView: (UIView *)view withPixelRatio:(float)pixelRatio;
- (instancetype)initWithData: (GLubyte *)data withWidth:(int)width withHeight:(int)height; - (instancetype)initWithData: (GLubyte *)data withWidth:(int)width withHeight:(int)height;
......
#import "GLImageData.h" #import "GLImageData.h"
#import "RCTUtils.h"
#import "RCTLog.h" #import "RCTLog.h"
// This structure aims to be used in an immutable way // This structure aims to be used in an immutable way
...@@ -55,16 +54,16 @@ GLImageData *EMPTY_PIXELS; ...@@ -55,16 +54,16 @@ GLImageData *EMPTY_PIXELS;
return [[GLImageData alloc] initWithData:data withWidth:width withHeight:height]; return [[GLImageData alloc] initWithData:data withWidth:width withHeight:height];
} }
+ (GLImageData *)genPixelsWithView: (UIView *)view + (GLImageData *)genPixelsWithView: (UIView *)view withPixelRatio:(float)pixelRatio
{ {
float width = RCTScreenScale() * view.bounds.size.width; float width = pixelRatio * view.bounds.size.width;
float height = RCTScreenScale() * view.bounds.size.height; float height = pixelRatio * view.bounds.size.height;
GLubyte *data = (GLubyte *)malloc(4 * width * height); GLubyte *data = (GLubyte *)malloc(4 * width * height);
CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB(); CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef ctx = CGBitmapContextCreate(data, width, height, 8, 4 * width, colourSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); CGContextRef ctx = CGBitmapContextCreate(data, width, height, 8, 4 * width, colourSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colourSpace); CGColorSpaceRelease(colourSpace);
CGContextClearRect(ctx, CGRectMake(0.0, 0.0, width, height)); CGContextClearRect(ctx, CGRectMake(0.0, 0.0, width, height));
CGContextScaleCTM(ctx, RCTScreenScale(), RCTScreenScale()); CGContextScaleCTM(ctx, pixelRatio, pixelRatio);
[view.layer renderInContext:ctx]; [view.layer renderInContext:ctx];
CGContextRelease(ctx); CGContextRelease(ctx);
return [[GLImageData alloc] initWithData:data withWidth:width withHeight:height]; return [[GLImageData alloc] initWithData:data withWidth:width withHeight:height];
......
...@@ -7,8 +7,8 @@ ...@@ -7,8 +7,8 @@
@property (nonatomic) GLShader *shader; @property (nonatomic) GLShader *shader;
@property (nonatomic) NSDictionary *uniforms; @property (nonatomic) NSDictionary *uniforms;
@property (nonatomic) NSDictionary *textures; @property (nonatomic) NSDictionary *textures;
@property (nonatomic) NSNumber *width; @property (nonatomic) int width;
@property (nonatomic) NSNumber *height; @property (nonatomic) int height;
@property (nonatomic) int fboId; @property (nonatomic) int fboId;
@property (nonatomic) NSArray *contextChildren; @property (nonatomic) NSArray *contextChildren;
@property (nonatomic) NSArray *children; @property (nonatomic) NSArray *children;
...@@ -16,8 +16,8 @@ ...@@ -16,8 +16,8 @@
-(instancetype) initWithShader: (GLShader *)shader -(instancetype) initWithShader: (GLShader *)shader
withUniforms:(NSDictionary *)uniforms withUniforms:(NSDictionary *)uniforms
withTextures: (NSDictionary *)textures withTextures: (NSDictionary *)textures
withWidth: (NSNumber *)width withWidth: (int)width
withHeight: (NSNumber *)height withHeight: (int)height
withFboId: (int)fboId withFboId: (int)fboId
withContextChildren: (NSArray *)contextChildren withContextChildren: (NSArray *)contextChildren
withChildren: (NSArray *)children; withChildren: (NSArray *)children;
......
...@@ -6,8 +6,8 @@ ...@@ -6,8 +6,8 @@
-(instancetype) initWithShader: (GLShader *)shader -(instancetype) initWithShader: (GLShader *)shader
withUniforms:(NSDictionary *)uniforms withUniforms:(NSDictionary *)uniforms
withTextures: (NSDictionary *)textures withTextures: (NSDictionary *)textures
withWidth: (NSNumber *)width withWidth: (int)width
withHeight: (NSNumber *)height withHeight: (int)height
withFboId: (int)fboId withFboId: (int)fboId
withContextChildren: (NSArray *)contextChildren withContextChildren: (NSArray *)contextChildren
withChildren: (NSArray *)children withChildren: (NSArray *)children
......
#import <GLKit/GLKit.h> #import <GLKit/GLKit.h>
#import "RCTBridgeModule.h" #import "RCTBridgeModule.h"
NS_ENUM(NSInteger) {
GLContextFailure = 87001,
GLLinkingFailure = 87002,
GLCompileFailure = 87003,
GLNotAProgram = 87004
};
@interface GLShader: NSObject @interface GLShader: NSObject
@property EAGLContext *context; @property EAGLContext *context;
...@@ -18,10 +25,7 @@ ...@@ -18,10 +25,7 @@
*/ */
- (void) bind; - (void) bind;
/** - (bool) ensureCompiles: (NSError**)error;
* Check the shader validity
*/
- (void) validate;
/** /**
* Set the value of an uniform * Set the value of an uniform
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
#import "RCTConvert.h" #import "RCTConvert.h"
#import "GLShader.h" #import "GLShader.h"
GLuint compileShader (NSString* shaderName, NSString* shaderString, GLenum shaderType) { GLuint compileShader (NSString* shaderName, NSString* shaderString, GLenum shaderType, NSError **error) {
GLuint shaderHandle = glCreateShader(shaderType); GLuint shaderHandle = glCreateShader(shaderType);
...@@ -20,8 +20,10 @@ GLuint compileShader (NSString* shaderName, NSString* shaderString, GLenum shade ...@@ -20,8 +20,10 @@ GLuint compileShader (NSString* shaderName, NSString* shaderString, GLenum shade
if (compileSuccess == GL_FALSE) { if (compileSuccess == GL_FALSE) {
GLchar messages[256]; GLchar messages[256];
glGetShaderInfoLog(shaderHandle, sizeof(messages), 0, &messages[0]); glGetShaderInfoLog(shaderHandle, sizeof(messages), 0, &messages[0]);
NSString *messageString = [NSString stringWithUTF8String:messages]; *error = [[NSError alloc]
RCTLogError(@"Shader '%@' failed to compile: %@", shaderName, messageString); initWithDomain:[NSString stringWithUTF8String:messages]
code:GLCompileFailure
userInfo:nil];
return -1; return -1;
} }
...@@ -41,6 +43,7 @@ GLuint compileShader (NSString* shaderName, NSString* shaderString, GLenum shade ...@@ -41,6 +43,7 @@ GLuint compileShader (NSString* shaderName, NSString* shaderString, GLenum shade
GLint pointerLoc; // The "pointer" attribute is used to iterate over vertex GLint pointerLoc; // The "pointer" attribute is used to iterate over vertex
NSDictionary *_uniformTypes; // The types of the GLSL uniforms (N.B: array are not supported) NSDictionary *_uniformTypes; // The types of the GLSL uniforms (N.B: array are not supported)
NSDictionary *_uniformLocations; // The uniform locations cache NSDictionary *_uniformLocations; // The uniform locations cache
NSError *_error;
} }
- (instancetype)initWithContext: (EAGLContext*)context withName:(NSString *)name withVert:(NSString *)vert withFrag:(NSString *)frag - (instancetype)initWithContext: (EAGLContext*)context withName:(NSString *)name withVert:(NSString *)vert withFrag:(NSString *)frag
...@@ -51,7 +54,10 @@ GLuint compileShader (NSString* shaderName, NSString* shaderString, GLenum shade ...@@ -51,7 +54,10 @@ GLuint compileShader (NSString* shaderName, NSString* shaderString, GLenum shade
_context = context; _context = context;
_vert = vert; _vert = vert;
_frag = frag; _frag = frag;
[self makeProgram]; NSError *error;
if (![self makeProgram:&error]) {
_error = error;
}
} }
return self; return self;
} }
...@@ -60,12 +66,21 @@ GLuint compileShader (NSString* shaderName, NSString* shaderString, GLenum shade ...@@ -60,12 +66,21 @@ GLuint compileShader (NSString* shaderName, NSString* shaderString, GLenum shade
{ {
glDeleteProgram(program); glDeleteProgram(program);
glDeleteBuffers(1, &buffer); glDeleteBuffers(1, &buffer);
_name = nil;
_context = nil;
_vert = nil;
_frag = nil;
_uniformLocations = nil;
_uniformTypes = nil;
program = 0;
buffer = 0;
pointerLoc = 0;
} }
- (bool) ensureContext - (bool) ensureContext: (NSError **)error
{ {
if (![EAGLContext setCurrentContext:_context]) { if (!_context || ![EAGLContext setCurrentContext:_context]) {
RCTLogError(@"Shader '%@': Failed to set current OpenGL context", _name); *error = [[NSError alloc] initWithDomain:@"Failed to set current OpenGL context" code:GLContextFailure userInfo:nil];
return false; return false;
} }
return true; return true;
...@@ -73,11 +88,6 @@ GLuint compileShader (NSString* shaderName, NSString* shaderString, GLenum shade ...@@ -73,11 +88,6 @@ GLuint compileShader (NSString* shaderName, NSString* shaderString, GLenum shade
- (void) bind - (void) bind
{ {
if (![self ensureContext]) return;
if ( glIsProgram(program) != GL_TRUE ){
RCTLogError(@"Shader '%@': not a program!", _name);
return;
}
glUseProgram(program); glUseProgram(program);
glBindBuffer(GL_ARRAY_BUFFER, buffer); glBindBuffer(GL_ARRAY_BUFFER, buffer);
glEnableVertexAttribArray(pointerLoc); glEnableVertexAttribArray(pointerLoc);
...@@ -307,19 +317,6 @@ GLuint compileShader (NSString* shaderName, NSString* shaderString, GLenum shade ...@@ -307,19 +317,6 @@ GLuint compileShader (NSString* shaderName, NSString* shaderString, GLenum shade
} }
} }
- (void) validate
{
glValidateProgram(program);
GLint validSuccess;
glGetProgramiv(program, GL_VALIDATE_STATUS, &validSuccess);
if (validSuccess == GL_FALSE) {
GLchar messages[256];
glGetProgramInfoLog(program, sizeof(messages), 0, &messages[0]);
NSString *messageString = [NSString stringWithUTF8String:messages];
RCTLogError(@"Shader '%@': Validation failed %@", _name, messageString);
}
}
- (void) computeMeta - (void) computeMeta
{ {
NSMutableDictionary *uniforms = @{}.mutableCopy; NSMutableDictionary *uniforms = @{}.mutableCopy;
...@@ -342,15 +339,29 @@ GLuint compileShader (NSString* shaderName, NSString* shaderString, GLenum shade ...@@ -342,15 +339,29 @@ GLuint compileShader (NSString* shaderName, NSString* shaderString, GLenum shade
_uniformLocations = locations; _uniformLocations = locations;
} }
- (void) makeProgram - (bool) ensureCompiles: (NSError **)error
{ {
if (![self ensureContext]) return; if (![self ensureContext:error]) {
return false;
}
if (!glIsProgram(program)) {
*error = [[NSError alloc] initWithDomain:@"not a program" code:GLNotAProgram userInfo:nil];
return false;
}
if (_error == nil) return true;
*error = _error;
return false;
}
GLuint vertex = compileShader(_name, _vert, GL_VERTEX_SHADER); - (bool) makeProgram: (NSError **)error
if (vertex == -1) return; {
if (![self ensureContext:error]) return false;
GLuint fragment = compileShader(_name, _frag, GL_FRAGMENT_SHADER); GLuint vertex = compileShader(_name, _vert, GL_VERTEX_SHADER, error);
if (fragment == -1) return; if (vertex == -1) return false;
GLuint fragment = compileShader(_name, _frag, GL_FRAGMENT_SHADER, error);
if (fragment == -1) return false;
program = glCreateProgram(); program = glCreateProgram();
glAttachShader(program, vertex); glAttachShader(program, vertex);
...@@ -362,9 +373,11 @@ GLuint compileShader (NSString* shaderName, NSString* shaderString, GLenum shade ...@@ -362,9 +373,11 @@ GLuint compileShader (NSString* shaderName, NSString* shaderString, GLenum shade
if (linkSuccess == GL_FALSE) { if (linkSuccess == GL_FALSE) {
GLchar messages[256]; GLchar messages[256];
glGetProgramInfoLog(program, sizeof(messages), 0, &messages[0]); glGetProgramInfoLog(program, sizeof(messages), 0, &messages[0]);
NSString *messageString = [NSString stringWithUTF8String:messages]; *error = [[NSError alloc]
RCTLogError(@"Shader '%@': Linking failed %@", _name, messageString); initWithDomain:[NSString stringWithUTF8String:messages]
return; code:GLLinkingFailure
userInfo:nil];
return false;
} }
glUseProgram(program); glUseProgram(program);
...@@ -384,6 +397,8 @@ GLuint compileShader (NSString* shaderName, NSString* shaderString, GLenum shade ...@@ -384,6 +397,8 @@ GLuint compileShader (NSString* shaderName, NSString* shaderString, GLenum shade
1.0, 1.0 1.0, 1.0
}; };
glBufferData(GL_ARRAY_BUFFER, sizeof(buf), buf, GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, sizeof(buf), buf, GL_STATIC_DRAW);
return true;
} }
......
#import "RCTConvert.h"
#import "CaptureConfig.h"
@interface RCTConvert (CaptureConfig)
+ (CaptureConfig *)CaptureConfig:(id)json;
@end
//
// RCTConvert+CaptureConfig.m
// RNGL
//
// Created by Gaetan Renaudeau on 30/12/15.
//
//
#import "RCTConvert+CaptureConfig.h"
@implementation RCTConvert (CaptureConfig)
+ (CaptureConfig *)CaptureConfig:(id)json
{
return [[CaptureConfig alloc]
initWithFormat:[RCTConvert NSString:json[@"format"]]
withType:[RCTConvert NSString:json[@"type"]]
withQuality:[RCTConvert NSNumber:json[@"quality"]]
withFilePath:[RCTConvert NSString:json[@"filePath"]]];
}
@end
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
NSDictionary *uniforms = [self NSDictionary:json[@"uniforms"]]; NSDictionary *uniforms = [self NSDictionary:json[@"uniforms"]];
NSNumber *width = [self NSNumber:json[@"width"]]; NSNumber *width = [self NSNumber:json[@"width"]];
NSNumber *height = [self NSNumber:json[@"height"]]; NSNumber *height = [self NSNumber:json[@"height"]];
NSNumber *pixelRatio = [self NSNumber:json[@"pixelRatio"]];
NSNumber *fboId = [self NSNumber:json[@"fboId"]]; NSNumber *fboId = [self NSNumber:json[@"fboId"]];
NSArray *contextChildrenJSON = [self NSArray: json[@"contextChildren"]]; NSArray *contextChildrenJSON = [self NSArray: json[@"contextChildren"]];
NSArray *childrenJSON = [self NSArray: json[@"children"]]; NSArray *childrenJSON = [self NSArray: json[@"children"]];
...@@ -30,6 +31,7 @@ ...@@ -30,6 +31,7 @@
withUniforms: uniforms withUniforms: uniforms
withWidth: width withWidth: width
withHeight: height withHeight: height
withPixelRatio: pixelRatio
withFboId: fboId withFboId: fboId
withContextChildren: contextChildren withContextChildren: contextChildren
withChildren: children]; withChildren: children];
......
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
346089D81BEFD0A500C90DB5 /* GLTexture.m in Sources */ = {isa = PBXBuildFile; fileRef = 346089CB1BEFD0A500C90DB5 /* GLTexture.m */; }; 346089D81BEFD0A500C90DB5 /* GLTexture.m in Sources */ = {isa = PBXBuildFile; fileRef = 346089CB1BEFD0A500C90DB5 /* GLTexture.m */; };
346089D91BEFD0A500C90DB5 /* RCTConvert+GLData.m in Sources */ = {isa = PBXBuildFile; fileRef = 346089CD1BEFD0A500C90DB5 /* RCTConvert+GLData.m */; }; 346089D91BEFD0A500C90DB5 /* RCTConvert+GLData.m in Sources */ = {isa = PBXBuildFile; fileRef = 346089CD1BEFD0A500C90DB5 /* RCTConvert+GLData.m */; };
346089DA1BEFD0A500C90DB5 /* RNGLContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 346089CF1BEFD0A500C90DB5 /* RNGLContext.m */; }; 346089DA1BEFD0A500C90DB5 /* RNGLContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 346089CF1BEFD0A500C90DB5 /* RNGLContext.m */; };
34C990421C34939C002F49FC /* RCTConvert+CaptureConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 34C990411C34939C002F49FC /* RCTConvert+CaptureConfig.m */; };
34C990471C349422002F49FC /* CaptureConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 34C990461C349422002F49FC /* CaptureConfig.m */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */ /* Begin PBXCopyFilesBuildPhase section */
...@@ -48,13 +50,17 @@ ...@@ -48,13 +50,17 @@
346089C61BEFD0A500C90DB5 /* GLRenderData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GLRenderData.h; sourceTree = "<group>"; }; 346089C61BEFD0A500C90DB5 /* GLRenderData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GLRenderData.h; sourceTree = "<group>"; };
346089C71BEFD0A500C90DB5 /* GLRenderData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GLRenderData.m; sourceTree = "<group>"; }; 346089C71BEFD0A500C90DB5 /* GLRenderData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GLRenderData.m; sourceTree = "<group>"; };
346089C81BEFD0A500C90DB5 /* GLShader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GLShader.h; sourceTree = "<group>"; }; 346089C81BEFD0A500C90DB5 /* GLShader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GLShader.h; sourceTree = "<group>"; };
346089C91BEFD0A500C90DB5 /* GLShader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GLShader.m; sourceTree = "<group>"; }; 346089C91BEFD0A500C90DB5 /* GLShader.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.objc; path = GLShader.m; sourceTree = "<group>"; tabWidth = 2; };
346089CA1BEFD0A500C90DB5 /* GLTexture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GLTexture.h; sourceTree = "<group>"; }; 346089CA1BEFD0A500C90DB5 /* GLTexture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GLTexture.h; sourceTree = "<group>"; };
346089CB1BEFD0A500C90DB5 /* GLTexture.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.objc; path = GLTexture.m; sourceTree = "<group>"; tabWidth = 2; }; 346089CB1BEFD0A500C90DB5 /* GLTexture.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.objc; path = GLTexture.m; sourceTree = "<group>"; tabWidth = 2; };
346089CC1BEFD0A500C90DB5 /* RCTConvert+GLData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTConvert+GLData.h"; sourceTree = "<group>"; }; 346089CC1BEFD0A500C90DB5 /* RCTConvert+GLData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTConvert+GLData.h"; sourceTree = "<group>"; };
346089CD1BEFD0A500C90DB5 /* RCTConvert+GLData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+GLData.m"; sourceTree = "<group>"; }; 346089CD1BEFD0A500C90DB5 /* RCTConvert+GLData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+GLData.m"; sourceTree = "<group>"; };
346089CE1BEFD0A500C90DB5 /* RNGLContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNGLContext.h; sourceTree = "<group>"; }; 346089CE1BEFD0A500C90DB5 /* RNGLContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNGLContext.h; sourceTree = "<group>"; };
346089CF1BEFD0A500C90DB5 /* RNGLContext.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.objc; path = RNGLContext.m; sourceTree = "<group>"; tabWidth = 2; }; 346089CF1BEFD0A500C90DB5 /* RNGLContext.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.objc; path = RNGLContext.m; sourceTree = "<group>"; tabWidth = 2; };
34C990401C34939C002F49FC /* RCTConvert+CaptureConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTConvert+CaptureConfig.h"; sourceTree = "<group>"; };
34C990411C34939C002F49FC /* RCTConvert+CaptureConfig.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+CaptureConfig.m"; sourceTree = "<group>"; tabWidth = 2; };
34C990451C34941C002F49FC /* CaptureConfig.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CaptureConfig.h; sourceTree = "<group>"; };
34C990461C349422002F49FC /* CaptureConfig.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.objc; path = CaptureConfig.m; sourceTree = "<group>"; tabWidth = 2; };
4107012F1ACB723B00C6AA39 /* libRNGL.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNGL.a; sourceTree = BUILT_PRODUCTS_DIR; }; 4107012F1ACB723B00C6AA39 /* libRNGL.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNGL.a; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */ /* End PBXFileReference section */
...@@ -92,6 +98,10 @@ ...@@ -92,6 +98,10 @@
346089CB1BEFD0A500C90DB5 /* GLTexture.m */, 346089CB1BEFD0A500C90DB5 /* GLTexture.m */,
346089CC1BEFD0A500C90DB5 /* RCTConvert+GLData.h */, 346089CC1BEFD0A500C90DB5 /* RCTConvert+GLData.h */,
346089CD1BEFD0A500C90DB5 /* RCTConvert+GLData.m */, 346089CD1BEFD0A500C90DB5 /* RCTConvert+GLData.m */,
34C990461C349422002F49FC /* CaptureConfig.m */,
34C990451C34941C002F49FC /* CaptureConfig.h */,
34C990401C34939C002F49FC /* RCTConvert+CaptureConfig.h */,
34C990411C34939C002F49FC /* RCTConvert+CaptureConfig.m */,
346089CE1BEFD0A500C90DB5 /* RNGLContext.h */, 346089CE1BEFD0A500C90DB5 /* RNGLContext.h */,
346089CF1BEFD0A500C90DB5 /* RNGLContext.m */, 346089CF1BEFD0A500C90DB5 /* RNGLContext.m */,
410701301ACB723B00C6AA39 /* Products */, 410701301ACB723B00C6AA39 /* Products */,
...@@ -161,10 +171,12 @@ ...@@ -161,10 +171,12 @@
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
34C990421C34939C002F49FC /* RCTConvert+CaptureConfig.m in Sources */,
346089D31BEFD0A500C90DB5 /* GLFBO.m in Sources */, 346089D31BEFD0A500C90DB5 /* GLFBO.m in Sources */,
346089DA1BEFD0A500C90DB5 /* RNGLContext.m in Sources */, 346089DA1BEFD0A500C90DB5 /* RNGLContext.m in Sources */,
346089D21BEFD0A500C90DB5 /* GLData.m in Sources */, 346089D21BEFD0A500C90DB5 /* GLData.m in Sources */,
346089D91BEFD0A500C90DB5 /* RCTConvert+GLData.m in Sources */, 346089D91BEFD0A500C90DB5 /* RCTConvert+GLData.m in Sources */,
34C990471C349422002F49FC /* CaptureConfig.m in Sources */,
346089D51BEFD0A500C90DB5 /* GLImageData.m in Sources */, 346089D51BEFD0A500C90DB5 /* GLImageData.m in Sources */,
346089D41BEFD0A500C90DB5 /* GLImage.m in Sources */, 346089D41BEFD0A500C90DB5 /* GLImage.m in Sources */,
346089D61BEFD0A500C90DB5 /* GLRenderData.m in Sources */, 346089D61BEFD0A500C90DB5 /* GLRenderData.m in Sources */,
......
...@@ -45,9 +45,73 @@ RCT_EXPORT_MODULE() ...@@ -45,9 +45,73 @@ RCT_EXPORT_MODULE()
return _context; return _context;
} }
- (void)_addShader:(nonnull NSNumber *)id
withConfig:(NSDictionary *)config
withOnCompile:(RCTResponseSenderBlock)onCompile
{
NSString *frag = [RCTConvert NSString:config[@"frag"]];
NSString *name = [RCTConvert NSString:config[@"name"]];
if (!frag) {
RCTLogError(@"Shader '%@': missing frag field", name);
return;
}
GLShader *shader = [[GLShader alloc] initWithContext:_context withName:name withVert:fullViewportVert withFrag:frag];
NSError *error;
bool success = [shader ensureCompiles:&error];
if (onCompile) {
if (!success) {
onCompile(@[error.domain]);
}
else {
onCompile(@[[NSNull null],
@{
@"uniforms": shader.uniformTypes
}]);
}
}
else {
if (!success) {
RCTLogError(@"Shader '%@': %@", name, error.domain);
}
}
_shaders[id] = shader;
}
static NSString* fullViewportVert = @"attribute vec2 position;varying vec2 uv;void main() {gl_Position = vec4(position,0.0,1.0);uv = vec2(0.5, 0.5) * (position+vec2(1.0, 1.0));}"; static NSString* fullViewportVert = @"attribute vec2 position;varying vec2 uv;void main() {gl_Position = vec4(position,0.0,1.0);uv = vec2(0.5, 0.5) * (position+vec2(1.0, 1.0));}";
RCT_EXPORT_METHOD(addShader:(nonnull NSNumber *)id withConfig:(NSDictionary *)config) { NSString* glTypeString (int type) {
switch (type) {
case GL_FLOAT: return @"float";
case GL_FLOAT_VEC2: return @"vec2";
case GL_FLOAT_VEC3: return @"vec3";
case GL_FLOAT_VEC4: return @"vec4";
case GL_INT: return @"int";
case GL_INT_VEC2: return @"ivec2";
case GL_INT_VEC3: return @"ivec3";
case GL_INT_VEC4: return @"ivec4";
case GL_BOOL: return @"bool";
case GL_BOOL_VEC2: return @"bvec2";
case GL_BOOL_VEC3: return @"bvec3";
case GL_BOOL_VEC4: return @"bvec4";
case GL_FLOAT_MAT2: return @"mat2";
case GL_FLOAT_MAT3: return @"mat3";
case GL_FLOAT_MAT4: return @"mat4";
case GL_SAMPLER_2D: return @"sampler2D";
case GL_SAMPLER_CUBE: return @"samplerCube";
}
return @"";
}
NSDictionary* glTypesString (NSDictionary *types) {
NSMutableDictionary *dict = types.mutableCopy;
for (NSString *key in [dict allKeys]) {
dict[key] = glTypeString([dict[key] intValue]);
}
return dict;
}
RCT_EXPORT_METHOD(addShader:(nonnull NSNumber *)id
withConfig:(NSDictionary *)config
withOnCompile:(RCTResponseSenderBlock)onCompile) {
NSString *frag = [RCTConvert NSString:config[@"frag"]]; NSString *frag = [RCTConvert NSString:config[@"frag"]];
NSString *name = [RCTConvert NSString:config[@"name"]]; NSString *name = [RCTConvert NSString:config[@"name"]];
if (!frag) { if (!frag) {
...@@ -55,9 +119,36 @@ RCT_EXPORT_METHOD(addShader:(nonnull NSNumber *)id withConfig:(NSDictionary *)co ...@@ -55,9 +119,36 @@ RCT_EXPORT_METHOD(addShader:(nonnull NSNumber *)id withConfig:(NSDictionary *)co
return; return;
} }
GLShader *shader = [[GLShader alloc] initWithContext:_context withName:name withVert:fullViewportVert withFrag:frag]; GLShader *shader = [[GLShader alloc] initWithContext:_context withName:name withVert:fullViewportVert withFrag:frag];
NSError *error;
bool success = [shader ensureCompiles:&error];
if (onCompile) {
if (!success) {
onCompile(@[error.domain]);
}
else {
onCompile(@[[NSNull null],
@{
@"uniforms": glTypesString(shader.uniformTypes)
}]);
}
}
else {
if (!success) {
RCTLogError(@"Shader '%@': %@", name, error.domain);
}
}
_shaders[id] = shader; _shaders[id] = shader;
} }
RCT_EXPORT_METHOD(removeShader:(nonnull NSNumber *)id) {
GLShader *shader = [_shaders objectForKey:id];
if (!shader) {
RCTLogError(@"removeShader(%@): shader does not exist", id);
return;
}
[_shaders removeObjectForKey:id];
}
@end @end
@implementation RCTBridge (RNGLContext) @implementation RCTBridge (RNGLContext)
......
{ {
"name": "gl-react-native", "name": "gl-react-native",
"version": "2.17.8", "version": "2.18.0-rc",
"description": "OpenGL bindings for react-native to implement complex effects over images and components, in the descriptive VDOM paradigm", "description": "OpenGL bindings for react-native to implement complex effects over images and components, in the descriptive VDOM paradigm",
"repository": { "repository": {
"type": "git", "type": "git",
...@@ -19,15 +19,10 @@ ...@@ -19,15 +19,10 @@
"author": "Project September <tech@projectseptember.com>", "author": "Project September <tech@projectseptember.com>",
"license": "MIT", "license": "MIT",
"peerDependencies": { "peerDependencies": {
"react-native": ">= 0.17.0 <0.18.0", "react-native": "0.18.0-rc",
"gl-react": ">= 2.0.3 <2.1.0" "gl-react": "^2.1.0"
}, },
"dependencies": { "dependencies": {
"invariant": "2.2.0" "invariant": "2.2.0"
},
"devDependencies": {
"babel-eslint": "^4.1.6",
"eslint": "^1.9.0",
"eslint-plugin-react": "^3.8.0"
} }
} }
...@@ -12,4 +12,4 @@ See README install instructions. ...@@ -12,4 +12,4 @@ See README install instructions.
React.NativeModules.UIManager.GLCanvas is %s`, GLCanvas); React.NativeModules.UIManager.GLCanvas is %s`, GLCanvas);
const {Commands} = GLCanvas; const {Commands} = GLCanvas;
module.exports = handle => UIManager.dispatchViewManagerCommand(handle, Commands.captureFrame, []); module.exports = (handle, config) => UIManager.dispatchViewManagerCommand(handle, Commands.captureFrame, [ config ]);
...@@ -10,4 +10,4 @@ See README install instructions. ...@@ -10,4 +10,4 @@ See README install instructions.
React.NativeModules.GLCanvasManager is %s`, GLCanvasManager); React.NativeModules.GLCanvasManager is %s`, GLCanvasManager);
module.exports = handle => GLCanvasManager.capture(handle); module.exports = (handle, config) => GLCanvasManager.capture(handle, config);
const invariant = require("invariant");
const React = require("react-native"); const React = require("react-native");
const { const {
Component, Component,
...@@ -6,6 +7,9 @@ const { ...@@ -6,6 +7,9 @@ const {
const captureFrame = require("./GLCanvas.captureFrame"); const captureFrame = require("./GLCanvas.captureFrame");
const serializeOption = config =>
config.format + ":" + config.type + ":" + config.quality;
const GLCanvasNative = requireNativeComponent("GLCanvas", GLCanvas, { const GLCanvasNative = requireNativeComponent("GLCanvas", GLCanvas, {
nativeOnly: { nativeOnly: {
onGLChange: true, onGLChange: true,
...@@ -25,21 +29,85 @@ function defer() { ...@@ -25,21 +29,85 @@ function defer() {
} }
class GLCanvas extends Component { class GLCanvas extends Component {
captureFrame (cb) {
const promise = ( componentWillMount () {
this._pendingCaptureFrame || // use pending capture OR create a new captureFrame pending this._pendingCaptureFrame = {};
(captureFrame(React.findNodeHandle(this.refs.native)), this._pendingCaptureFrame = defer()) }
).promise;
if (typeof cb === "function") { componentWillUnmount () {
console.warn("GLSurface: callback parameter of captureFrame is deprecated, use the returned promise instead"); // eslint-disable-line no-console Object.keys(this._pendingCaptureFrame).forEach(key =>
promise.then(cb); this._pendingCaptureFrame[key].reject(new Error("GLCanvas is unmounting")));
this._pendingCaptureFrame = null;
}
addPendingCaptureFrame (config) {
const key = serializeOption(config);
return this._pendingCaptureFrame[key] || (
(captureFrame(React.findNodeHandle(this.refs.native), config),
this._pendingCaptureFrame[key] = defer())
);
}
captureFrame (configArg) {
let config;
if (configArg) {
invariant(typeof configArg==="object", "captureFrame takes an object option in parameter");
let nb = 0;
if ("format" in configArg) {
invariant(
typeof configArg.format === "string",
"captureFrame({format}): format must be a string (e.g: 'base64'), Got: '%s'",
configArg.format);
if (configArg.format === "file") invariant(
typeof configArg.filePath === "string" && configArg.filePath,
"captureFrame({filePath}): filePath must be defined when using 'file' format and be an non-empty string, Got: '%s'",
configArg.filePath);
nb ++;
}
if ("type" in configArg) {
invariant(
typeof configArg.type === "string",
"captureFrame({type}): type must be a string (e.g: 'png', 'jpg'), Got: '%s'",
configArg.type);
nb ++;
}
if ("quality" in configArg) {
invariant(
typeof configArg.quality === "number" &&
configArg.quality >= 0 &&
configArg.quality <= 1,
"captureFrame({quality}): quality must be a number between 0 and 1, Got: '%s'",
configArg.quality);
nb ++;
}
if ("filePath" in configArg) {
nb ++;
}
const keys = Object.keys(configArg);
invariant(keys.length === nb, "captureFrame(config): config must be an object with {format, type, quality, filePath}, found some invalid keys in '%s'", keys);
config = configArg;
} }
return promise; return this.addPendingCaptureFrame({
format: "base64",
type: "png",
quality: 1,
filePath: "",
...config
}).promise;
} }
onGLCaptureFrame = ({ nativeEvent: {frame} }) => {
this._pendingCaptureFrame.resolve(frame); onGLCaptureFrame = ({ nativeEvent: { error, result, config } }) => {
this._pendingCaptureFrame = undefined; const key = serializeOption(config);
invariant(key in this._pendingCaptureFrame, "capture '%s' is not scheduled in this._pendingCaptureFrame", key);
if (error) {
this._pendingCaptureFrame[key].reject(error);
}
else {
this._pendingCaptureFrame[key].resolve(result);
}
delete this._pendingCaptureFrame[key];
}; };
render () { render () {
const { width, height, onLoad, onProgress, eventsThrough, ...restProps } = this.props; const { width, height, onLoad, onProgress, eventsThrough, ...restProps } = this.props;
return <GLCanvasNative return <GLCanvasNative
......
const {createShaders} = require("gl-react");
const { NativeModules: { RNGLContext } } = require("react-native");
module.exports = createShaders(function (id, shader) {
RNGLContext.addShader(id, shader);
});
...@@ -2,11 +2,13 @@ const invariant = require("invariant"); ...@@ -2,11 +2,13 @@ const invariant = require("invariant");
const {createSurface} = require("gl-react"); const {createSurface} = require("gl-react");
invariant(typeof createSurface === "function", "gl-react createSurface is not a function. Check your gl-react dependency"); invariant(typeof createSurface === "function", "gl-react createSurface is not a function. Check your gl-react dependency");
const React = require("react-native"); const React = require("react-native");
const GLCanvas = require("./GLCanvas");
const { const {
View, View,
PixelRatio
} = React; } = React;
const GLCanvas = require("./GLCanvas");
const getPixelRatio = props => props.scale || PixelRatio.get();
function renderVcontent (width, height, id, children, { visibleContent }) { function renderVcontent (width, height, id, children, { visibleContent }) {
const childrenStyle = { const childrenStyle = {
...@@ -40,4 +42,4 @@ function renderVcontainer ({ style, width, height, visibleContent, eventsThrough ...@@ -40,4 +42,4 @@ function renderVcontainer ({ style, width, height, visibleContent, eventsThrough
</View>; </View>;
} }
module.exports = createSurface(renderVcontainer, renderVcontent, renderVGL); module.exports = createSurface(renderVcontainer, renderVcontent, renderVGL, getPixelRatio);
...@@ -10,8 +10,8 @@ See README install instructions. ...@@ -10,8 +10,8 @@ See README install instructions.
React.NativeModules.RNGLContext is %s`, RNGLContext); React.NativeModules.RNGLContext is %s`, RNGLContext);
// Hook Shaders to RNGLContext // Hook Shaders to RNGLContext
Shaders.list().map(id => RNGLContext.addShader(id, Shaders.get(id))); Shaders.on("add", (id, shader, onCompile) => RNGLContext.addShader(id, shader, onCompile));
Shaders.on("add", (id, shader) => RNGLContext.addShader(id, shader)); Shaders.on("remove", id => RNGLContext.removeShader(id));
module.exports = { module.exports = {
Surface Surface
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment