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 }
39 
~WarpRenderer()40 WarpRenderer::~WarpRenderer() {
41 }
42 
SetViewportMatrix(int w,int h,int W,int H)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 
SetScalingMatrix(float xscale,float yscale)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 
InitializeGLProgram()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 
DrawTexture(GLfloat * affine)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 
VertexShaderSource() const158 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 
FragmentShaderSource() const176 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