/*
- * Sixth 3D engine. Copyright ©2012-2016, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 3 of the GNU Lesser General Public License
- * or later as published by the Free Software Foundation.
- *
+ * Sixth 3D engine. Author: Svjatoslav Agejenko.
+ * This project is released under Creative Commons Zero (CC0) license.
*/
-
package eu.svjatoslav.sixth.e3d.renderer.raster.shapes.basic;
import eu.svjatoslav.sixth.e3d.geometry.Point3D;
import eu.svjatoslav.sixth.e3d.renderer.raster.Color;
import eu.svjatoslav.sixth.e3d.renderer.raster.texture.Texture;
+import java.util.Collections;
+import java.util.Set;
+import java.util.WeakHashMap;
+
+import static java.lang.Math.pow;
+import static java.lang.Math.sqrt;
+
public class GlowingPoint extends ForwardOrientedTexture {
- private static final int TEXTURE_SIZE = 50;
+ private static final int TEXTURE_RESOLUTION_PIXELS = 100;
+ /**
+ * A set of all existing glowing points.
+ * Used to reuse textures of glowing points of the same color.
+ */
+ private static final Set<GlowingPoint> glowingPoints = Collections.newSetFromMap(new WeakHashMap<>());
private final Color color;
public GlowingPoint(final Point3D point, final double pointSize,
final Color color) {
- super(point, pointSize, getTexture(color));
+ super(point, computeScale(pointSize), getTexture(color));
this.color = color;
- getTexture(color);
+ synchronized (glowingPoints) {
+ glowingPoints.add(this);
+ }
+ }
+
+ private static double computeScale(double pointSize) {
+ return pointSize / ((double) (TEXTURE_RESOLUTION_PIXELS / 50f));
}
- public static Texture getTexture(final Color color) {
- final Texture texture = new Texture(TEXTURE_SIZE, TEXTURE_SIZE, 1);
- for (int x = 0; x < TEXTURE_SIZE; x++)
- for (int y = 0; y < TEXTURE_SIZE; y++) {
+ /**
+ * Returns a texture for a glowing point of the given color.
+ * The texture is a circle with a gradient from transparent to the given color.
+ */
+ private static Texture getTexture(final Color color) {
+ // attempt to reuse texture from existing glowing point of the same color
+ synchronized (glowingPoints) {
+ for (GlowingPoint glowingPoint : glowingPoints)
+ if (color.equals(glowingPoint.color))
+ return glowingPoint.texture;
+ }
+
+ // existing texture not found, creating new one
+ return createTexture(color);
+ }
+
+ /**
+ * Creates a texture for a glowing point of the given color.
+ * The texture is a circle with a gradient from transparent to the given color.
+ */
+ private static Texture createTexture(final Color color) {
+ final Texture texture = new Texture(TEXTURE_RESOLUTION_PIXELS, TEXTURE_RESOLUTION_PIXELS, 1);
+ int halfResolution = TEXTURE_RESOLUTION_PIXELS / 2;
+
+ for (int x = 0; x < TEXTURE_RESOLUTION_PIXELS; x++)
+ for (int y = 0; y < TEXTURE_RESOLUTION_PIXELS; y++) {
int address = texture.primaryBitmap.getAddress(x, y);
- final int distance = (int) Math
- .sqrt((((TEXTURE_SIZE / 2) - x) * ((TEXTURE_SIZE / 2) - x))
- + (((TEXTURE_SIZE / 2) - y) * ((TEXTURE_SIZE / 2) - y)));
+ final int distanceFromCenter = (int) sqrt(pow(halfResolution - x, 2) + pow(halfResolution - y, 2));
- int alpha = 255 - ((270 * distance) / (TEXTURE_SIZE / 2));
+ int alpha = 255 - ((270 * distanceFromCenter) / halfResolution);
if (alpha < 0)
alpha = 0;