Home | History | Annotate | Download | only in jni
      1 /*
      2  * Copyright 2013 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 "gles3jni.h"
     18 #include <EGL/egl.h>
     19 
     20 static const char VERTEX_SHADER[] =
     21     "#version 100\n"
     22     "uniform mat2 scaleRot;\n"
     23     "uniform vec2 offset;\n"
     24     "attribute vec2 pos;\n"
     25     "attribute vec4 color;\n"
     26     "varying vec4 vColor;\n"
     27     "void main() {\n"
     28     "    gl_Position = vec4(scaleRot*pos + offset, 0.0, 1.0);\n"
     29     "    vColor = color;\n"
     30     "}\n";
     31 
     32 static const char FRAGMENT_SHADER[] =
     33     "#version 100\n"
     34     "precision mediump float;\n"
     35     "varying vec4 vColor;\n"
     36     "void main() {\n"
     37     "    gl_FragColor = vColor;\n"
     38     "}\n";
     39 
     40 class RendererES2: public Renderer {
     41 public:
     42     RendererES2();
     43     virtual ~RendererES2();
     44     bool init();
     45 
     46 private:
     47     virtual float* mapOffsetBuf();
     48     virtual void unmapOffsetBuf();
     49     virtual float* mapTransformBuf();
     50     virtual void unmapTransformBuf();
     51     virtual void draw(unsigned int numInstances);
     52 
     53     const EGLContext mEglContext;
     54     GLuint mProgram;
     55     GLuint mVB;
     56     GLint mPosAttrib;
     57     GLint mColorAttrib;
     58     GLint mScaleRotUniform;
     59     GLint mOffsetUniform;
     60 
     61     float mOffsets[2*MAX_INSTANCES];
     62     float mScaleRot[4*MAX_INSTANCES];   // array of 2x2 column-major matrices
     63 };
     64 
     65 Renderer* createES2Renderer() {
     66     RendererES2* renderer = new RendererES2;
     67     if (!renderer->init()) {
     68         delete renderer;
     69         return NULL;
     70     }
     71     return renderer;
     72 }
     73 
     74 RendererES2::RendererES2()
     75 :   mEglContext(eglGetCurrentContext()),
     76     mProgram(0),
     77     mVB(0),
     78     mPosAttrib(-1),
     79     mColorAttrib(-1),
     80     mScaleRotUniform(-1),
     81     mOffsetUniform(-1)
     82 {}
     83 
     84 bool RendererES2::init() {
     85     mProgram = createProgram(VERTEX_SHADER, FRAGMENT_SHADER);
     86     if (!mProgram)
     87         return false;
     88     mPosAttrib = glGetAttribLocation(mProgram, "pos");
     89     mColorAttrib = glGetAttribLocation(mProgram, "color");
     90     mScaleRotUniform = glGetUniformLocation(mProgram, "scaleRot");
     91     mOffsetUniform = glGetUniformLocation(mProgram, "offset");
     92 
     93     glGenBuffers(1, &mVB);
     94     glBindBuffer(GL_ARRAY_BUFFER, mVB);
     95     glBufferData(GL_ARRAY_BUFFER, sizeof(QUAD), &QUAD[0], GL_STATIC_DRAW);
     96 
     97     ALOGV("Using OpenGL ES 2.0 renderer");
     98     return true;
     99 }
    100 
    101 RendererES2::~RendererES2() {
    102     /* The destructor may be called after the context has already been
    103      * destroyed, in which case our objects have already been destroyed.
    104      *
    105      * If the context exists, it must be current. This only happens when we're
    106      * cleaning up after a failed init().
    107      */
    108     if (eglGetCurrentContext() != mEglContext)
    109         return;
    110     glDeleteBuffers(1, &mVB);
    111     glDeleteProgram(mProgram);
    112 }
    113 
    114 float* RendererES2::mapOffsetBuf() {
    115     return mOffsets;
    116 }
    117 
    118 void RendererES2::unmapOffsetBuf() {
    119 }
    120 
    121 float* RendererES2::mapTransformBuf() {
    122     return mScaleRot;
    123 }
    124 
    125 void RendererES2::unmapTransformBuf() {
    126 }
    127 
    128 void RendererES2::draw(unsigned int numInstances) {
    129     glUseProgram(mProgram);
    130 
    131     glBindBuffer(GL_ARRAY_BUFFER, mVB);
    132     glVertexAttribPointer(mPosAttrib, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)offsetof(Vertex, pos));
    133     glVertexAttribPointer(mColorAttrib, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), (const GLvoid*)offsetof(Vertex, rgba));
    134     glEnableVertexAttribArray(mPosAttrib);
    135     glEnableVertexAttribArray(mColorAttrib);
    136 
    137     for (unsigned int i = 0; i < numInstances; i++) {
    138         glUniformMatrix2fv(mScaleRotUniform, 1, GL_FALSE, mScaleRot + 4*i);
    139         glUniform2fv(mOffsetUniform, 1, mOffsets + 2*i);
    140         glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    141     }
    142 }
    143