Преобразование OpenGL ES 2.0 визуализированной текстуры в растровое изображение и обратно

Я хотел бы размыть обработанную текстуру с помощью RenderScript, и для этого мне нужно преобразовать ее в формат растрового изображения и использовать ее. Мне нужно преобразовать ее обратно в текстуру OpenGL.

Работа с текстурой работает. Проблема должна быть где-то здесь, но я не понимаю, почему она не работает. Я получаю черный экран

public void renderToTexture(){ GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fb[0]); GLES20.glClearColor(1.0f, 1.0f, 1.0f, 1.0f); GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT); // specify texture as color attachment GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, renderTex[0], 0); // attach render buffer as depth buffer GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, GLES20.GL_DEPTH_ATTACHMENT, GLES20.GL_RENDERBUFFER, depthRb[0]); // check status int status = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER); drawRender(); Bitmap bitmap = SavePixels(0,0,texW,texH); //blur bitmap and get back a bluredBitmap not yet implemented texture = TextureHelper.loadTexture(bluredBitmap, 128); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); GLES20.glClearColor(1.0f, 1.0f, 1.0f, 1.0f); GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture); drawRender2(); } 

Чтобы создать растровое изображение, я читал пиксели из фреймбуфера, потому что не нашел другого способа сделать это, но я открыт для других методов

  public static Bitmap SavePixels(int x, int y, int w, int h) { int b[]=new int[w*(y+h)]; int bt[]=new int[w*h]; IntBuffer ib=IntBuffer.wrap(b); ib.position(0); GLES20.glReadPixels(0, 0, w, h, GLES20.GL_RGB, GLES20.GL_UNSIGNED_BYTE, ib); for(int i=0, k=0; i<h; i++, k++) { for(int j=0; j<w; j++) { int pix=b[i*w+j]; int pb=(pix>>16)&0xff; int pr=(pix<<16)&0x00ff0000; int pix1=(pix&0xff00ff00) | pr | pb; bt[(hk-1)*w+j]=pix1; } } Bitmap sb=Bitmap.createBitmap(bt, w, h, Bitmap.Config.ARGB_8888); return sb; } 

Вот битмап к текстурному коду:

  public static int loadTexture(final Bitmap pics, int size) { final int[] textureHandle = new int[1]; GLES20.glGenTextures(1, textureHandle, 0); if (textureHandle[0] != 0) { // Read in the resource final Bitmap bitmap = pics; GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA); GLES20.glEnable(GLES20.GL_BLEND); // Bind to the texture in OpenGL GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]); // Set filtering GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST); // Load the bitmap into the bound texture. GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0); // Recycle the bitmap, since its data has been loaded into OpenGL. bitmap.recycle(); } if (textureHandle[0] == 0) { throw new RuntimeException("Error loading texture."); } return textureHandle[0]; } 

    Вы должны были использовать:

     GLES20.glReadPixels(0, 0, w, h, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, ib); 

    Предполагается, что ваш цикл for конвертирует RGBA в ARGB_8888

    Вы можете видеть материал Android MediaCodec , также можете напрямую видеть ExtractMpegFramesTest_egl14.java , а фрагмент кода здесь:

      [/** * Saves][1] the current frame to disk as a PNG image. */ public void saveFrame(String filename) throws IOException { // glReadPixels gives us a ByteBuffer filled with what is essentially big-endian RGBA // data (ie a byte of red, followed by a byte of green...). To use the Bitmap // constructor that takes an int[] array with pixel data, we need an int[] filled // with little-endian ARGB data. // // If we implement this as a series of buf.get() calls, we can spend 2.5 seconds just // copying data around for a 720p frame. It's better to do a bulk get() and then // rearrange the data in memory. (For comparison, the PNG compress takes about 500ms // for a trivial frame.) // // So... we set the ByteBuffer to little-endian, which should turn the bulk IntBuffer // get() into a straight memcpy on most Android devices. Our ints will hold ABGR data. // Swapping B and R gives us ARGB. We need about 30ms for the bulk get(), and another // 270ms for the color swap. // // We can avoid the costly B/R swap here if we do it in the fragment shader (see // http://stackoverflow.com/questions/21634450/ ). // // Having said all that... it turns out that the Bitmap#copyPixelsFromBuffer() // method wants RGBA pixels, not ARGB, so if we create an empty bitmap and then // copy pixel data in we can avoid the swap issue entirely, and just copy straight // into the Bitmap from the ByteBuffer. // // Making this even more interesting is the upside-down nature of GL, which means // our output will look upside-down relative to what appears on screen if the // typical GL conventions are used. (For ExtractMpegFrameTest, we avoid the issue // by inverting the frame when we render it.) // // Allocating large buffers is expensive, so we really want mPixelBuf to be // allocated ahead of time if possible. We still get some allocations from the // Bitmap / PNG creation. mPixelBuf.rewind(); GLES20.glReadPixels(0, 0, mWidth, mHeight, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, mPixelBuf); BufferedOutputStream bos = null; try { bos = new BufferedOutputStream(new FileOutputStream(filename)); Bitmap bmp = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888); mPixelBuf.rewind(); bmp.copyPixelsFromBuffer(mPixelBuf); bmp.compress(Bitmap.CompressFormat.PNG, 90, bos); bmp.recycle(); } finally { if (bos != null) bos.close(); } if (VERBOSE) { Log.d(TAG, "Saved " + mWidth + "x" + mHeight + " frame as '" + filename + "'"); } }