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 
WarpRenderer()36 WarpRenderer::WarpRenderer() : Renderer()
37 {
38     // suppress warnings of unused private fields
39     (void) mTexHandle;
40     (void) mTexCoordHandle;
41     (void) mTriangleVerticesHandle;
42 }
43 
~WarpRenderer()44 WarpRenderer::~WarpRenderer() {
45 }
46 
SetViewportMatrix(int w,int h,int W,int H)47 void WarpRenderer::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 
SetScalingMatrix(float xscale,float yscale)62 void WarpRenderer::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 
InitializeGLProgram()75 bool WarpRenderer::InitializeGLProgram()
76 {
77     bool succeeded = false;
78     do {
79         GLuint glProgram;
80         glProgram = createProgram(VertexShaderSource(),
81                 FragmentShaderSource());
82         if (!glProgram) {
83             break;
84         }
85 
86         glUseProgram(glProgram);
87         if (!checkGlError("glUseProgram")) break;
88 
89         // Get attribute locations
90         mPositionLoc     = glGetAttribLocation(glProgram, "a_position");
91         mAffinetransLoc  = glGetUniformLocation(glProgram, "u_affinetrans");
92         mViewporttransLoc = glGetUniformLocation(glProgram, "u_viewporttrans");
93         mScalingtransLoc = glGetUniformLocation(glProgram, "u_scalingtrans");
94         mTexCoordLoc     = glGetAttribLocation(glProgram, "a_texCoord");
95 
96         // Get sampler location
97         mSamplerLoc      = glGetUniformLocation(glProgram, "s_texture");
98 
99         mGlProgram = glProgram;
100         succeeded = true;
101     } while (false);
102 
103     if (!succeeded && (mGlProgram != 0))
104     {
105         glDeleteProgram(mGlProgram);
106         checkGlError("glDeleteProgram");
107         mGlProgram = 0;
108     }
109     return succeeded;
110 }
111 
DrawTexture(GLfloat * affine)112 bool WarpRenderer::DrawTexture(GLfloat *affine)
113 {
114     bool succeeded = false;
115     do {
116         bool rt = (mFrameBuffer == NULL)?
117                 SetupGraphics(mSurfaceWidth, mSurfaceHeight) :
118                 SetupGraphics(mFrameBuffer);
119 
120         if(!rt)
121             break;
122 
123         glDisable(GL_BLEND);
124 
125         glActiveTexture(GL_TEXTURE0);
126         if (!checkGlError("glActiveTexture")) break;
127 
128         const GLenum texture_type = InputTextureType();
129         glBindTexture(texture_type, mInputTextureName);
130         if (!checkGlError("glBindTexture")) break;
131 
132         // Set the sampler texture unit to 0
133         glUniform1i(mSamplerLoc, 0);
134 
135         // Load the vertex position
136         glVertexAttribPointer(mPositionLoc, 4, GL_FLOAT,
137                 GL_FALSE, VERTEX_STRIDE, g_vVertices);
138 
139         // Load the texture coordinate
140         glVertexAttribPointer(mTexCoordLoc, 2, GL_FLOAT,
141                 GL_FALSE, VERTEX_STRIDE, &g_vVertices[4]);
142 
143         glEnableVertexAttribArray(mPositionLoc);
144         glEnableVertexAttribArray(mTexCoordLoc);
145 
146         // pass matrix information to the vertex shader
147         glUniformMatrix4fv(mAffinetransLoc, 1, GL_FALSE, affine);
148         glUniformMatrix4fv(mViewporttransLoc, 1, GL_FALSE, mViewportMatrix);
149         glUniformMatrix4fv(mScalingtransLoc, 1, GL_FALSE, mScalingMatrix);
150 
151         // And, finally, execute the GL draw command.
152         glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, g_iIndices);
153 
154         checkGlError("glDrawElements");
155 
156         glBindFramebuffer(GL_FRAMEBUFFER, 0);
157         succeeded = true;
158     } while (false);
159     return succeeded;
160 }
161 
VertexShaderSource() const162 const char* WarpRenderer::VertexShaderSource() const
163 {
164     static const char gVertexShader[] =
165         "uniform mat4 u_affinetrans;  \n"
166         "uniform mat4 u_viewporttrans;  \n"
167         "uniform mat4 u_scalingtrans;  \n"
168         "attribute vec4 a_position;   \n"
169         "attribute vec2 a_texCoord;   \n"
170         "varying vec2 v_texCoord;     \n"
171         "void main()                  \n"
172         "{                            \n"
173         "   gl_Position = u_scalingtrans * u_viewporttrans * u_affinetrans * a_position; \n"
174         "   v_texCoord = a_texCoord;  \n"
175         "}                            \n";
176 
177     return gVertexShader;
178 }
179 
FragmentShaderSource() const180 const char* WarpRenderer::FragmentShaderSource() const
181 {
182     static const char gFragmentShader[] =
183         "precision mediump float;                            \n"
184         "varying vec2 v_texCoord;                            \n"
185         "uniform sampler2D s_texture;                        \n"
186         "void main()                                         \n"
187         "{                                                   \n"
188         "  vec4 color;                                       \n"
189         "  color = texture2D(s_texture, v_texCoord);       \n"
190         "  gl_FragColor = color;                             \n"
191         "}                                                   \n";
192 
193     return gFragmentShader;
194 }
195