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