/* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "SurfaceTextureRenderer.h" #include <GLES2/gl2ext.h> const GLfloat g_vVertices[] = { -1.f, -1.f, 0.0f, 1.0f, // Position 0 0.0f, 0.0f, // TexCoord 0 1.f, -1.f, 0.0f, 1.0f, // Position 1 1.0f, 0.0f, // TexCoord 1 -1.f, 1.f, 0.0f, 1.0f, // Position 2 0.0f, 1.0f, // TexCoord 2 1.f, 1.f, 0.0f, 1.0f, // Position 3 1.0f, 1.0f // TexCoord 3 }; GLushort g_iIndices2[] = { 0, 1, 2, 3 }; const int GL_TEXTURE_EXTERNAL_OES_ENUM = 0x8D65; const int VERTEX_STRIDE = 6 * sizeof(GLfloat); SurfaceTextureRenderer::SurfaceTextureRenderer() : Renderer() { memset(mSTMatrix, 0.0, 16*sizeof(float)); mSTMatrix[0] = 1.0f; mSTMatrix[5] = 1.0f; mSTMatrix[10] = 1.0f; mSTMatrix[15] = 1.0f; } SurfaceTextureRenderer::~SurfaceTextureRenderer() { } void SurfaceTextureRenderer::SetViewportMatrix(int w, int h, int W, int H) { for(int i=0; i<16; i++) { mViewportMatrix[i] = 0.0f; } mViewportMatrix[0] = float(w)/float(W); mViewportMatrix[5] = float(h)/float(H); mViewportMatrix[10] = 1.0f; mViewportMatrix[12] = -1.0f + float(w)/float(W); mViewportMatrix[13] = -1.0f + float(h)/float(H); mViewportMatrix[15] = 1.0f; } void SurfaceTextureRenderer::SetScalingMatrix(float xscale, float yscale) { for(int i=0; i<16; i++) { mScalingMatrix[i] = 0.0f; } mScalingMatrix[0] = xscale; mScalingMatrix[5] = yscale; mScalingMatrix[10] = 1.0f; mScalingMatrix[15] = 1.0f; } void SurfaceTextureRenderer::SetSTMatrix(float *stmat) { memcpy(mSTMatrix, stmat, 16*sizeof(float)); } bool SurfaceTextureRenderer::InitializeGLProgram() { bool succeeded = false; do { GLuint glProgram; glProgram = createProgram(VertexShaderSource(), FragmentShaderSource()); if (!glProgram) { break; } glUseProgram(glProgram); if (!checkGlError("glUseProgram")) break; maPositionHandle = glGetAttribLocation(glProgram, "aPosition"); checkGlError("glGetAttribLocation aPosition"); maTextureHandle = glGetAttribLocation(glProgram, "aTextureCoord"); checkGlError("glGetAttribLocation aTextureCoord"); muSTMatrixHandle = glGetUniformLocation(glProgram, "uSTMatrix"); checkGlError("glGetUniformLocation uSTMatrix"); mScalingtransLoc = glGetUniformLocation(glProgram, "u_scalingtrans"); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); mGlProgram = glProgram; succeeded = true; } while (false); if (!succeeded && (mGlProgram != 0)) { glDeleteProgram(mGlProgram); checkGlError("glDeleteProgram"); mGlProgram = 0; } return succeeded; } bool SurfaceTextureRenderer::DrawTexture(GLfloat *affine) { bool succeeded = false; do { bool rt = (mFrameBuffer == NULL)? SetupGraphics(mSurfaceWidth, mSurfaceHeight) : SetupGraphics(mFrameBuffer); if(!rt) break; glDisable(GL_BLEND); glActiveTexture(GL_TEXTURE0); if (!checkGlError("glActiveTexture")) break; const GLenum texture_type = InputTextureType(); glBindTexture(texture_type, mInputTextureName); if (!checkGlError("glBindTexture")) break; glUniformMatrix4fv(mScalingtransLoc, 1, GL_FALSE, mScalingMatrix); glUniformMatrix4fv(muSTMatrixHandle, 1, GL_FALSE, mSTMatrix); // Load the vertex position glVertexAttribPointer(maPositionHandle, 4, GL_FLOAT, GL_FALSE, VERTEX_STRIDE, g_vVertices); glEnableVertexAttribArray(maPositionHandle); // Load the texture coordinate glVertexAttribPointer(maTextureHandle, 2, GL_FLOAT, GL_FALSE, VERTEX_STRIDE, &g_vVertices[4]); glEnableVertexAttribArray(maTextureHandle); // And, finally, execute the GL draw command. glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, g_iIndices2); glBindFramebuffer(GL_FRAMEBUFFER, 0); succeeded = true; } while (false); return succeeded; } const char* SurfaceTextureRenderer::VertexShaderSource() const { static const char gVertexShader[] = "uniform mat4 uSTMatrix;\n" "uniform mat4 u_scalingtrans; \n" "attribute vec4 aPosition;\n" "attribute vec4 aTextureCoord;\n" "varying vec2 vTextureNormCoord;\n" "void main() {\n" " gl_Position = u_scalingtrans * aPosition;\n" " vTextureNormCoord = (uSTMatrix * aTextureCoord).xy;\n" "}\n"; return gVertexShader; } const char* SurfaceTextureRenderer::FragmentShaderSource() const { static const char gFragmentShader[] = "#extension GL_OES_EGL_image_external : require\n" "precision mediump float;\n" "varying vec2 vTextureNormCoord;\n" "uniform samplerExternalOES sTexture;\n" "void main() {\n" " gl_FragColor = texture2D(sTexture, vTextureNormCoord);\n" "}\n"; return gFragmentShader; }