Save 2D texture to png in Android OpenGL ES

I am new to OpenGL ES in Android. But now I need to use OpenGL ES 2.0 for editing photos. I found the "Hello-effect" code sample in Android 4.1.2, it completed the editing of the photo and displayed it in the window. But right now, I also need to save the edited photo in a local bitmap. I think there might be some way to get the data directly from the texture, but the only method I found is glReadPixels(...) . So I am trying to use it:

The first test I do:

  • I am using GLSurfaceView to display a photo edited by the android.media.effect API.
  • I add a button in the same layout as GLSurfaceView.
  • When I click the button, I call glReadPixels (...) to get the photo information. But as step 3, I received only cotton data.
I assume that when I click the button, the window framebuffer is replaced with the contents of the button.

Second test:

  • I am creating a FBO to save the edited photo and use glReadPixels (...) to get the photo data, but this is black rice.

The code is as follows:

 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); } 

My question is, is my assumption correct? And as an FBO method, I can lose some important step to finish my work.

+4
source share
1 answer

Try reading pixels immediately after

 GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); 

Also make sure that glReadPixels is called from the right thread, i.e. in a subclass of your visualizer.

And one more thing, I see that you are binding the texture used for FBO as an input to a shader, you cannot do this.

I believe that after RTT you show the result on a quad or something on the screen, right?

Can you show the rest of the code you use to read pixels?

0
source

Source: https://habr.com/ru/post/1445971/


All Articles