blob: 5469aad11963b1594bf47024b97284ca10130aee [file] [log] [blame]
ztenghui55bfb4e2013-12-03 10:38:55 -08001/*
2 * Copyright (C) 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#define LOG_TAG "OpenGLRenderer"
Chris Craik87f9df82014-03-07 14:34:42 -080018#define ATRACE_TAG ATRACE_TAG_VIEW
ztenghui55bfb4e2013-12-03 10:38:55 -080019
20#include <math.h>
21#include <utils/Log.h>
Chris Craik87f9df82014-03-07 14:34:42 -080022#include <utils/Trace.h>
ztenghui55bfb4e2013-12-03 10:38:55 -080023
24#include "AmbientShadow.h"
25#include "ShadowTessellator.h"
ztenghui7b4516e2014-01-07 10:42:55 -080026#include "SpotShadow.h"
ztenghui55bfb4e2013-12-03 10:38:55 -080027
28namespace android {
29namespace uirenderer {
30
ztenghui7b4516e2014-01-07 10:42:55 -080031template<typename T>
32static inline T max(T a, T b) {
33 return a > b ? a : b;
34}
35
ztenghui63d41ab2014-02-14 13:13:41 -080036void ShadowTessellator::tessellateAmbientShadow(const Vector3* casterPolygon,
37 int casterVertexCount, const Vector3& centroid3d,
Chris Craik15a07a22014-01-26 13:43:53 -080038 VertexBuffer& shadowVertexBuffer) {
Chris Craik87f9df82014-03-07 14:34:42 -080039 ATRACE_CALL();
40
ztenghui55bfb4e2013-12-03 10:38:55 -080041 // A bunch of parameters to tweak the shadow.
42 // TODO: Allow some of these changable by debug settings or APIs.
ztenghui7b4516e2014-01-07 10:42:55 -080043 const float heightFactor = 128;
44 const float geomFactor = 64;
ztenghui55bfb4e2013-12-03 10:38:55 -080045
ztenghui63d41ab2014-02-14 13:13:41 -080046 AmbientShadow::createAmbientShadow(casterPolygon, casterVertexCount,
47 centroid3d, heightFactor, geomFactor, shadowVertexBuffer);
ztenghui55bfb4e2013-12-03 10:38:55 -080048
49}
50
Chris Craik15a07a22014-01-26 13:43:53 -080051void ShadowTessellator::tessellateSpotShadow(const Vector3* casterPolygon, int casterVertexCount,
ztenghuicc3c2562014-01-17 10:34:10 -080052 const Vector3& lightPosScale, const mat4& receiverTransform,
Chris Craik15a07a22014-01-26 13:43:53 -080053 int screenWidth, int screenHeight, VertexBuffer& shadowVertexBuffer) {
Chris Craik87f9df82014-03-07 14:34:42 -080054 ATRACE_CALL();
55
ztenghui7b4516e2014-01-07 10:42:55 -080056 // A bunch of parameters to tweak the shadow.
57 // TODO: Allow some of these changable by debug settings or APIs.
ztenghui7b4516e2014-01-07 10:42:55 -080058 int maximal = max(screenWidth, screenHeight);
ztenghuicc3c2562014-01-17 10:34:10 -080059 Vector3 lightCenter(screenWidth * lightPosScale.x, screenHeight * lightPosScale.y,
60 maximal * lightPosScale.z);
ztenghui7b4516e2014-01-07 10:42:55 -080061#if DEBUG_SHADOW
62 ALOGD("light center %f %f %f", lightCenter.x, lightCenter.y, lightCenter.z);
63#endif
Chris Craik3197cde2014-01-16 14:03:39 -080064
65 // light position (because it's in local space) needs to compensate for receiver transform
66 // TODO: should apply to light orientation, not just position
67 Matrix4 reverseReceiverTransform;
68 reverseReceiverTransform.loadInverse(receiverTransform);
69 reverseReceiverTransform.mapPoint3d(lightCenter);
70
ztenghuicc3c2562014-01-17 10:34:10 -080071 const float lightSize = maximal / 4;
ztenghui7b4516e2014-01-07 10:42:55 -080072 const int lightVertexCount = 16;
73
ztenghui63d41ab2014-02-14 13:13:41 -080074 SpotShadow::createSpotShadow(casterPolygon, casterVertexCount, lightCenter,
75 lightSize, lightVertexCount, shadowVertexBuffer);
ztenghui7b4516e2014-01-07 10:42:55 -080076
77}
ztenghui63d41ab2014-02-14 13:13:41 -080078
79void ShadowTessellator::generateShadowIndices(uint16_t* shadowIndices) {
80 int currentIndex = 0;
81 const int layers = SHADOW_LAYER_COUNT;
82 const int rays = SHADOW_RAY_COUNT;
83 // For the penumbra area.
84 for (int i = 0; i < layers; i++) {
85 for (int j = 0; j < rays; j++) {
86 shadowIndices[currentIndex++] = i * rays + j;
87 shadowIndices[currentIndex++] = (i + 1) * rays + j;
88 }
89 // To close the loop, back to the ray 0.
90 shadowIndices[currentIndex++] = i * rays;
91 shadowIndices[currentIndex++] = (i + 1) * rays;
92 }
93 uint16_t base = layers * rays;
94 uint16_t centroidIndex = (layers + 1) * rays;
95 // For the umbra area, using strips to simulate the fans.
96 for (int k = 0; k < rays; k++) {
97 shadowIndices[currentIndex++] = base + k;
98 shadowIndices[currentIndex++] = centroidIndex;
99 }
100 shadowIndices[currentIndex++] = base;
101
102#if DEBUG_SHADOW
103 if (currentIndex != SHADOW_INDEX_COUNT) {
104 ALOGE("vertex index count is wrong. current %d, expected %d",
105 currentIndex, SHADOW_INDEX_COUNT);
106 }
107 for (int i = 0; i < SHADOW_INDEX_COUNT; i++) {
108 ALOGD("vertex index is (%d, %d)", i, shadowIndices[i]);
109 }
110#endif
111}
112
113/**
114 * Calculate the centroid of a 2d polygon.
115 *
116 * @param poly The polygon, which is represented in a Vector2 array.
117 * @param polyLength The length of the polygon in terms of number of vertices.
118 * @return the centroid of the polygon.
119 */
120Vector2 ShadowTessellator::centroid2d(const Vector2* poly, int polyLength) {
121 double sumx = 0;
122 double sumy = 0;
123 int p1 = polyLength - 1;
124 double area = 0;
125 for (int p2 = 0; p2 < polyLength; p2++) {
126 double x1 = poly[p1].x;
127 double y1 = poly[p1].y;
128 double x2 = poly[p2].x;
129 double y2 = poly[p2].y;
130 double a = (x1 * y2 - x2 * y1);
131 sumx += (x1 + x2) * a;
132 sumy += (y1 + y2) * a;
133 area += a;
134 p1 = p2;
135 }
136
137 Vector2 centroid = poly[0];
138 if (area != 0) {
139 centroid = Vector2(sumx / (3 * area), sumy / (3 * area));
140 } else {
141 ALOGE("Area is 0 while computing centroid!");
142 }
143 return centroid;
144}
145
ztenghui55bfb4e2013-12-03 10:38:55 -0800146}; // namespace uirenderer
147}; // namespace android