diff options
Diffstat (limited to 'libs/hwui/ShadowTessellator.cpp')
-rw-r--r-- | libs/hwui/ShadowTessellator.cpp | 85 |
1 files changed, 74 insertions, 11 deletions
diff --git a/libs/hwui/ShadowTessellator.cpp b/libs/hwui/ShadowTessellator.cpp index 7700ea0..526772b 100644 --- a/libs/hwui/ShadowTessellator.cpp +++ b/libs/hwui/ShadowTessellator.cpp @@ -31,18 +31,16 @@ static inline T max(T a, T b) { return a > b ? a : b; } -void ShadowTessellator::tessellateAmbientShadow(const Vector3* casterPolygon, int casterVertexCount, +void ShadowTessellator::tessellateAmbientShadow(const Vector3* casterPolygon, + int casterVertexCount, const Vector3& centroid3d, VertexBuffer& shadowVertexBuffer) { // A bunch of parameters to tweak the shadow. // TODO: Allow some of these changable by debug settings or APIs. - const int rays = 128; - const int layers = 2; - const float strength = 0.5; const float heightFactor = 128; const float geomFactor = 64; - AmbientShadow::createAmbientShadow(casterPolygon, casterVertexCount, rays, layers, strength, - heightFactor, geomFactor, shadowVertexBuffer); + AmbientShadow::createAmbientShadow(casterPolygon, casterVertexCount, + centroid3d, heightFactor, geomFactor, shadowVertexBuffer); } @@ -51,9 +49,6 @@ void ShadowTessellator::tessellateSpotShadow(const Vector3* casterPolygon, int c int screenWidth, int screenHeight, VertexBuffer& shadowVertexBuffer) { // A bunch of parameters to tweak the shadow. // TODO: Allow some of these changable by debug settings or APIs. - const int rays = 256; - const int layers = 2; - const float strength = 0.5; int maximal = max(screenWidth, screenHeight); Vector3 lightCenter(screenWidth * lightPosScale.x, screenHeight * lightPosScale.y, maximal * lightPosScale.z); @@ -70,9 +65,77 @@ void ShadowTessellator::tessellateSpotShadow(const Vector3* casterPolygon, int c const float lightSize = maximal / 4; const int lightVertexCount = 16; - SpotShadow::createSpotShadow(casterPolygon, casterVertexCount, lightCenter, lightSize, - lightVertexCount, rays, layers, strength, shadowVertexBuffer); + SpotShadow::createSpotShadow(casterPolygon, casterVertexCount, lightCenter, + lightSize, lightVertexCount, shadowVertexBuffer); } + +void ShadowTessellator::generateShadowIndices(uint16_t* shadowIndices) { + int currentIndex = 0; + const int layers = SHADOW_LAYER_COUNT; + const int rays = SHADOW_RAY_COUNT; + // For the penumbra area. + for (int i = 0; i < layers; i++) { + for (int j = 0; j < rays; j++) { + shadowIndices[currentIndex++] = i * rays + j; + shadowIndices[currentIndex++] = (i + 1) * rays + j; + } + // To close the loop, back to the ray 0. + shadowIndices[currentIndex++] = i * rays; + shadowIndices[currentIndex++] = (i + 1) * rays; + } + uint16_t base = layers * rays; + uint16_t centroidIndex = (layers + 1) * rays; + // For the umbra area, using strips to simulate the fans. + for (int k = 0; k < rays; k++) { + shadowIndices[currentIndex++] = base + k; + shadowIndices[currentIndex++] = centroidIndex; + } + shadowIndices[currentIndex++] = base; + +#if DEBUG_SHADOW + if (currentIndex != SHADOW_INDEX_COUNT) { + ALOGE("vertex index count is wrong. current %d, expected %d", + currentIndex, SHADOW_INDEX_COUNT); + } + for (int i = 0; i < SHADOW_INDEX_COUNT; i++) { + ALOGD("vertex index is (%d, %d)", i, shadowIndices[i]); + } +#endif +} + +/** + * Calculate the centroid of a 2d polygon. + * + * @param poly The polygon, which is represented in a Vector2 array. + * @param polyLength The length of the polygon in terms of number of vertices. + * @return the centroid of the polygon. + */ +Vector2 ShadowTessellator::centroid2d(const Vector2* poly, int polyLength) { + double sumx = 0; + double sumy = 0; + int p1 = polyLength - 1; + double area = 0; + for (int p2 = 0; p2 < polyLength; p2++) { + double x1 = poly[p1].x; + double y1 = poly[p1].y; + double x2 = poly[p2].x; + double y2 = poly[p2].y; + double a = (x1 * y2 - x2 * y1); + sumx += (x1 + x2) * a; + sumy += (y1 + y2) * a; + area += a; + p1 = p2; + } + + Vector2 centroid = poly[0]; + if (area != 0) { + centroid = Vector2(sumx / (3 * area), sumy / (3 * area)); + } else { + ALOGE("Area is 0 while computing centroid!"); + } + return centroid; +} + }; // namespace uirenderer }; // namespace android |