Subversion Repositories AndroidProjects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1051 chris 1
package com.gebauz.bauzoid.graphics.model;
2
 
3
import java.nio.ByteBuffer;
4
import java.nio.FloatBuffer;
5
import java.nio.IntBuffer;
6
import java.util.ArrayList;
7
import java.util.List;
8
 
9
import com.badlogic.gdx.Gdx;
10
import com.badlogic.gdx.graphics.GL20;
11
import com.badlogic.gdx.utils.BufferUtils;
12
import com.gebauz.bauzoid.app.Consts;
13
import com.gebauz.bauzoid.graphics.Graphics;
14
import com.gebauz.bauzoid.graphics.GraphicsObject;
15
 
16
/** Vertex Stream that supports individual or interleaved vertex attributes. */
17
public class VertexStream extends GraphicsObject
18
{
19
        /** Type of stream - single attribute or multi-attribute interleaved. */
20
        public enum StreamType
21
        {
22
                INDIVIDUAL,
23
                INTERLEAVED
24
        };
25
 
26
        private static List<VertexStream> mManagedStreams = new ArrayList<VertexStream>();
27
 
28
        private StreamType mStreamType;
29
        private String mName;
30
        private FloatBuffer mData = null;
31
        private ByteBuffer mByteBuffer = null;
32
 
33
        private boolean mIsDynamic = false;
34
 
35
        private int mVertexCount = 0;
36
        private int mCoordsPerElement = 0;
37
        private int mBytesPerElement = 0;
38
 
39
        private int mBufferID = 0;
40
        //private static int[] BUFFERID = new int[1];
41
        private static final IntBuffer BUFFERID = BufferUtils.newIntBuffer(1);
42
 
43
        private VertexAttribute[] mAttribs;
44
 
45
        /** Constructor. */
46
        public VertexStream(Graphics graphics, StreamType streamType, String name, VertexAttribute[] attribs, boolean isDynamic)
47
        {
48
                super(graphics);
49
                mStreamType = streamType;
50
                mName = name;
51
                mAttribs = attribs;
52
                mIsDynamic = isDynamic;
53
 
54
                mManagedStreams.add(this);
55
        }
56
 
57
        /** Destroy all internal data. */
58
        public void dispose()
59
        {
60
                mManagedStreams.remove(this);
61
 
62
                unload();
63
                mAttribs = null;
64
                mVertexCount = 0;
65
                mCoordsPerElement = 0;
66
                mBytesPerElement = 0;
67
 
68
                if (mByteBuffer != null)
69
                {
70
                        BufferUtils.disposeUnsafeByteBuffer(mByteBuffer);
71
                        mByteBuffer = null;
72
                }
73
                mData = null;
74
        }
75
 
76
        /** Reload all managed vertex streams. */
77
        public static void reloadManagedStreams()
78
        {
79
                for (int i = 0; i < mManagedStreams.size(); i++)
80
                {
81
                        VertexStream stream = mManagedStreams.get(i);
82
                        stream.upload();
83
                        Gdx.app.log(Consts.LOG_TAG, "VertexStream '" + stream.getName() + "' reloaded!");
84
                }
85
        }      
86
 
87
        /** Set the buffer data. */
88
        public void setData(byte[] data, int coordsPerElement, int bytesPerElement)
89
        {
90
                if (data == null)
91
                {
92
                        dispose();
93
                        return;
94
                }
95
 
96
                int newVertexCount = data.length / bytesPerElement;
97
                if ((mVertexCount != newVertexCount) || (mByteBuffer == null))
98
                {
99
                        // reallocate
100
                        allocateBuffer(data.length);
101
                }              
102
 
103
                mVertexCount = newVertexCount;
104
                mCoordsPerElement = coordsPerElement;
105
                mBytesPerElement = bytesPerElement;
106
 
107
                /*ByteBuffer byteBuffer = ByteBuffer.allocateDirect(data.length);
108
                byteBuffer.order(ByteOrder.nativeOrder());
109
                byteBuffer.put(data);
110
                byteBuffer.position(0);
111
                mData = byteBuffer.asFloatBuffer();*/
112
 
113
                BufferUtils.copy(data, 0, mData, data.length);
114
                mData.position(0);
115
                mData.limit(data.length);
116
        }
117
 
118
        /** Set the buffer data. */
119
        public void setData(float[] data, int coordsPerElement, int bytesPerElement)
120
        {
121
                if (data == null)
122
                {
123
                        dispose();
124
                        return;
125
                }
126
 
127
                int newVertexCount = data.length / coordsPerElement;
128
                if ((mVertexCount != newVertexCount) || (mByteBuffer == null))
129
                {
130
                        // reallocate
131
                        allocateBuffer(data.length * Consts.SIZEOF_FLOAT);
132
                }              
133
 
134
                mVertexCount = data.length / coordsPerElement;
135
                mCoordsPerElement = coordsPerElement;
136
                mBytesPerElement = bytesPerElement;
137
 
138
                BufferUtils.copy(data, mByteBuffer, data.length, 0);
139
                mData.position(0);
140
                mData.limit(data.length);
141
        }
142
 
143
 
144
        public void allocateBuffer(int newSize)
145
        {
146
                if (mByteBuffer != null)
147
                        BufferUtils.disposeUnsafeByteBuffer(mByteBuffer);
148
 
149
                mByteBuffer = BufferUtils.newUnsafeByteBuffer(newSize);
150
                mData = mByteBuffer.asFloatBuffer();
151
                mData.flip();
152
                mByteBuffer.flip();
153
        }
154
 
155
        /** Create GL handle and upload vertex data to hardware. */
156
        public final void upload()
157
        {
158
                if (mData == null)
159
                        return;
160
 
161
                Gdx.gl20.glGenBuffers(1, BUFFERID);
162
                mBufferID = BUFFERID.get(0);
163
 
164
                Gdx.gl20.glBindBuffer(GL20.GL_ARRAY_BUFFER, mBufferID);
165
 
166
                int usage = GL20.GL_STATIC_DRAW;
167
                if (isDynamic())
168
                        usage = GL20.GL_DYNAMIC_DRAW;
169
 
170
                //Gdx.gl20.glBufferData(GL20.GL_ARRAY_BUFFER, mData.capacity() * Consts.SIZEOF_FLOAT, mData, usage);
171
                Gdx.gl20.glBufferData(GL20.GL_ARRAY_BUFFER, mByteBuffer.limit(), mByteBuffer, usage);
172
                Gdx.gl20.glBindBuffer(GL20.GL_ARRAY_BUFFER, 0);
173
        }
174
 
175
        /** Reupload data to hardware. */
176
        public final void reupload()
177
        {
178
                if (mBufferID == 0)
179
                {
180
                        // perform initial upload
181
                        upload();
182
                        return;
183
                }
184
 
185
                if (mData == null)
186
                        return;
187
 
188
                Gdx.gl20.glBindBuffer(GL20.GL_ARRAY_BUFFER, mBufferID);
189
                Gdx.gl20.glBufferSubData(GL20.GL_ARRAY_BUFFER, 0, mData.capacity() * Consts.SIZEOF_FLOAT, mData);
190
                Gdx.gl20.glBindBuffer(GL20.GL_ARRAY_BUFFER, 0);
191
        }
192
 
193
        /** Unload vertex data from hardware. */
194
        public final void unload()
195
        {
196
                deactivate();
197
                BUFFERID.put(0, mBufferID);
198
                Gdx.gl20.glDeleteBuffers(1, BUFFERID);
199
                mBufferID = 0;
200
        }
201
 
202
        //static int mCurrentBufferId = 0;
203
 
204
        /** Activate stream for rendering. */
205
        public final void activate()
206
        {
207
                // TODO: buffer state tracking
208
                //if (mCurrentBufferId != mBufferID)
209
                {
210
                        Gdx.gl20.glBindBuffer(GL20.GL_ARRAY_BUFFER, mBufferID);
211
                        //mCurrentBufferId = mBufferID;
212
                }
213
 
214
                for (int i = 0; i < mAttribs.length; i++)
215
                {
216
                        VertexAttribute attrib = mAttribs[i];
217
 
218
                        // TODO: attrib to handle adapter
219
                        Gdx.gl20.glVertexAttribPointer(attrib.getAttribType(), attrib.getCoordsPerElement(), GL20.GL_FLOAT, false, getBytesPerElement(), attrib.getByteOffset());
220
                        Gdx.gl20.glEnableVertexAttribArray(attrib.getAttribType());
221
                }              
222
 
223
        }
224
 
225
        public final void deactivate()
226
        {
227
                for (int i = 0; i < mAttribs.length; i++)
228
                {
229
                        VertexAttribute attrib = mAttribs[i];
230
 
231
                        // TODO: attrib to handle adapter
232
                        Gdx.gl20.glDisableVertexAttribArray(attrib.getAttribType());
233
                }              
234
 
235
                // TODO: buffer state tracking
236
                //Gdx.gl20.glBindBuffer(GL20.GL_ARRAY_BUFFER, 0);
237
        }
238
 
239
        /** Get Coords per element. */
240
        public final int getCoordsPerElement()
241
        {
242
                return mCoordsPerElement;
243
        }
244
 
245
        /** Get number of bytes per complete element (equals vertex stride). */
246
        public final int getBytesPerElement()
247
        {
248
                return mBytesPerElement;
249
        }
250
 
251
        /** Get number of elements. */
252
        public final int getVertexCount()
253
        {
254
                return mVertexCount;
255
        }
256
 
257
        /** Get name of vertex stream. */
258
        public final String getName()
259
        {
260
                return mName;
261
        }
262
 
263
        /** Get stream type. */
264
        public final StreamType getStreamType()
265
        {
266
                return mStreamType;
267
        }
268
 
269
        /** Check if the stream is dynamic or static. */
270
        public final boolean isDynamic()
271
        {
272
                return mIsDynamic;
273
        }
274
}
275