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