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