I am pretty much late in the party.. but this is awesome, I did the same 
and now I can run shaders on screen with cam2 api :)
but I want to change them on run time i.e. without closing the camera or 
disturbing UX.  

On Thursday, December 22, 2011 at 10:46:46 PM UTC+5:30, Romain Guy wrote:
>
> It is definitely an option, that's what SurfaceTexture is for. It's very 
> simple:
>
> Create an OpenGL context
> Generate an OpenGL texture name
> Create a SurfaceTexture with the texture name
> Pass the SurfaceTexture to Camera
> Listen for updates
> On SurfaceTexture update, draw the texture with OpenGL using the shader 
> you want
>
> Simple :)
>
> On Thu, Dec 22, 2011 at 11:59 AM, Brad Grimm <sna...@gmail.com 
> <javascript:>> wrote:
> > Thanks Romain.  I really just want to swap out the pixel shader on the
> > SurfaceTexture's OpenGL texture so I can do some filtering on the
> > camera preview.  But it sounds like that isn't an option.   I have
> > used ColorMatrixFilters on the view itself and they work quite well,
> > just not powerful enough for what I want to do.
> >
> > On Dec 21, 8:18 pm, Romain Guy <romain...@android.com> wrote:
> >> 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-surfac.
> ..
> >> > 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;
> >> > > >             }
> >>
> >> ...
> >>
> >> 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-d...@googlegroups.com 
> <javascript:>
> > To unsubscribe from this group, send email to
> > android-developers+unsubscr...@googlegroups.com <javascript:>
> > For more options, visit this group at
> > http://groups.google.com/group/android-developers?hl=en
>
> -- 
> Romain Guy
> Android framework engineer
> roma...@android.com <javascript:>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Android Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to android-developers+unsubscr...@googlegroups.com.
To post to this group, send email to android-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/android-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/android-developers/37982e7c-4ac2-4528-9577-411c62f554f9%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to