Cómo compartir una asignación Renderscript con OpenGL en Android

Tengo un Renderscript que procesa una imagen que se da en salida a una asignación. Quiero utilizar esta asignación como una textura en mi programa OpenGL, pero no sé cómo obtener un ID de textura de la asignación.

Por otro lado, sé que podría usar un Renderscript gráfico, pero como se ha desaprobado, supongo que debe haber alguna otra forma de lograr el mismo resultado.

Especifique USAGE_IO_OUTPUT cuando cree la asignación. Suponiendo que está generando los datos de textura en un script también agregaría USAGE_SCRIPT. A continuación, puede llamar

Allocation.setSurface (theGLSurface)

Para vincular la asignación a una textura. Cada vez que desee actualizar la textura con el contenido de la secuencia de comandos que necesita llamar.

Allocation.ioSend ()

Esto moverá los datos sin hacer copias adicionales.

Has formulado la pregunta en términos de transformar una Asignación en una textura, pero es más fácil pensar en crear una textura y luego conceder la propiedad de Asignación de esa textura. De esta forma, conocerá el ID de textura antes de pasarlo a la asignación. Tenga cuidado: la Asignación tiene el poder de cambiar radicalmente las propiedades de la textura.

Paso a paso:

  1. Crear una textura GL

  2. Crear una SurfaceTexture utilizando su ID

  3. Crear una asignación con la Allocation.USAGE_IO_OUTPUT | Allocation.USAGE_SCRIPT Allocation.USAGE_IO_OUTPUT | Allocation.USAGE_SCRIPT

  4. Pase la SurfaceTexture a la asignación con setSurface()

  5. Colocar datos en la asignación

  6. Llame a ioSend() en la asignación para actualizar la textura

  7. Repita los pasos 5 y 6 siempre que desee actualizar la textura

Estoy muy lejos de un experto GL, por lo que el paso 2 es francamente conjetura. A continuación se muestra una adaptación de la muestra HelloCompute en la que reemplazo displayout con un TextureView , que es una vista que crea una textura y una SurfaceTexture para mí. A partir de entonces, sigo los pasos anteriores.

 package com.example.android.rs.hellocompute; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.SurfaceTexture; import android.os.Bundle; import android.renderscript.Allocation; import android.renderscript.Element; import android.renderscript.RenderScript; import android.renderscript.Type; import android.view.Surface; import android.view.Surface.OutOfResourcesException; import android.view.TextureView; import android.widget.ImageView; public class HelloCompute extends Activity { private Bitmap mBitmapIn; private RenderScript mRS; private ScriptC_mono mScript; private Allocation mSurfaceAllocation; private Allocation mCanvasAllocation; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mBitmapIn = loadBitmap(R.drawable.data); int x = mBitmapIn.getWidth(); int y = mBitmapIn.getHeight(); ImageView in = (ImageView) findViewById(R.id.displayin); in.setImageBitmap(mBitmapIn); mRS = RenderScript.create(this); mScript = new ScriptC_mono(mRS, getResources(), R.raw.mono); mCanvasAllocation = Allocation.createTyped(mRS, new Type.Builder(mRS, Element.RGBA_8888(mRS)) .setX(x).setY(y).create(), Allocation.USAGE_IO_INPUT | Allocation.USAGE_SCRIPT); mSurfaceAllocation = Allocation.createTyped(mRS, new Type.Builder(mRS, Element.RGBA_8888(mRS)) .setX(x).setY(y).create(), Allocation.USAGE_IO_OUTPUT | Allocation.USAGE_SCRIPT); TextureView mTextureView = (TextureView) findViewById(R.id.displayout); mTextureView.setSurfaceTextureListener( new TextureView.SurfaceTextureListener() { @Override public void onSurfaceTextureAvailable(SurfaceTexture s, int w, int h) { if(s != null) mSurfaceAllocation.setSurface(new Surface(s)); mScript.forEach_root(mCanvasAllocation, mSurfaceAllocation); mSurfaceAllocation.ioSend(); } @Override public void onSurfaceTextureUpdated(SurfaceTexture s) { } @Override public void onSurfaceTextureSizeChanged(SurfaceTexture s, int w, int h) { if(s != null) mSurfaceAllocation.setSurface(new Surface(s)); } @Override public boolean onSurfaceTextureDestroyed(SurfaceTexture s) { mSurfaceAllocation.setSurface(null); return true; } }); try { Surface surface = mCanvasAllocation.getSurface(); Canvas canvas = surface.lockCanvas(new Rect(0,0,100,100)); canvas.drawBitmap(mBitmapIn, 0, 0, new Paint()); surface.unlockCanvasAndPost(canvas); mCanvasAllocation.ioReceive(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (OutOfResourcesException e) { e.printStackTrace(); } } private Bitmap loadBitmap(int resource) { final BitmapFactory.Options options = new BitmapFactory.Options(); options.inPreferredConfig = Bitmap.Config.ARGB_8888; return BitmapFactory.decodeResource(getResources(), resource, options); } } 
  • ¿Por qué mi programa de shader openGL para puntos tiene anillos de artefactos?
  • ¿Cómo acceder a OpenGL ES 2 a través de C ++ / NDK si EGL_NATIVE_RENDERABLE no es compatible?
  • Cómo pasar los datos correctos a un programa de shader OpenGL-ES 2.0
  • GLSurfaceView - cómo hacer el fondo translúcido
  • Cómo renderizar vídeo a través de openGLES2 con Android NDK
  • Error al intentar obtener Alraedy creado Surface y recibir EGLNativeWindowType ya conectado a otro error de API
  • Fondos de Android Live con OpenGL ES 2.0?
  • La textura de OpenGL no sigue la geometría
  • Android OpenGL ES 2.0: El modelo de cubo no sólo está distorsionado (la perspectiva es incorrecta?), Sino también las caras se cargan incorrectamente (los vértices no son correctos?)
  • Android OpenGL2.0 que muestra texturas negras
  • GLES2.0: Usar GL_TEXTURE_EXTERNAL_OES a través de glEGLImageTargetTexture2DOES
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.