Commit c75cf213 authored by Gaëtan Renaudeau's avatar Gaëtan Renaudeau

WIP

parent ca1d7889
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.projectseptember.RNGL"> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.projectseptember.RNGL">
<uses-feature android:glEsVersion="0x00020000" android:required="true" /> <uses-feature android:glEsVersion="0x00020000" android:required="true" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest> </manifest>
package com.projectseptember.RNGL; package com.projectseptember.RNGL;
import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.ConfigurationInfo;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.util.Log; import android.util.Log;
...@@ -15,59 +12,60 @@ import com.facebook.react.uimanager.ReactProp; ...@@ -15,59 +12,60 @@ import com.facebook.react.uimanager.ReactProp;
public class GLCanvasManager extends SimpleViewManager<GLCanvas> { public class GLCanvasManager extends SimpleViewManager<GLCanvas> {
public static final String REACT_CLASS = "GLCanvas"; public static final String REACT_CLASS = "GLCanvas";
@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);
} }
@ReactProp(name="renderId") @ReactProp(name="renderId")
public void setRenderId (GLCanvas view, int renderId) { public void setRenderId (GLCanvas view, int renderId) {
view.setRenderId(renderId); view.setRenderId(renderId);
} }
@ReactProp(name="opaque") @ReactProp(name="opaque")
public void setOpaque(GLCanvas view, boolean opaque) { public void setOpaque (GLCanvas view, boolean opaque) {
view.setOpaque(opaque); view.setOpaque(opaque);
} }
@ReactProp(name="autoRedraw") @ReactProp(name="autoRedraw")
public void setAutoRedraw(GLCanvas view, boolean autoRedraw) { public void setAutoRedraw (GLCanvas view, boolean autoRedraw) {
view.setAutoRedraw(autoRedraw); view.setAutoRedraw(autoRedraw);
} }
@ReactProp(name="eventsThrough") @ReactProp(name="eventsThrough")
public void setEventsThrough(GLCanvas view, boolean eventsThrough) { public void setEventsThrough (GLCanvas view, boolean eventsThrough) {
view.setEventsThrough(eventsThrough); view.setEventsThrough(eventsThrough);
} }
@ReactProp(name="visibleContent") @ReactProp(name="visibleContent")
public void setVisibleContent(GLCanvas view, boolean visibleContent) { public void setVisibleContent (GLCanvas view, boolean visibleContent) {
view.setVisibleContent(visibleContent); view.setVisibleContent(visibleContent);
} }
@ReactProp(name="captureNextFrameId") @ReactProp(name="captureNextFrameId")
public void setCaptureNextFrameId(GLCanvas view, int captureNextFrameId) { public void setCaptureNextFrameId (GLCanvas view, int captureNextFrameId) {
view.setCaptureNextFrameId(captureNextFrameId); view.setCaptureNextFrameId(captureNextFrameId);
} }
@ReactProp(name="data") @ReactProp(name="data")
public void setData(GLCanvas view, @Nullable ReadableMap glData) { public void setData (GLCanvas view, @Nullable ReadableMap data) {
view.setData(glData == null ? null : GLData.fromMap(glData)); view.setData(data == null ? null : GLData.fromMap(data));
} }
@ReactProp(name="imagesToPreload") @ReactProp(name="imagesToPreload")
public void setImagesToPreload(GLCanvas view, @Nullable ReadableArray imageToPreload) { public void setImagesToPreload (GLCanvas view, @Nullable ReadableArray imageToPreload) {
view.setImagesToPreload(imageToPreload); view.setImagesToPreload(imageToPreload);
} }
@Override @Override
public String getName() { public String getName() {
return REACT_CLASS; return REACT_CLASS;
} }
@Override @Override
public GLCanvas createViewInstance(ThemedReactContext context) { public GLCanvas createViewInstance (ThemedReactContext context) {
return new GLCanvas(context); Log.i("GLCanvas", "createViewInstance...");
} return new GLCanvas(context);
}
} }
package com.projectseptember.RNGL; package com.projectseptember.RNGL;
import android.util.Log;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.logging.Logger;
import static android.opengl.GLES20.*; import static android.opengl.GLES20.*;
public class GLFBO { public class GLFBO {
private static final Logger logger = Logger.getLogger(GLFBO.class.getName());
public final List<GLTexture> color = new ArrayList<>(); public final List<GLTexture> color = new ArrayList<>();
private int handle; private int handle;
private int width = 0; private int width = 0;
...@@ -18,10 +17,11 @@ public class GLFBO { ...@@ -18,10 +17,11 @@ public class GLFBO {
GLTexture texture = new GLTexture(); GLTexture texture = new GLTexture();
texture.bind(); texture.bind();
texture.setShape(width, height); texture.setShape(width, height);
glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, texture.handle, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, texture.getHandle(), 0);
return texture; return texture;
} }
/*
int initRenderBuffer (int width, int height, int component, int attachment) int initRenderBuffer (int width, int height, int component, int attachment)
{ {
int[] handleArr = new int[1]; int[] handleArr = new int[1];
...@@ -32,7 +32,9 @@ public class GLFBO { ...@@ -32,7 +32,9 @@ public class GLFBO {
glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, handle); glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, handle);
return handle; return handle;
} }
*/
/*
class FBOState { class FBOState {
private int fbo; private int fbo;
...@@ -55,9 +57,11 @@ public class GLFBO { ...@@ -55,9 +57,11 @@ public class GLFBO {
glBindTexture(GL_FRAMEBUFFER, tex); glBindTexture(GL_FRAMEBUFFER, tex);
} }
} }
*/
public GLFBO() { public GLFBO() {
FBOState state = new FBOState(); Log.i("GLFBO", "new");
//FBOState state = new FBOState();
int[] handleArr = new int[1]; int[] handleArr = new int[1];
glGenFramebuffers(1, handleArr, 0); glGenFramebuffers(1, handleArr, 0);
...@@ -70,12 +74,12 @@ public class GLFBO { ...@@ -70,12 +74,12 @@ public class GLFBO {
for(int i=0; i<numColors; ++i) { for(int i=0; i<numColors; ++i) {
color.add(initTexture(width, height, GL_COLOR_ATTACHMENT0 + i)); color.add(initTexture(width, height, GL_COLOR_ATTACHMENT0 + i));
} }
// state.restore();
state.restore();
} }
@Override @Override
protected void finalize() throws Throwable { protected void finalize() throws Throwable {
Log.i("GLFBO", "finalize");
super.finalize(); super.finalize();
int[] handleArr = new int[] { handle }; int[] handleArr = new int[] { handle };
glDeleteFramebuffers(1, handleArr, 0); glDeleteFramebuffers(1, handleArr, 0);
...@@ -87,40 +91,37 @@ public class GLFBO { ...@@ -87,40 +91,37 @@ public class GLFBO {
if(status != GL_FRAMEBUFFER_COMPLETE) { if(status != GL_FRAMEBUFFER_COMPLETE) {
switch (status) { switch (status) {
case GL_FRAMEBUFFER_UNSUPPORTED: case GL_FRAMEBUFFER_UNSUPPORTED:
logger.severe("Framebuffer unsupported"); throw new RuntimeException("Framebuffer unsupported");
break;
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
logger.severe("Framebuffer incomplete attachment"); throw new RuntimeException("Framebuffer incomplete attachment");
break;
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
logger.severe("Framebuffer incomplete dimensions"); throw new RuntimeException("Framebuffer incomplete dimensions");
break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
logger.severe("Framebuffer incomplete missing attachment"); throw new RuntimeException("Framebuffer incomplete missing attachment");
break;
default: default:
logger.severe("Failed to create framebuffer: " + status); throw new RuntimeException("Failed to create framebuffer: " + status);
} }
} }
} }
public void bind () { public void bind () {
Log.i("GLFBO", "bind");
glBindFramebuffer(GL_FRAMEBUFFER, handle); glBindFramebuffer(GL_FRAMEBUFFER, handle);
glViewport(0, 0, width, height); glViewport(0, 0, width, height);
} }
public void setShape(int w, int h) { public void setShape(int w, int h) {
Log.i("GLFBO", "setShape "+w+" "+h);
if (w == width && h == height) return; if (w == width && h == height) return;
int[] maxFBOSize = new int[1]; int[] maxFBOSize = new int[1];
glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, maxFBOSize, 0); glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, maxFBOSize, 0);
if( w < 0 || w > maxFBOSize[0] || h < 0 || h > maxFBOSize[0]) { if( w < 0 || w > maxFBOSize[0] || h < 0 || h > maxFBOSize[0]) {
logger.severe("Can't resize framebuffer. Invalid dimensions"); throw new IllegalArgumentException("Can't resize framebuffer. Invalid dimensions");
return;
} }
width = w; width = w;
height = h; height = h;
FBOState state = new FBOState(); //FBOState state = new FBOState();
for (GLTexture clr: color) { for (GLTexture clr: color) {
clr.setShape(w, h); clr.setShape(w, h);
...@@ -129,6 +130,6 @@ public class GLFBO { ...@@ -129,6 +130,6 @@ public class GLFBO {
glBindFramebuffer(GL_FRAMEBUFFER, handle); glBindFramebuffer(GL_FRAMEBUFFER, handle);
checkStatus(); checkStatus();
state.restore(); //state.restore();
} }
} }
...@@ -5,18 +5,13 @@ import android.database.Cursor; ...@@ -5,18 +5,13 @@ import android.database.Cursor;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.graphics.Matrix; import android.graphics.Matrix;
import android.media.ExifInterface;
import android.net.Uri; import android.net.Uri;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.provider.MediaStore; import android.provider.MediaStore;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import com.facebook.common.util.UriUtil; import com.facebook.common.util.UriUtil;
import com.facebook.drawee.interfaces.DraweeController;
import com.facebook.imagepipeline.request.ImageRequest;
import com.facebook.imagepipeline.request.ImageRequestBuilder;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.URL; import java.net.URL;
...@@ -216,29 +211,25 @@ public class GLImage { ...@@ -216,29 +211,25 @@ public class GLImage {
if (bitmap == null) { if (bitmap == null) {
return null; return null;
} }
bitmap = rotateImage(bitmap);
return bitmap;
}
Bitmap transformedBitmap;
Matrix matrix = new Matrix();
private Bitmap rotateImage(final Bitmap bitmap) {
if (bitmap == null) {
return null;
}
Bitmap rotatedBitmap = bitmap;
try { try {
int orientation = getImageOrientation(); int orientation = getImageOrientation();
if (orientation != 0) { if (orientation != 0) {
Matrix matrix = new Matrix();
matrix.postRotate(orientation); matrix.postRotate(orientation);
rotatedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
bitmap.getHeight(), matrix, true);
bitmap.recycle();
} }
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
return rotatedBitmap;
matrix.postScale(1, -1);
transformedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
bitmap.recycle();
return transformedBitmap;
} }
protected abstract int getImageOrientation() throws IOException; protected abstract int getImageOrientation() throws IOException;
......
package com.projectseptember.RNGL; package com.projectseptember.RNGL;
import static android.opengl.GLES20.*; import static android.opengl.GLES20.*;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
...@@ -8,12 +9,9 @@ import java.nio.FloatBuffer; ...@@ -8,12 +9,9 @@ import java.nio.FloatBuffer;
import java.nio.IntBuffer; import java.nio.IntBuffer;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.logging.Logger;
public class GLShader { public class GLShader {
private static final Logger logger = Logger.getLogger(GLShader.class.getName());
private final String name; private final String name;
private final String vert; private final String vert;
private final String frag; private final String frag;
...@@ -38,10 +36,15 @@ public class GLShader { ...@@ -38,10 +36,15 @@ public class GLShader {
} }
} }
public void runtimeException (String msg) {
throw new RuntimeException("Shader '"+name+"': "+msg);
}
public void bind () { public void bind () {
ensureCompile();
if (!glIsProgram(program)) { if (!glIsProgram(program)) {
logger.severe("Shader '"+name+"': not a program!"); runtimeException("not a program");
return;
} }
glUseProgram(program); glUseProgram(program);
glBindBuffer(GL_ARRAY_BUFFER, buffer[0]); glBindBuffer(GL_ARRAY_BUFFER, buffer[0]);
...@@ -55,7 +58,7 @@ public class GLShader { ...@@ -55,7 +58,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);
logger.severe("Shader '" + name + "': Validation failed " + glGetProgramInfoLog(program)); runtimeException("Validation failed " + glGetProgramInfoLog(program));
} }
} }
...@@ -86,7 +89,7 @@ public class GLShader { ...@@ -86,7 +89,7 @@ public class GLShader {
glUniformMatrix4fv(uniformLocations.get(name), 1, false, buf); glUniformMatrix4fv(uniformLocations.get(name), 1, false, buf);
break; break;
default: default:
throw new Error("Unsupported case: uniform '" + name + "' type: " + type); runtimeException("Unsupported case: uniform '" + name + "' type: " + type);
} }
} }
public void setUniform (String name, IntBuffer buf, int type) { public void setUniform (String name, IntBuffer buf, int type) {
...@@ -104,7 +107,7 @@ public class GLShader { ...@@ -104,7 +107,7 @@ public class GLShader {
glUniform4iv(uniformLocations.get(name), 1, buf); glUniform4iv(uniformLocations.get(name), 1, buf);
break; break;
default: default:
throw new Error("Unsupported case: uniform '"+name+"' type: "+type); runtimeException("Unsupported case: uniform '"+name+"' type: "+type);
} }
} }
...@@ -117,14 +120,14 @@ public class GLShader { ...@@ -117,14 +120,14 @@ public class GLShader {
} }
private static int compileShader (String name, String code, int shaderType) { private int compileShader (String code, int shaderType) {
int shaderHandle = glCreateShader(shaderType); int shaderHandle = glCreateShader(shaderType);
glShaderSource(shaderHandle, code); glShaderSource(shaderHandle, code);
glCompileShader(shaderHandle); glCompileShader(shaderHandle);
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) {
logger.severe("Shader '"+name+"' failed to compile: "+glGetShaderInfoLog(shaderHandle)); runtimeException("failed to compile: " + glGetShaderInfoLog(shaderHandle));
return -1; return -1;
} }
return shaderHandle; return shaderHandle;
...@@ -149,10 +152,10 @@ public class GLShader { ...@@ -149,10 +152,10 @@ public class GLShader {
} }
private void makeProgram () { private void makeProgram () {
int vertex = compileShader(name, vert, GL_VERTEX_SHADER); int vertex = compileShader(vert, GL_VERTEX_SHADER);
if (vertex == -1) return; if (vertex == -1) return;
int fragment = compileShader(name, frag, GL_FRAGMENT_SHADER); int fragment = compileShader(frag, GL_FRAGMENT_SHADER);
if (fragment == -1) return; if (fragment == -1) return;
program = glCreateProgram(); program = glCreateProgram();
...@@ -163,12 +166,13 @@ public class GLShader { ...@@ -163,12 +166,13 @@ 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) {
logger.severe("Shader '"+name+"': Linking failed "+glGetProgramInfoLog(program)); runtimeException("Linking failed "+glGetProgramInfoLog(program));
return;
} }
glUseProgram(program); glUseProgram(program);
validate();
computeMeta(); computeMeta();
pointerLoc = glGetAttribLocation(program, "position"); pointerLoc = glGetAttribLocation(program, "position");
......
...@@ -3,16 +3,23 @@ package com.projectseptember.RNGL; ...@@ -3,16 +3,23 @@ package com.projectseptember.RNGL;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.Matrix;
import android.opengl.GLUtils; import android.opengl.GLUtils;
import android.view.View; import android.view.View;
import static android.opengl.GLES20.*; import static android.opengl.GLES20.*;
public class GLTexture { public class GLTexture {
public int handle; private int handle;
public Bitmap bitmapCurrentlyUploaded = null; private Bitmap bitmapCurrentlyUploaded = null;
private void dealloc () { public GLTexture () {
makeTexture();
}
@Override
protected void finalize() throws Throwable {
super.finalize();
int[] handleArr = new int[] { handle }; int[] handleArr = new int[] { handle };
glDeleteTextures(1, handleArr, 0); glDeleteTextures(1, handleArr, 0);
bitmapCurrentlyUploaded = null; bitmapCurrentlyUploaded = null;
...@@ -66,16 +73,27 @@ public class GLTexture { ...@@ -66,16 +73,27 @@ public class GLTexture {
setPixels(bitmap); setPixels(bitmap);
} }
public void setPixelsWithView (View view) { public void setShape (int width, int height) {
Bitmap bitmap = Bitmap.createBitmap( view.getLayoutParams().width, view.getLayoutParams().height, Bitmap.Config.ARGB_8888); bind();
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, null);
}
public static Bitmap captureView (View view) {
int w = view.getWidth();
int h = view.getHeight();
if (w <= 0 || h <= 0) return Bitmap.createBitmap(2, 2, Bitmap.Config.ARGB_8888);
Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap); Canvas canvas = new Canvas(bitmap);
view.layout(view.getLeft(), view.getTop(), view.getRight(), view.getBottom()); view.layout(0, 0, view.getWidth(), view.getHeight());
view.draw(canvas); view.draw(canvas);
setPixels(bitmap); Matrix matrix = new Matrix();
matrix.postScale(1, -1);
Bitmap transformedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
bitmap.recycle();
return transformedBitmap;
} }
public void setShape (int width, int height) { public int getHandle() {
bind(); return handle;
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, null);
} }
} }
package com.projectseptember.RNGL; package com.projectseptember.RNGL;
import android.opengl.GLSurfaceView;
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;
......
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