1 /*
2  * Copyright (C) 2012 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 "Flatland.h"
18 #include "GLHelper.h"
19 
20 namespace android {
21 
22 static float colors[][4] = {
23     { .85f, .14f, .44f, 1.0f },
24     { .91f, .72f, .10f, 1.0f },
25     { .04f, .66f, .42f, 1.0f },
26     { .84f, .39f, .68f, 1.0f },
27     { .38f, .53f, .78f, 1.0f },
28 };
29 
30 static size_t g_colorIndex;
31 
genColor()32 const float* genColor() {
33     float* color = colors[g_colorIndex];
34     g_colorIndex = (g_colorIndex + 1) % NELEMS(colors);
35     return color;
36 }
37 
resetColorGenerator()38 void resetColorGenerator() {
39     g_colorIndex = 0;
40 }
41 
42 class GradientRenderer {
43 
44 public:
45 
setUp(GLHelper * helper)46     bool setUp(GLHelper* helper) {
47         bool result;
48 
49         result = helper->getShaderProgram("Gradient", &mGradPgm);
50         if (!result) {
51             return false;
52         }
53 
54         result = helper->getDitherTexture(&mDitherTexName);
55         if (!result) {
56             return false;
57         }
58 
59         mPosAttribLoc = glGetAttribLocation(mGradPgm, "position");
60         mUVAttribLoc = glGetAttribLocation(mGradPgm, "uv");
61         mUVToInterpUniformLoc = glGetUniformLocation(mGradPgm, "uvToInterp");
62         mObjToNdcUniformLoc = glGetUniformLocation(mGradPgm, "objToNdc");
63         mDitherKernelSamplerLoc = glGetUniformLocation(mGradPgm, "ditherKernel");
64         mInvDitherKernelSizeUniformLoc = glGetUniformLocation(mGradPgm,
65                 "invDitherKernelSize");
66         mInvDitherKernelSizeSqUniformLoc = glGetUniformLocation(mGradPgm,
67                 "invDitherKernelSizeSq");
68         mColor0UniformLoc = glGetUniformLocation(mGradPgm, "color0");
69         mColor1UniformLoc = glGetUniformLocation(mGradPgm, "color1");
70 
71         return true;
72     }
73 
tearDown()74     void tearDown() {
75     }
76 
drawGradient()77     bool drawGradient() {
78         float identity[16] = {
79             1.0f,   0.0f,   0.0f,   0.0f,
80             0.0f,   1.0f,   0.0f,   0.0f,
81             0.0f,   0.0f,   1.0f,   0.0f,
82             0.0f,   0.0f,   0.0f,   1.0f,
83         };
84         const float pos[] = {
85             -1.0f,  -1.0f,
86             1.0f,   -1.0f,
87             -1.0f,  1.0f,
88             1.0f,   1.0f,
89         };
90         const float uv[] = {
91             0.0f, 0.0f,
92             1.0f, 0.0f,
93             0.0f, 1.0f,
94             1.0f, 1.0f,
95         };
96         const float* color0 = genColor();
97         const float* color1 = genColor();
98 
99         glUseProgram(mGradPgm);
100 
101         glVertexAttribPointer(mPosAttribLoc, 2, GL_FLOAT, GL_FALSE, 0, pos);
102         glVertexAttribPointer(mUVAttribLoc, 2, GL_FLOAT, GL_FALSE, 0, uv);
103         glEnableVertexAttribArray(mPosAttribLoc);
104         glEnableVertexAttribArray(mUVAttribLoc);
105 
106         float invDitherKernelSize = 1.0f / float(GLHelper::DITHER_KERNEL_SIZE);
107         float invDitherKernelSizeSq = invDitherKernelSize * invDitherKernelSize;
108 
109         glUniformMatrix4fv(mObjToNdcUniformLoc, 1, GL_FALSE, identity);
110         glUniformMatrix4fv(mUVToInterpUniformLoc, 1, GL_FALSE, identity);
111         glUniform1f(mInvDitherKernelSizeUniformLoc, invDitherKernelSize);
112         glUniform1f(mInvDitherKernelSizeSqUniformLoc, invDitherKernelSizeSq);
113         glUniform4fv(mColor0UniformLoc, 1, color0);
114         glUniform4fv(mColor1UniformLoc, 1, color1);
115 
116         if (glGetError() != GL_NO_ERROR) {
117             fprintf(stderr, "GL error! 0\n");
118         }
119 
120         glActiveTexture(GL_TEXTURE0);
121         glBindTexture(GL_TEXTURE_2D, mDitherTexName);
122 
123         if (glGetError() != GL_NO_ERROR) {
124             fprintf(stderr, "GL error! 1\n");
125         }
126 
127         glUniform1i(mDitherKernelSamplerLoc, 0);
128 
129         glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
130 
131         glDisableVertexAttribArray(mPosAttribLoc);
132         glDisableVertexAttribArray(mUVAttribLoc);
133 
134         if (glGetError() != GL_NO_ERROR) {
135             fprintf(stderr, "GL error! 2\n");
136         }
137 
138         return true;
139     }
140 
141     GLuint mGradPgm;
142     GLuint mDitherTexName;
143     GLuint mPosAttribLoc;
144     GLuint mUVAttribLoc;
145     GLuint mObjToNdcUniformLoc;
146     GLuint mUVToInterpUniformLoc;
147     GLuint mDitherKernelSamplerLoc;
148     GLuint mInvDitherKernelSizeUniformLoc;
149     GLuint mInvDitherKernelSizeSqUniformLoc;
150     GLuint mColor0UniformLoc;
151     GLuint mColor1UniformLoc;
152 };
153 
staticGradient()154 Renderer* staticGradient() {
155     class NoRenderer : public Renderer {
156         virtual bool setUp(GLHelper* helper) {
157             mIsFirstFrame = true;
158             mGLHelper = helper;
159             return mGradientRenderer.setUp(helper);
160         }
161 
162         virtual void tearDown() {
163             mGradientRenderer.tearDown();
164         }
165 
166         virtual bool render(EGLSurface surface) {
167             if (mIsFirstFrame) {
168                 bool result;
169                 mIsFirstFrame = false;
170 
171                 result = mGLHelper->makeCurrent(surface);
172                 if (!result) {
173                     return false;
174                 }
175 
176                 result = mGradientRenderer.drawGradient();
177                 if (!result) {
178                     return false;
179                 }
180 
181                 result = mGLHelper->swapBuffers(surface);
182                 if (!result) {
183                     return false;
184                 }
185             }
186             return true;
187         }
188 
189         bool mIsFirstFrame;
190         GLHelper* mGLHelper;
191         GradientRenderer mGradientRenderer;
192     };
193     return new NoRenderer;
194 }
195 
196 
197 } // namespace android
198