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