Subversion Repositories AndroidProjects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1051 chris 1
package com.gebauz.bauzoid.graphics.sprite;
2
 
3
import com.badlogic.gdx.Gdx;
4
import com.badlogic.gdx.graphics.Texture;
5
import com.gebauz.bauzoid.graphics.Graphics;
6
import com.gebauz.bauzoid.graphics.GraphicsObject;
7
import com.gebauz.bauzoid.graphics.model.SimpleGeometry;
8
import com.gebauz.bauzoid.graphics.model.Geometry.PrimitiveType;
9
import com.gebauz.bauzoid.graphics.renderstates.RenderStates;
10
import com.gebauz.bauzoid.graphics.sprite.SpriteRegion;
11
import com.gebauz.bauzoid.graphics.sprite.SpriteShader;
12
import com.gebauz.bauzoid.math.Vector4;
13
 
14
/** Sprite class that loads a texture and allows definition of regions (for atlasing, or multi-framing). */
15
public class Sprite extends GraphicsObject
16
{
17
 
18
        // Constants========================================================================================
19
 
20
        public static int NUM_INDICES_PER_REGION = 6;
21
        public static int NUM_ATTRIBUTES_PER_REGION = 4;
22
 
23
        // Embedded Types===================================================================================
24
 
25
        // Fields===========================================================================================
26
 
27
        /** The texture this sprite is based on. */
28
        protected Texture mTexture = null;
29
 
30
        /** Stores the separate regions of the sprite that were defined. */
31
        private SpriteRegion[] mRegions = null;
32
 
33
        /** Stores all Geometry of all SpriteRegions. */
34
        private SimpleGeometry mMesh = null;
35
 
36
        /** Store the texture filename so it can be loaded asynchronously later. */
37
        protected String mTextureFilename = null;
38
 
39
        /** Store the atlas region definition filename so it can be loaded asynchronously later. */
40
        protected String mRegionDefFilename = null;
41
 
42
        /** Flag to check if asynchronous or synchronous loading was requested. */
43
        protected boolean mIsAsync = false;
44
 
45
        // Methods==========================================================================================
46
 
47
        public Sprite(Graphics graphics, String textureFile)
48
        {
49
                super(graphics);
50
                mTextureFilename = textureFile;
51
        }
52
 
53
        public Sprite(Graphics graphics, String textureFile, String atlasFile)
54
        {
55
                this(graphics, textureFile);
56
                mRegionDefFilename = atlasFile;
57
        }
58
 
59
        /** Called during asynchronous loading to initiate AssetManager's loading mechanism. */
60
        public void initAsync()
61
        {
62
                if (mTextureFilename == null)
63
                        return; // maybe ASSERT?
64
 
65
                mIsAsync = true;
66
                getAssetManager().load(mTextureFilename, Texture.class);
67
 
68
                if (mRegionDefFilename != null)
69
                {
70
                        getAssetManager().load(mRegionDefFilename, SpriteRegionDefinition.class);
71
                }
72
        }
73
 
74
        /** Called synchronously (or after initAsync() for asynchronous loading). */
75
        public void init()
76
        {
77
                if (mTextureFilename == null)
78
                        return;
79
 
80
                if (!mIsAsync)
81
                {
82
                        // load texture synchronously
83
                        mTexture = new Texture(Gdx.files.internal(mTextureFilename));
84
                }
85
                else
86
                {
87
                        // grab texture that should be loaded asynchronously already
88
                        mTexture = getAssetManager().get(mTextureFilename, Texture.class);
89
                }
90
 
91
                if (mRegionDefFilename != null)
92
                {
93
                        SpriteRegionDefinition atlas = null;
94
 
95
                        if (!mIsAsync)
96
                        {
97
                                // load synchronously
98
                                atlas = SpriteUtil.readSpriteRegionInfo(Gdx.files.internal(mRegionDefFilename));
99
                        }
100
                        else
101
                        {
102
                                atlas = getAssetManager().get(mRegionDefFilename, SpriteRegionDefinition.class);
103
                        }
104
                        SpriteRegion regions[] = new SpriteRegion[atlas.frames.size()];
105
                        for (int i = 0; i < atlas.frames.size(); i++)
106
                        {
107
                                SpriteRegionDefinition.FrameInfo info = atlas.frames.get(i);
108
                                regions[i] = new SpriteRegion(this, i, info.x, info.y, info.w, info.h, true);
109
                        }
110
 
111
                        setRegions(regions);
112
                }
113
                else
114
                {
115
                        // create default geometry for entire sprite (make 1 region)
116
                        SpriteRegion regions[] = new SpriteRegion[1];
117
                        regions[0] = new SpriteRegion(this, 0, 0, 0, getTextureWidth(), getTextureHeight(), true);
118
 
119
                        setRegions(regions);
120
                }
121
        }
122
 
123
        /** Destroy sprite. */
124
        public void dispose()
125
        {
126
                if (mRegions != null)
127
                        mRegions = null;
128
 
129
                if (mTexture != null)
130
                {
131
                        if (mIsAsync)
132
                        {
133
                                getAssetManager().unload(mTextureFilename);
134
                        }
135
                        else
136
                        {
137
                                mTexture.dispose();
138
                        }
139
                        mTexture = null;
140
                }
141
 
142
                if (mRegionDefFilename != null)
143
                {
144
                        if (mIsAsync)
145
                        {
146
                                getAssetManager().unload(mRegionDefFilename);
147
                        }
148
                }
149
        }
150
 
151
        public void setRegions(SpriteRegion[] regions)
152
        {
153
                if (mMesh != null)
154
                {
155
                        mMesh.dispose();
156
                        mMesh = null;
157
                }
158
 
159
                mRegions = regions;
160
                mMesh = createGeometry();      
161
        }
162
 
163
        public SimpleGeometry createGeometry()
164
        {
165
                float[] vertices = new float[NUM_ATTRIBUTES_PER_REGION * SimpleGeometry.POSITION_COORD_PER_ELEMENT * mRegions.length];
166
                float[] texCoords = new float[NUM_ATTRIBUTES_PER_REGION * SimpleGeometry.TEXCOORD_COORD_PER_ELEMENT * mRegions.length];
167
                float[] colors = new float[NUM_ATTRIBUTES_PER_REGION * SimpleGeometry.COLOR_COORD_PER_ELEMENT * mRegions.length];
168
 
169
                // two triangles per region
170
                short[] indices = new short[NUM_INDICES_PER_REGION * mRegions.length];
171
 
172
                for (int i = 0; i < mRegions.length; i++)
173
                {
174
                        SpriteRegion r = getRegion(i);
175
 
176
                        float[] v =
177
                        {
178
                                -1.0f, -1.0f, 0.0f,
179
                                 1.0f, -1.0f, 0.0f,
180
                                 1.0f,  1.0f, 0.0f,
181
                                -1.0f,  1.0f, 0.0f
182
                        };
183
 
184
                        float[] t =
185
                        {
186
                                r.left, r.top,
187
                                r.right, r.top,
188
                                r.right, r.bottom,
189
                                r.left, r.bottom
190
                        };
191
 
192
                        float[] c =
193
                        {
194
                                1, 1, 1, 1,
195
                                1, 1, 1, 1,
196
                                1, 1, 1, 1,
197
                                1, 1, 1, 1
198
                        };
199
 
200
                        System.arraycopy(v, 0, vertices, NUM_ATTRIBUTES_PER_REGION * SimpleGeometry.POSITION_COORD_PER_ELEMENT * i, v.length);
201
                        System.arraycopy(t, 0, texCoords, NUM_ATTRIBUTES_PER_REGION * SimpleGeometry.TEXCOORD_COORD_PER_ELEMENT * i, t.length);
202
                        System.arraycopy(c, 0, colors, NUM_ATTRIBUTES_PER_REGION * SimpleGeometry.COLOR_COORD_PER_ELEMENT * i, c.length);
203
 
204
                        int n = i*NUM_INDICES_PER_REGION;                      
205
                        short base = (short)(i * NUM_ATTRIBUTES_PER_REGION);
206
                        indices[n++] = base; indices[n++] = (short)(base+1); indices[n++] = (short)(base+2);
207
                        indices[n++] = base; indices[n++] = (short)(base+2); indices[n++] = (short)(base+3);
208
                }
209
 
210
 
211
                SimpleGeometry mesh = new SimpleGeometry(getGraphics(), PrimitiveType.TRIANGLES);
212
                mesh.setPositions(vertices);
213
                mesh.setTexCoords(texCoords);
214
                mesh.setColors(colors);
215
                mesh.setIndices(indices);
216
 
217
                return mesh;
218
        }
219
 
220
        /** Create a single SpriteInstance for a single region. */
221
        public final SpriteInstance createSpriteInstance(int regionIndex)
222
        {
223
                return new SpriteInstance(getRegion(regionIndex));
224
        }
225
 
226
        /** Create a multiple SpriteInstances, each for a single region. */
227
        public void createSpriteInstances(SpriteInstance[] instances)
228
        {
229
                if (instances.length < mRegions.length)
230
                        return;
231
 
232
                for (int i = 0; i < instances.length; i++)
233
                {
234
                        instances[i] = createSpriteInstance(i);
235
                }
236
        }
237
 
238
        /** Create a multiple SpriteInstances, each for a single region. */
239
        public SpriteInstance[] createSpriteInstances()
240
        {
241
                SpriteInstance frames[] = new SpriteInstance[mRegions.length];
242
                createSpriteInstances(frames);
243
                return frames;
244
        }
245
 
246
        /** Create a single SpriteInstance for all regions. */
247
        public SpriteInstance createSpriteInstanceForAll()
248
        {
249
                SpriteInstance instance = new SpriteInstance(mRegions);
250
                return instance;
251
        }
252
 
253
        /** Peforms the actual render without any model matrix handling. */
254
        public void performRender(int region, float alpha, Vector4 color)
255
        {
256
                RenderStates rs = getRenderStates();
257
                SpriteShader shader = getGraphics().getSpriteShader();
258
 
259
                // draw sprite
260
                shader.activate(getTexture(), alpha, color);
261
                {
262
                        rs.blending.setEnabled(true);                  
263
                        rs.culling.setEnabled(false);
264
                        rs.activate();
265
                        rs.blending.activate(true);
266
                        {
267
                                mMesh.render(getMeshStartIndex(region), NUM_INDICES_PER_REGION);
268
                        }
269
                        rs.deactivate();
270
                }
271
                shader.deactivate();
272
        }
273
 
274
        // Getters/Setters==================================================================================
275
 
276
        /** Get a reference to the texture. */
277
        public final Texture getTexture()
278
        {
279
                return mTexture;
280
        }
281
 
282
        /** Get the sprite texture's total width. */
283
        public final int getTextureWidth()
284
        {
285
                if (mTexture == null)
286
                        return 0;
287
                return mTexture.getWidth();
288
        }
289
 
290
        /** Get the sprite texture's total height. */
291
        public final int getTextureHeight()
292
        {
293
                if (mTexture == null)
294
                        return 0;
295
                return mTexture.getHeight();
296
        }
297
 
298
        /** Get number of defined regions. */
299
        public final int getRegionCount()
300
        {
301
                if (mRegions == null)
302
                        return 0;
303
 
304
                return mRegions.length;
305
        }
306
 
307
        /** Get region. */
308
        public final SpriteRegion getRegion(int i)
309
        {
310
                if (mRegions == null)
311
                        return null;
312
 
313
                return mRegions[i];
314
        }
315
 
316
        /** Get regions array.*/
317
        public final SpriteRegion[] getRegions()
318
        {
319
                return mRegions;
320
        }
321
 
322
        /** Get starting index for region mesh rendering. */
323
        private final int getMeshStartIndex(int regionIndex)
324
        {
325
                return (regionIndex * NUM_INDICES_PER_REGION);
326
        }
327
 
328
 
329
 
330
}
331
 
332
 
333