Home | History | Annotate | Download | only in fullpipeline
      1 /*
      2  * Copyright (C) 2013 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
      5  * in compliance with the License. You may obtain a copy of the License at
      6  *
      7  * http://www.apache.org/licenses/LICENSE-2.0
      8  *
      9  * Unless required by applicable law or agreed to in writing, software distributed under the License
     10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
     11  * or implied. See the License for the specific language governing permissions and limitations under
     12  * the License.
     13  */
     14 #include <EGL/egl.h>
     15 #include <GLES2/gl2.h>
     16 #include <GLES2/gl2ext.h>
     17 
     18 #include "FullPipelineRenderer.h"
     19 
     20 #include <graphics/PerspectiveMeshNode.h>
     21 #include <graphics/GLUtils.h>
     22 #include <graphics/TransformationNode.h>
     23 
     24 #include <Trace.h>
     25 
     26 static const int FP_NUM_VERTICES = 6;
     27 
     28 static const float FP_VERTICES[FP_NUM_VERTICES * 3] = {
     29         1.0f, 1.0f, 0.0f,
     30         0.0f, 1.0f, 0.0f,
     31         0.0f, 0.0f, 0.0f,
     32         0.0f, 0.0f, 0.0f,
     33         1.0f, 0.0f, 0.0f,
     34         1.0f, 1.0f, 0.0f };
     35 
     36 static const float FP_NORMALS[FP_NUM_VERTICES * 3] = {
     37         0.0f, 0.0f, 1.0f,
     38         0.0f, 0.0f, 1.0f,
     39         0.0f, 0.0f, 1.0f,
     40         0.0f, 0.0f, 1.0f,
     41         0.0f, 0.0f, 1.0f,
     42         0.0f, 0.0f, 1.0f };
     43 
     44 static const float FP_TEX_COORDS[FP_NUM_VERTICES * 2] = {
     45         1.0f, 1.0f,
     46         0.0f, 1.0f,
     47         0.0f, 0.0f,
     48         0.0f, 0.0f,
     49         1.0f, 0.0f,
     50         1.0f, 1.0f };
     51 
     52 static const char* FP_VERTEX =
     53         "uniform mat4 u_MVPMatrix;"
     54         "uniform mat4 u_MVMatrix;"
     55         "attribute vec4 a_Position;"
     56         "attribute vec3 a_Normal;"
     57         "attribute vec2 a_TexCoordinate;"
     58         "varying vec3 v_Position;"
     59         "varying vec3 v_Normal;"
     60         "varying vec2 v_TexCoordinate;"
     61         "void main() {\n"
     62         "  // Transform the vertex into eye space.\n"
     63         "  v_Position = vec3(u_MVMatrix * a_Position);\n"
     64         "  // Pass through the texture coordinate.\n"
     65         "  v_TexCoordinate = a_TexCoordinate;\n"
     66         "  // Transform the normal\'s orientation into eye space.\n"
     67         "  v_Normal = vec3(u_MVMatrix * vec4(a_Normal, 0.0));\n"
     68         "  // Multiply to get the final point in normalized screen coordinates.\n"
     69         "  gl_Position = u_MVPMatrix * a_Position;\n"
     70         "}";
     71 
     72 static const char* FP_FRAGMENT =
     73         "precision mediump float;"
     74         "uniform vec3 u_LightPos;"
     75         "uniform sampler2D u_Texture;"
     76         "varying vec3 v_Position;"
     77         "varying vec3 v_Normal;"
     78         "varying vec2 v_TexCoordinate;"
     79         "void main() {\n"
     80         "  // Will be used for attenuation.\n"
     81         "  float distance = length(u_LightPos - v_Position);\n"
     82         "  // Get a lighting direction vector from the light to the vertex.\n"
     83         "  vec3 lightVector = normalize(u_LightPos - v_Position);\n"
     84         "  // Calculate the dot product of the light vector and vertex normal.\n"
     85         "  float diffuse = max(dot(v_Normal, lightVector), 0.0);\n"
     86         "  // Add attenuation.\n"
     87         "  diffuse = diffuse * (1.0 / (1.0 + (0.01 * distance)));\n"
     88         "  // Add ambient lighting\n"
     89         "  diffuse = diffuse + 0.25;\n"
     90         "  // Multiply the diffuse illumination and texture to get final output color.\n"
     91         "  gl_FragColor = (diffuse * texture2D(u_Texture, v_TexCoordinate));\n"
     92         "}";
     93 
     94 FullPipelineRenderer::FullPipelineRenderer(ANativeWindow* window, bool offscreen) :
     95         Renderer(window, offscreen), mProgram(NULL), mSceneGraph(NULL),
     96         mModelMatrix(NULL), mViewMatrix(NULL), mProjectionMatrix(NULL), mMesh(NULL),
     97         mTextureId(0) {
     98 }
     99 
    100 bool FullPipelineRenderer::setUp(int workload) {
    101     SCOPED_TRACE();
    102     if (!Renderer::setUp(workload)) {
    103         return false;
    104     }
    105 
    106     mProgramId = GLUtils::createProgram(&FP_VERTEX, &FP_FRAGMENT);
    107     if (mProgramId == 0) {
    108         return false;
    109     }
    110     mProgram = new PerspectiveProgram(mProgramId);
    111 
    112     mModelMatrix = new Matrix();
    113 
    114     // Position the eye in front of the origin.
    115     float eyeX = 0.0f;
    116     float eyeY = 0.0f;
    117     float eyeZ = 1.5f;
    118 
    119     // We are looking at the origin
    120     float centerX = 0.0f;
    121     float centerY = 0.0f;
    122     float centerZ = 0.0f;
    123 
    124     // Set our up vector.
    125     float upX = 0.0f;
    126     float upY = 1.0f;
    127     float upZ = 0.0f;
    128 
    129     // Set the view matrix.
    130     mViewMatrix = Matrix::newLookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ);
    131 
    132     // Create a new perspective projection matrix. The height will stay the same
    133     // while the width will vary as per aspect ratio.
    134     float ratio = (float) mWidth / mHeight;
    135     float left = -ratio;
    136     float right = ratio;
    137     float bottom = -1.0f;
    138     float top = 1.0f;
    139     float near = 1.0f;
    140     float far = 2.0f;
    141 
    142     mProjectionMatrix = Matrix::newFrustum(left, right, bottom, top, near, far);
    143 
    144     // Setup texture.
    145     mTextureId = GLUtils::genTexture(mWidth, mHeight, GLUtils::RANDOM_FILL);
    146     if (mTextureId == 0) {
    147         return false;
    148     }
    149 
    150     float count = workload * workload;
    151     float middle = count / 2.0f;
    152     float scale = 2.0f / count;
    153 
    154     mMesh = new Mesh(FP_VERTICES, FP_NORMALS, FP_TEX_COORDS, FP_NUM_VERTICES);
    155     mSceneGraph = new ProgramNode(*mProgram);
    156 
    157     for (int i = 0; i < count; i++) {
    158         for (int j = 0; j < count; j++) {
    159             Matrix* transformMatrix = Matrix::newScale(scale, scale, scale);
    160             transformMatrix->translate(i - middle, j - middle, 0.0f);
    161             TransformationNode* transformNode = new TransformationNode(transformMatrix);
    162             mSceneGraph->addChild(transformNode);
    163             PerspectiveMeshNode* meshNode = new PerspectiveMeshNode(mMesh, mTextureId);
    164             transformNode->addChild(meshNode);
    165         }
    166     }
    167     return true;
    168 }
    169 
    170 bool FullPipelineRenderer::tearDown() {
    171     SCOPED_TRACE();
    172     if (mTextureId != 0) {
    173         glDeleteTextures(1, &mTextureId);
    174         mTextureId = 0;
    175     }
    176     if (!Renderer::tearDown()) {
    177         return false;
    178     }
    179     delete mModelMatrix;
    180     mModelMatrix = NULL;
    181     delete mViewMatrix;
    182     mViewMatrix = NULL;
    183     delete mProjectionMatrix;
    184     mProjectionMatrix = NULL;
    185     delete mProgram;
    186     mProgram = NULL;
    187     delete mSceneGraph;
    188     mSceneGraph = NULL;
    189     delete mMesh;
    190     mMesh = NULL;
    191     return true;
    192 }
    193 
    194 void FullPipelineRenderer::drawWorkload() {
    195     SCOPED_TRACE();
    196     // Set the background clear color to black.
    197     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    198     // Use culling to remove back faces.
    199     glEnable(GL_CULL_FACE);
    200     // Use depth testing.
    201     glEnable(GL_DEPTH_TEST);
    202     glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
    203     mModelMatrix->identity();
    204     mSceneGraph->drawProgram(*mModelMatrix, *mViewMatrix, *mProjectionMatrix);
    205 }
    206