Subversion Repositories AndroidProjects

Rev

Rev 1488 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
797 chris 1
using System;
2
using System.Collections.Generic;
3
using System.Linq;
4
using System.Text;
5
using System.Threading.Tasks;
1488 chris 6
using System.Drawing;
797 chris 7
 
8
using BauzoidNET.math;
9
using BauzoidNET.graphics.renderstates;
10
using BauzoidNET.graphics.texture;
11
using BauzoidNET.graphics.model;
12
 
801 chris 13
using Tao.OpenGl;
14
 
797 chris 15
namespace BauzoidNET.graphics.sprite
16
{
17
    public class Sprite : GraphicsObject
18
    {
1304 chris 19
        public const int NUM_INDICES_PER_REGION = 6;
20
        public const int NUM_ATTRIBUTES_PER_REGION = 4;
21
 
797 chris 22
            protected Texture mTexture = null;
1304 chris 23
 
24
        private SpriteRegion[] mRegions = null;
25
 
797 chris 26
            protected SimpleGeometry mMesh = null;
1304 chris 27
 
28
            protected String mTextureFilename = null;
1488 chris 29
        protected Bitmap mTextureBitmap = null;
1304 chris 30
 
31
        protected String mRegionDefFilename = null;
797 chris 32
 
33
            /** Constructor. Does not load anything yet
34
             */
35
            public Sprite(Graphics graphics, String filename)
36
            : base(graphics)
37
            {
1304 chris 38
                    mTextureFilename = filename;
797 chris 39
            }
40
 
1488 chris 41
        public Sprite(Graphics graphics, Bitmap bm)
42
            : base(graphics)
43
        {
44
            mTextureBitmap = bm;
45
        }
46
 
1304 chris 47
        public Sprite(Graphics graphics, String textureFile, String atlasFile)
48
            : this(graphics, textureFile)
49
        {
50
            mRegionDefFilename = atlasFile;
51
        }
1488 chris 52
 
53
        public Sprite(Graphics graphics, Bitmap bm, String atlasFile)
54
            : this(graphics, bm)
55
        {
56
            mRegionDefFilename = atlasFile;
57
        }
797 chris 58
 
59
            public void init()
60
            {
1488 chris 61
            if ((mTextureFilename == null) && (mTextureBitmap == null))
1304 chris 62
                return;
63
 
64
            // load texture synchronously
1488 chris 65
            if (mTextureFilename != null)
66
                mTexture = new Texture(getGraphics(), mTextureFilename);
67
            else if (mTextureBitmap != null)
68
                mTexture = new Texture(getGraphics(), mTextureBitmap);
1304 chris 69
 
70
            if (mRegionDefFilename != null)
71
            {
72
                List<SpriteUtil.SpriteRegionInfo> atlas = SpriteUtil.readSpriteRegionInfo(mRegionDefFilename);
73
 
74
                SpriteRegion[] regions = new SpriteRegion[atlas.Count];
75
                for (int i = 0; i < atlas.Count; i++)
76
                {
77
                    regions[i] = new SpriteRegion(this, i, atlas[i].x, atlas[i].y, atlas[i].w, atlas[i].h, true);
78
                }
79
 
80
                setRegions(regions);
81
            }
82
            else
83
            {
84
                // create default geometry for entire sprite (make 1 region)
85
                SpriteRegion[] regions = new SpriteRegion[1];
86
                regions[0] = new SpriteRegion(this, 0, 0, 0, getTextureWidth(), getTextureHeight(), true);
87
 
88
                setRegions(regions);
89
            }
797 chris 90
            }
91
 
1304 chris 92
        public void dispose()
93
        {
94
            if (mRegions != null)
95
                mRegions = null;
805 chris 96
 
1304 chris 97
            if (mTexture != null)
98
            {
99
                mTexture.dispose();
100
                mTexture = null;
101
            }
102
        }
805 chris 103
 
1304 chris 104
        public void setRegions(SpriteRegion[] regions)
105
        {
106
            if (mMesh != null)
107
            {
108
                mMesh.dispose();
109
                mMesh = null;
110
            }
805 chris 111
 
1304 chris 112
            mRegions = regions;
113
            mMesh = createGeometry();
114
        }
805 chris 115
 
1304 chris 116
        public SimpleGeometry createGeometry()
797 chris 117
            {
1304 chris 118
                    float[] vertices = new float[NUM_ATTRIBUTES_PER_REGION * SimpleGeometry.POSITION_COORD_PER_ELEMENT * mRegions.Length];
119
                    float[] texCoords = new float[NUM_ATTRIBUTES_PER_REGION * SimpleGeometry.TEXCOORD_COORD_PER_ELEMENT * mRegions.Length];
120
                    float[] colors = new float[NUM_ATTRIBUTES_PER_REGION * SimpleGeometry.COLOR_COORD_PER_ELEMENT * mRegions.Length];
797 chris 121
 
1304 chris 122
                    // two triangles per region
123
                    short[] indices = new short[NUM_INDICES_PER_REGION * mRegions.Length];
797 chris 124
 
1304 chris 125
                    for (int i = 0; i < mRegions.Length; i++)
797 chris 126
                    {
1304 chris 127
                            SpriteRegion r = getRegion(i);
797 chris 128
 
1304 chris 129
                            float[] v =
797 chris 130
                            {
1304 chris 131
                                    -1.0f, -1.0f, 0.0f,
132
                                     1.0f, -1.0f, 0.0f,
133
                                     1.0f,  1.0f, 0.0f,
134
                                    -1.0f,  1.0f, 0.0f
135
                            };
136
 
137
                            float[] t =
138
                            {
139
                                    r.left, r.top,
140
                                    r.right, r.top,
141
                                    r.right, r.bottom,
142
                                    r.left, r.bottom
143
                            };
144
 
145
                            float[] c =
146
                            {
147
                                    1, 1, 1, 1,
148
                                    1, 1, 1, 1,
149
                                    1, 1, 1, 1,
150
                                    1, 1, 1, 1
151
                            };
152
 
153
                            Array.Copy(v, 0, vertices, NUM_ATTRIBUTES_PER_REGION * SimpleGeometry.POSITION_COORD_PER_ELEMENT * i, v.Length);
154
                            Array.Copy(t, 0, texCoords, NUM_ATTRIBUTES_PER_REGION * SimpleGeometry.TEXCOORD_COORD_PER_ELEMENT * i, t.Length);
155
                            Array.Copy(c, 0, colors, NUM_ATTRIBUTES_PER_REGION * SimpleGeometry.COLOR_COORD_PER_ELEMENT * i, c.Length);
803 chris 156
 
1304 chris 157
                            int n = i*NUM_INDICES_PER_REGION;                  
158
                            short baseIndex = (short)(i * NUM_ATTRIBUTES_PER_REGION);
159
                indices[n++] = baseIndex; indices[n++] = (short)(baseIndex + 1); indices[n++] = (short)(baseIndex + 2);
160
                indices[n++] = baseIndex; indices[n++] = (short)(baseIndex + 2); indices[n++] = (short)(baseIndex + 3);
161
                    }
801 chris 162
 
1304 chris 163
                    SimpleGeometry mesh = new SimpleGeometry(getGraphics(), Geometry.PrimitiveType.TRIANGLES);
164
                    mesh.setPositions(vertices);
165
                    mesh.setTexCoords(texCoords);
166
                    mesh.setColors(colors);
167
                    mesh.setIndices(indices);
168
 
169
                    return mesh;
170
            }
801 chris 171
 
1304 chris 172
        /** Create a single SpriteInstance for a single region. */
173
            public SpriteInstance createSpriteInstance(int regionIndex)
174
            {
175
                    return new SpriteInstance(getRegion(regionIndex));
176
            }
801 chris 177
 
1304 chris 178
        /** Create a multiple SpriteInstances, each for a single region. */
179
        public void createSpriteInstances(SpriteInstance[] instances)
180
        {
181
            if (instances.Length < mRegions.Length)
182
                return;
801 chris 183
 
1304 chris 184
            for (int i = 0; i < instances.Length; i++)
185
            {
186
                instances[i] = createSpriteInstance(i);
187
            }
188
        }
801 chris 189
 
1304 chris 190
        /** Create a multiple SpriteInstances, each for a single region. */
191
        public SpriteInstance[] createSpriteInstances()
192
        {
193
                SpriteInstance[] frames = new SpriteInstance[mRegions.Length];
194
                createSpriteInstances(frames);
195
                    return frames;
196
            }
801 chris 197
 
1304 chris 198
        /** Create a single SpriteInstance for all regions. */
199
        public SpriteInstance createSpriteInstanceForAll()
200
        {
201
            SpriteInstance instance = new SpriteInstance(mRegions);
202
            return instance;
203
        }
801 chris 204
 
1304 chris 205
        /** Peforms the actual render without any model matrix handling. */
1499 chris 206
        public void performRender(int region, float alpha, Vector4 color, Vector4 fogColor)
1304 chris 207
        {
208
            RenderStates rs = getRenderStates();
209
            SpriteShader shader = getGraphics().getSpriteShader();
797 chris 210
 
1304 chris 211
            // draw sprite
1499 chris 212
            shader.activate(getTexture(), alpha, color, fogColor);
1304 chris 213
            {
214
                rs.blending.setEnabled(true);
215
                rs.culling.setEnabled(false);
216
                rs.activate();
217
                rs.blending.activate(true);
218
                {
219
                    mMesh.render(getMeshStartIndex(region), NUM_INDICES_PER_REGION);
220
                }
221
                rs.deactivate();
222
            }
223
            shader.deactivate();
224
        }
225
 
797 chris 226
            /** Get the sprite texture's total width. */
227
            public int getTextureWidth()
228
            {
229
                    if (mTexture == null)
230
                            return 0;
231
                    return mTexture.getWidth();
232
            }
233
 
234
            /** Get the sprite texture's total height. */
235
            public int getTextureHeight()
236
            {
237
                    if (mTexture == null)
238
                            return 0;
239
                    return mTexture.getHeight();
240
            }
241
 
242
            /** Get a reference to the texture. */
243
            public Texture getTexture()
244
            {
245
                    return mTexture;
246
            }
247
 
248
            /** Set a new texture, with the old one (if any) getting destroyed. */
249
            public void setTexture(Texture texture)
250
            {
251
                    if (mTexture != null)
252
                            mTexture.dispose();
253
 
254
                    mTexture = texture;
255
            }
256
 
1304 chris 257
            /** Get number of defined regions. */
258
            public int getRegionCount()
797 chris 259
            {
1304 chris 260
                    if (mRegions == null)
261
                            return 0;
262
 
263
                    return mRegions.Length;
797 chris 264
            }
265
 
1304 chris 266
            /** Get region. */
267
            public SpriteRegion getRegion(int i)
797 chris 268
            {
1304 chris 269
                    if (mRegions == null)
270
                            return null;
271
 
272
                    return mRegions[i];
797 chris 273
            }
274
 
1304 chris 275
            /** Get regions array.*/
276
            public SpriteRegion[] getRegions()
797 chris 277
            {
1304 chris 278
                    return mRegions;
797 chris 279
            }
280
 
1304 chris 281
            /** Get starting index for region mesh rendering. */
282
            private int getMeshStartIndex(int regionIndex)
797 chris 283
            {
1304 chris 284
                    return (regionIndex * NUM_INDICES_PER_REGION);
797 chris 285
            }
286
    }
287
}