| /* |
| * 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 <string.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; |
| } |