There's no need to get the camera preview out of SurfaceTexture. The whole
point of SurfaceTexture is to let a producer like the camera render into an
OpenGL texture. Just use SurfaceTexture.

To draw on top of TextureView, just add another view on top of it.
On Dec 21, 2011 9:35 PM, "Brad Grimm" <sna...@gmail.com> wrote:

> Thanks for the post, it has been really helpful.
>
> But say I want to draw on top of a SurfaceTexture that is connected to
> a Camera via setPreviewTexture. I can get the SurfaceTexture by a
> SurfaceTextureListener. But if I just try to use
> eglCreateWindowSurface & eglMakeCurrent it fails due to the surface
> already being connected.
> 1) Is it possible to draw on this surface at all? Or does binding it
> to the camera make it impossible to do that.
> 2) If it isn't possible. Can the surface be used (or copied) quickly
> to an OpenGL texture and used in a separate surface? If so how?
> 3) If not, what would be the fastest way to get the camera preview out
> of a SurfaceTexture and into OpenGL?
> P.S. - I too followed suit and posted to StackOverflow:
>
> http://stackoverflow.com/questions/8582090/possible-to-draw-on-surfacetexture-attached-to-camera
> On Nov 23, 11:45 am, plafayette <pierre.lafaye...@gmail.com> wrote:
> > Thanks for the quick response Romain and the sample code! Will give it
> > a try.
> >
> > On Nov 23, 12:17 pm, Romain Guy <romain...@android.com> wrote:
> >
> >
> >
> >
> >
> >
> >
> > > GLSurfaceView handles GL setup for you, whichTextureViewwill not do. A
> > >TextureViewcan be used as the native window when you create an EGL
> > > surface. Here is an example (the interesting part is the call
> > > to eglCreateWindowSurface()):
> >
> > >     @Override
> > >     public void onSurfaceTextureAvailable(SurfaceTexture surface, int
> > > width, int height) {
> > >         mRenderThread = new RenderThread(getResources(), surface);
> > >         mRenderThread.start();
> > >     }
> >
> > >     private static class RenderThread extends Thread {
> > >         private static final String LOG_TAG = "GLTextureView";
> >
> > >         static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
> > >         static final int EGL_OPENGL_ES2_BIT = 4;
> >
> > >         private volatile boolean mFinished;
> >
> > >         private final Resources mResources;
> > >         private final SurfaceTexture mSurface;
> >
> > >         private EGL10 mEgl;
> > >         private EGLDisplay mEglDisplay;
> > >         private EGLConfig mEglConfig;
> > >         private EGLContext mEglContext;
> > >         private EGLSurface mEglSurface;
> > >         private GL mGL;
> >
> > >         RenderThread(Resources resources, SurfaceTexture surface) {
> > >             mResources = resources;
> > >             mSurface = surface;
> > >         }
> >
> > >         private static final String sSimpleVS =
> > >                 "attribute vec4 position;\n" +
> > >                 "attribute vec2 texCoords;\n" +
> > >                 "varying vec2 outTexCoords;\n" +
> > >                 "\nvoid main(void) {\n" +
> > >                 "    outTexCoords = texCoords;\n" +
> > >                 "    gl_Position = position;\n" +
> > >                 "}\n\n";
> > >         private static final String sSimpleFS =
> > >                 "precision mediump float;\n\n" +
> > >                 "varying vec2 outTexCoords;\n" +
> > >                 "uniform sampler2D texture;\n" +
> > >                 "\nvoid main(void) {\n" +
> > >                 "    gl_FragColor = texture2D(texture,
> outTexCoords);\n" +
> > >                 "}\n\n";
> >
> > >         private static final int FLOAT_SIZE_BYTES = 4;
> > >         private static final int TRIANGLE_VERTICES_DATA_STRIDE_BYTES =
> 5 *
> > > FLOAT_SIZE_BYTES;
> > >         private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0;
> > >         private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3;
> > >         private final float[] mTriangleVerticesData = {
> > >                 // X, Y, Z, U, V
> > >                 -1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
> > >                  1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
> > >                 -1.0f,  1.0f, 0.0f, 0.0f, 1.0f,
> > >                  1.0f,  1.0f, 0.0f, 1.0f, 1.0f,
> > >         };
> >
> > >         @Override
> > >         public void run() {
> > >             initGL();
> >
> > >             FloatBuffer triangleVertices =
> > > ByteBuffer.allocateDirect(mTriangleVerticesData.length
> > >                     *
> > > FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
> > >             triangleVertices.put(mTriangleVerticesData).position(0);
> >
> > >             int texture = loadTexture(R.drawable.large_photo);
> > >             int program = buildProgram(sSimpleVS, sSimpleFS);
> >
> > >             int attribPosition = glGetAttribLocation(program,
> "position");
> > >             checkGlError();
> >
> > >             int attribTexCoords = glGetAttribLocation(program,
> "texCoords");
> > >             checkGlError();
> >
> > >             int uniformTexture = glGetUniformLocation(program,
> "texture");
> > >             checkGlError();
> >
> > >             glBindTexture(GL_TEXTURE_2D, texture);
> > >             checkGlError();
> >
> > >             glUseProgram(program);
> > >             checkGlError();
> >
> > >             glEnableVertexAttribArray(attribPosition);
> > >             checkGlError();
> >
> > >             glEnableVertexAttribArray(attribTexCoords);
> > >             checkGlError();
> >
> > >             glUniform1i(uniformTexture, texture);
> > >             checkGlError();
> >
> > >             while (!mFinished) {
> > >                 checkCurrent();
> >
> > >                 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
> > >                 checkGlError();
> >
> > >                 glClear(GL_COLOR_BUFFER_BIT);
> > >                 checkGlError();
> >
> > >                 // drawQuad
> >
> > > triangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
> > >                 glVertexAttribPointer(attribPosition, 3, GL_FLOAT,
> false,
> > >                         TRIANGLE_VERTICES_DATA_STRIDE_BYTES,
> > > triangleVertices);
> >
> > >
> triangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET);
> > >                 glVertexAttribPointer(attribTexCoords, 3, GL_FLOAT,
> false,
> > >                         TRIANGLE_VERTICES_DATA_STRIDE_BYTES,
> > > triangleVertices);
> >
> > >                 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
> >
> > >                 if (!mEgl.eglSwapBuffers(mEglDisplay, mEglSurface)) {
> > >                     throw new RuntimeException("Cannot swap buffers");
> > >                 }
> > >                 checkEglError();
> >
> > >                 try {
> > >                     Thread.sleep(2000);
> > >                 } catch (InterruptedException e) {
> > >                     // Ignore
> > >                 }
> > >             }
> >
> > >             finishGL();
> > >         }
> >
> > >         private int loadTexture(int resource) {
> > >             int[] textures = new int[1];
> >
> > >             glActiveTexture(GL_TEXTURE0);
> > >             glGenTextures(1, textures, 0);
> > >             checkGlError();
> >
> > >             int texture = textures[0];
> > >             glBindTexture(GL_TEXTURE_2D, texture);
> > >             checkGlError();
> >
> > >             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
> > > GL_LINEAR);
> > >             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
> > > GL_LINEAR);
> >
> > >             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
> > > GL_CLAMP_TO_EDGE);
> > >             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
> > > GL_CLAMP_TO_EDGE);
> >
> > >             Bitmap bitmap = BitmapFactory.decodeResource(mResources,
> > > resource);
> >
> > >             GLUtils.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bitmap,
> > > GL_UNSIGNED_BYTE, 0);
> > >             checkGlError();
> >
> > >             bitmap.recycle();
> >
> > >             return texture;
> > >         }
> >
> > >         private int buildProgram(String vertex, String fragment) {
> > >             int vertexShader = buildShader(vertex, GL_VERTEX_SHADER);
> > >             if (vertexShader == 0) return 0;
> >
> > >             int fragmentShader = buildShader(fragment,
> GL_FRAGMENT_SHADER);
> > >             if (fragmentShader == 0) return 0;
> >
> > >             int program = glCreateProgram();
> > >             glAttachShader(program, vertexShader);
> > >             checkGlError();
> >
> > >             glAttachShader(program, fragmentShader);
> > >             checkGlError();
> >
> > >             glLinkProgram(program);
> > >             checkGlError();
> >
> > >             int[] status = new int[1];
> > >             glGetProgramiv(program, GL_LINK_STATUS, status, 0);
> > >             if (status[0] != GL_TRUE) {
> > >                 String error = glGetProgramInfoLog(program);
> > >                 Log.d(LOG_TAG, "Error while linking program:\n" +
> error);
> > >                 glDeleteShader(vertexShader);
> > >                 glDeleteShader(fragmentShader);
> > >                 glDeleteProgram(program);
> > >                 return 0;
> > >             }
> >
> > >             return program;
> > >         }
> >
> > >         private int buildShader(String source, int type) {
> > >             int shader = glCreateShader(type);
> >
> > >             glShaderSource(shader, source);
> > >             checkGlError();
> >
> > >             glCompileShader(shader);
> > >             checkGlError();
> >
> > >             int[] status = new int[1];
> > >             glGetShaderiv(shader, GL_COMPILE_STATUS, status, 0);
> > >             if (status[0] != GL_TRUE) {
> > >                 String error = glGetShaderInfoLog(shader);
> > >                 Log.d(LOG_TAG, "Error while compiling shader:\n" +
> error);
> > >                 glDeleteShader(shader);
> > >                 return 0;
> > >             }
> >
> > >             return shader;
> > >         }
> >
> > >         private void checkEglError() {
> > >             int error = mEgl.eglGetError();
> > >             if (error != EGL10.EGL_SUCCESS) {
> > >                 Log.w(LOG_TAG, "EGL error = 0x" +
> > > Integer.toHexString(error));
> > >             }
> > >         }
> >
> > >         private void checkGlError() {
> > >             int error = glGetError();
> > >             if (error != GL_NO_ERROR) {
> > >                 Log.w(LOG_TAG, "GL error = 0x" +
> > > Integer.toHexString(error));
> > >             }
> > >         }
> >
> > >         private void finishGL() {
> > >             mEgl.eglDestroyContext(mEglDisplay, mEglContext);
> > >             mEgl.eglDestroySurface(mEglDisplay, mEglSurface);
> > >         }
> >
> > >         private void checkCurrent() {
> > >             if (!mEglContext.equals(mEgl.eglGetCurrentContext()) ||
> >
> > > !mEglSurface.equals(mEgl.eglGetCurrentSurface(EGL10.EGL_DRAW))) {
> > >                 if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface,
> > > mEglSurface, mEglContext)) {
> > >                    ...
> >
> > read more ยป
>
> --
> You received this message because you are subscribed to the Google
> Groups "Android Developers" group.
> To post to this group, send email to android-developers@googlegroups.com
> To unsubscribe from this group, send email to
> android-developers+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/android-developers?hl=en
>

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Reply via email to