Subversion Repositories AndroidProjects

Rev

Rev 1732 | Blame | Compare with Previous | Last modification | View Log | RSS feed

package com.gebauz.bauzoid2.graphics.sprite;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.gebauz.bauzoid2.game.Engine;
import com.gebauz.bauzoid2.graphics.geometry.Geometry;
import com.gebauz.bauzoid2.graphics.geometry.SimpleGeometry;
import com.gebauz.bauzoid2.math.MathUtil;
import com.gebauz.bauzoid2.math.Vector4;
import com.gebauz.bauzoid2.util.IAsyncLoadable;

public class SpriteSheet implements IAsyncLoadable
{
        // Constants========================================================================================

    public static final int NUM_INDICES_PER_REGION = 6;
    public static final int NUM_ATTRIBUTES_PER_REGION = 4;

        // Embedded Types===================================================================================

        // Fields===========================================================================================
       
        private String mTextureFile = null;
        private String mSheetFile = null;
       
        private Texture mTexture = null;
    private SimpleGeometry mGeometry = null;
       
        private SpriteSheetRegion[] mRegions = null;
       
        private IAsyncLoadable.Tracker mAsync = new IAsyncLoadable.Tracker();

        // Methods==========================================================================================
       
        public SpriteSheet(String textureFile)
        {
                mTextureFile = textureFile;
        }
       
        public SpriteSheet(String textureFile, String sheetFile)
        {
                mTextureFile = textureFile;
                mSheetFile = sheetFile;
        }

    public SpriteSheet(String textureFile, SpriteSheetRegion[] regions)
    {
        this(textureFile);
        mRegions = regions;
    }
       
        public void initAsync()
        {
                if (mTextureFile == null)
                {
                        // need at least a texture file
                        Engine.logError("No texture file specified in Sprite");
                        return;
                }
               
                mAsync.setAsync();
                Engine.assets.load(mTextureFile, Texture.class);
               
                if (mSheetFile != null)
                {
                        Engine.assets.load(mSheetFile, SpriteSheetDefinition.class);
                }
        }
       
        public void init()
        {
                if (mTextureFile == null)
                        return;
               
                SpriteSheetDefinition def = null;
               
                if (mAsync.isAsync())
                {
                        mTexture = Engine.assets.get(mTextureFile);
                        if (mSheetFile != null)
                                def = Engine.assets.get(mSheetFile);
                }
                else
                {
                        // load texture synchronously
                        mTexture = new Texture(Gdx.files.internal(mTextureFile));
            if (mSheetFile != null)
                            def = SpriteUtil.readSpriteRegionInfo(Gdx.files.internal(mSheetFile));
                }

        if ((mSheetFile != null) && (mRegions == null))
                    processRegionInfo(def);

        if (mGeometry != null)
        {
            mGeometry.dispose();
            mGeometry = null;
        }
        mGeometry = createGeometry();
        }
       
        public void processRegionInfo(SpriteSheetDefinition def)
        {
                if ((def == null) || (def.frames.size() == 0))
                {
                        // whole texture as region
                        mRegions = new SpriteSheetRegion[1];
                        mRegions[0] = new SpriteSheetRegion(this, 0, 0, mTexture.getWidth()-1, mTexture.getHeight()-1, true);
                       
                        return;
                }
               
                mRegions = new SpriteSheetRegion[def.frames.size()];
               
                for (int i = 0; i < def.frames.size(); i++)
                {
                        SpriteSheetDefinition.FrameInfo frame = def.frames.get(i);
                       
                        float w = mTexture.getWidth()-1;
                        float h = mTexture.getHeight()-1;
                       
                        float left = MathUtil.clamp(frame.x, 0, w);
                        float top = MathUtil.clamp(frame.y, 0, h);
                        float right = MathUtil.clamp(frame.x + frame.w, 0, w);
                        float bottom = MathUtil.clamp(frame.y + frame.h, 0, h);
                       
                        mRegions[i] = new SpriteSheetRegion(this, Math.min(left, right), Math.min(top, bottom), Math.max(left, right), Math.max(top, bottom), true);
                }
        }

    public SimpleGeometry createGeometry()
    {
        float[] vertices = new float[NUM_ATTRIBUTES_PER_REGION * SimpleGeometry.POSITION_COORD_PER_ELEMENT * mRegions.length];
        float[] texCoords = new float[NUM_ATTRIBUTES_PER_REGION * SimpleGeometry.TEXCOORD_COORD_PER_ELEMENT * mRegions.length];
        float[] colors = new float[NUM_ATTRIBUTES_PER_REGION * SimpleGeometry.COLOR_COORD_PER_ELEMENT * mRegions.length];

        // two triangles per region
        short[] indices = new short[NUM_INDICES_PER_REGION * mRegions.length];

        for (int i = 0; i < mRegions.length; i++)
        {
            SpriteSheetRegion region = mRegions[i];
            region.regionIndex = i;

            float[] v =
                {
                    -1.0f, -1.0f, 0.0f,
                    1.0f, -1.0f, 0.0f,
                    1.0f,  1.0f, 0.0f,
                    -1.0f,  1.0f, 0.0f
                };

            float[] t =
                {
                    region.left, region.top,
                    region.right, region.top,
                    region.right, region.bottom,
                    region.left, region.bottom
                };

            float[] c =
                {
                    1, 1, 1, 1,
                    1, 1, 1, 1,
                    1, 1, 1, 1,
                    1, 1, 1, 1
                };

            System.arraycopy(v, 0, vertices, NUM_ATTRIBUTES_PER_REGION * SimpleGeometry.POSITION_COORD_PER_ELEMENT * i, v.length);
            System.arraycopy(t, 0, texCoords, NUM_ATTRIBUTES_PER_REGION * SimpleGeometry.TEXCOORD_COORD_PER_ELEMENT * i, t.length);
            System.arraycopy(c, 0, colors, NUM_ATTRIBUTES_PER_REGION * SimpleGeometry.COLOR_COORD_PER_ELEMENT * i, c.length);

            int n = i*NUM_INDICES_PER_REGION;
            short base = (short)(i * NUM_ATTRIBUTES_PER_REGION);
            indices[n++] = base; indices[n++] = (short)(base+1); indices[n++] = (short)(base+2);
            indices[n++] = base; indices[n++] = (short)(base+2); indices[n++] = (short)(base+3);
        }

        SimpleGeometry mesh = new SimpleGeometry(Geometry.PrimitiveType.TRIANGLES);
        mesh.setPositions(vertices);
        mesh.setTexCoords(texCoords);
        mesh.setColors(colors);
        mesh.setIndices(indices);

        return mesh;
    }
       
        public void dispose()
        {
                mRegions = null;

                if (mTexture != null)
                {
                        mTexture.dispose();
                        mTexture = null;
                }

        if (mGeometry != null)
        {
            mGeometry.dispose();
            mGeometry = null;
        }
        }

    public void render(int regionIndex, float alpha, Vector4 color, Vector4 fogColor)
    {
        // draw sprite
        Engine.graphics.getSpriteShader().activate(getTexture(), alpha, color, fogColor);
        {
            Engine.graphics.renderStates.blending.setEnabled(true);
            Engine.graphics.renderStates.culling.setEnabled(false);
            Engine.graphics.renderStates.activate();
            Engine.graphics.renderStates.blending.activate(true);
            {
                mGeometry.render(regionIndex * NUM_INDICES_PER_REGION, NUM_INDICES_PER_REGION);
            }
            Engine.graphics.renderStates.deactivate();
        }
        Engine.graphics.getSpriteShader().deactivate();
    }

        // Getters/Setters==================================================================================

       
        public final Texture getTexture()
        {
                return mTexture;
        }
       
        public final SpriteSheetRegion getRegion(int i)
        {
                return mRegions[i];
        }
       
        public final int getRegionCount()
        {
                return mRegions.length;
        }


}