19c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis/*
29c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis * Copyright (C) 2012 The Android Open Source Project
39c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis *
49c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis * Licensed under the Apache License, Version 2.0 (the "License");
59c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis * you may not use this file except in compliance with the License.
69c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis * You may obtain a copy of the License at
79c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis *
89c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis *      http://www.apache.org/licenses/LICENSE-2.0
99c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis *
109c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis * Unless required by applicable law or agreed to in writing, software
119c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis * distributed under the License is distributed on an "AS IS" BASIS,
129c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis * See the License for the specific language governing permissions and
149c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis * limitations under the License.
159c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis */
169c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis
179c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis#include "Flatland.h"
189c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis#include "GLHelper.h"
199c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis
209c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennisnamespace android {
219c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis
229c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennisstatic float colors[][4] = {
239c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis    { .85f, .14f, .44f, 1.0f },
249c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis    { .91f, .72f, .10f, 1.0f },
259c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis    { .04f, .66f, .42f, 1.0f },
269c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis    { .84f, .39f, .68f, 1.0f },
279c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis    { .38f, .53f, .78f, 1.0f },
289c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis};
299c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis
309c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennisstatic size_t g_colorIndex;
319c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis
329c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennisconst float* genColor() {
339c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis    float* color = colors[g_colorIndex];
349c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis    g_colorIndex = (g_colorIndex + 1) % NELEMS(colors);
359c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis    return color;
369c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis}
379c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis
389c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennisvoid resetColorGenerator() {
399c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis    g_colorIndex = 0;
409c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis}
419c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis
429c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennisclass GradientRenderer {
439c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis
449c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennispublic:
459c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis
469c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis    bool setUp(GLHelper* helper) {
479c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        bool result;
489c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis
499c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        result = helper->getShaderProgram("Gradient", &mGradPgm);
509c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        if (!result) {
519c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis            return false;
529c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        }
539c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis
549c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        result = helper->getDitherTexture(&mDitherTexName);
559c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        if (!result) {
569c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis            return false;
579c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        }
589c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis
599c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        mPosAttribLoc = glGetAttribLocation(mGradPgm, "position");
609c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        mUVAttribLoc = glGetAttribLocation(mGradPgm, "uv");
619c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        mUVToInterpUniformLoc = glGetUniformLocation(mGradPgm, "uvToInterp");
629c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        mObjToNdcUniformLoc = glGetUniformLocation(mGradPgm, "objToNdc");
639c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        mDitherKernelSamplerLoc = glGetUniformLocation(mGradPgm, "ditherKernel");
649c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        mInvDitherKernelSizeUniformLoc = glGetUniformLocation(mGradPgm,
659c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis                "invDitherKernelSize");
669c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        mInvDitherKernelSizeSqUniformLoc = glGetUniformLocation(mGradPgm,
679c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis                "invDitherKernelSizeSq");
689c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        mColor0UniformLoc = glGetUniformLocation(mGradPgm, "color0");
699c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        mColor1UniformLoc = glGetUniformLocation(mGradPgm, "color1");
709c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis
719c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        return true;
729c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis    }
739c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis
749c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis    void tearDown() {
759c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis    }
769c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis
779c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis    bool drawGradient() {
789c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        float identity[16] = {
799c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis            1.0f,   0.0f,   0.0f,   0.0f,
809c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis            0.0f,   1.0f,   0.0f,   0.0f,
819c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis            0.0f,   0.0f,   1.0f,   0.0f,
829c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis            0.0f,   0.0f,   0.0f,   1.0f,
839c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        };
849c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        const float pos[] = {
859c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis            -1.0f,  -1.0f,
869c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis            1.0f,   -1.0f,
879c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis            -1.0f,  1.0f,
889c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis            1.0f,   1.0f,
899c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        };
909c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        const float uv[] = {
919c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis            0.0f, 0.0f,
929c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis            1.0f, 0.0f,
939c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis            0.0f, 1.0f,
949c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis            1.0f, 1.0f,
959c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        };
969c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        const float* color0 = genColor();
979c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        const float* color1 = genColor();
989c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis
999c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        glUseProgram(mGradPgm);
1009c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis
1019c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        glVertexAttribPointer(mPosAttribLoc, 2, GL_FLOAT, GL_FALSE, 0, pos);
1029c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        glVertexAttribPointer(mUVAttribLoc, 2, GL_FLOAT, GL_FALSE, 0, uv);
1039c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        glEnableVertexAttribArray(mPosAttribLoc);
1049c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        glEnableVertexAttribArray(mUVAttribLoc);
1059c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis
1069c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        float invDitherKernelSize = 1.0f / float(GLHelper::DITHER_KERNEL_SIZE);
1079c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        float invDitherKernelSizeSq = invDitherKernelSize * invDitherKernelSize;
1089c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis
1099c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        glUniformMatrix4fv(mObjToNdcUniformLoc, 1, GL_FALSE, identity);
1109c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        glUniformMatrix4fv(mUVToInterpUniformLoc, 1, GL_FALSE, identity);
1119c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        glUniform1f(mInvDitherKernelSizeUniformLoc, invDitherKernelSize);
1129c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        glUniform1f(mInvDitherKernelSizeSqUniformLoc, invDitherKernelSizeSq);
1139c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        glUniform4fv(mColor0UniformLoc, 1, color0);
1149c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        glUniform4fv(mColor1UniformLoc, 1, color1);
1159c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis
1169c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        if (glGetError() != GL_NO_ERROR) {
1179c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis            fprintf(stderr, "GL error! 0\n");
1189c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        }
1199c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis
1209c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        glActiveTexture(GL_TEXTURE0);
1219c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        glBindTexture(GL_TEXTURE_2D, mDitherTexName);
1229c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis
1239c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        if (glGetError() != GL_NO_ERROR) {
1249c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis            fprintf(stderr, "GL error! 1\n");
1259c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        }
1269c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis
1279c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        glUniform1i(mDitherKernelSamplerLoc, 0);
1289c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis
1299c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
1309c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis
1319c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        glDisableVertexAttribArray(mPosAttribLoc);
1329c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        glDisableVertexAttribArray(mUVAttribLoc);
1339c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis
1349c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        if (glGetError() != GL_NO_ERROR) {
1359c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis            fprintf(stderr, "GL error! 2\n");
1369c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        }
1379c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis
1389c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        return true;
1399c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis    }
1409c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis
1419c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis    GLuint mGradPgm;
1429c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis    GLuint mDitherTexName;
1439c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis    GLuint mPosAttribLoc;
1449c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis    GLuint mUVAttribLoc;
1459c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis    GLuint mObjToNdcUniformLoc;
1469c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis    GLuint mUVToInterpUniformLoc;
1479c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis    GLuint mDitherKernelSamplerLoc;
1489c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis    GLuint mInvDitherKernelSizeUniformLoc;
1499c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis    GLuint mInvDitherKernelSizeSqUniformLoc;
1509c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis    GLuint mColor0UniformLoc;
1519c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis    GLuint mColor1UniformLoc;
1529c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis};
1539c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis
1549c183f2493222000fa512d927cfde3f4c748eda0Jamie GennisRenderer* staticGradient() {
1559c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis    class NoRenderer : public Renderer {
1569c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        virtual bool setUp(GLHelper* helper) {
1579c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis            mIsFirstFrame = true;
1589c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis            mGLHelper = helper;
1599c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis            return mGradientRenderer.setUp(helper);
1609c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        }
1619c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis
1629c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        virtual void tearDown() {
1639c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis            mGradientRenderer.tearDown();
1649c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        }
1659c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis
1669c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        virtual bool render(EGLSurface surface) {
1679c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis            if (mIsFirstFrame) {
1689c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis                bool result;
1699c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis                mIsFirstFrame = false;
1709c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis
1719c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis                result = mGLHelper->makeCurrent(surface);
1729c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis                if (!result) {
1739c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis                    return false;
1749c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis                }
1759c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis
1769c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis                result = mGradientRenderer.drawGradient();
1779c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis                if (!result) {
1789c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis                    return false;
1799c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis                }
1809c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis
1819c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis                result = mGLHelper->swapBuffers(surface);
1829c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis                if (!result) {
1839c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis                    return false;
1849c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis                }
1859c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis            }
1869c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis            return true;
1879c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        }
1889c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis
1899c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        bool mIsFirstFrame;
1909c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        GLHelper* mGLHelper;
1919c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis        GradientRenderer mGradientRenderer;
1929c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis    };
1939c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis    return new NoRenderer;
1949c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis}
1959c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis
1969c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis
1979c183f2493222000fa512d927cfde3f4c748eda0Jamie Gennis} // namespace android
198