I've been working on a project in which a user can interact with a GLSurfaceView
to draw shapes on a screen. This all works fine and dandy, but now I'm attempting to do two things: 1) create a thumbnail of their drawing, and 2) save their drawing. It's important to note that the user can draw an image which is larger than the screen.
As far as my research shows, this is best achieved using a Bitmap
(which can be 1) rendered to a Canvas
for a thumbnail, and 2) be saved to the file system, which achieves both of my goals).
Initially, I tried to read the Renderer
from the GLSurfaceView
via glReadPixels
, but it turns out I couldn't get the off-screen data from this. Instead, I opted to do an off-screen buffer to produce a render of the image, which could be converted to a Bitmap
.
I found a lovely post which provided a code for a class called PixelBuffer
, which I am now using. (I've made a few tweaks, but all issues I've had occur with or without said tweaking.)
Now, when using the getBitmap()
of the code (which I will post below in the event the PixelBuffer
forum thread is unreadable), I get a bunch of called unimplemented OpenGL ES API
. This struck me as odd at first, so I did some investigating. It turns out that, for some reason, the PixelBuffer
class is using OpenGL ES 2.0, while the GLSurfaceView is using OpenGL ES 1.1. The device I'm using (Galaxy Nexus) doesn't support 2.0. (And moreover, I'd like to support the largest range of devices possible.)
So, here is my question: How can I force my PixelBuffer
class to use the OpenGL ES 1.1 API? I have already added the following in my Manifest:
<uses-feature android:glEsVersion="0x00010001" />
Additionally, I have attempted to set the version using int[] version = new int[] { 1, 1 };
, to no avail.
The PixelBuffer
code I'm using: Link. The line in question that calls the Renderer
is on line 91. The version code is on line 39-ish onward.
This is the code I use to create the PixelBuffer
, called from the GLSurfaceView
object:
setEGLConfigChooser(8, 8, 8, 8, 0, 0);
mRenderer = new MyRenderer(this);
setRenderer(mRenderer);
mPixelBuffer = new CPPixelBuffer(1440, 1280); // TODO Temporary hardcode for Galaxy Nexus wallpaper size
mPixelBuffer.setRenderer(mRenderer);
If it is not possible to use version 1.1 for an offscreen render, what is the best way to convert my GL surface to a Bitmap
using version 1.1 or lower?
EDIT: Through some testing, I discovered that using the below code causes these errors:
// int[] version = new int[2];
int[] version = new int[] { // When using this line, as well as the other marked lines, instead of the line above, the errors are produced.
1, 1 // Marked
}; // Marked
int[] attribList = new int[] {
EGL_WIDTH, mWidth,
EGL_HEIGHT, mHeight,
EGL_VERSION, 1, // Marked
EGL_NONE
};
06-11 15:41:52.316: E/libEGL(5618): eglMakeCurrent:674 error 3009 (EGL_BAD_MATCH)
06-11 15:41:52.316: E/libEGL(5618): call to OpenGL ES API with no current context (logged once per thread)
However, neither of these setups alleviate the issue at hand. They are just both present in my PasteBin'd code, so I thought it would be good to point it out.
onDrawFrame
call) give it to me. Evengl.glLoadIdentity()
; my window is literally spammed by them. It's nothing 2.0-specific, which is why this is so odd to me. (However, this doesn't resolve the issue for older 1.1-compatible devices...) – EricsetEGLContextClientVersion
method onGLSurfaceView
that internally sets themEGLContextClientVersion
field. Have a look at how this field is interpreted. – Stefan Hanke