From c75cf2135c0ce26e127d7e29b7e19e6b8613417e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Renaudeau?= Date: Sun, 15 Nov 2015 23:22:02 +0100 Subject: [PATCH] WIP --- android/src/main/AndroidManifest.xml | 2 + .../com/projectseptember/RNGL/GLCanvas.java | 165 +++++++++++------- .../RNGL/GLCanvasManager.java | 94 +++++----- .../java/com/projectseptember/RNGL/GLFBO.java | 41 ++--- .../com/projectseptember/RNGL/GLImage.java | 27 +-- .../com/projectseptember/RNGL/GLShader.java | 32 ++-- .../com/projectseptember/RNGL/GLTexture.java | 38 ++-- .../projectseptember/RNGL/RNGLContext.java | 2 - 8 files changed, 227 insertions(+), 174 deletions(-) diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml index c170c5b..f3a988f 100644 --- a/android/src/main/AndroidManifest.xml +++ b/android/src/main/AndroidManifest.xml @@ -1,3 +1,5 @@ + + diff --git a/android/src/main/java/com/projectseptember/RNGL/GLCanvas.java b/android/src/main/java/com/projectseptember/RNGL/GLCanvas.java index 7638d65..9a5815d 100644 --- a/android/src/main/java/com/projectseptember/RNGL/GLCanvas.java +++ b/android/src/main/java/com/projectseptember/RNGL/GLCanvas.java @@ -2,10 +2,11 @@ package com.projectseptember.RNGL; import static android.opengl.GLES20.*; +import android.graphics.Bitmap; import android.graphics.PixelFormat; import android.opengl.GLSurfaceView; import android.util.DisplayMetrics; -import android.view.View; +import android.util.Log; import android.view.ViewGroup; import com.facebook.react.bridge.Arguments; @@ -27,21 +28,18 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Queue; -import java.util.logging.Logger; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; public class GLCanvas extends GLSurfaceView implements GLSurfaceView.Renderer, RunInGLThread { - private static final Logger logger = Logger.getLogger(GLCanvas.class.getName()); - private ReactContext reactContext; private RNGLContext rnglContext; private boolean preloadingDone = false; private boolean deferredRendering = false; private GLRenderData renderData; - private int[] defaultFBO; + private int defaultFBO; private int nbContentTextures; private int renderId; @@ -57,6 +55,7 @@ public class GLCanvas extends GLSurfaceView implements GLSurfaceView.Renderer, R private Map images = new HashMap<>(); private List contentTextures = new ArrayList<>(); + private List contentBitmaps = new ArrayList<>(); private Map shaders = new HashMap<>(); private Map fbos = new HashMap<>(); @@ -64,14 +63,21 @@ public class GLCanvas extends GLSurfaceView implements GLSurfaceView.Renderer, R public GLCanvas(ThemedReactContext context) { super(context); reactContext = context; - this.rnglContext = context.getNativeModule(RNGLContext.class); - this.setEGLContextClientVersion(2); - this.setEGLConfigChooser(8, 8, 8, 8, 16, 0); - this.getHolder().setFormat(PixelFormat.RGBA_8888); - this.setRenderer(this); - this.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); - this.requestRender(); + rnglContext = context.getNativeModule(RNGLContext.class); + setEGLContextClientVersion(2); + setEGLConfigChooser(8, 8, 8, 8, 16, 0); + getHolder().setFormat(PixelFormat.RGBA_8888); + setRenderer(this); + setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); + Log.i("GLCanvas", "created"); + } + @Override + protected void onAttachedToWindow() { + Log.i("GLCanvas", "onAttachedToWindow"); + super.onAttachedToWindow(); + syncContentBitmaps(); + requestRender(); preloadingDone = true; // TODO } @@ -87,6 +93,7 @@ public class GLCanvas extends GLSurfaceView implements GLSurfaceView.Renderer, R @Override public void onDrawFrame(GL10 gl) { + Log.i("GLCanvas", "onDrawFrame"); runAll(mRunOnDraw); syncEventsThrough(); // FIXME, really need to do this ? @@ -97,33 +104,42 @@ public class GLCanvas extends GLSurfaceView implements GLSurfaceView.Renderer, R return; } - boolean needsDeferredRendering = nbContentTextures > 0 && !autoRedraw; - if (needsDeferredRendering && !deferredRendering) { - deferredRendering = true; - this.requestRender(); // FIXME is this working correctly? - /* - dispatch_async(dispatch_get_main_queue(), ^{ - if (!weakSelf) return; - deferredRendering = true; - [weakSelf setNeedsDisplay]; + final boolean shouldRenderNow = deferredRendering || autoRedraw || nbContentTextures == 0; + if (nbContentTextures > 0) { + reactContext.runOnUiQueueThread(new Runnable() { + public void run() { + syncContentBitmaps(); + if (!deferredRendering) { + deferredRendering = true; + requestRender(); + } + } }); - */ } - else { + + if (shouldRenderNow) { this.render(); deferredRendering = false; } } - public void setNbContentTextures(int nbContentTextures) { - resizeUniformContentTextures(nbContentTextures); - this.nbContentTextures = nbContentTextures; + public void setNbContentTextures(int n) { + this.nbContentTextures = n; + runInGLThread(new Runnable() { + @Override + public void run() { + resizeUniformContentTextures(nbContentTextures); + if (preloadingDone) syncContentBitmaps(); + } + }); } public void setRenderId(int renderId) { this.renderId = renderId; - if (nbContentTextures > 0) - this.requestRender(); + if (nbContentTextures > 0) { + if (preloadingDone) syncContentBitmaps(); + requestRender(); + } } public void setOpaque(boolean opaque) { @@ -162,27 +178,30 @@ public class GLCanvas extends GLSurfaceView implements GLSurfaceView.Renderer, R private boolean ensureCompiledShader (List data) { for (GLData d: data) { - if (!ensureCompiledShader(d)); + if (!ensureCompiledShader(d)) { return false; + } } return true; } private boolean ensureCompiledShader (GLData data) { GLShader shader = rnglContext.getShader(data.shader); - if (shader == null) return false; - shader.ensureCompile(); - return ensureCompiledShader(data.children) && ensureCompiledShader(data.contextChildren); + return shader != null && + shader.ensureCompile() && + ensureCompiledShader(data.children) && + ensureCompiledShader(data.contextChildren); } public void setData (GLData data) { this.data = data; - this.requestSyncData(); + if (preloadingDone) syncContentBitmaps(); + requestSyncData(); } public void setImagesToPreload(ReadableArray imagesToPreload) { - logger.info("setImageToPreload, working correctly?"); // TODO + // FIXME setImageToPreload, working correctly? if (preloadingDone) return; if (imagesToPreload.size() == 0) { dispatchOnLoad(); @@ -215,6 +234,7 @@ public class GLCanvas extends GLSurfaceView implements GLSurfaceView.Renderer, R public void requestSyncData () { runInGLThread(new Runnable() { public void run() { + Log.i("GLCanvas", "requestSyncData"); if (ensureCompiledShader(data)) syncData(); else @@ -223,16 +243,35 @@ public class GLCanvas extends GLSurfaceView implements GLSurfaceView.Renderer, R }); } - public void syncContextTextures () { - int i = 0; - for (GLTexture texture: contentTextures) { - View view = ((ViewGroup) this.getParent()).getChildAt(i); - texture.setPixelsWithView(view); - i ++; + /** + * Snapshot the content views and save to contentBitmaps (must run in UI Thread) + */ + public int syncContentBitmaps() { + List bitmaps = new ArrayList<>(); + ViewGroup parent = (ViewGroup) this.getParent(); + int count = parent == null ? 0 : parent.getChildCount() - 1; + for (int i = 0; i < count; i++) { + bitmaps.add(GLTexture.captureView(parent.getChildAt(i))); } + contentBitmaps = bitmaps; + + //Log.i("GLCanvas", "syncContentBitmaps "+count+" "+parent); + return count; + } + + /** + * Draw contentBitmaps to contentTextures (must run in GL Thread) + */ + public int syncContentTextures() { + int size = Math.min(contentTextures.size(), contentBitmaps.size()); + for (int i=0; i contextChildren = new ArrayList<>(); List children = new ArrayList<>(); - shader.bind(); - for (GLData child: data.contextChildren) { contextChildren.add(recSyncData(child, images)); } @@ -325,13 +362,12 @@ public class GLCanvas extends GLSurfaceView implements GLSurfaceView.Renderer, R textures.put(uniformName, emptyTexture); } else { + // FIXME: in case of require() it's now a number... + // TODO: need to support this. as well as on iOS side ReadableMap value = dataUniforms.getMap(uniformName); String t = value.getString("type"); if (t.equals("content")) { int id = value.getInt("id"); - if (id >= contentTextures.size()) { - this.resizeUniformContentTextures(id + 1); - } textures.put(uniformName, contentTextures.get(id)); } else if (t.equals("fbo")) { @@ -342,7 +378,7 @@ public class GLCanvas extends GLSurfaceView implements GLSurfaceView.Renderer, R else if (t.equals("uri")) { final String src = srcResource(value); if (src==null || src.equals("")) { - logger.severe("Shader '"+shader.getName()+": texture uniform '"+uniformName+"': Invalid uri format '"+value+"'"); + shader.runtimeException("texture uniform '"+uniformName+"': Invalid uri format '"+value+"'"); } GLImage image = images.get(src); @@ -363,7 +399,7 @@ public class GLCanvas extends GLSurfaceView implements GLSurfaceView.Renderer, R textures.put(uniformName, image.getTexture()); } else { - logger.severe("Shader '"+shader.getName()+": texture uniform '"+uniformName+"': Unexpected type '"+type+"'"); + shader.runtimeException("texture uniform '" + uniformName + "': Unexpected type '" + type + "'"); } } } @@ -389,8 +425,8 @@ public class GLCanvas extends GLSurfaceView implements GLSurfaceView.Renderer, R case GL_FLOAT_MAT4: ReadableArray arr = dataUniforms.getArray(uniformName); if (arraySizeForType(type) != arr.size()) { - throw new Error("Shader '"+shader.getName()+ - "' uniform '"+uniformName+ + shader.runtimeException( + "uniform '"+uniformName+ "': Invalid array size: "+arr.size()+ ". Expected: "+arraySizeForType(type)); } @@ -405,8 +441,8 @@ public class GLCanvas extends GLSurfaceView implements GLSurfaceView.Renderer, R case GL_BOOL_VEC4: ReadableArray arr2 = dataUniforms.getArray(uniformName); if (arraySizeForType(type) != arr2.size()) { - throw new Error("Shader '"+shader.getName()+ - "' uniform '"+uniformName+ + shader.runtimeException( + "uniform '"+uniformName+ "': Invalid array size: "+arr2.size()+ ". Expected: "+arraySizeForType(type)); } @@ -414,8 +450,8 @@ public class GLCanvas extends GLSurfaceView implements GLSurfaceView.Renderer, R break; default: - throw new Error("Shader '"+shader.getName()+ - "' uniform '"+uniformName+ + shader.runtimeException( + "uniform '"+uniformName+ "': type not supported: "+type); } @@ -425,7 +461,7 @@ public class GLCanvas extends GLSurfaceView implements GLSurfaceView.Renderer, R int[] maxTextureUnits = new int[1]; glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, maxTextureUnits, 0); if (units > maxTextureUnits[0]) { - logger.severe("Shader '"+shader.getName()+": Maximum number of texture reach. got "+units+" >= max "+maxTextureUnits); + shader.runtimeException("Maximum number of texture reach. got " + units + " >= max " + maxTextureUnits); } for (String uniformName: uniformTypes.keySet()) { @@ -433,7 +469,7 @@ public class GLCanvas extends GLSurfaceView implements GLSurfaceView.Renderer, R !uniformsInteger.containsKey(uniformName) && !uniformsFloatBuffer.containsKey(uniformName) && !uniformsIntBuffer.containsKey(uniformName)) { - logger.severe("Shader '"+shader.getName()+": All defined uniforms must be provided. Missing '"+uniformName+"'"); + shader.runtimeException("All defined uniforms must be provided. Missing '"+uniformName+"'"); } } @@ -503,6 +539,7 @@ public class GLCanvas extends GLSurfaceView implements GLSurfaceView.Renderer, R } public void syncData () { + Log.i("GLCanvas", "syncData "+data); if (data == null) return; HashMap images = new HashMap<>(); renderData = recSyncData(data, images); @@ -511,10 +548,11 @@ public class GLCanvas extends GLSurfaceView implements GLSurfaceView.Renderer, R } public void recRender (GLRenderData renderData) { + Log.i("GLCanvas", "recRender "+renderData.fboId); DisplayMetrics dm = reactContext.getResources().getDisplayMetrics(); - int w = new Float(renderData.width.floatValue() * dm.density).intValue(); - int h = new Float(renderData.height.floatValue() * dm.density).intValue(); + int w = Float.valueOf(renderData.width.floatValue() * dm.density).intValue(); + int h = Float.valueOf(renderData.height.floatValue() * dm.density).intValue(); for (GLRenderData child: renderData.contextChildren) recRender(child); @@ -523,7 +561,7 @@ public class GLCanvas extends GLSurfaceView implements GLSurfaceView.Renderer, R recRender(child); if (renderData.fboId == -1) { - glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO[0]); + glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO); glViewport(0, 0, w, h); } else { @@ -538,6 +576,7 @@ public class GLCanvas extends GLSurfaceView implements GLSurfaceView.Renderer, R GLTexture texture = renderData.textures.get(uniformName); int unit = renderData.uniformsInteger.get(uniformName); texture.bind(unit); + Log.i("GLCanvas", uniformName+" "+unit); } Map uniformTypes = renderData.shader.getUniformTypes(); @@ -562,14 +601,16 @@ public class GLCanvas extends GLSurfaceView implements GLSurfaceView.Renderer, R public void render () { if (renderData == null) return; - syncContextTextures(); + syncContentTextures(); + Log.i("GLCanvas", "render"); - defaultFBO = new int[1]; - glGetIntegerv(GL_FRAMEBUFFER_BINDING, defaultFBO, 0); + int[] defaultFBOArr = new int[1]; + glGetIntegerv(GL_FRAMEBUFFER_BINDING, defaultFBOArr, 0); + defaultFBO = defaultFBOArr[0]; glEnable(GL_BLEND); recRender(renderData); glDisable(GL_BLEND); - glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO[0]); + glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO); } public void syncEventsThrough () { diff --git a/android/src/main/java/com/projectseptember/RNGL/GLCanvasManager.java b/android/src/main/java/com/projectseptember/RNGL/GLCanvasManager.java index 028a377..2134691 100644 --- a/android/src/main/java/com/projectseptember/RNGL/GLCanvasManager.java +++ b/android/src/main/java/com/projectseptember/RNGL/GLCanvasManager.java @@ -1,8 +1,5 @@ package com.projectseptember.RNGL; -import android.app.ActivityManager; -import android.content.Context; -import android.content.pm.ConfigurationInfo; import android.support.annotation.Nullable; import android.util.Log; @@ -15,59 +12,60 @@ import com.facebook.react.uimanager.ReactProp; public class GLCanvasManager extends SimpleViewManager { - public static final String REACT_CLASS = "GLCanvas"; + public static final String REACT_CLASS = "GLCanvas"; - @ReactProp(name="nbContentTextures") - public void setNbContentTextures (GLCanvas view, int nbContentTextures) { - view.setNbContentTextures(nbContentTextures); - } - @ReactProp(name="renderId") - public void setRenderId (GLCanvas view, int renderId) { - view.setRenderId(renderId); - } + @ReactProp(name="nbContentTextures") + public void setNbContentTextures (GLCanvas view, int nbContentTextures) { + view.setNbContentTextures(nbContentTextures); + } + @ReactProp(name="renderId") + public void setRenderId (GLCanvas view, int renderId) { + view.setRenderId(renderId); + } - @ReactProp(name="opaque") - public void setOpaque(GLCanvas view, boolean opaque) { - view.setOpaque(opaque); - } + @ReactProp(name="opaque") + public void setOpaque (GLCanvas view, boolean opaque) { + view.setOpaque(opaque); + } - @ReactProp(name="autoRedraw") - public void setAutoRedraw(GLCanvas view, boolean autoRedraw) { - view.setAutoRedraw(autoRedraw); - } + @ReactProp(name="autoRedraw") + public void setAutoRedraw (GLCanvas view, boolean autoRedraw) { + view.setAutoRedraw(autoRedraw); + } - @ReactProp(name="eventsThrough") - public void setEventsThrough(GLCanvas view, boolean eventsThrough) { - view.setEventsThrough(eventsThrough); - } + @ReactProp(name="eventsThrough") + public void setEventsThrough (GLCanvas view, boolean eventsThrough) { + view.setEventsThrough(eventsThrough); + } - @ReactProp(name="visibleContent") - public void setVisibleContent(GLCanvas view, boolean visibleContent) { - view.setVisibleContent(visibleContent); - } + @ReactProp(name="visibleContent") + public void setVisibleContent (GLCanvas view, boolean visibleContent) { + view.setVisibleContent(visibleContent); + } - @ReactProp(name="captureNextFrameId") - public void setCaptureNextFrameId(GLCanvas view, int captureNextFrameId) { - view.setCaptureNextFrameId(captureNextFrameId); - } + @ReactProp(name="captureNextFrameId") + public void setCaptureNextFrameId (GLCanvas view, int captureNextFrameId) { + view.setCaptureNextFrameId(captureNextFrameId); + } - @ReactProp(name="data") - public void setData(GLCanvas view, @Nullable ReadableMap glData) { - view.setData(glData == null ? null : GLData.fromMap(glData)); - } + @ReactProp(name="data") + public void setData (GLCanvas view, @Nullable ReadableMap data) { + view.setData(data == null ? null : GLData.fromMap(data)); + } - @ReactProp(name="imagesToPreload") - public void setImagesToPreload(GLCanvas view, @Nullable ReadableArray imageToPreload) { - view.setImagesToPreload(imageToPreload); - } + @ReactProp(name="imagesToPreload") + public void setImagesToPreload (GLCanvas view, @Nullable ReadableArray imageToPreload) { + view.setImagesToPreload(imageToPreload); + } - @Override - public String getName() { - return REACT_CLASS; - } + @Override + public String getName() { + return REACT_CLASS; + } - @Override - public GLCanvas createViewInstance(ThemedReactContext context) { - return new GLCanvas(context); - } + @Override + public GLCanvas createViewInstance (ThemedReactContext context) { + Log.i("GLCanvas", "createViewInstance..."); + return new GLCanvas(context); + } } diff --git a/android/src/main/java/com/projectseptember/RNGL/GLFBO.java b/android/src/main/java/com/projectseptember/RNGL/GLFBO.java index 87477fe..b5f6009 100644 --- a/android/src/main/java/com/projectseptember/RNGL/GLFBO.java +++ b/android/src/main/java/com/projectseptember/RNGL/GLFBO.java @@ -1,14 +1,13 @@ package com.projectseptember.RNGL; +import android.util.Log; + import java.util.ArrayList; import java.util.List; -import java.util.logging.Logger; import static android.opengl.GLES20.*; public class GLFBO { - private static final Logger logger = Logger.getLogger(GLFBO.class.getName()); - public final List color = new ArrayList<>(); private int handle; private int width = 0; @@ -18,10 +17,11 @@ public class GLFBO { GLTexture texture = new GLTexture(); texture.bind(); 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; } + /* int initRenderBuffer (int width, int height, int component, int attachment) { int[] handleArr = new int[1]; @@ -32,7 +32,9 @@ public class GLFBO { glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, handle); return handle; } + */ + /* class FBOState { private int fbo; @@ -55,9 +57,11 @@ public class GLFBO { glBindTexture(GL_FRAMEBUFFER, tex); } } + */ public GLFBO() { - FBOState state = new FBOState(); + Log.i("GLFBO", "new"); + //FBOState state = new FBOState(); int[] handleArr = new int[1]; glGenFramebuffers(1, handleArr, 0); @@ -70,12 +74,12 @@ public class GLFBO { for(int i=0; i maxFBOSize[0] || h < 0 || h > maxFBOSize[0]) { - logger.severe("Can't resize framebuffer. Invalid dimensions"); - return; + throw new IllegalArgumentException("Can't resize framebuffer. Invalid dimensions"); } width = w; height = h; - FBOState state = new FBOState(); + //FBOState state = new FBOState(); for (GLTexture clr: color) { clr.setShape(w, h); @@ -129,6 +130,6 @@ public class GLFBO { glBindFramebuffer(GL_FRAMEBUFFER, handle); checkStatus(); - state.restore(); + //state.restore(); } } diff --git a/android/src/main/java/com/projectseptember/RNGL/GLImage.java b/android/src/main/java/com/projectseptember/RNGL/GLImage.java index 7248f88..e291ecc 100644 --- a/android/src/main/java/com/projectseptember/RNGL/GLImage.java +++ b/android/src/main/java/com/projectseptember/RNGL/GLImage.java @@ -5,18 +5,13 @@ import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; -import android.media.ExifInterface; import android.net.Uri; import android.os.AsyncTask; import android.provider.MediaStore; import android.support.annotation.Nullable; 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.InputStream; import java.net.URL; @@ -216,29 +211,25 @@ public class GLImage { if (bitmap == 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 { int orientation = getImageOrientation(); if (orientation != 0) { - Matrix matrix = new Matrix(); matrix.postRotate(orientation); - rotatedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), - bitmap.getHeight(), matrix, true); - bitmap.recycle(); } } catch (IOException e) { 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; diff --git a/android/src/main/java/com/projectseptember/RNGL/GLShader.java b/android/src/main/java/com/projectseptember/RNGL/GLShader.java index 932e43f..16b0184 100644 --- a/android/src/main/java/com/projectseptember/RNGL/GLShader.java +++ b/android/src/main/java/com/projectseptember/RNGL/GLShader.java @@ -1,5 +1,6 @@ package com.projectseptember.RNGL; + import static android.opengl.GLES20.*; import java.nio.ByteBuffer; @@ -8,12 +9,9 @@ import java.nio.FloatBuffer; import java.nio.IntBuffer; import java.util.HashMap; import java.util.Map; -import java.util.logging.Logger; public class GLShader { - private static final Logger logger = Logger.getLogger(GLShader.class.getName()); - private final String name; private final String vert; private final String frag; @@ -38,10 +36,15 @@ public class GLShader { } } + public void runtimeException (String msg) { + throw new RuntimeException("Shader '"+name+"': "+msg); + } + public void bind () { + ensureCompile(); + if (!glIsProgram(program)) { - logger.severe("Shader '"+name+"': not a program!"); - return; + runtimeException("not a program"); } glUseProgram(program); glBindBuffer(GL_ARRAY_BUFFER, buffer[0]); @@ -55,7 +58,7 @@ public class GLShader { glGetProgramiv(program, GL_VALIDATE_STATUS, validSuccess, 0); if (validSuccess[0] == GL_FALSE) { glGetProgramInfoLog(program); - logger.severe("Shader '" + name + "': Validation failed " + glGetProgramInfoLog(program)); + runtimeException("Validation failed " + glGetProgramInfoLog(program)); } } @@ -86,7 +89,7 @@ public class GLShader { glUniformMatrix4fv(uniformLocations.get(name), 1, false, buf); break; 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) { @@ -104,7 +107,7 @@ public class GLShader { glUniform4iv(uniformLocations.get(name), 1, buf); break; default: - throw new Error("Unsupported case: uniform '"+name+"' type: "+type); + runtimeException("Unsupported case: uniform '"+name+"' type: "+type); } } @@ -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); glShaderSource(shaderHandle, code); glCompileShader(shaderHandle); int compileSuccess[] = new int[1]; glGetShaderiv(shaderHandle, GL_COMPILE_STATUS, compileSuccess, 0); if (compileSuccess[0] == GL_FALSE) { - logger.severe("Shader '"+name+"' failed to compile: "+glGetShaderInfoLog(shaderHandle)); + runtimeException("failed to compile: " + glGetShaderInfoLog(shaderHandle)); return -1; } return shaderHandle; @@ -149,10 +152,10 @@ public class GLShader { } private void makeProgram () { - int vertex = compileShader(name, vert, GL_VERTEX_SHADER); + int vertex = compileShader(vert, GL_VERTEX_SHADER); if (vertex == -1) return; - int fragment = compileShader(name, frag, GL_FRAGMENT_SHADER); + int fragment = compileShader(frag, GL_FRAGMENT_SHADER); if (fragment == -1) return; program = glCreateProgram(); @@ -163,12 +166,13 @@ public class GLShader { int[] linkSuccess = new int[1]; glGetProgramiv(program, GL_LINK_STATUS, linkSuccess, 0); if (linkSuccess[0] == GL_FALSE) { - logger.severe("Shader '"+name+"': Linking failed "+glGetProgramInfoLog(program)); - return; + runtimeException("Linking failed "+glGetProgramInfoLog(program)); } glUseProgram(program); + validate(); + computeMeta(); pointerLoc = glGetAttribLocation(program, "position"); diff --git a/android/src/main/java/com/projectseptember/RNGL/GLTexture.java b/android/src/main/java/com/projectseptember/RNGL/GLTexture.java index c57fd87..08d0e32 100644 --- a/android/src/main/java/com/projectseptember/RNGL/GLTexture.java +++ b/android/src/main/java/com/projectseptember/RNGL/GLTexture.java @@ -3,16 +3,23 @@ package com.projectseptember.RNGL; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; +import android.graphics.Matrix; import android.opengl.GLUtils; import android.view.View; import static android.opengl.GLES20.*; public class GLTexture { - public int handle; - public Bitmap bitmapCurrentlyUploaded = null; + private int handle; + private Bitmap bitmapCurrentlyUploaded = null; - private void dealloc () { + public GLTexture () { + makeTexture(); + } + + @Override + protected void finalize() throws Throwable { + super.finalize(); int[] handleArr = new int[] { handle }; glDeleteTextures(1, handleArr, 0); bitmapCurrentlyUploaded = null; @@ -66,16 +73,27 @@ public class GLTexture { setPixels(bitmap); } - public void setPixelsWithView (View view) { - Bitmap bitmap = Bitmap.createBitmap( view.getLayoutParams().width, view.getLayoutParams().height, Bitmap.Config.ARGB_8888); + public void setShape (int width, int height) { + 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); - view.layout(view.getLeft(), view.getTop(), view.getRight(), view.getBottom()); + view.layout(0, 0, view.getWidth(), view.getHeight()); 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) { - bind(); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, null); + public int getHandle() { + return handle; } } diff --git a/android/src/main/java/com/projectseptember/RNGL/RNGLContext.java b/android/src/main/java/com/projectseptember/RNGL/RNGLContext.java index 7a393ab..6e9233c 100644 --- a/android/src/main/java/com/projectseptember/RNGL/RNGLContext.java +++ b/android/src/main/java/com/projectseptember/RNGL/RNGLContext.java @@ -1,7 +1,5 @@ package com.projectseptember.RNGL; -import android.opengl.GLSurfaceView; - import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; -- 2.26.2