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
FullPipelineRenderer(ANativeWindow * window,bool offscreen)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
setUp(int workload)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
tearDown()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
drawWorkload()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