com.badlogic.gdx.graphics.g2d.TextureRegion.java Source code

Java tutorial

Introduction

Here is the source code for com.badlogic.gdx.graphics.g2d.TextureRegion.java

Source

/*******************************************************************************
 * Copyright 2011 See AUTHORS file.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/

package com.badlogic.gdx.graphics.g2d;

import com.badlogic.gdx.graphics.Texture;

/** Defines a rectangular area of a texture. The coordinate system used has its origin in the upper left corner with the x-axis
 * pointing to the right and the y axis pointing downwards.
 * @author mzechner
 * @author Nathan Sweet */
public class TextureRegion {
    Texture texture;
    float u, v;
    float u2, v2;
    int regionWidth, regionHeight;

    /** Constructs a region with no texture and no coordinates defined. */
    public TextureRegion() {
    }

    /** Constructs a region the size of the specified texture. */
    public TextureRegion(Texture texture) {
        if (texture == null)
            throw new IllegalArgumentException("texture cannot be null.");
        this.texture = texture;
        setRegion(0, 0, texture.getWidth(), texture.getHeight());
    }

    /** @param width The width of the texture region. May be negative to flip the sprite when drawn.
     * @param height The height of the texture region. May be negative to flip the sprite when drawn. */
    public TextureRegion(Texture texture, int width, int height) {
        this.texture = texture;
        setRegion(0, 0, width, height);
    }

    /** @param width The width of the texture region. May be negative to flip the sprite when drawn.
     * @param height The height of the texture region. May be negative to flip the sprite when drawn. */
    public TextureRegion(Texture texture, int x, int y, int width, int height) {
        this.texture = texture;
        setRegion(x, y, width, height);
    }

    public TextureRegion(Texture texture, float u, float v, float u2, float v2) {
        this.texture = texture;
        setRegion(u, v, u2, v2);
    }

    /** Constructs a region with the same texture and coordinates of the specified region. */
    public TextureRegion(TextureRegion region) {
        setRegion(region);
    }

    /** Constructs a region with the same texture as the specified region and sets the coordinates relative to the specified region.
     * @param width The width of the texture region. May be negative to flip the sprite when drawn.
     * @param height The height of the texture region. May be negative to flip the sprite when drawn. */
    public TextureRegion(TextureRegion region, int x, int y, int width, int height) {
        setRegion(region, x, y, width, height);
    }

    /** Sets the texture and sets the coordinates to the size of the specified texture. */
    public void setRegion(Texture texture) {
        this.texture = texture;
        setRegion(0, 0, texture.getWidth(), texture.getHeight());
    }

    /** @param width The width of the texture region. May be negative to flip the sprite when drawn.
     * @param height The height of the texture region. May be negative to flip the sprite when drawn. */
    public void setRegion(int x, int y, int width, int height) {
        float invTexWidth = 1f / texture.getWidth();
        float invTexHeight = 1f / texture.getHeight();
        setRegion(x * invTexWidth, y * invTexHeight, (x + width) * invTexWidth, (y + height) * invTexHeight);
        regionWidth = Math.abs(width);
        regionHeight = Math.abs(height);
    }

    public void setRegion(float u, float v, float u2, float v2) {
        int texWidth = texture.getWidth(), texHeight = texture.getHeight();
        regionWidth = Math.round(Math.abs(u2 - u) * texWidth);
        regionHeight = Math.round(Math.abs(v2 - v) * texHeight);

        // For a 1x1 region, adjust UVs toward pixel center to avoid filtering artifacts on AMD GPUs when drawing very stretched.
        if (regionWidth == 1 && regionHeight == 1) {
            float adjustX = 0.25f / texWidth;
            u += adjustX;
            u2 -= adjustX;
            float adjustY = 0.25f / texHeight;
            v += adjustY;
            v2 -= adjustY;
        }

        this.u = u;
        this.v = v;
        this.u2 = u2;
        this.v2 = v2;
    }

    /** Sets the texture and coordinates to the specified region. */
    public void setRegion(TextureRegion region) {
        texture = region.texture;
        setRegion(region.u, region.v, region.u2, region.v2);
    }

    /** Sets the texture to that of the specified region and sets the coordinates relative to the specified region. */
    public void setRegion(TextureRegion region, int x, int y, int width, int height) {
        texture = region.texture;
        setRegion(region.getRegionX() + x, region.getRegionY() + y, width, height);
    }

    public Texture getTexture() {
        return texture;
    }

    public void setTexture(Texture texture) {
        this.texture = texture;
    }

    public float getU() {
        return u;
    }

    public void setU(float u) {
        this.u = u;
        regionWidth = Math.round(Math.abs(u2 - u) * texture.getWidth());
    }

    public float getV() {
        return v;
    }

    public void setV(float v) {
        this.v = v;
        regionHeight = Math.round(Math.abs(v2 - v) * texture.getHeight());
    }

    public float getU2() {
        return u2;
    }

    public void setU2(float u2) {
        this.u2 = u2;
        regionWidth = Math.round(Math.abs(u2 - u) * texture.getWidth());
    }

    public float getV2() {
        return v2;
    }

    public void setV2(float v2) {
        this.v2 = v2;
        regionHeight = Math.round(Math.abs(v2 - v) * texture.getHeight());
    }

    public int getRegionX() {
        return Math.round(u * texture.getWidth());
    }

    public void setRegionX(int x) {
        setU(x / (float) texture.getWidth());
    }

    public int getRegionY() {
        return Math.round(v * texture.getHeight());
    }

    public void setRegionY(int y) {
        setV(y / (float) texture.getHeight());
    }

    /** Returns the region's width. */
    public int getRegionWidth() {
        return regionWidth;
    }

    public void setRegionWidth(int width) {
        if (isFlipX()) {
            setU(u2 + width / (float) texture.getWidth());
        } else {
            setU2(u + width / (float) texture.getWidth());
        }
    }

    /** Returns the region's height. */
    public int getRegionHeight() {
        return regionHeight;
    }

    public void setRegionHeight(int height) {
        if (isFlipY()) {
            setV(v2 + height / (float) texture.getHeight());
        } else {
            setV2(v + height / (float) texture.getHeight());
        }
    }

    public void flip(boolean x, boolean y) {
        if (x) {
            float temp = u;
            u = u2;
            u2 = temp;
        }
        if (y) {
            float temp = v;
            v = v2;
            v2 = temp;
        }
    }

    public boolean isFlipX() {
        return u > u2;
    }

    public boolean isFlipY() {
        return v > v2;
    }

    /** Offsets the region relative to the current region. Generally the region's size should be the entire size of the texture in
     * the direction(s) it is scrolled.
     * @param xAmount The percentage to offset horizontally.
     * @param yAmount The percentage to offset vertically. This is done in texture space, so up is negative. */
    public void scroll(float xAmount, float yAmount) {
        if (xAmount != 0) {
            float width = (u2 - u) * texture.getWidth();
            u = (u + xAmount) % 1;
            u2 = u + width / texture.getWidth();
        }
        if (yAmount != 0) {
            float height = (v2 - v) * texture.getHeight();
            v = (v + yAmount) % 1;
            v2 = v + height / texture.getHeight();
        }
    }

    /** Helper function to create tiles out of this TextureRegion starting from the top left corner going to the right and ending at
     * the bottom right corner. Only complete tiles will be returned so if the region's width or height are not a multiple of the
     * tile width and height not all of the region will be used. This will not work on texture regions returned form a TextureAtlas
     * that either have whitespace removed or where flipped before the region is split.
     * 
     * @param tileWidth a tile's width in pixels
     * @param tileHeight a tile's height in pixels
     * @return a 2D array of TextureRegions indexed by [row][column]. */
    public TextureRegion[][] split(int tileWidth, int tileHeight) {
        int x = getRegionX();
        int y = getRegionY();
        int width = regionWidth;
        int height = regionHeight;

        int rows = height / tileHeight;
        int cols = width / tileWidth;

        int startX = x;
        TextureRegion[][] tiles = new TextureRegion[rows][cols];
        for (int row = 0; row < rows; row++, y += tileHeight) {
            x = startX;
            for (int col = 0; col < cols; col++, x += tileWidth) {
                tiles[row][col] = new TextureRegion(texture, x, y, tileWidth, tileHeight);
            }
        }

        return tiles;
    }

    /** Helper function to create tiles out of the given {@link Texture} starting from the top left corner going to the right and
     * ending at the bottom right corner. Only complete tiles will be returned so if the texture's width or height are not a
     * multiple of the tile width and height not all of the texture will be used.
     * 
     * @param texture the Texture
     * @param tileWidth a tile's width in pixels
     * @param tileHeight a tile's height in pixels
     * @return a 2D array of TextureRegions indexed by [row][column]. */
    public static TextureRegion[][] split(Texture texture, int tileWidth, int tileHeight) {
        TextureRegion region = new TextureRegion(texture);
        return region.split(tileWidth, tileHeight);
    }
}