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