Commit 216d445a authored by Gaëtan Renaudeau's avatar Gaëtan Renaudeau

WIP

parent 76f6b237
...@@ -30,5 +30,6 @@ repositories { ...@@ -30,5 +30,6 @@ repositories {
} }
dependencies { dependencies {
compile 'com.facebook.react:react-native:0.11.+' // FIXME: version shouldn't be hardcoded? how do to peerDep ?
compile 'com.facebook.react:react-native:0.14.+'
} }
This diff is collapsed.
package com.projectseptember.RNGL; package com.projectseptember.RNGL;
import android.opengl.GLSurfaceView; import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.ConfigurationInfo;
import android.support.annotation.Nullable;
import android.util.Log;
import com.facebook.react.uimanager.CatalystStylesDiffMap; import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.uimanager.SimpleViewManager; import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.uimanager.ThemedReactContext; import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.ReactProp;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
public class GLCanvasManager extends SimpleViewManager<GLCanvas> {
public class GLCanvasManager extends SimpleViewManager<GLSurfaceView> {
public static final String REACT_CLASS = "GLCanvas"; public static final String REACT_CLASS = "GLCanvas";
// TODO... props @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);
}
@Override @ReactProp(name="opaque")
public String getName() { public void setOpaque(GLCanvas view, boolean opaque) {
return REACT_CLASS; view.setOpaque(opaque);
} }
@Override @ReactProp(name="autoRedraw")
public GLSurfaceView createViewInstance(ThemedReactContext context) { public void setAutoRedraw(GLCanvas view, boolean autoRedraw) {
GLSurfaceView view = new GLSurfaceView(context); view.setAutoRedraw(autoRedraw);
view.setRenderer(new GLSurfaceView.Renderer() { }
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
} @ReactProp(name="eventsThrough")
public void setEventsThrough(GLCanvas view, boolean eventsThrough) {
view.setEventsThrough(eventsThrough);
}
@Override @ReactProp(name="visibleContent")
public void onSurfaceChanged(GL10 gl, int width, int height) { public void setVisibleContent(GLCanvas view, boolean visibleContent) {
gl.glViewport(0, 0, width, height); view.setVisibleContent(visibleContent);
} }
@Override @ReactProp(name="captureNextFrameId")
public void onDrawFrame(GL10 gl) { public void setCaptureNextFrameId(GLCanvas view, int captureNextFrameId) {
gl.glClearColor(1.0f, 0.0f, 0.0f, 1.0f); view.setCaptureNextFrameId(captureNextFrameId);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT); }
}
}); @ReactProp(name="data")
return view; public void setData(GLCanvas view, @Nullable ReadableMap glData) {
view.setData(glData == null ? null : GLData.fromMap(glData));
}
@ReactProp(name="imagesToPreload")
public void setImagesToPreload(GLCanvas view, @Nullable ReadableArray imageToPreload) {
view.setImagesToPreload(imageToPreload);
}
@Override
public String getName() {
return REACT_CLASS;
} }
@Override @Override
public void updateView(final GLSurfaceView view, final CatalystStylesDiffMap props) { public GLCanvas createViewInstance(ThemedReactContext context) {
super.updateView(view, props); return new GLCanvas(context);
// TODO... call setters with props
// view.requestRender();
} }
} }
package com.projectseptember.RNGL;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import java.util.ArrayList;
import java.util.List;
public class GLData {
final Integer shader;
final ReadableMap uniforms;
final Integer width;
final Integer height;
final Integer fboId;
final List<GLData> contextChildren;
final List<GLData> children;
public GLData(Integer shader, ReadableMap uniforms, Integer width, Integer height, Integer fboId, List<GLData> contextChildren, List<GLData> children) {
this.shader = shader;
this.uniforms = uniforms;
this.width = width;
this.height = height;
this.fboId = fboId;
this.contextChildren = contextChildren;
this.children = children;
}
public static List<GLData> fromArray (ReadableArray arr) {
ArrayList<GLData> list = new ArrayList<>();
for (int i=0; i < arr.size(); i++) {
list.add(fromMap(arr.getMap(i)));
}
return list;
}
public static GLData fromMap (ReadableMap map) {
Integer shader = map.getInt("shader");
ReadableMap uniforms = map.getMap("uniforms");
Integer width = map.getInt("width");
Integer height = map.getInt("height");
Integer fboId = map.getInt("fboId");
List<GLData> children = fromArray(map.getArray("children"));
List<GLData> contextChildren = fromArray(map.getArray("contextChildren"));
return new GLData(shader, uniforms, width, height, fboId, contextChildren, children);
}
}
package com.projectseptember.RNGL;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import static android.opengl.GLES20.*;
public class GLFBO {// TODO
private static final Logger logger = Logger.getLogger(GLFBO.class.getName());
public final List<GLTexture> color = new ArrayList<>();
private int handle;
private int width = 0;
private int height = 0;
private static GLTexture initTexture (int width, int height, int attachment) {
GLTexture texture = new GLTexture();
texture.bind();
texture.setShape(width, height);
glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, texture.handle, 0);
return texture;
}
int initRenderBuffer (int width, int height, int component, int attachment)
{
int[] handleArr = new int[1];
glGenRenderbuffers(1, handleArr, 0);
int handle = handleArr[0];
glBindRenderbuffer(GL_RENDERBUFFER, handle);
glRenderbufferStorage(GL_RENDERBUFFER, component, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, handle);
return handle;
}
class FBOState {
private int fbo;
private int rbo;
private int tex;
public FBOState() {
int[] fbo = new int[1], rbo = new int[1], tex = new int[1];
glGetIntegerv(GL_FRAMEBUFFER_BINDING, fbo, 0);
glGetIntegerv(GL_RENDERBUFFER_BINDING, rbo, 0);
glGetIntegerv(GL_TEXTURE_BINDING_2D, tex, 0);
this.fbo = fbo[0];
this.rbo = rbo[0];
this.tex = tex[0];
}
private void restore() {
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glBindRenderbuffer(GL_FRAMEBUFFER, rbo);
glBindTexture(GL_FRAMEBUFFER, tex);
}
}
public GLFBO() {
FBOState state = new FBOState();
int[] handleArr = new int[1];
glGenFramebuffers(1, handleArr, 0);
handle = handleArr[0];
int numColors = 1;
glBindFramebuffer(GL_FRAMEBUFFER, handle);
for(int i=0; i<numColors; ++i) {
color.add(initTexture(width, height, GL_COLOR_ATTACHMENT0 + i));
}
state.restore();
}
@Override
protected void finalize() throws Throwable {
super.finalize();
int[] handleArr = new int[] { handle };
glDeleteFramebuffers(1, handleArr, 0);
}
void checkStatus () {
int status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(status != GL_FRAMEBUFFER_COMPLETE) {
switch (status) {
case GL_FRAMEBUFFER_UNSUPPORTED:
logger.severe("Framebuffer unsupported");
break;
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
logger.severe("Framebuffer incomplete attachment");
break;
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
logger.severe("Framebuffer incomplete dimensions");
break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
logger.severe("Framebuffer incomplete missing attachment");
break;
default:
logger.severe("Failed to create framebuffer: " + status);
}
}
}
public void bind () {
glBindFramebuffer(GL_FRAMEBUFFER, handle);
glViewport(0, 0, width, height);
}
public void setShape(int w, int h) {
if (w == width && h == height) return;
int[] maxFBOSize = new int[1];
glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, maxFBOSize, 0);
if( w < 0 || w > maxFBOSize[0] || h < 0 || h > maxFBOSize[0]) {
logger.severe("Can't resize framebuffer. Invalid dimensions");
return;
}
width = w;
height = h;
FBOState state = new FBOState();
for (GLTexture clr: color) {
clr.setShape(w, h);
}
glBindFramebuffer(GL_FRAMEBUFFER, handle);
checkStatus();
state.restore();
}
}
package com.projectseptember.RNGL;
import android.content.Context;
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;
/*
This class is maintained and inspired from
https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.java
also inspired from
https://github.com/CyberAgent/android-gpuimage/blob/master/library/src/jp/co/cyberagent/android/gpuimage/GPUImage.java
*/
public class GLImage {
private final Context context;
private String src;
private GLTexture texture;
private Uri uri;
private boolean isLocalImage;
private boolean isDirty;
private AsyncTask<Void, Void, Bitmap> task;
private Runnable onload;
public GLImage (Context context, Runnable onload) {
this.context = context;
this.onload = onload;
this.texture = new GLTexture();
}
public void setSrc(String src) {
if (this.src == src) return;
this.src = src;
reloadImage();
}
private void reloadImage () {
uri = null;
if (src != null) {
try {
uri = Uri.parse(src);
// Verify scheme is set, so that relative uri (used by static resources) are not handled.
if (uri.getScheme() == null) {
uri = null;
}
} catch (Exception e) {
// ignore malformed uri, then attempt to extract resource ID.
}
if (uri == null) {
uri = getResourceDrawableUri(context, src);
isLocalImage = true;
} else {
isLocalImage = false;
}
}
isDirty = true;
}
public void onLoad (Bitmap bitmap) {
texture.setPixels(bitmap);
this.onload.run();
}
public GLTexture getTexture() {
if (isDirty) {
if (task != null) task.cancel(true);
task = new LoadImageUriTask(this, uri).execute();
isDirty = false;
}
return texture;
}
private static @Nullable Uri getResourceDrawableUri(Context context, @Nullable String name) {
if (name == null || name.isEmpty()) {
return null;
}
name = name.toLowerCase().replace("-", "_");
int resId = context.getResources().getIdentifier(
name,
"drawable",
context.getPackageName());
return new Uri.Builder()
.scheme(UriUtil.LOCAL_RESOURCE_SCHEME)
.path(String.valueOf(resId))
.build();
}
private class LoadImageUriTask extends LoadImageTask {
private final Uri mUri;
public LoadImageUriTask(GLImage gpuImage, Uri uri) {
super(gpuImage);
mUri = uri;
}
@Override
protected Bitmap decode(BitmapFactory.Options options) {
try {
InputStream inputStream;
if (mUri.getScheme().startsWith("http") || mUri.getScheme().startsWith("https")) {
inputStream = new URL(mUri.toString()).openStream();
} else {
inputStream = context.getContentResolver().openInputStream(mUri);
}
return BitmapFactory.decodeStream(inputStream, null, options);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
protected int getImageOrientation() throws IOException {
Cursor cursor = context.getContentResolver().query(mUri,
new String[] { MediaStore.Images.ImageColumns.ORIENTATION }, null, null, null);
if (cursor == null || cursor.getCount() != 1) {
return 0;
}
cursor.moveToFirst();
int orientation = cursor.getInt(0);
cursor.close();
return orientation;
}
}
/*
private class LoadImageFileTask extends LoadImageTask {
private final File mImageFile;
public LoadImageFileTask(GLImage gpuImage, File file) {
super(gpuImage);
mImageFile = file;
}
@Override
protected Bitmap decode(BitmapFactory.Options options) {
return BitmapFactory.decodeFile(mImageFile.getAbsolutePath(), options);
}
@Override
protected int getImageOrientation() throws IOException {
ExifInterface exif = new ExifInterface(mImageFile.getAbsolutePath());
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
switch (orientation) {
case ExifInterface.ORIENTATION_NORMAL:
return 0;
case ExifInterface.ORIENTATION_ROTATE_90:
return 90;
case ExifInterface.ORIENTATION_ROTATE_180:
return 180;
case ExifInterface.ORIENTATION_ROTATE_270:
return 270;
default:
return 0;
}
}
}
*/
private abstract class LoadImageTask extends AsyncTask<Void, Void, Bitmap> {
private GLImage glImage;
public LoadImageTask (GLImage glImage) {
this.glImage = glImage;
}
@Override
protected Bitmap doInBackground(Void... params) {
return loadResizedImage();
}
@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
glImage.onLoad(bitmap);
}
protected abstract Bitmap decode(BitmapFactory.Options options);
private Bitmap loadResizedImage() {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
decode(options);
options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.RGB_565;
options.inTempStorage = new byte[32 * 1024];
Bitmap bitmap = decode(options);
if (bitmap == null) {
return null;
}
bitmap = rotateImage(bitmap);
return bitmap;
}
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;
}
protected abstract int getImageOrientation() throws IOException;
}
}
package com.projectseptember.RNGL;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.List;
import java.util.Map;
public class GLRenderData {
final GLShader shader;
final Map<String, Integer> uniformsInteger;
final Map<String, Float> uniformsFloat;
final Map<String, IntBuffer> uniformsIntBuffer;
final Map<String, FloatBuffer> uniformsFloatBuffer;
final Map<String, GLTexture> textures;
final Integer width;
final Integer height;
final Integer fboId;
final List<GLRenderData> contextChildren;
final List<GLRenderData> children;
public GLRenderData(
GLShader shader,
Map<String, Integer> uniformsInteger,
Map<String, Float> uniformsFloat,
Map<String, IntBuffer> uniformsIntBuffer,
Map<String, FloatBuffer> uniformsFloatBuffer,
Map<String, GLTexture> textures,
Integer width,
Integer height,
Integer fboId,
List<GLRenderData> contextChildren,
List<GLRenderData> children) {
this.shader = shader;
this.uniformsInteger = uniformsInteger;
this.uniformsFloat = uniformsFloat;
this.uniformsIntBuffer = uniformsIntBuffer;
this.uniformsFloatBuffer = uniformsFloatBuffer;
this.textures = textures;
this.width = width;
this.height = height;
this.fboId = fboId;
this.contextChildren = contextChildren;
this.children = children;
}
}
package com.projectseptember.RNGL;
import static android.opengl.GLES20.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
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;
private Map<String, Integer> uniformTypes;
private int program; // Program of the shader
private int buffer[]; // the buffer currently contains 2 static triangles covering the surface
private int pointerLoc; // The "pointer" attribute is used to iterate over vertex
private Map<String, Integer> uniformLocations; // The uniform locations cache
public GLShader(String name, String vert, String frag) {
this.name = name;
this.vert = vert;
this.frag = frag;
makeProgram();
}
@Override
protected void finalize() throws Throwable {
super.finalize();
if (buffer != null) {
glDeleteProgram(program);
glDeleteBuffers(1, buffer, 0);
}
}
public void bind () {
if (!glIsProgram(program)) {
logger.severe("Shader '"+name+"': not a program!");
return;
}
glUseProgram(program);
glBindBuffer(GL_ARRAY_BUFFER, buffer[0]);
glEnableVertexAttribArray(pointerLoc);
glVertexAttribPointer(pointerLoc, 2, GL_FLOAT, false, 0, 0);
}
public void validate () {
glValidateProgram(program);
int[] validSuccess = new int[1];
glGetProgramiv(program, GL_VALIDATE_STATUS, validSuccess, 0);
if (validSuccess[0] == GL_FALSE) {
glGetProgramInfoLog(program);
logger.severe("Shader '" + name + "': Validation failed " + glGetProgramInfoLog(program));
}
}
public void setUniform (String name, Integer i) {
glUniform1i(uniformLocations.get(name), i);
}
public void setUniform (String name, Float f) {
glUniform1f(uniformLocations.get(name), f);
}
public void setUniform (String name, FloatBuffer buf, int type) {
switch (type) {
case GL_FLOAT_VEC2:
glUniform2fv(uniformLocations.get(name), 1, buf);
break;
case GL_FLOAT_VEC3:
glUniform3fv(uniformLocations.get(name), 1, buf);
break;
case GL_FLOAT_VEC4:
glUniform4fv(uniformLocations.get(name), 1, buf);
break;
case GL_FLOAT_MAT2:
glUniformMatrix2fv(uniformLocations.get(name), 1, false, buf);
break;
case GL_FLOAT_MAT3:
glUniformMatrix3fv(uniformLocations.get(name), 1, false, buf);
break;
case GL_FLOAT_MAT4:
glUniformMatrix4fv(uniformLocations.get(name), 1, false, buf);
break;
default:
throw new Error("Unsupported case: uniform '" + name + "' type: " + type);
}
}
public void setUniform (String name, IntBuffer buf, int type) {
switch (type) {
case GL_INT_VEC2:
case GL_BOOL_VEC2:
glUniform2iv(uniformLocations.get(name), 1, buf);
break;
case GL_INT_VEC3:
case GL_BOOL_VEC3:
glUniform3iv(uniformLocations.get(name), 1, buf);
break;
case GL_INT_VEC4:
case GL_BOOL_VEC4:
glUniform4iv(uniformLocations.get(name), 1, buf);
break;
default:
throw new Error("Unsupported case: uniform '"+name+"' type: "+type);
}
}
public String getName() {
return name;
}
public Map<String, Integer> getUniformTypes() {
return uniformTypes;
}
private static int compileShader (String name, 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));
return -1;
}
return shaderHandle;
}
private void computeMeta () {
Map<String, Integer> uniforms = new HashMap<>();
Map<String, Integer> locations = new HashMap<>();
int[] nbUniforms = new int[1];
int[] type = new int[1];
int[] size = new int[1];
glGetProgramiv(program, GL_ACTIVE_UNIFORMS, nbUniforms, 0);
for (int i=0; i < nbUniforms[0]; i++) {
String uniformName = glGetActiveUniform(program, i, size, 0, type, 0);
int location = glGetUniformLocation(program, uniformName);
uniforms.put(uniformName, type[0]);
locations.put(uniformName, location);
}
this.uniformTypes = uniforms;
this.uniformLocations = locations;
}
private void makeProgram () {
int vertex = compileShader(name, vert, GL_VERTEX_SHADER);
if (vertex == -1) return;
int fragment = compileShader(name, frag, GL_FRAGMENT_SHADER);
if (fragment == -1) return;
program = glCreateProgram();
glAttachShader(program, vertex);
glAttachShader(program, fragment);
glLinkProgram(program);
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;
}
glUseProgram(program);
computeMeta();
pointerLoc = glGetAttribLocation(program, "position");
buffer = new int[1];
glGenBuffers(1, buffer, 0);
glBindBuffer(GL_ARRAY_BUFFER, buffer[0]);
float buf[] = {
-1.0f, -1.0f,
1.0f, -1.0f,
-1.0f, 1.0f,
-1.0f, 1.0f,
1.0f, -1.0f,
1.0f, 1.0f
};
FloatBuffer bufferData = ByteBuffer.allocateDirect(buf.length * 4)
.order(ByteOrder.nativeOrder())
.asFloatBuffer();
bufferData.put(buf).position(0);
glBufferData(GL_ARRAY_BUFFER, buf.length * 4, bufferData, GL_STATIC_DRAW);
}
public boolean isReady () {
return buffer != null && uniformLocations != null;
}
public boolean ensureCompile() {
if (!isReady()) makeProgram();
return isReady();
}
}
package com.projectseptember.RNGL;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.opengl.GLUtils;
import android.view.View;
import static android.opengl.GLES20.*;
public class GLTexture {
public int handle;
public Bitmap bitmapCurrentlyUploaded = null;
private void dealloc () {
int[] handleArr = new int[] { handle };
glDeleteTextures(1, handleArr, 0);
bitmapCurrentlyUploaded = null;
}
private void makeTexture () {
int[] handleArr = new int[1];
glGenTextures(1, handleArr, 0);
handle = handleArr[0];
glBindTexture(GL_TEXTURE_2D, handle);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
public int bind (int unit) {
glActiveTexture(GL_TEXTURE0 + unit);
glBindTexture(GL_TEXTURE_2D, handle);
return unit;
}
public void bind () {
glBindTexture(GL_TEXTURE_2D, handle);
}
public void setPixels (Bitmap bitmap) {
if (bitmap != bitmapCurrentlyUploaded) {
bitmapCurrentlyUploaded = bitmap;
bind();
GLUtils.texImage2D(GL_TEXTURE_2D, 0, bitmap, 0);
}
}
public void setPixelsRandom (int width, int height) {
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
bitmap.setPixel(x, y, Color.rgb(
(int)(255.0 * Math.random()),
(int)(255.0 * Math.random()),
(int)(255.0 * Math.random())));
}
}
setPixels(bitmap);
}
public void setPixelsEmpty () {
Bitmap bitmap = Bitmap.createBitmap(2, 2, Bitmap.Config.ARGB_8888);
setPixels(bitmap);
}
public void setPixelsWithView (View view) {
Bitmap bitmap = Bitmap.createBitmap( view.getLayoutParams().width, view.getLayoutParams().height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.layout(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
view.draw(canvas);
setPixels(bitmap);
}
public void setShape (int width, int height) {
bind();
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;
import com.facebook.react.bridge.ReadableMap; import com.facebook.react.bridge.ReadableMap;
import java.util.HashMap;
import java.util.Map;
import javax.microedition.khronos.egl.EGLContext;
public class RNGLContext extends ReactContextBaseJavaModule { public class RNGLContext extends ReactContextBaseJavaModule {
// Share GL Context ?
// http://developer.android.com/training/graphics/opengl/environment.html
// http://stackoverflow.com/questions/8845491/sharing-the-egl2-0-context-between-2-glsurfaceviews-caused-egl-bad-access-on-and
// http://stackoverflow.com/questions/5675355/sharing-the-gles20-context-and-textures-between-different-glsurfaceviews
private static String STATIC_VERT =
"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));"+
"}";
private Map<Integer, GLShader> shaders = new HashMap<>();
private Map<Integer, GLFBO> fbos = new HashMap<>();
public RNGLContext (ReactApplicationContext reactContext) { public RNGLContext (ReactApplicationContext reactContext) {
super(reactContext); super(reactContext);
} }
...@@ -16,10 +39,21 @@ public class RNGLContext extends ReactContextBaseJavaModule { ...@@ -16,10 +39,21 @@ public class RNGLContext extends ReactContextBaseJavaModule {
return "RNGLContext"; return "RNGLContext";
} }
public GLShader getShader (Integer id) {
return shaders.get(id);
}
public GLFBO getFBO (Integer id) {
if (!fbos.containsKey(id)) {
fbos.put(id, new GLFBO());
}
return fbos.get(id);
}
@ReactMethod @ReactMethod
public void addShader (Integer id, ReadableMap config) { public void addShader (final Integer id, final ReadableMap config) {
String frag = config.getString("frag"); final String frag = config.getString("frag");
String name = config.getString("name"); final String name = config.getString("name");
System.out.println("TODO... addShader: "+id+" "+name); shaders.put(id, new GLShader(name, STATIC_VERT, frag));
} }
} }
...@@ -13,7 +13,7 @@ import com.facebook.react.bridge.JavaScriptModule; ...@@ -13,7 +13,7 @@ import com.facebook.react.bridge.JavaScriptModule;
public class RNGLPackage implements ReactPackage { public class RNGLPackage implements ReactPackage {
@Override @Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactApplicationContext) { public List<NativeModule> createNativeModules(ReactApplicationContext reactApplicationContext) {
List<NativeModule> modules = new ArrayList<>(); List<NativeModule> modules = new ArrayList<>();
modules.add(new RNGLContext(reactApplicationContext)); modules.add(new RNGLContext(reactApplicationContext));
......
package com.projectseptember.RNGL;
import com.facebook.react.bridge.ReadableMap;
public class UniformValue {
}
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