1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "SurfaceTextureRenderer.h" 18 19 #include <string.h> 20 21 #include <GLES2/gl2ext.h> 22 const GLfloat g_vVertices[] = { 23 -1.f, -1.f, 0.0f, 1.0f, // Position 0 24 0.0f, 0.0f, // TexCoord 0 25 1.f, -1.f, 0.0f, 1.0f, // Position 1 26 1.0f, 0.0f, // TexCoord 1 27 -1.f, 1.f, 0.0f, 1.0f, // Position 2 28 0.0f, 1.0f, // TexCoord 2 29 1.f, 1.f, 0.0f, 1.0f, // Position 3 30 1.0f, 1.0f // TexCoord 3 31 }; 32 GLushort g_iIndices2[] = { 0, 1, 2, 3 }; 33 34 const int GL_TEXTURE_EXTERNAL_OES_ENUM = 0x8D65; 35 36 const int VERTEX_STRIDE = 6 * sizeof(GLfloat); 37 38 SurfaceTextureRenderer::SurfaceTextureRenderer() : Renderer() { 39 memset(mSTMatrix, 0.0, 16*sizeof(float)); 40 mSTMatrix[0] = 1.0f; 41 mSTMatrix[5] = 1.0f; 42 mSTMatrix[10] = 1.0f; 43 mSTMatrix[15] = 1.0f; 44 } 45 46 SurfaceTextureRenderer::~SurfaceTextureRenderer() { 47 } 48 49 void SurfaceTextureRenderer::SetViewportMatrix(int w, int h, int W, int H) 50 { 51 for(int i=0; i<16; i++) 52 { 53 mViewportMatrix[i] = 0.0f; 54 } 55 56 mViewportMatrix[0] = float(w)/float(W); 57 mViewportMatrix[5] = float(h)/float(H); 58 mViewportMatrix[10] = 1.0f; 59 mViewportMatrix[12] = -1.0f + float(w)/float(W); 60 mViewportMatrix[13] = -1.0f + float(h)/float(H); 61 mViewportMatrix[15] = 1.0f; 62 } 63 64 void SurfaceTextureRenderer::SetScalingMatrix(float xscale, float yscale) 65 { 66 for(int i=0; i<16; i++) 67 { 68 mScalingMatrix[i] = 0.0f; 69 } 70 71 mScalingMatrix[0] = xscale; 72 mScalingMatrix[5] = yscale; 73 mScalingMatrix[10] = 1.0f; 74 mScalingMatrix[15] = 1.0f; 75 } 76 77 void SurfaceTextureRenderer::SetSTMatrix(float *stmat) 78 { 79 memcpy(mSTMatrix, stmat, 16*sizeof(float)); 80 } 81 82 83 bool SurfaceTextureRenderer::InitializeGLProgram() 84 { 85 bool succeeded = false; 86 do { 87 GLuint glProgram; 88 glProgram = createProgram(VertexShaderSource(), 89 FragmentShaderSource()); 90 if (!glProgram) { 91 break; 92 } 93 94 glUseProgram(glProgram); 95 if (!checkGlError("glUseProgram")) break; 96 97 maPositionHandle = glGetAttribLocation(glProgram, "aPosition"); 98 checkGlError("glGetAttribLocation aPosition"); 99 maTextureHandle = glGetAttribLocation(glProgram, "aTextureCoord"); 100 checkGlError("glGetAttribLocation aTextureCoord"); 101 muSTMatrixHandle = glGetUniformLocation(glProgram, "uSTMatrix"); 102 checkGlError("glGetUniformLocation uSTMatrix"); 103 mScalingtransLoc = glGetUniformLocation(glProgram, "u_scalingtrans"); 104 105 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 106 mGlProgram = glProgram; 107 succeeded = true; 108 } while (false); 109 110 if (!succeeded && (mGlProgram != 0)) 111 { 112 glDeleteProgram(mGlProgram); 113 checkGlError("glDeleteProgram"); 114 mGlProgram = 0; 115 } 116 return succeeded; 117 } 118 119 bool SurfaceTextureRenderer::DrawTexture(GLfloat *affine) 120 { 121 bool succeeded = false; 122 do { 123 bool rt = (mFrameBuffer == NULL)? 124 SetupGraphics(mSurfaceWidth, mSurfaceHeight) : 125 SetupGraphics(mFrameBuffer); 126 127 if(!rt) 128 break; 129 130 glDisable(GL_BLEND); 131 132 glActiveTexture(GL_TEXTURE0); 133 if (!checkGlError("glActiveTexture")) break; 134 135 const GLenum texture_type = InputTextureType(); 136 glBindTexture(texture_type, mInputTextureName); 137 if (!checkGlError("glBindTexture")) break; 138 139 glUniformMatrix4fv(mScalingtransLoc, 1, GL_FALSE, mScalingMatrix); 140 glUniformMatrix4fv(muSTMatrixHandle, 1, GL_FALSE, mSTMatrix); 141 142 // Load the vertex position 143 glVertexAttribPointer(maPositionHandle, 4, GL_FLOAT, 144 GL_FALSE, VERTEX_STRIDE, g_vVertices); 145 glEnableVertexAttribArray(maPositionHandle); 146 // Load the texture coordinate 147 glVertexAttribPointer(maTextureHandle, 2, GL_FLOAT, 148 GL_FALSE, VERTEX_STRIDE, &g_vVertices[4]); 149 glEnableVertexAttribArray(maTextureHandle); 150 151 // And, finally, execute the GL draw command. 152 glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, g_iIndices2); 153 154 glBindFramebuffer(GL_FRAMEBUFFER, 0); 155 succeeded = true; 156 } while (false); 157 return succeeded; 158 } 159 160 const char* SurfaceTextureRenderer::VertexShaderSource() const 161 { 162 static const char gVertexShader[] = 163 "uniform mat4 uSTMatrix;\n" 164 "uniform mat4 u_scalingtrans; \n" 165 "attribute vec4 aPosition;\n" 166 "attribute vec4 aTextureCoord;\n" 167 "varying vec2 vTextureNormCoord;\n" 168 "void main() {\n" 169 " gl_Position = u_scalingtrans * aPosition;\n" 170 " vTextureNormCoord = (uSTMatrix * aTextureCoord).xy;\n" 171 "}\n"; 172 173 return gVertexShader; 174 } 175 176 const char* SurfaceTextureRenderer::FragmentShaderSource() const 177 { 178 static const char gFragmentShader[] = 179 "#extension GL_OES_EGL_image_external : require\n" 180 "precision mediump float;\n" 181 "varying vec2 vTextureNormCoord;\n" 182 "uniform samplerExternalOES sTexture;\n" 183 "void main() {\n" 184 " gl_FragColor = texture2D(sTexture, vTextureNormCoord);\n" 185 "}\n"; 186 187 return gFragmentShader; 188 } 189