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