将2D纹理保存到Android OpenGL ES中的png

时间:2012-11-14 10:10:11

标签: android opengl-es fbo

我是Android新手OpenGL ES。但是现在,我需要使用OpenGL ES 2.0进行一些照片编辑。我在Android 4.1.2中找到了示例代码"Hello-effect",它完成了编辑照片并将其渲染到窗口的工作。但是现在,我还需要将编辑过的照片保存到本地位图。我认为可能有一些方法可以直接从纹理中获取数据,但我找到的唯一方法是glReadPixels(...)。所以我尝试使用它:

我做的第一个测试:  

     
  1. 我使用GLSurfaceView显示已由android.media.effect API编辑的照片。
  2.  
  3. 我在包含GLSurfaceView的相同布局中添加了一个按钮。
  4.  
  5. 单击按钮时,我调用glReadPixels(...)来获取照片数据。  但是作为第3步,我只得到了botton的数据。
  6.    我想当我点击按钮时,窗口的帧缓冲已经被按钮的内容所取代。

    我做的第二次测试:

    1. 我创建了一个FBO来保存已编辑的照片并使用glReadPixels(...)来获取照片数据,但这是一张黑色照片。
    2. 代码如下所示:

      public void renderTextureOffscreen (int texId) {
          // Bind default FBO
          GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, offScreenFrameBuffer[0]); 
          GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER,GLES20.GL_COLOR_ATTACHMENT0,GLES20.GL_TEXTURE_2D, texId , 0);
      
          int status = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER);
          if(status == GLES20.GL_FRAMEBUFFER_COMPLETE)
          {
              // Set viewport
              GLES20.glViewport(0, 0, mViewWidth, mViewHeight);
              GLToolbox.checkGlError("glViewport");
      
              // Disable blending
              GLES20.glDisable(GLES20.GL_BLEND);
      
              // Set the vertex attributes
              GLES20.glVertexAttribPointer(mTexCoordHandle, 2, GLES20.GL_FLOAT, false,
                  0, mTexVertices);
              GLES20.glEnableVertexAttribArray(mTexCoordHandle);
              GLES20.glVertexAttribPointer(mPosCoordHandle, 2, GLES20.GL_FLOAT, false,
                  0, mPosVertices);
              GLES20.glEnableVertexAttribArray(mPosCoordHandle);
              GLToolbox.checkGlError("vertex attribute setup");
      
              // Set the input texture
              GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
              GLToolbox.checkGlError("glActiveTexture");
              GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
              GLToolbox.checkGlError("glBindTexture");
              GLES20.glUniform1i(mTexSamplerHandle, 0);
      
              // Draw
              GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
              GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
              GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
          }
      

      我的问题是我的猜测是否正确?作为FBO方法,我是否会失去一些关键步骤来完成我的工作。

1 个答案:

答案 0 :(得分:0)

尝试在

之后立即读取像素
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); 

还要确保从右侧线程调用glReadPixels,即在渲染器子类中调用。

另外,我看到你将用于FBO的纹理绑定为着色器的输入,你不能这样做。

我想在RTT之后,你将结果渲染到四边形或屏幕上的东西是对的吗?

您能否显示用于读取像素的其余代码?