1 package org.newdawn.slick.opengl.renderer;
2
3 import java.nio.DoubleBuffer;
4 import java.nio.FloatBuffer;
5
6 import org.lwjgl.BufferUtils;
7 import org.lwjgl.opengl.GL11;
8
9 import javax.annotation.Nonnull;
10
11
12
13
14
15
16
17 public class VAOGLRenderer extends ImmediateModeOGLRenderer {
18
19 private static final int TOLERANCE = 20;
20
21 private static final int NONE = -1;
22
23 private static final int MAX_VERTS = 5000;
24
25
26 private int currentType = NONE;
27
28 @Nonnull
29 private final float[] color = new float[] {1f,1f,1f,1f};
30
31 @Nonnull
32 private final float[] tex = new float[] {0f,0f};
33
34 private int vertIndex;
35
36
37 @Nonnull
38 private final float[] verts = new float[MAX_VERTS*3];
39
40 @Nonnull
41 private final float[] cols = new float[MAX_VERTS*4];
42
43 @Nonnull
44 private final float[] texs = new float[MAX_VERTS*3];
45
46
47 private final FloatBuffer vertices = BufferUtils.createFloatBuffer(MAX_VERTS * 3);
48
49 private final FloatBuffer colors = BufferUtils.createFloatBuffer(MAX_VERTS * 4);
50
51 private final FloatBuffer textures = BufferUtils.createFloatBuffer(MAX_VERTS * 2);
52
53
54 private int listMode = 0;
55
56
57
58
59 public void initDisplay(int width, int height) {
60 super.initDisplay(width, height);
61
62 startBuffer();
63 GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
64 GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
65 GL11.glEnableClientState(GL11.GL_COLOR_ARRAY);
66 }
67
68
69
70
71 private void startBuffer() {
72 vertIndex = 0;
73 }
74
75
76
77
78 private void flushBuffer() {
79 if (vertIndex == 0) {
80 return;
81 }
82 if (currentType == NONE) {
83 return;
84 }
85
86 if (vertIndex < TOLERANCE) {
87 GL11.glBegin(currentType);
88 for (int i=0;i<vertIndex;i++) {
89 GL11.glColor4f(cols[(i * 4)], cols[(i*4)+1], cols[(i*4)+2], cols[(i*4)+3]);
90 GL11.glTexCoord2f(texs[(i * 2)], texs[(i*2)+1]);
91 GL11.glVertex3f(verts[(i * 3)], verts[(i*3)+1], verts[(i*3)+2]);
92 }
93 GL11.glEnd();
94 currentType = NONE;
95 return;
96 }
97 vertices.clear();
98 colors.clear();
99 textures.clear();
100
101 vertices.put(verts,0,vertIndex*3);
102 colors.put(cols,0,vertIndex*4);
103 textures.put(texs,0,vertIndex*2);
104
105 vertices.flip();
106 colors.flip();
107 textures.flip();
108
109 GL11.glVertexPointer(3,0,vertices);
110 GL11.glColorPointer(4,0,colors);
111 GL11.glTexCoordPointer(2,0,textures);
112
113 GL11.glDrawArrays(currentType, 0, vertIndex);
114 currentType = NONE;
115 }
116
117
118
119
120 private void applyBuffer() {
121 if (listMode > 0) {
122 return;
123 }
124
125 if (vertIndex != 0) {
126 flushBuffer();
127 startBuffer();
128 }
129
130 super.glColor4f(color[0], color[1], color[2], color[3]);
131 }
132
133
134
135
136 public void flush() {
137 super.flush();
138
139 applyBuffer();
140 }
141
142
143
144
145 public void glBegin(int geomType) {
146 if (listMode > 0) {
147 super.glBegin(geomType);
148 return;
149 }
150
151 if (currentType != geomType) {
152 applyBuffer();
153 currentType = geomType;
154 }
155 }
156
157
158
159
160 public void glColor4f(float r, float g, float b, float a) {
161 a *= alphaScale;
162
163 color[0] = r;
164 color[1] = g;
165 color[2] = b;
166 color[3] = a;
167
168 if (listMode > 0) {
169 super.glColor4f(r,g,b,a);
170 }
171 }
172
173
174
175
176 public void glEnd() {
177 if (listMode > 0) {
178 super.glEnd();
179 }
180 }
181
182
183
184
185 public void glTexCoord2f(float u, float v) {
186 if (listMode > 0) {
187 super.glTexCoord2f(u,v);
188 return;
189 }
190
191 tex[0] = u;
192 tex[1] = v;
193 }
194
195
196
197
198 public void glVertex2f(float x, float y) {
199 if (listMode > 0) {
200 super.glVertex2f(x,y);
201 return;
202 }
203
204 glVertex3f(x,y,0);
205 }
206
207
208
209
210 public void glVertex3f(float x, float y, float z) {
211 if (listMode > 0) {
212 super.glVertex3f(x,y,z);
213 return;
214 }
215
216 verts[(vertIndex * 3)] = x;
217 verts[(vertIndex*3)+1] = y;
218 verts[(vertIndex*3)+2] = z;
219 cols[(vertIndex * 4)] = color[0];
220 cols[(vertIndex*4)+1] = color[1];
221 cols[(vertIndex*4)+2] = color[2];
222 cols[(vertIndex*4)+3] = color[3];
223 texs[(vertIndex * 2)] = tex[0];
224 texs[(vertIndex*2)+1] = tex[1];
225 vertIndex++;
226
227 if (vertIndex > MAX_VERTS - 50) {
228 if (isSplittable(vertIndex, currentType)) {
229 int type = currentType;
230 applyBuffer();
231 currentType = type;
232 }
233 }
234 }
235
236
237
238
239
240
241
242
243 private boolean isSplittable(int count, int type) {
244 switch (type) {
245 case GL11.GL_QUADS:
246 return count % 4 == 0;
247 case GL11.GL_TRIANGLES:
248 return count % 3 == 0;
249 case GL11.GL_LINE:
250 return count % 2 == 0;
251 }
252
253 return false;
254 }
255
256
257
258
259 public void glBindTexture(int target, int id) {
260 applyBuffer();
261 super.glBindTexture(target, id);
262 }
263
264
265
266
267 public void glBlendFunc(int src, int dest) {
268 applyBuffer();
269 super.glBlendFunc(src, dest);
270 }
271
272
273
274
275 public void glCallList(int id) {
276 applyBuffer();
277 super.glCallList(id);
278 }
279
280
281
282
283 public void glClear(int value) {
284 applyBuffer();
285 super.glClear(value);
286 }
287
288
289
290
291 public void glClipPlane(int plane, DoubleBuffer buffer) {
292 applyBuffer();
293 super.glClipPlane(plane, buffer);
294 }
295
296
297
298
299 public void glColorMask(boolean red, boolean green, boolean blue, boolean alpha) {
300 applyBuffer();
301 super.glColorMask(red, green, blue, alpha);
302 }
303
304
305
306
307 public void glDisable(int item) {
308 applyBuffer();
309 super.glDisable(item);
310 }
311
312
313
314
315 public void glEnable(int item) {
316 applyBuffer();
317 super.glEnable(item);
318 }
319
320
321
322
323 public void glLineWidth(float width) {
324 applyBuffer();
325 super.glLineWidth(width);
326 }
327
328
329
330
331 public void glPointSize(float size) {
332 applyBuffer();
333 super.glPointSize(size);
334 }
335
336
337
338
339 public void glPopMatrix() {
340 applyBuffer();
341 super.glPopMatrix();
342 }
343
344
345
346
347 public void glPushMatrix() {
348 applyBuffer();
349 super.glPushMatrix();
350 }
351
352
353
354
355 public void glRotatef(float angle, float x, float y, float z) {
356 applyBuffer();
357 super.glRotatef(angle, x, y, z);
358 }
359
360
361
362
363 public void glScalef(float x, float y, float z) {
364 applyBuffer();
365 super.glScalef(x, y, z);
366 }
367
368
369
370
371 public void glScissor(int x, int y, int width, int height) {
372 applyBuffer();
373 super.glScissor(x, y, width, height);
374 }
375
376
377
378
379 public void glTexEnvi(int target, int mode, int value) {
380 applyBuffer();
381 super.glTexEnvi(target, mode, value);
382 }
383
384
385
386
387 public void glTranslatef(float x, float y, float z) {
388 applyBuffer();
389 super.glTranslatef(x, y, z);
390 }
391
392
393
394
395 public void glEndList() {
396 listMode--;
397 super.glEndList();
398 }
399
400
401
402
403 public void glNewList(int id, int option) {
404 listMode++;
405 super.glNewList(id, option);
406 }
407
408
409
410
411 @Nonnull
412 public float[] getCurrentColor() {
413 return color;
414 }
415
416
417
418
419 public void glLoadMatrix(FloatBuffer buffer) {
420 flushBuffer();
421 super.glLoadMatrix(buffer);
422 }
423 }