Package com.ardor3d.extension.ui.util

Source Code of com.ardor3d.extension.ui.util.SubTexUtil

/**
* Copyright (c) 2008-2012 Ardor Labs, Inc.
*
* This file is part of Ardor3D.
*
* Ardor3D is free software: you can redistribute it and/or modify it
* under the terms of its license which may be found in the accompanying
* LICENSE file or at <http://www.ardor3d.com/LICENSE>.
*/

package com.ardor3d.extension.ui.util;

import com.ardor3d.extension.ui.UIComponent;
import com.ardor3d.math.ColorRGBA;
import com.ardor3d.math.Transform;
import com.ardor3d.math.Vector3;
import com.ardor3d.math.type.ReadOnlyColorRGBA;
import com.ardor3d.math.type.ReadOnlyTransform;
import com.ardor3d.renderer.IndexMode;
import com.ardor3d.renderer.Renderer;
import com.ardor3d.renderer.state.BlendState;
import com.ardor3d.renderer.state.BlendState.DestinationFunction;
import com.ardor3d.renderer.state.BlendState.SourceFunction;
import com.ardor3d.renderer.state.TextureState;
import com.ardor3d.scenegraph.FloatBufferData;
import com.ardor3d.scenegraph.Mesh;
import com.ardor3d.util.geom.BufferUtils;

/**
* SubTexUtil is a utility for drawing SubTex objects to a renderer.
*/
public class SubTexUtil {

    private static final Mesh _mesh = SubTexUtil.createMesh();
    private static final float[] _vals = new float[8];
    private static final float[] _texc = new float[8];
    private static TextureState _tstate = new TextureState();
    private static final Transform _helperT = new Transform();

    /**
     * Draw the given SubTex, as-is, to the screen at the given location.
     *
     * @param renderer
     *            the renderer to use
     * @param subTex
     *            the SubTex to draw
     * @param x
     *            the x coordinate of the screen location to draw at
     * @param y
     *            the y coordinate of the screen location to draw at
     */
    public static void drawSubTex(final Renderer renderer, final SubTex subTex, final int x, final int y) {
        SubTexUtil.drawSubTex(renderer, subTex, x, y, subTex.getWidth(), subTex.getHeight(), false, null);
    }

    /**
     * Draw the given SubTex to the screen at the given location. Use the given width and height instead of those
     * supplied in the SubTex.
     *
     * @param renderer
     *            the renderer to use
     * @param subTex
     *            the SubTex to draw
     * @param x
     *            the x coordinate of the screen location to draw at
     * @param y
     *            the y coordinate of the screen location to draw at
     * @param width
     *            the width in screen pixels to use when drawing the SubTex.
     * @param height
     *            the height in screen pixels to use when drawing the SubTex.
     * @param appliedTransform
     *            an optional transform to apply to the rendered subtex
     */
    public static void drawSubTex(final Renderer renderer, final SubTex subTex, final int x, final int y,
            final int width, final int height, final ReadOnlyTransform appliedTransform) {
        SubTexUtil.drawSubTex(renderer, subTex, x, y, width, height, false, appliedTransform);
    }

    /**
     * Draw the given SubTex to the screen at the given location. Use the given width and height instead of those
     * supplied in the SubTex. Does not flip vertically.
     *
     * @param renderer
     *            the renderer to use
     * @param subTex
     *            the SubTex to draw
     * @param x
     *            the x coordinate of the screen location to draw at
     * @param y
     *            the y coordinate of the screen location to draw at
     * @param width
     *            the width in screen pixels to use when drawing the SubTex.
     * @param height
     *            the height in screen pixels to use when drawing the SubTex.
     * @param appliedTransform
     *            an optional transform to apply to the rendered subtex
     */
    public static void drawSubTex(final Renderer renderer, final SubTex subTex, final double x, final double y,
            final double width, final double height, final ReadOnlyTransform appliedTransform) {
        SubTexUtil.drawSubTex(renderer, subTex, (int) Math.round(x), (int) Math.round(y), (int) Math.round(width),
                (int) Math.round(height), false, appliedTransform, null);
    }

    /**
     * Draw the given SubTex to the screen at the given location. Use the given width and height instead of those
     * supplied in the SubTex. Does not flip vertically.
     *
     * @param renderer
     *            the renderer to use
     * @param subTex
     *            the SubTex to draw
     * @param x
     *            the x coordinate of the screen location to draw at
     * @param y
     *            the y coordinate of the screen location to draw at
     * @param width
     *            the width in screen pixels to use when drawing the SubTex.
     * @param height
     *            the height in screen pixels to use when drawing the SubTex.
     * @param appliedTransform
     *            an optional transform to apply to the rendered subtex
     */
    public static void drawSubTex(final Renderer renderer, final SubTex subTex, final double x, final double y,
            final double width, final double height, final ReadOnlyTransform appliedTransform,
            final ReadOnlyColorRGBA tintOverride) {
        SubTexUtil.drawSubTex(renderer, subTex, (int) Math.round(x), (int) Math.round(y), (int) Math.round(width),
                (int) Math.round(height), false, appliedTransform, tintOverride);
    }

    /**
     * Draw the given SubTex to the screen at the given location. Use the given width and height instead of those
     * supplied in the SubTex.
     *
     * @param renderer
     *            the renderer to use
     * @param subTex
     *            the SubTex to draw
     * @param x
     *            the x coordinate of the screen location to draw at
     * @param y
     *            the y coordinate of the screen location to draw at
     * @param width
     *            the width in screen pixels to use when drawing the SubTex.
     * @param height
     *            the height in screen pixels to use when drawing the SubTex.
     */
    public static void drawSubTex(final Renderer renderer, final SubTex subTex, final double x, final double y,
            final double width, final double height) {
        SubTexUtil.drawSubTex(renderer, subTex, (int) Math.round(x), (int) Math.round(y), (int) Math.round(width),
                (int) Math.round(height), false, null);
    }

    /**
     * Draw the given SubTex, optionally inverted on the Y axis, to the screen at the given location. Use the given
     * width and height instead of those supplied in the SubTex.
     *
     * @param renderer
     *            the renderer to use
     * @param subTex
     *            the SubTex to draw
     * @param x
     *            the x offset to draw at
     * @param y
     *            the y offset to draw at
     * @param width
     *            the width in screen pixels to use when drawing the SubTex.
     * @param height
     *            the height in screen pixels to use when drawing the SubTex.
     * @param flipVertical
     *            if true, invert the image vertically before drawing
     * @param appliedTransform
     *            an optional transform to apply to the rendered subtex
     */
    public static void drawSubTex(final Renderer renderer, final SubTex subTex, final int x, final int y,
            final int width, final int height, final boolean flipVertical, final ReadOnlyTransform appliedTransform) {
        SubTexUtil.drawSubTex(renderer, subTex, x, y, width, height, flipVertical, appliedTransform, null);
    }

    /**
     * Draw the given SubTex, optionally inverted on the Y axis, to the screen at the given location. Use the given
     * width and height instead of those supplied in the SubTex.
     *
     * @param renderer
     *            the renderer to use
     * @param subTex
     *            the SubTex to draw
     * @param x
     *            the x offset to draw at
     * @param y
     *            the y offset to draw at
     * @param width
     *            the width in screen pixels to use when drawing the SubTex.
     * @param height
     *            the height in screen pixels to use when drawing the SubTex.
     * @param flipVertical
     *            if true, invert the image vertically before drawing
     * @param appliedTransform
     *            an optional transform to apply to the rendered subtex
     * @param tintOverride
     *            an optional override for the SubTex tintColor.
     */
    public static void drawSubTex(final Renderer renderer, final SubTex subTex, final int x, final int y,
            final int width, final int height, final boolean flipVertical, final ReadOnlyTransform appliedTransform,
            final ReadOnlyColorRGBA tintOverride) {

        if (width == 0 || height == 0 || subTex == null || subTex.getTexture() == null) {
            return; // no need to draw
        }

        // Optimization: Check to see if the given SubTex's Texture is the same one we used "last time".
        if (SubTexUtil._tstate.getNumberOfSetTextures() == 0 || SubTexUtil._tstate.getTexture().getTextureKey() == null
                || !SubTexUtil._tstate.getTexture().getTextureKey().equals(subTex.getTexture().getTextureKey())) {
            SubTexUtil._tstate.setTexture(subTex.getTexture());
            SubTexUtil._mesh.setRenderState(SubTexUtil._tstate);
            SubTexUtil._mesh.updateWorldRenderStates(false);
        }

        // Setup our tint color and alpha value.
        final ColorRGBA defaultColor = ColorRGBA.fetchTempInstance();
        if (tintOverride != null) {
            defaultColor.set(tintOverride);
            defaultColor.setAlpha(UIComponent.getCurrentOpacity() * tintOverride.getAlpha());
        } else if (subTex.getTint() != null) {
            defaultColor.set(subTex.getTint());
            defaultColor.setAlpha(UIComponent.getCurrentOpacity() * subTex.getTint().getAlpha());
        } else {
            defaultColor.set(ColorRGBA.WHITE);
            defaultColor.setAlpha(UIComponent.getCurrentOpacity());
        }
        SubTexUtil._mesh.setDefaultColor(defaultColor);
        ColorRGBA.releaseTempInstance(defaultColor);

        final float endY = subTex.getEndY();
        final float endX = subTex.getEndX();

        final float startX = subTex.getStartX();
        final float startY = subTex.getStartY();

        // Set up texture coordinates based on vertical flip
        if (!flipVertical) {
            SubTexUtil._texc[0] = startX;
            SubTexUtil._texc[1] = endY;
            SubTexUtil._texc[2] = endX;
            SubTexUtil._texc[3] = endY;
            SubTexUtil._texc[4] = endX;
            SubTexUtil._texc[5] = startY;
            SubTexUtil._texc[6] = startX;
            SubTexUtil._texc[7] = startY;
        } else {
            SubTexUtil._texc[0] = startX;
            SubTexUtil._texc[1] = startY;
            SubTexUtil._texc[2] = endX;
            SubTexUtil._texc[3] = startY;
            SubTexUtil._texc[4] = endX;
            SubTexUtil._texc[5] = endY;
            SubTexUtil._texc[6] = startX;
            SubTexUtil._texc[7] = endY;
        }

        SubTexUtil._vals[0] = 0;
        SubTexUtil._vals[1] = 0;
        SubTexUtil._vals[2] = width;
        SubTexUtil._vals[3] = 0;
        SubTexUtil._vals[4] = width;
        SubTexUtil._vals[5] = height;
        SubTexUtil._vals[6] = 0;
        SubTexUtil._vals[7] = height;

        // Set our transform
        final ReadOnlyTransform worldT = appliedTransform != null ? appliedTransform : Transform.IDENTITY;
        final Vector3 v = Vector3.fetchTempInstance();
        v.set(x, y, 0);
        SubTexUtil._helperT.set(worldT);
        SubTexUtil._helperT.applyForwardVector(v);
        SubTexUtil._helperT.translate(v);
        Vector3.releaseTempInstance(v);
        SubTexUtil._mesh.setWorldTransform(SubTexUtil._helperT);

        // set our vertices into the mesh
        SubTexUtil._mesh.getMeshData().getVertexBuffer().rewind();
        SubTexUtil._mesh.getMeshData().getVertexBuffer().put(SubTexUtil._vals);

        // set our texture coords into the mesh
        SubTexUtil._mesh.getMeshData().getTextureBuffer(0).rewind();
        SubTexUtil._mesh.getMeshData().getTextureBuffer(0).put(SubTexUtil._texc);

        // draw mesh
        SubTexUtil._mesh.render(renderer);
    }

    /**
     * Draw the given TransformedSubTex, optionally inverted on the Y axis, to the screen at the given location. Use the
     * given width and height instead of those supplied in the TransformedSubTex.
     *
     * @param renderer
     *            the renderer to use
     * @param subTex
     *            the TransformedSubTex to draw
     * @param x
     *            the x coordinate of the screen location to draw at
     * @param y
     *            the y coordinate of the screen location to draw at
     * @param width
     *            the width in screen pixels to use when drawing the TransformedSubTex.
     * @param height
     *            the height in screen pixels to use when drawing the TransformedSubTex.
     * @param flipVertical
     *            if true, invert the image vertically before drawing
     * @param appliedTransform
     *            an optional transform to apply to the rendered subtex
     */
    public static void drawTransformedSubTex(final Renderer renderer, final TransformedSubTex subTex, final int x,
            final int y, final int width, final int height, final boolean flipVertical,
            final ReadOnlyTransform appliedTransform) {

        if (width == 0 || height == 0 || subTex == null || subTex.getTexture() == null) {
            return; // no need to draw
        }

        // Optimization: Check to see if the given SubTex's Texture is the same one we used "last time".
        if (SubTexUtil._tstate.getNumberOfSetTextures() == 0 || SubTexUtil._tstate.getTexture().getTextureKey() == null
                || !SubTexUtil._tstate.getTexture().getTextureKey().equals(subTex.getTexture().getTextureKey())) {
            SubTexUtil._tstate.setTexture(subTex.getTexture());
            SubTexUtil._mesh.setRenderState(SubTexUtil._tstate);
            SubTexUtil._mesh.updateWorldRenderStates(false);
        }

        // Setup our tint color and alpha value.
        final ColorRGBA defaultColor = ColorRGBA.fetchTempInstance();
        if (subTex.getTint() != null) {
            defaultColor.set(subTex.getTint());
            defaultColor.setAlpha(UIComponent.getCurrentOpacity() * subTex.getTint().getAlpha());
        } else {
            defaultColor.set(ColorRGBA.WHITE);
            defaultColor.setAlpha(UIComponent.getCurrentOpacity());
        }
        SubTexUtil._mesh.setDefaultColor(defaultColor);
        ColorRGBA.releaseTempInstance(defaultColor);

        final float endY = subTex.getEndY();
        final float endX = subTex.getEndX();

        final float startX = subTex.getStartX();
        final float startY = subTex.getStartY();

        // Set up texture coordinates based on vertical flip
        if (!flipVertical) {
            SubTexUtil._texc[0] = startX;
            SubTexUtil._texc[1] = endY;
            SubTexUtil._texc[2] = endX;
            SubTexUtil._texc[3] = endY;
            SubTexUtil._texc[4] = endX;
            SubTexUtil._texc[5] = startY;
            SubTexUtil._texc[6] = startX;
            SubTexUtil._texc[7] = startY;
        } else {
            SubTexUtil._texc[0] = startX;
            SubTexUtil._texc[1] = startY;
            SubTexUtil._texc[2] = endX;
            SubTexUtil._texc[3] = startY;
            SubTexUtil._texc[4] = endX;
            SubTexUtil._texc[5] = endY;
            SubTexUtil._texc[6] = startX;
            SubTexUtil._texc[7] = endY;
        }

        final float leftW = -subTex.getPivot().getXf() * width;
        final float rightW = (1f - subTex.getPivot().getXf()) * width;
        final float leftH = -subTex.getPivot().getYf() * height;
        final float rightH = (1f - subTex.getPivot().getYf()) * height;
        SubTexUtil._vals[0] = leftW;
        SubTexUtil._vals[1] = leftH;
        SubTexUtil._vals[2] = rightW;
        SubTexUtil._vals[3] = leftH;
        SubTexUtil._vals[4] = rightW;
        SubTexUtil._vals[5] = rightH;
        SubTexUtil._vals[6] = leftW;
        SubTexUtil._vals[7] = rightH;

        // Set our transform
        final ReadOnlyTransform worldT = appliedTransform != null ? appliedTransform : Transform.IDENTITY;
        final Vector3 v = Vector3.fetchTempInstance();
        v.set(x, y, 0);
        worldT.applyForwardVector(v);
        worldT.multiply(subTex.getTransform(), SubTexUtil._helperT);
        SubTexUtil._helperT.translate(v);
        Vector3.releaseTempInstance(v);
        SubTexUtil._mesh.setWorldTransform(SubTexUtil._helperT);

        // set our vertices into the mesh
        SubTexUtil._mesh.getMeshData().getVertexBuffer().rewind();
        SubTexUtil._mesh.getMeshData().getVertexBuffer().put(SubTexUtil._vals);

        // set our texture coords into the mesh
        SubTexUtil._mesh.getMeshData().getTextureBuffer(0).rewind();
        SubTexUtil._mesh.getMeshData().getTextureBuffer(0).put(SubTexUtil._texc);

        // draw mesh
        SubTexUtil._mesh.render(renderer);
    }

    private static Mesh createMesh() {
        final Mesh mesh = new Mesh();
        mesh.getMeshData().setVertexCoords(new FloatBufferData(BufferUtils.createVector2Buffer(4), 2));
        mesh.getMeshData().setTextureBuffer(BufferUtils.createVector2Buffer(4), 0);
        mesh.getMeshData().setIndexMode(IndexMode.TriangleFan);

        mesh.setRenderState(SubTexUtil._tstate);

        final BlendState blend = new BlendState();
        blend.setBlendEnabled(true);
        blend.setSourceFunction(SourceFunction.SourceAlpha);
        blend.setDestinationFunction(DestinationFunction.OneMinusSourceAlpha);
        mesh.setRenderState(blend);

        mesh.updateWorldRenderStates(false);

        return mesh;
    }
}
TOP

Related Classes of com.ardor3d.extension.ui.util.SubTexUtil

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.