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