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 "YVURenderer.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_iIndices3[] = { 0, 1, 2, 3 };
35
YVURenderer()36 YVURenderer::YVURenderer() : Renderer()
37 {
38 }
39
~YVURenderer()40 YVURenderer::~YVURenderer() {
41 }
42
InitializeGLProgram()43 bool YVURenderer::InitializeGLProgram()
44 {
45 bool succeeded = false;
46 do {
47 GLuint glProgram;
48 glProgram = createProgram(VertexShaderSource(),
49 FragmentShaderSource());
50 if (!glProgram) {
51 break;
52 }
53
54 glUseProgram(glProgram);
55 if (!checkGlError("glUseProgram")) break;
56
57 // Get attribute locations
58 mPositionLoc = glGetAttribLocation(glProgram, "a_Position");
59 mTexCoordLoc = glGetAttribLocation(glProgram, "a_texCoord");
60
61 // Get sampler location
62 mSamplerLoc = glGetUniformLocation(glProgram, "s_texture");
63
64 mGlProgram = glProgram;
65 succeeded = true;
66 } while (false);
67
68 if (!succeeded && (mGlProgram != 0))
69 {
70 glDeleteProgram(mGlProgram);
71 checkGlError("glDeleteProgram");
72 mGlProgram = 0;
73 }
74 return succeeded;
75 }
76
DrawTexture()77 bool YVURenderer::DrawTexture()
78 {
79 bool succeeded = false;
80 do {
81 bool rt = (mFrameBuffer == NULL)?
82 SetupGraphics(mSurfaceWidth, mSurfaceHeight) :
83 SetupGraphics(mFrameBuffer);
84
85 if(!rt)
86 break;
87
88 glDisable(GL_BLEND);
89
90 glActiveTexture(GL_TEXTURE0);
91 if (!checkGlError("glActiveTexture")) break;
92
93 const GLenum texture_type = InputTextureType();
94 glBindTexture(texture_type, mInputTextureName);
95 if (!checkGlError("glBindTexture")) break;
96
97 // Set the sampler texture unit to 0
98 glUniform1i(mSamplerLoc, 0);
99
100 // Load the vertex position
101 glVertexAttribPointer(mPositionLoc, 4, GL_FLOAT,
102 GL_FALSE, VERTEX_STRIDE, g_vVertices);
103
104 // Load the texture coordinate
105 glVertexAttribPointer(mTexCoordLoc, 2, GL_FLOAT,
106 GL_FALSE, VERTEX_STRIDE, &g_vVertices[4]);
107
108 glEnableVertexAttribArray(mPositionLoc);
109 glEnableVertexAttribArray(mTexCoordLoc);
110
111 // And, finally, execute the GL draw command.
112 glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, g_iIndices3);
113
114 checkGlError("glDrawElements");
115
116 glBindFramebuffer(GL_FRAMEBUFFER, 0);
117 succeeded = true;
118 } while (false);
119 return succeeded;
120 }
121
VertexShaderSource() const122 const char* YVURenderer::VertexShaderSource() const
123 {
124 // All this really does is copy the coordinates into
125 // variables for the fragment shader to pick up.
126 static const char gVertexShader[] =
127 "attribute vec4 a_Position;\n"
128 "attribute vec2 a_texCoord;\n"
129 "varying vec2 v_texCoord;\n"
130 "void main() {\n"
131 " gl_Position = a_Position;\n"
132 " v_texCoord = a_texCoord;\n"
133 "}\n";
134
135 return gVertexShader;
136 }
137
FragmentShaderSource() const138 const char* YVURenderer::FragmentShaderSource() const
139 {
140 static const char gFragmentShader[] =
141 "precision mediump float;\n"
142 "uniform sampler2D s_texture;\n"
143 "const vec4 coeff_y = vec4(0.257, 0.594, 0.098, 0.063);\n"
144 "const vec4 coeff_v = vec4(0.439, -0.368, -0.071, 0.500);\n"
145 "const vec4 coeff_u = vec4(-0.148, -0.291, 0.439, 0.500);\n"
146 "varying vec2 v_texCoord;\n"
147 "void main() {\n"
148 " vec4 p;\n"
149 " p = texture2D(s_texture, v_texCoord);\n"
150 " gl_FragColor[0] = dot(p, coeff_y);\n"
151 " p = texture2D(s_texture, v_texCoord);\n"
152 " gl_FragColor[1] = dot(p, coeff_v);\n"
153 " p = texture2D(s_texture, v_texCoord);\n"
154 " gl_FragColor[2] = dot(p, coeff_u);\n"
155 " p = texture2D(s_texture, v_texCoord);\n"
156 " gl_FragColor[3] = dot(p, coeff_y);\n"
157 "}\n";
158
159 return gFragmentShader;
160 }
161