diff options
Diffstat (limited to 'src/libnoiseforjava/util/RendererImage.java')
-rw-r--r-- | src/libnoiseforjava/util/RendererImage.java | 755 |
1 files changed, 755 insertions, 0 deletions
diff --git a/src/libnoiseforjava/util/RendererImage.java b/src/libnoiseforjava/util/RendererImage.java new file mode 100644 index 0000000..e437f89 --- /dev/null +++ b/src/libnoiseforjava/util/RendererImage.java @@ -0,0 +1,755 @@ +/*
+ * Copyright (C) 2003, 2004 Jason Bevins (original libnoise code)
+ * Copyright 2010 Thomas J. Hodge (java port of libnoise)
+ *
+ * This file is part of libnoiseforjava.
+ *
+ * libnoiseforjava is a Java port of the C++ library libnoise, which may be found at
+ * http://libnoise.sourceforge.net/. libnoise was developed by Jason Bevins, who may be
+ * contacted at [email protected] (for great email, take off every 'zig').
+ * Porting to Java was done by Thomas Hodge, who may be contacted at
+ * [email protected] (remove every 'zag').
+ *
+ * libnoiseforjava is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * libnoiseforjava is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * libnoiseforjava. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+package libnoiseforjava.util;
+
+import libnoiseforjava.Interp;
+import libnoiseforjava.exception.ExceptionInvalidParam;
+
+public class RendererImage {
+
+ // / Renders an image from a noise map.
+ // /
+ // / This class renders an image given the contents of a noise-map object.
+ // /
+ // / An application can configure the output of the image in three ways:
+ // / - Specify the color gradient.
+ // / - Specify the light source parameters.
+ // / - Specify the background image.
+ // /
+ // / <b>Specify the color gradient</b>
+ // /
+ // / This class uses a color gradient to calculate the color for each pixel
+ // / in the destination image according to the value from the corresponding
+ // / position in the noise map.
+ // /
+ // / A color gradient is a list of gradually-changing colors. A color
+ // / gradient is defined by a list of <i>gradient points</i>. Each
+ // / gradient point has a position and a color. In a color gradient, the
+ // / colors between two adjacent gradient points are linearly interpolated.
+ // /
+ // / For example, suppose this class contains the following color gradient:
+ // /
+ // / - -1.0 maps to dark blue.
+ // / - -0.2 maps to light blue.
+ // / - -0.1 maps to tan.
+ // / - 0.0 maps to green.
+ // / - 1.0 maps to white.
+ // /
+ // / The value 0.5 maps to a greenish-white color because 0.5 is halfway
+ // / between 0.0 (mapped to green) and 1.0 (mapped to white).
+ // /
+ // / The value -0.6 maps to a medium blue color because -0.6 is halfway
+ // / between -1.0 (mapped to dark blue) and -0.2 (mapped to light blue).
+ // /
+ // / The color gradient requires a minimum of two gradient points.
+ // /
+ // / This class contains two pre-made gradients: a grayscale gradient and a
+ // / color gradient suitable for terrain. To use these pre-made gradients,
+ // / call the buildGrayscaleGradient() or buildTerrainGradient() methods,
+ // / respectively.
+ // /
+ // / @note The color value passed to addGradientPoint() has an alpha
+ // / channel. This alpha channel specifies how a pixel in the background
+ // / image (if specified) is blended with the calculated color. If the
+ // / alpha value is high, this class weighs the blend towards the
+ // / calculated color, and if the alpha value is low, this class weighs the
+ // / blend towards the color from the corresponding pixel in the background
+ // / image.
+ // /
+ // / <b>Specify the light source parameters</b>
+ // /
+ // / This class contains a parallel light source that lights the image. It
+ // / interprets the noise map as a bump map.
+ // /
+ // / To enable or disable lighting, pass a Boolean value to the
+ // / enableLight() method.
+ // /
+ // / To set the position of the light source in the "sky", call the
+ // / setLightAzimuth() and setLightElev() methods.
+ // /
+ // / To set the color of the light source, call the setLightColor() method.
+ // /
+ // / To set the intensity of the light source, call the setLightIntensity()
+ // / method. A good intensity value is 2.0, although that value tends to
+ // / "wash out" very light colors from the image.
+ // /
+ // / To set the contrast amount between areas in light and areas in shadow,
+ // / call the setLightContrast() method. Determining the correct contrast
+ // / amount requires some trial and error, but if your application
+ // / interprets the noise map as a height map that has its elevation values
+ // / measured in meters and has a horizontal resolution of @a h meters, a
+ // / good contrast amount to use is ( 1.0 / @a h ).
+ // /
+ // / <b>Specify the background image</b>
+ // /
+ // / To specify a background image, pass an Image object to the
+ // / setBackgroundImage() method.
+ // /
+ // / This class determines the color of a pixel in the destination image by
+ // / blending the calculated color with the color of the corresponding
+ // / pixel from the background image.
+ // /
+ // / The blend amount is determined by the alpha of the calculated color.
+ // / If the alpha value is high, this class weighs the blend towards the
+ // / calculated color, and if the alpha value is low, this class weighs the
+ // / blend towards the color from the corresponding pixel in the background
+ // / image.
+ // /
+ // / <b>Rendering the image</b>
+ // /
+ // / To render the image, perform the following steps:
+ // / - Pass a NoiseMap object to the setSourceNoiseMap() method.
+ // / - Pass an ImageCafe object to the setDestImage() method.
+ // / - Pass an ImageCafe object to the setBackgroundImage() method
+ // (optional)
+ // / - Call the render() method.
+
+ static final double SQRT_2 = 1.4142135623730950488;
+
+ // / The cosine of the azimuth of the light source.
+ double cosAzimuth;
+
+ // / The cosine of the elevation of the light source.
+ double cosElev;
+
+ // / The color gradient used to specify the image colors.
+ GradientColor gradient;
+
+ // / A flag specifying whether lighting is enabled.
+ boolean isLightEnabled;
+
+ // / A flag specifying whether wrapping is enabled.
+ boolean isWrapEnabled;
+
+ // / The azimuth of the light source, in degrees.
+ double lightAzimuth;
+
+ // / The brightness of the light source.
+ double lightBrightness;
+
+ // / The color of the light source.
+ ColorCafe lightColor;
+
+ // / The contrast between areas in light and areas in shadow.
+ double lightContrast;
+
+ // / The elevation of the light source, in degrees.
+ double lightElev;
+
+ // / The intensity of the light source.
+ double lightIntensity;
+
+ // / A pointer to the background image.
+ ImageCafe backgroundImage;
+
+ // / A pointer to the destination image.
+ ImageCafe destImageCafe;
+
+ // / A pointer to the source noise map.
+ NoiseMap sourceNoiseMap;
+
+ // / Used by the calcLightIntensity() method to recalculate the light
+ // / values only if the light parameters change.
+ // /
+ // / When the light parameters change, this value is set to True. When
+ // / the calcLightIntensity() method is called, this value is set to
+ // / false.
+ boolean recalcLightValues;
+
+ // / The sine of the azimuth of the light source.
+ double sinAzimuth;
+
+ // / The sine of the elevation of the light source.
+ double sinElev;
+
+ public RendererImage() throws ExceptionInvalidParam {
+ isLightEnabled = false;
+ isWrapEnabled = false;
+ lightAzimuth = 45.0;
+ lightBrightness = 1.0;
+ lightColor = new ColorCafe(255, 255, 255, 255);
+ lightContrast = 1.0;
+ lightElev = 45.0;
+ lightIntensity = 1.0;
+ backgroundImage = null;
+ destImageCafe = null;
+ sourceNoiseMap = null;
+ recalcLightValues = true;
+
+ buildGrayscaleGradient();
+ }
+
+ // / Adds a gradient point to this gradient object.
+ // /
+ // / @param gradientPos The position of this gradient point.
+ // / @param gradientColor The color of this gradient point.
+ // /
+ // / @pre No two gradient points have the same position.
+ // /
+ // / @throw noise::ExceptionInvalidParam See the preconditions.
+ // /
+ // / This object uses a color gradient to calculate the color for each
+ // / pixel in the destination image according to the value from the
+ // / corresponding position in the noise map.
+ // /
+ // / The gradient requires a minimum of two gradient points.
+ // /
+ // / The specified color value passed to this method has an alpha
+ // / channel. This alpha channel specifies how a pixel in the
+ // / background image (if specified) is blended with the calculated
+ // / color. If the alpha value is high, this object weighs the blend
+ // / towards the calculated color, and if the alpha value is low, this
+ // / object weighs the blend towards the color from the corresponding
+ // / pixel in the background image.
+ public void addGradientPoint(double gradientPos, ColorCafe gradientColor) throws ExceptionInvalidParam {
+ gradient.addGradientPoint(gradientPos, gradientColor);
+ }
+
+ // / Builds a grayscale gradient.
+ // /
+ // / @post The original gradient is cleared and a grayscale gradient is
+ // / created.
+ // /
+ // / This color gradient contains the following gradient points:
+ // / - -1.0 maps to black
+ // / - 1.0 maps to white
+ public void buildGrayscaleGradient() throws ExceptionInvalidParam {
+ clearGradient();
+ gradient.addGradientPoint(-1.0, new ColorCafe(0, 0, 0, 255));
+ gradient.addGradientPoint(1.0, new ColorCafe(255, 255, 255, 255));
+ }
+
+ // / Builds a color gradient suitable for terrain.
+ // /
+ // / @post The original gradient is cleared and a terrain gradient is
+ // / created.
+ // /
+ // / This gradient color at position 0.0 is the "sea level". Above
+ // / that value, the gradient contains greens, browns, and whites.
+ // / Below that value, the gradient contains various shades of blue.
+ public void buildTerrainGradient() throws ExceptionInvalidParam {
+ clearGradient();
+ gradient.addGradientPoint(-1.00, new ColorCafe(0, 0, 128, 255));
+ gradient.addGradientPoint(-0.20, new ColorCafe(32, 64, 128, 255));
+ gradient.addGradientPoint(-0.04, new ColorCafe(64, 96, 192, 255));
+ gradient.addGradientPoint(-0.02, new ColorCafe(192, 192, 128, 255));
+ gradient.addGradientPoint(0.00, new ColorCafe(0, 192, 0, 255));
+ gradient.addGradientPoint(0.25, new ColorCafe(192, 192, 0, 255));
+ gradient.addGradientPoint(0.50, new ColorCafe(160, 96, 64, 255));
+ gradient.addGradientPoint(0.75, new ColorCafe(128, 255, 255, 255));
+ gradient.addGradientPoint(1.00, new ColorCafe(255, 255, 255, 255));
+ }
+
+ // / Calculates the destination color.
+ // /
+ // / @param sourceColor The source color generated from the color
+ // / gradient.
+ // / @param backgroundColor The color from the background image at the
+ // / corresponding position.
+ // / @param lightValue The intensity of the light at that position.
+ // /
+ // / @returns The destination color.
+ public ColorCafe calcDestColor(ColorCafe sourceColor, ColorCafe backgroundColor, double lightValue) {
+ double sourceRed = (double) sourceColor.red / 255.0;
+ double sourceGreen = (double) sourceColor.green / 255.0;
+ double sourceBlue = (double) sourceColor.blue / 255.0;
+ double sourceAlpha = (double) sourceColor.alpha / 255.0;
+ double backgroundRed = (double) backgroundColor.red / 255.0;
+ double backgroundGreen = (double) backgroundColor.green / 255.0;
+ double backgroundBlue = (double) backgroundColor.blue / 255.0;
+
+ // First, blend the source color to the background color using the alpha
+ // of the source color.
+ double red = Interp.linearInterp(backgroundRed, sourceRed, sourceAlpha);
+ double green = Interp.linearInterp(backgroundGreen, sourceGreen, sourceAlpha);
+ double blue = Interp.linearInterp(backgroundBlue, sourceBlue, sourceAlpha);
+
+ if (isLightEnabled) {
+ // Now calculate the light color.
+ double lightRed = lightValue * (double) lightColor.red / 255.0;
+ double lightGreen = lightValue * (double) lightColor.green / 255.0;
+ double lightBlue = lightValue * (double) lightColor.blue / 255.0;
+
+ // Apply the light color to the new color.
+ red *= lightRed;
+ green *= lightGreen;
+ blue *= lightBlue;
+ }
+
+ // Clamp the color channels to the (0..1) range.
+ red = (red < 0.0) ? 0.0 : red;
+ red = (red > 1.0) ? 1.0 : red;
+ green = (green < 0.0) ? 0.0 : green;
+ green = (green > 1.0) ? 1.0 : green;
+ blue = (blue < 0.0) ? 0.0 : blue;
+ blue = (blue > 1.0) ? 1.0 : blue;
+
+ // Rescale the color channels to the noise::uint8 (0..255) range and
+ // return
+ // the new color.
+ ColorCafe newColor = new ColorCafe((int) (red * 255.0) & 0xff, (int) (green * 255.0) & 0xff,
+ (int) (blue * 255.0) & 0xff, Math.max(sourceColor.alpha, backgroundColor.alpha));
+ return newColor;
+ }
+
+ // / Calculates the intensity of the light given some elevation values.
+ // /
+ // / @param center Elevation of the center point.
+ // / @param left Elevation of the point directly left of the center
+ // / point.
+ // / @param right Elevation of the point directly right of the center
+ // / point.
+ // / @param down Elevation of the point directly below the center
+ // / point.
+ // / @param up Elevation of the point directly above the center point.
+ // /
+ // / These values come directly from the noise map.
+ public double calcLightIntensity(double center, double left, double right, double down, double up) {
+ // Recalculate the sine and cosine of the various light values if
+ // necessary so it does not have to be calculated each time this method
+ // is
+ // called.
+ if (recalcLightValues) {
+ cosAzimuth = Math.cos(Math.toRadians(lightAzimuth));
+ sinAzimuth = Math.sin(Math.toRadians(lightAzimuth));
+ cosElev = Math.cos(Math.toRadians(lightElev));
+ sinElev = Math.sin(Math.toRadians(lightElev));
+ recalcLightValues = false;
+ }
+
+ // Now do the lighting calculations.
+ double I_MAX = 1.0;
+ double io = I_MAX * SQRT_2 * sinElev / 2.0;
+ double ix = (I_MAX - io) * lightContrast * SQRT_2 * cosElev * cosAzimuth;
+ double iy = (I_MAX - io) * lightContrast * SQRT_2 * cosElev * sinAzimuth;
+ double intensity = (ix * (left - right) + iy * (down - up) + io);
+
+ if (intensity < 0.0)
+ intensity = 0.0;
+
+ return intensity;
+ }
+
+ // / Clears the color gradient.
+ // /
+ // / Before calling the render() method, the application must specify a
+ // / new color gradient with at least two gradient points.
+ public void clearGradient() {
+ gradient = new GradientColor();
+ gradient.clear();
+ }
+
+ // / Renders the destination image using the contents of the source
+ // / noise map and an optional background image.
+ // /
+ // / @pre setSourceNoiseMap() has been previously called.
+ // / @pre setDestImage() has been previously called.
+ // / @pre There are at least two gradient points in the color gradient.
+ // / @pre No two gradient points have the same position.
+ // / @pre If a background image was specified, it has the exact same
+ // / size as the source height map.
+ // /
+ // / @post The original contents of the destination image is destroyed.
+ // /
+ // / @throw ExceptionInvalidParam See the preconditions.
+ // /
+ // / The background image and the destination image can safely refer to
+ // / the same image, although in this case, the destination image is
+ // / irretrievably blended into the background image.
+ public void render() throws ExceptionInvalidParam {
+ if (sourceNoiseMap == null || destImageCafe == null || sourceNoiseMap.getWidth() <= 0
+ || sourceNoiseMap.getHeight() <= 0 || gradient.getGradientPointCount() < 2)
+ throw new ExceptionInvalidParam("Invalid Parameter in RendererImage");
+
+ int width = sourceNoiseMap.getWidth();
+ int height = sourceNoiseMap.getHeight();
+
+ // If a background image was provided, make sure it is the same size the
+ // source noise map.
+ if (backgroundImage != null)
+ if (backgroundImage.getWidth() != width || backgroundImage.getHeight() != height)
+ throw new ExceptionInvalidParam("Invalid Parameter in RendererImage");
+
+ // Create the destination image. It is safe to reuse it if this is also
+ // the
+ // background image.
+ if (destImageCafe != backgroundImage)
+ destImageCafe.setSize(width, height);
+
+ for (int y = 0; y < height; y++) {
+ @SuppressWarnings("unused")
+ ColorCafe background = new ColorCafe(255, 255, 255, 255);
+
+ for (int x = 0; x < width; x++) {
+ // Get the color based on the value at the current point in the
+ // noise
+ // map.
+ ColorCafe destColor = gradient.getColor(sourceNoiseMap.getValue(x, y));
+
+ // If lighting is enabled, calculate the light intensity based
+ // on the
+ // rate of change at the current point in the noise map.
+ double lightIntensity;
+ if (isLightEnabled) {
+ // Calculate the positions of the current point's
+ // four-neighbors.
+ int xLeftOffset, xRightOffset;
+ int yUpOffset, yDownOffset;
+ if (isWrapEnabled) {
+ if (x == 0) {
+ xLeftOffset = (int) width - 1;
+ xRightOffset = 1;
+ } else if (x == (int) width - 1) {
+ xLeftOffset = -1;
+ xRightOffset = -((int) width - 1);
+ } else {
+ xLeftOffset = -1;
+ xRightOffset = 1;
+ }
+
+ if (y == 0) {
+ yDownOffset = (int) height - 1;
+ yUpOffset = 1;
+ } else if (y == (int) height - 1) {
+ yDownOffset = -1;
+ yUpOffset = -((int) height - 1);
+ } else {
+ yDownOffset = -1;
+ yUpOffset = 1;
+ }
+ } else {
+ if (x == 0) {
+ xLeftOffset = 0;
+ xRightOffset = 1;
+ } else if (x == (int) width - 1) {
+ xLeftOffset = -1;
+ xRightOffset = 0;
+ } else {
+ xLeftOffset = -1;
+ xRightOffset = 1;
+ }
+
+ if (y == 0) {
+ yDownOffset = 0;
+ yUpOffset = 1;
+ } else if (y == (int) height - 1) {
+ yDownOffset = -1;
+ yUpOffset = 0;
+ } else {
+ yDownOffset = -1;
+ yUpOffset = 1;
+ }
+ }
+
+ // Get the noise value of the current point in the source
+ // noise map
+ // and the noise values of its four-neighbors.
+ double nc = (double) (sourceNoiseMap.getValue(x, y));
+ double nl = (double) (sourceNoiseMap.getValue(x + xLeftOffset, y));
+ double nr = (double) (sourceNoiseMap.getValue(x + xRightOffset, y));
+ double nd = (double) (sourceNoiseMap.getValue(x, y + yDownOffset));
+ double nu = (double) (sourceNoiseMap.getValue(x, y + yUpOffset));
+
+ // Now we can calculate the lighting intensity.
+ lightIntensity = calcLightIntensity(nc, nl, nr, nd, nu);
+ lightIntensity *= lightBrightness;
+
+ } else {
+ // These values will apply no lighting to the destination
+ // image.
+ lightIntensity = 1.0;
+ }
+
+ // Get the current background color from the background image.
+ ColorCafe backgroundColor = new ColorCafe(255, 255, 255, 255);
+ if (backgroundImage != null)
+ backgroundColor = backgroundImage.getValue(x, y);
+
+ // Blend the destination color, background color, and the light
+ // intensity together, then update the destination image with
+ // that
+ // color.
+ destImageCafe.setValue(x, y, calcDestColor(destColor, backgroundColor, lightIntensity));
+ }
+ }
+ }
+
+ // / Enables or disables the light source.
+ // /
+ // / @param enable A flag that enables or disables the light source.
+ // /
+ // / If the light source is enabled, this object will interpret the
+ // / noise map as a bump map.
+ public void enableLight(boolean enable) {
+ isLightEnabled = enable;
+ }
+
+ // / Enables or disables noise-map wrapping.
+ // /
+ // / @param enable A flag that enables or disables noise-map wrapping.
+ // /
+ // / This object requires five points (the initial point and its four
+ // / neighbors) to calculate light shading. If wrapping is enabled,
+ // / and the initial point is on the edge of the noise map, the
+ // / appropriate neighbors that lie outside of the noise map will
+ // / "wrap" to the opposite side(s) of the noise map. Otherwise, the
+ // / appropriate neighbors are cropped to the edge of the noise map.
+ // /
+ // / Enabling wrapping is useful when creating spherical renderings and
+ // / tileable textures.
+ public void enableWrap(boolean enable) {
+ isWrapEnabled = enable;
+ }
+
+ // / Returns the azimuth of the light source, in degrees.
+ // /
+ // / @returns The azimuth of the light source.
+ // /
+ // / The azimuth is the location of the light source around the
+ // / horizon:
+ // / - 0.0 degrees is east.
+ // / - 90.0 degrees is north.
+ // / - 180.0 degrees is west.
+ // / - 270.0 degrees is south.
+ public double getLightAzimuth() {
+ return lightAzimuth;
+ }
+
+ // / Returns the brightness of the light source.
+ // /
+ // / @returns The brightness of the light source.
+ public double getLightBrightness() {
+ return lightBrightness;
+ }
+
+ // / Returns the color of the light source.
+ // /
+ // / @returns The color of the light source.
+ public ColorCafe getLightColor() {
+ return lightColor;
+ }
+
+ // / Returns the contrast of the light source.
+ // /
+ // / @returns The contrast of the light source.
+ // /
+ // / The contrast specifies how sharp the boundary is between the
+ // / light-facing areas and the shadowed areas.
+ // /
+ // / The contrast determines the difference between areas in light and
+ // / areas in shadow. Determining the correct contrast amount requires
+ // / some trial and error, but if your application interprets the noise
+ // / map as a height map that has a spatial resolution of @a h meters
+ // / and an elevation resolution of 1 meter, a good contrast amount to
+ // / use is ( 1.0 / @a h ).
+ public double getLightContrast() {
+ return lightContrast;
+ }
+
+ // / Returns the elevation of the light source, in degrees.
+ // /
+ // / @returns The elevation of the light source.
+ // /
+ // / The elevation is the angle above the horizon:
+ // / - 0 degrees is on the horizon.
+ // / - 90 degrees is straight up.
+ public double getLightElev() {
+ return lightElev;
+ }
+
+ // / Returns the intensity of the light source.
+ // /
+ // / @returns The intensity of the light source.
+ public double getLightIntensity() {
+ return lightIntensity;
+ }
+
+ // / Determines if the light source is enabled.
+ // /
+ // / @returns
+ // / - @a true if the light source is enabled.
+ // / - @a false if the light source is disabled.
+ public boolean isLightEnabled() {
+ return isLightEnabled;
+ }
+
+ // / Determines if noise-map wrapping is enabled.
+ // /
+ // / @returns
+ // / - @a true if noise-map wrapping is enabled.
+ // / - @a false if noise-map wrapping is disabled.
+ // /
+ // / This object requires five points (the initial point and its four
+ // / neighbors) to calculate light shading. If wrapping is enabled,
+ // / and the initial point is on the edge of the noise map, the
+ // / appropriate neighbors that lie outside of the noise map will
+ // / "wrap" to the opposite side(s) of the noise map. Otherwise, the
+ // / appropriate neighbors are cropped to the edge of the noise map.
+ // /
+ // / Enabling wrapping is useful when creating spherical renderings and
+ // / tileable textures
+ public boolean isWrapEnabled() {
+ return isWrapEnabled;
+ }
+
+ // / Sets the background image.
+ // /
+ // / @param backgroundImage The background image.
+ // /
+ // / If a background image has been specified, the Render() method
+ // / blends the pixels from the background image onto the corresponding
+ // / pixels in the destination image. The blending weights are
+ // / determined by the alpha channel in the pixels in the destination
+ // / image.
+ // /
+ // / The destination image must exist throughout the lifetime of this
+ // / object unless another image replaces that image.
+ public void setBackgroundImage(ImageCafe backgroundImage) {
+ this.backgroundImage = backgroundImage;
+ }
+
+ // / Sets the destination image.
+ // /
+ // / @param destImage The destination image.
+ // /
+ // / The destination image will contain the rendered image after a
+ // / successful call to the Render() method.
+ // /
+ // / The destination image must exist throughout the lifetime of this
+ // / object unless another image replaces that image.
+ public void setDestImage(ImageCafe destImage) {
+ this.destImageCafe = destImage;
+ }
+
+ // / Sets the azimuth of the light source, in degrees.
+ // /
+ // / @param lightAzimuth The azimuth of the light source.
+ // /
+ // / The azimuth is the location of the light source around the
+ // / horizon:
+ // / - 0.0 degrees is east.
+ // / - 90.0 degrees is north.
+ // / - 180.0 degrees is west.
+ // / - 270.0 degrees is south.
+ // /
+ // / Make sure the light source is enabled via a call to the
+ // / EnableLight() method before calling the Render() method.
+ public void setLightAzimuth(double lightAzimuth) {
+ this.lightAzimuth = lightAzimuth;
+ this.recalcLightValues = true;
+ }
+
+ // / Sets the brightness of the light source.
+ // /
+ // / @param lightBrightness The brightness of the light source.
+ // /
+ // / Make sure the light source is enabled via a call to the
+ // / EnableLight() method before calling the Render() method.
+ public void setLightBrightness(double lightBrightness) {
+ this.lightBrightness = lightBrightness;
+ this.recalcLightValues = true;
+ }
+
+ // / Sets the color of the light source.
+ // /
+ // / @param lightColor The light color.
+ // /
+ // / Make sure the light source is enabled via a call to the
+ // / EnableLight() method before calling the Render() method.
+ public void setLightColor(ColorCafe lightColor) {
+ this.lightColor = lightColor;
+ }
+
+ // / Sets the contrast of the light source.
+ // /
+ // / @param lightContrast The contrast of the light source.
+ // /
+ // / @pre The specified light contrast is positive.
+ // /
+ // / @throw noise::ExceptionInvalidParam See the preconditions.
+ // /
+ // / The contrast specifies how sharp the boundary is between the
+ // / light-facing areas and the shadowed areas.
+ // /
+ // / The contrast determines the difference between areas in light and
+ // / areas in shadow. Determining the correct contrast amount requires
+ // / some trial and error, but if your application interprets the noise
+ // / map as a height map that has a spatial resolution of @a h meters
+ // / and an elevation resolution of 1 meter, a good contrast amount to
+ // / use is ( 1.0 / @a h ).
+ // /
+ // / Make sure the light source is enabled via a call to the
+ // / EnableLight() method before calling the Render() method.
+ public void setLightContrast(double lightContrast) throws ExceptionInvalidParam {
+ if (lightContrast <= 0.0)
+ throw new ExceptionInvalidParam("Invalid Parameter in RendererImage");
+
+ this.lightContrast = lightContrast;
+ this.recalcLightValues = true;
+ }
+
+ // / Sets the elevation of the light source, in degrees.
+ // /
+ // / @param lightElev The elevation of the light source.
+ // /
+ // / The elevation is the angle above the horizon:
+ // / - 0 degrees is on the horizon.
+ // / - 90 degrees is straight up.
+ // /
+ // / Make sure the light source is enabled via a call to the
+ // / EnableLight() method before calling the Render() method.
+ public void setLightElev(double lightElev) {
+ this.lightElev = lightElev;
+ this.recalcLightValues = true;
+ }
+
+ // / Sets the intensity of the light source.
+ // /
+ // / @returns The intensity of the light source.
+ // /
+ // / A good value for intensity is 2.0.
+ // /
+ // / Make sure the light source is enabled via a call to the
+ // / enableLight() method before calling the render() method.
+ public void setLightIntensity(double lightIntensity) throws ExceptionInvalidParam {
+ if (lightIntensity < 0.0)
+ throw new ExceptionInvalidParam("Invalid Parameter in RendererImage");
+
+ this.lightIntensity = lightIntensity;
+ this.recalcLightValues = true;
+ }
+
+ // / Sets the source noise map.
+ // /
+ // / @param sourceNoiseMap The source noise map.
+ // /
+ // / The destination image must exist throughout the lifetime of this
+ // / object unless another image replaces that image.
+ public void setSourceNoiseMap(NoiseMap sourceNoiseMap) {
+ this.sourceNoiseMap = sourceNoiseMap;
+ }
+
+}
|