⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shadedsurface.java

📁 Developing Games in Java 源代码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package com.brackeen.javagamebook.graphics3D.texture;

import java.lang.ref.SoftReference;
import java.util.List;
import com.brackeen.javagamebook.math3D.*;

/**
    A ShadedSurface is a pre-shaded Texture that maps onto a
    polygon.
*/
public final class ShadedSurface extends Texture {

    public static final int SURFACE_BORDER_SIZE = 1;

    public static final int SHADE_RES_BITS = 4;
    public static final int SHADE_RES = 1 << SHADE_RES_BITS;
    public static final int SHADE_RES_MASK = SHADE_RES - 1;
    public static final int SHADE_RES_SQ = SHADE_RES*SHADE_RES;
    public static final int SHADE_RES_SQ_BITS = SHADE_RES_BITS*2;

    private short[] buffer;
    private SoftReference bufferReference;
    private boolean dirty;
    private ShadedTexture sourceTexture;
    private Rectangle3D sourceTextureBounds;
    private Rectangle3D surfaceBounds;
    private byte[] shadeMap;
    private int shadeMapWidth;
    private int shadeMapHeight;

    // for incrementally calculating shade values
    private int shadeValue;
    private int shadeValueInc;

    /**
        Creates a ShadedSurface with the specified width and
        height.
    */
    public ShadedSurface(int width, int height) {
        this(null, width, height);
    }


    /**
        Creates a ShadedSurface with the specified buffer,
        width and height.
    */
    public ShadedSurface(short[] buffer, int width, int height) {
        super(width, height);
        this.buffer = buffer;
        bufferReference = new SoftReference(buffer);
        sourceTextureBounds = new Rectangle3D();
        dirty = true;
    }


    /**
        Creates a ShadedSurface for the specified polygon. The
        shade map is created from the specified list of point
        lights and ambient light intensity.
    */
    public static void createShadedSurface(
        TexturedPolygon3D poly, ShadedTexture texture,
        List lights, float ambientLightIntensity)
    {
        // create the texture bounds
        Vector3D origin = poly.getVertex(0);
        Vector3D dv = new Vector3D(poly.getVertex(1));
        dv.subtract(origin);
        Vector3D du = new Vector3D();
        du.setToCrossProduct(poly.getNormal(), dv);
        Rectangle3D bounds = new Rectangle3D(origin, du, dv,
            texture.getWidth(), texture.getHeight());

        createShadedSurface(poly, texture, bounds,
            lights, ambientLightIntensity);
    }


    /**
        Creates a ShadedSurface for the specified polygon. The
        shade map is created from the specified list of point
        lights and ambient light intensity.
    */
    public static void createShadedSurface(
        TexturedPolygon3D poly, ShadedTexture texture,
        Rectangle3D textureBounds,
        List lights, float ambientLightIntensity)
    {

        // create the surface bounds
        poly.setTexture(texture, textureBounds);
        Rectangle3D surfaceBounds = poly.calcBoundingRectangle();

        // give the surfaceBounds a border to correct for
        // slight errors when texture mapping
        Vector3D du = new Vector3D(surfaceBounds.getDirectionU());
        Vector3D dv = new Vector3D(surfaceBounds.getDirectionV());
        du.multiply(SURFACE_BORDER_SIZE);
        dv.multiply(SURFACE_BORDER_SIZE);
        surfaceBounds.getOrigin().subtract(du);
        surfaceBounds.getOrigin().subtract(dv);
        int width = (int)Math.ceil(surfaceBounds.getWidth() +
            SURFACE_BORDER_SIZE*2);
        int height = (int)Math.ceil(surfaceBounds.getHeight() +
            SURFACE_BORDER_SIZE*2);
        surfaceBounds.setWidth(width);
        surfaceBounds.setHeight(height);

        // create the shaded surface texture
        ShadedSurface surface = new ShadedSurface(width, height);
        surface.setTexture(texture, textureBounds);
        surface.setSurfaceBounds(surfaceBounds);

        // create the surface's shade map
        surface.buildShadeMap(lights, ambientLightIntensity);

        // set the polygon's surface
        poly.setTexture(surface, surfaceBounds);
    }


    /**
        Gets the 16-bit color of the pixel at location (x,y) in
        the bitmap. The x and y values are assumbed to be within
        the bounds of the surface; otherwise an
        ArrayIndexOutOfBoundsException occurs.
    */
    public short getColor(int x, int y) {
        //try {
            return buffer[x + y * width];
        //}
        //catch (ArrayIndexOutOfBoundsException ex) {
        //    return -2048;
        //}

    }


    /**
        Gets the 16-bit color of the pixel at location (x,y) in
        the bitmap. The x and y values are checked to be within
        the bounds of the surface, and if not, the pixel on the
        edge of the texture is returned.
    */
    public short getColorChecked(int x, int y) {
        if (x < 0) {
            x = 0;
        }
        else if (x >= width) {
            x = width-1;
        }
        if (y < 0) {
            y = 0;
        }
        else if (y >= height) {
            y = height-1;
        }
        return getColor(x,y);
    }


    /**
        Marks whether this surface is dirty. Surfaces marked as
        dirty may be cleared externally.
    */
    public void setDirty(boolean dirty) {
        this.dirty = dirty;
    }


    /**
        Checks wether this surface is dirty. Surfaces marked as
        dirty may be cleared externally.
    */
    public boolean isDirty() {
        return dirty;
    }


    /**
        Creates a new surface and add a SoftReference to it.
    */
    protected void newSurface(int width, int height) {
        buffer = new short[width*height];
        bufferReference = new SoftReference(buffer);
    }


    /**
        Clears this surface, allowing the garbage collector to
        remove it from memory if needed.
    */
    public void clearSurface() {
        buffer = null;
    }


    /**
        Checks if the surface has been cleared.
    */
    public boolean isCleared() {
        return (buffer == null);
    }


    /**
        If the buffer has been previously built and cleared but
        not yet removed from memory by the garbage collector,
        then this method attempts to retrieve it. Returns true if
        successfull.
    */
    public boolean retrieveSurface() {
        if (buffer == null) {
            buffer = (short[])bufferReference.get();
        }
        return !(buffer == null);
    }


    /**
        Sets the source texture for this ShadedSurface.
    */
    public void setTexture(ShadedTexture texture) {
        this.sourceTexture = texture;
        sourceTextureBounds.setWidth(texture.getWidth());
        sourceTextureBounds.setHeight(texture.getHeight());
    }


    /**
        Sets the source texture and source bounds for this
        ShadedSurface.
    */
    public void setTexture(ShadedTexture texture,
        Rectangle3D bounds)
    {
        setTexture(texture);
        sourceTextureBounds.setTo(bounds);
    }


    /**
        Sets the surface bounds for this ShadedSurface.
    */
    public void setSurfaceBounds(Rectangle3D surfaceBounds) {
        this.surfaceBounds = surfaceBounds;
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -