diff options
Diffstat (limited to 'jni/feature_mos/src/mosaic_renderer/SurfaceTextureRenderer.cpp')
-rwxr-xr-x | jni/feature_mos/src/mosaic_renderer/SurfaceTextureRenderer.cpp | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/jni/feature_mos/src/mosaic_renderer/SurfaceTextureRenderer.cpp b/jni/feature_mos/src/mosaic_renderer/SurfaceTextureRenderer.cpp new file mode 100755 index 000000000..88aac3626 --- /dev/null +++ b/jni/feature_mos/src/mosaic_renderer/SurfaceTextureRenderer.cpp @@ -0,0 +1,186 @@ +/* + * 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; +} |