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 <GLES2/gl2ext.h> 20 const GLfloat g_vVertices[] = { 21 -1.f, -1.f, 0.0f, 1.0f, // Position 0 22 0.0f, 0.0f, // TexCoord 0 23 1.f, -1.f, 0.0f, 1.0f, // Position 1 24 1.0f, 0.0f, // TexCoord 1 25 -1.f, 1.f, 0.0f, 1.0f, // Position 2 26 0.0f, 1.0f, // TexCoord 2 27 1.f, 1.f, 0.0f, 1.0f, // Position 3 28 1.0f, 1.0f // TexCoord 3 29 }; 30 GLushort g_iIndices2[] = { 0, 1, 2, 3 }; 31 32 const int GL_TEXTURE_EXTERNAL_OES_ENUM = 0x8D65; 33 34 const int VERTEX_STRIDE = 6 * sizeof(GLfloat); 35 36 SurfaceTextureRenderer::SurfaceTextureRenderer() : Renderer() { 37 memset(mSTMatrix, 0.0, 16*sizeof(float)); 38 mSTMatrix[0] = 1.0f; 39 mSTMatrix[5] = 1.0f; 40 mSTMatrix[10] = 1.0f; 41 mSTMatrix[15] = 1.0f; 42 } 43 44 SurfaceTextureRenderer::~SurfaceTextureRenderer() { 45 } 46 47 void SurfaceTextureRenderer::SetViewportMatrix(int w, int h, int W, int H) 48 { 49 for(int i=0; i<16; i++) 50 { 51 mViewportMatrix[i] = 0.0f; 52 } 53 54 mViewportMatrix[0] = float(w)/float(W); 55 mViewportMatrix[5] = float(h)/float(H); 56 mViewportMatrix[10] = 1.0f; 57 mViewportMatrix[12] = -1.0f + float(w)/float(W); 58 mViewportMatrix[13] = -1.0f + float(h)/float(H); 59 mViewportMatrix[15] = 1.0f; 60 } 61 62 void SurfaceTextureRenderer::SetScalingMatrix(float xscale, float yscale) 63 { 64 for(int i=0; i<16; i++) 65 { 66 mScalingMatrix[i] = 0.0f; 67 } 68 69 mScalingMatrix[0] = xscale; 70 mScalingMatrix[5] = yscale; 71 mScalingMatrix[10] = 1.0f; 72 mScalingMatrix[15] = 1.0f; 73 } 74 75 void SurfaceTextureRenderer::SetSTMatrix(float *stmat) 76 { 77 memcpy(mSTMatrix, stmat, 16*sizeof(float)); 78 } 79 80 81 bool SurfaceTextureRenderer::InitializeGLProgram() 82 { 83 bool succeeded = false; 84 do { 85 GLuint glProgram; 86 glProgram = createProgram(VertexShaderSource(), 87 FragmentShaderSource()); 88 if (!glProgram) { 89 break; 90 } 91 92 glUseProgram(glProgram); 93 if (!checkGlError("glUseProgram")) break; 94 95 maPositionHandle = glGetAttribLocation(glProgram, "aPosition"); 96 checkGlError("glGetAttribLocation aPosition"); 97 maTextureHandle = glGetAttribLocation(glProgram, "aTextureCoord"); 98 checkGlError("glGetAttribLocation aTextureCoord"); 99 muSTMatrixHandle = glGetUniformLocation(glProgram, "uSTMatrix"); 100 checkGlError("glGetUniformLocation uSTMatrix"); 101 mScalingtransLoc = glGetUniformLocation(glProgram, "u_scalingtrans"); 102 103 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 104 mGlProgram = glProgram; 105 succeeded = true; 106 } while (false); 107 108 if (!succeeded && (mGlProgram != 0)) 109 { 110 glDeleteProgram(mGlProgram); 111 checkGlError("glDeleteProgram"); 112 mGlProgram = 0; 113 } 114 return succeeded; 115 } 116 117 bool SurfaceTextureRenderer::DrawTexture(GLfloat *affine) 118 { 119 bool succeeded = false; 120 do { 121 bool rt = (mFrameBuffer == NULL)? 122 SetupGraphics(mSurfaceWidth, mSurfaceHeight) : 123 SetupGraphics(mFrameBuffer); 124 125 if(!rt) 126 break; 127 128 glDisable(GL_BLEND); 129 130 glActiveTexture(GL_TEXTURE0); 131 if (!checkGlError("glActiveTexture")) break; 132 133 const GLenum texture_type = InputTextureType(); 134 glBindTexture(texture_type, mInputTextureName); 135 if (!checkGlError("glBindTexture")) break; 136 137 glUniformMatrix4fv(mScalingtransLoc, 1, GL_FALSE, mScalingMatrix); 138 glUniformMatrix4fv(muSTMatrixHandle, 1, GL_FALSE, mSTMatrix); 139 140 // Load the vertex position 141 glVertexAttribPointer(maPositionHandle, 4, GL_FLOAT, 142 GL_FALSE, VERTEX_STRIDE, g_vVertices); 143 glEnableVertexAttribArray(maPositionHandle); 144 // Load the texture coordinate 145 glVertexAttribPointer(maTextureHandle, 2, GL_FLOAT, 146 GL_FALSE, VERTEX_STRIDE, &g_vVertices[4]); 147 glEnableVertexAttribArray(maTextureHandle); 148 149 // And, finally, execute the GL draw command. 150 glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, g_iIndices2); 151 152 glBindFramebuffer(GL_FRAMEBUFFER, 0); 153 succeeded = true; 154 } while (false); 155 return succeeded; 156 } 157 158 const char* SurfaceTextureRenderer::VertexShaderSource() const 159 { 160 static const char gVertexShader[] = 161 "uniform mat4 uSTMatrix;\n" 162 "uniform mat4 u_scalingtrans; \n" 163 "attribute vec4 aPosition;\n" 164 "attribute vec4 aTextureCoord;\n" 165 "varying vec2 vTextureNormCoord;\n" 166 "void main() {\n" 167 " gl_Position = u_scalingtrans * aPosition;\n" 168 " vTextureNormCoord = (uSTMatrix * aTextureCoord).xy;\n" 169 "}\n"; 170 171 return gVertexShader; 172 } 173 174 const char* SurfaceTextureRenderer::FragmentShaderSource() const 175 { 176 static const char gFragmentShader[] = 177 "#extension GL_OES_EGL_image_external : require\n" 178 "precision mediump float;\n" 179 "varying vec2 vTextureNormCoord;\n" 180 "uniform samplerExternalOES sTexture;\n" 181 "void main() {\n" 182 " gl_FragColor = texture2D(sTexture, vTextureNormCoord);\n" 183 "}\n"; 184 185 return gFragmentShader; 186 } 187