Subversion Repositories AndroidProjects

Rev

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

package com.gebauz.Bauzoid.graphics.sprite;

import com.badlogic.gdx.graphics.Texture;
import com.gebauz.Bauzoid.graphics.Graphics;
import com.gebauz.Bauzoid.graphics.model.SimpleGeometry;
import com.gebauz.Bauzoid.graphics.model.Geometry.PrimitiveType;
import com.gebauz.Bauzoid.graphics.renderstates.RenderStates;
import com.gebauz.Bauzoid.math.Matrix4;

/** Sprite atlas.
 * Implements a sprite that defines multiple regions that can be used
 * as Sprite Atlas or as Animated Sprite.
 *
 */

public class AtlasSprite extends Sprite
{
        public static int NUM_INDICES_PER_REGION = 6;
        public static int NUM_ATTRIBUTES_PER_REGION = 4;
       
        /** Stores the seperate regions of the sprite. */
        private SpriteRegion[] mRegions = null;
       
        /** Geometry cache so that updates of vertex texture coord streams are not necessary. */
        //private SimpleGeometry[] mGeometryCache = null;
       
        /** Stores all Geometry of all SpriteRegions. */
        private SimpleGeometry mMesh = null;
       
        /** Constructor. */
        public AtlasSprite(Graphics graphics, Texture texture, SpriteRegion[] regions)
        {
                super(graphics, texture);
               
                mRegions = regions;
                mMesh = createGeometry();              
               
               
/*              mGeometryCache = new SimpleGeometry[regions.length];
                for (int i = 0; i < mGeometryCache.length; i++)
                {
                        mGeometryCache[i] = createGeometry(i);
                }*/

        }
       
        public void dispose()
        {
                super.dispose();
                mRegions = null;
               
                if (mMesh != null)
                {
                        mMesh.dispose();
                        mMesh = null;
                }
               
/*              for (int i = 0; i < mGeometryCache.length; i++)
                {
                        mGeometryCache[i].dispose();
                        mGeometryCache[i] = null;
                }
                mGeometryCache = null;*/

        }
       
        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++)
                {
                        SpriteRegion r = getRegion(i);
                        float[] v =
                        {
                                0.0f, 0.0f, 0.0f,
                                1.0f, 0.0f, 0.0f,
                                1.0f, 1.0f, 0.0f,
                                0.0f, 1.0f, 0.0f
                        };
                        float[] t =
                        {
                                r.left, r.top,
                                r.right, r.top,
                                r.right, r.bottom,
                                r.left, r.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(getGraphics(), PrimitiveType.TRIANGLES);
                mesh.setPositions(vertices);
                mesh.setTexCoords(texCoords, false);
                mesh.setColors(colors);
                mesh.setIndices(indices);
               
                return mesh;
        }
       
        /*
        public SimpleGeometry createGeometry(int regionIndex)
        {
                float[] vertices =
                {
                        0.0f, 0.0f, 0.0f,
                        1.0f, 0.0f, 0.0f,
                        1.0f, 1.0f, 0.0f,
                        0.0f, 1.0f, 0.0f
                };
               
                SpriteRegion r = getRegion(regionIndex);
               
                float[] texCoords =
                {
                        r.left, r.top,
                        r.right, r.top,
                        r.right, r.bottom,
                        r.left, r.bottom
                };
               
                float[] colors =
                {
                        1, 1, 1,
                        1, 1, 1,
                        1, 1, 1,
                        1, 1, 1
                };
               
                short[] indices =
                {
                        0, 1, 2,
                        0, 2, 3
                };
               
                SimpleGeometry mesh = new SimpleGeometry(getGraphics(), PrimitiveType.TRIANGLES);
                mesh.setPositions(vertices);
                mesh.setTexCoords(texCoords, false);
                mesh.setColors(colors);
                mesh.setIndices(indices);      
               
                return mesh;
        }
        */

       
        public final AtlasSpriteInstance createSpriteInstance(int regionIndex)
        {
                return new AtlasSpriteInstance(this, regionIndex);
        }
               
        public void update(float deltaTime)
        {
               
        }
       
        public void render()
        {
        }
       
        public void render(int regionIndex)
        {
                render(regionIndex, x, y, w, h);
        }
       
        public void render(int regionIndex, float _x, float _y)
        {
                render(regionIndex, _x, _y, w, h);
        }
       
        public void render(int regionIndex, float _x, float _y, float _w, float _h)
        {
                if (mRegions == null)
                        return;
               
/*              SpriteRegion r = mRegions[regionIndex];
               
                float[] texCoords = {
                        r.left, r.top,
                        r.right, r.top,
                        r.right, r.bottom,
                        r.left, r.bottom
                };
               
                mMesh.setTexCoords(texCoords);
               
                super.render(_x, _y, _w, _h);*/

               
                SpriteShader shader = getGraphics().getSpriteShader();
                RenderStates rs = getRenderStates();
               
                Matrix4 modelMatrix = Matrix4.multiply(Matrix4.createScale(_w, _h, 1.0f), Matrix4.createTranslation(-pivotX, -pivotY, 0));
               
                modelMatrix = Matrix4.multiply(modelMatrix, Matrix4.createScale((mirrorX ? -1 : 1), (mirrorY ? -1 : 1), 1));

                modelMatrix = Matrix4.multiply(modelMatrix, Matrix4.createRotationZ(angle));

                modelMatrix = Matrix4.multiply(modelMatrix, Matrix4.createTranslation(_x, _y, 0));
               
                rs.pushModelMatrix();
                {
                        rs.model = modelMatrix;
                       
                        // draw sprite
                        shader.activate(getTexture(), alpha, color);
                        {
                                rs.blending.setEnabled(true);
                                rs.culling.setEnabled(false);
                                rs.activate();
                                {
                                        //getMesh(regionIndex).render();
                                        mMesh.render(getMeshStartIndex(regionIndex), NUM_INDICES_PER_REGION);
                                }
                                rs.deactivate();
                        }
                        shader.deactivate();
                }
                rs.popModelMatrix();
        }

        /** Set absolute coordinates for given region. */
        public void setAbsolute(int regionIndex, float x, float y, float w, float h)
        {
                if ((mTexture == null) || (mRegions == null) || (regionIndex >= mRegions.length))
                        return;
               
                if (mRegions[regionIndex] == null)
                {
                        // create region
                        mRegions[regionIndex] = new SpriteRegion(x, y, w, h);
                        return;
                }
               
                mRegions[regionIndex].setAbsolute(mTexture, x, y, w, h);
        }
       
        /** Get number of defined regions. */
        public final int getRegionCount()
        {
                if (mRegions == null)
                        return 0;
               
                return mRegions.length;
        }
       
        /** Get region. */
        public final SpriteRegion getRegion(int i)
        {
                if (mRegions == null)
                        return null;
               
                return mRegions[i];
        }
       
        /** Get a region's width. */
        public final float getRegionWidth(int i)
        {
                if (mRegions == null)
                        return 0.0f;
               
                return (mRegions[i].right - mRegions[i].left) * mTexture.getWidth();
        }
       
        /** Get a region's height. */
        public final float getRegionHeight(int i)
        {
                if (mRegions == null)
                        return 0.0f;
               
                return (mRegions[i].bottom - mRegions[i].top) * mTexture.getHeight();
        }
       
        /** Get cached mesh. */
        /*public final SimpleGeometry getMesh(int regionIndex)
        {
                return mGeometryCache[regionIndex];
        }*/

       
        /** Get the Geometry. */
        public final SimpleGeometry getMesh()
        {
                return mMesh;
        }
       
        /** Get starting index for region mesh rendering. */
        public final int getMeshStartIndex(int regionIndex)
        {
                return (regionIndex * NUM_INDICES_PER_REGION);
        }
       
}