Branch data Line data Source code
1 : : /* ______ ___ ___
2 : : * /\ _ \ /\_ \ /\_ \
3 : : * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
4 : : * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
5 : : * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
6 : : * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
7 : : * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
8 : : * /\____/
9 : : * \_/__/
10 : : *
11 : : * OpenGL implementation of some of the primitive routines.
12 : : *
13 : : *
14 : : * By Pavel Sountsov.
15 : : *
16 : : * See readme.txt for copyright information.
17 : : */
18 : :
19 : : #include "allegro5/allegro.h"
20 : : #include "allegro5/allegro_primitives.h"
21 : : #include "allegro5/allegro_opengl.h"
22 : : #include "allegro5/internal/aintern_prim_opengl.h"
23 : : #include "allegro5/internal/aintern_prim_soft.h"
24 : : #include "allegro5/platform/alplatf.h"
25 : : #include "allegro5/internal/aintern_prim.h"
26 : :
27 : : #ifdef ALLEGRO_CFG_OPENGL
28 : :
29 : : #include "allegro5/allegro_opengl.h"
30 : : #include "allegro5/internal/aintern_opengl.h"
31 : :
32 : 216 : static void setup_state(const char* vtxs, const ALLEGRO_VERTEX_DECL* decl, ALLEGRO_BITMAP* texture)
33 : : {
34 : 216 : ALLEGRO_DISPLAY *display = al_get_current_display();
35 : :
36 [ - + ]: 216 : if (display->flags & ALLEGRO_USE_PROGRAMMABLE_PIPELINE) {
37 : : #ifndef ALLEGRO_CFG_NO_GLES2
38 [ # # ]: 0 : if(decl) {
39 : : ALLEGRO_VERTEX_ELEMENT* e;
40 : 0 : e = &decl->elements[ALLEGRO_PRIM_POSITION];
41 [ # # ]: 0 : if(e->attribute) {
42 : 0 : int ncoord = 0;
43 : 0 : GLenum type = 0;
44 : :
45 [ # # ]: 0 : switch(e->storage) {
46 : : case ALLEGRO_PRIM_FLOAT_2:
47 : : ncoord = 2;
48 : : type = GL_FLOAT;
49 : : break;
50 : : case ALLEGRO_PRIM_FLOAT_3:
51 : : ncoord = 3;
52 : : type = GL_FLOAT;
53 : : break;
54 : : case ALLEGRO_PRIM_SHORT_2:
55 : : ncoord = 2;
56 : : type = GL_SHORT;
57 : : break;
58 : : }
59 : :
60 [ # # ]: 0 : if (display->ogl_extras->pos_loc >= 0) {
61 : 0 : glVertexAttribPointer(display->ogl_extras->pos_loc, ncoord, type, false, decl->stride, vtxs + e->offset);
62 : 0 : glEnableVertexAttribArray(display->ogl_extras->pos_loc);
63 : : }
64 : : } else {
65 [ # # ]: 0 : if (display->ogl_extras->pos_loc >= 0) {
66 : 0 : glDisableVertexAttribArray(display->ogl_extras->pos_loc);
67 : : }
68 : : }
69 : :
70 : 0 : e = &decl->elements[ALLEGRO_PRIM_TEX_COORD];
71 [ # # ]: 0 : if(!e->attribute)
72 : 0 : e = &decl->elements[ALLEGRO_PRIM_TEX_COORD_PIXEL];
73 [ # # ][ # # ]: 0 : if(texture && e->attribute) {
74 : 0 : GLenum type = 0;
75 : :
76 [ # # ]: 0 : switch(e->storage) {
77 : : case ALLEGRO_PRIM_FLOAT_2:
78 : : case ALLEGRO_PRIM_FLOAT_3:
79 : : type = GL_FLOAT;
80 : : break;
81 : : case ALLEGRO_PRIM_SHORT_2:
82 : : type = GL_SHORT;
83 : : break;
84 : : }
85 : :
86 [ # # ]: 0 : if (display->ogl_extras->texcoord_loc >= 0) {
87 : 0 : glVertexAttribPointer(display->ogl_extras->texcoord_loc, 2, type, false, decl->stride, vtxs + e->offset);
88 : 0 : glEnableVertexAttribArray(display->ogl_extras->texcoord_loc);
89 : : }
90 : : } else {
91 [ # # ]: 0 : if (display->ogl_extras->texcoord_loc >= 0) {
92 : 0 : glDisableVertexAttribArray(display->ogl_extras->texcoord_loc);
93 : : }
94 : : }
95 : :
96 : 0 : e = &decl->elements[ALLEGRO_PRIM_COLOR_ATTR];
97 [ # # ]: 0 : if(e->attribute) {
98 [ # # ]: 0 : if (display->ogl_extras->color_loc >= 0) {
99 : 0 : glVertexAttribPointer(display->ogl_extras->color_loc, 4, GL_FLOAT, true, decl->stride, vtxs + e->offset);
100 : 0 : glEnableVertexAttribArray(display->ogl_extras->color_loc);
101 : : }
102 : : } else {
103 [ # # ]: 0 : if (display->ogl_extras->color_loc >= 0) {
104 : 0 : glDisableVertexAttribArray(display->ogl_extras->color_loc);
105 : : }
106 : : }
107 : : } else {
108 [ # # ]: 0 : if (display->ogl_extras->pos_loc >= 0) {
109 : 0 : glVertexAttribPointer(display->ogl_extras->pos_loc, 3, GL_FLOAT, false, sizeof(ALLEGRO_VERTEX), vtxs + offsetof(ALLEGRO_VERTEX, x));
110 : 0 : glEnableVertexAttribArray(display->ogl_extras->pos_loc);
111 : : }
112 : :
113 [ # # ]: 0 : if (display->ogl_extras->texcoord_loc >= 0) {
114 : 0 : glVertexAttribPointer(display->ogl_extras->texcoord_loc, 2, GL_FLOAT, false, sizeof(ALLEGRO_VERTEX), vtxs + offsetof(ALLEGRO_VERTEX, u));
115 : 0 : glEnableVertexAttribArray(display->ogl_extras->texcoord_loc);
116 : : }
117 : :
118 [ # # ]: 0 : if (display->ogl_extras->color_loc >= 0) {
119 : 0 : glVertexAttribPointer(display->ogl_extras->color_loc, 4, GL_FLOAT, true, sizeof(ALLEGRO_VERTEX), vtxs + offsetof(ALLEGRO_VERTEX, color));
120 : 0 : glEnableVertexAttribArray(display->ogl_extras->color_loc);
121 : : }
122 : : }
123 : : #endif
124 : : }
125 : : else {
126 [ - + ]: 216 : if(decl) {
127 : : ALLEGRO_VERTEX_ELEMENT* e;
128 : 0 : e = &decl->elements[ALLEGRO_PRIM_POSITION];
129 [ # # ]: 0 : if(e->attribute) {
130 : 0 : int ncoord = 0;
131 : 0 : GLenum type = 0;
132 : :
133 : 0 : glEnableClientState(GL_VERTEX_ARRAY);
134 : :
135 [ # # ]: 0 : switch(e->storage) {
136 : : case ALLEGRO_PRIM_FLOAT_2:
137 : : ncoord = 2;
138 : : type = GL_FLOAT;
139 : : break;
140 : : case ALLEGRO_PRIM_FLOAT_3:
141 : : ncoord = 3;
142 : : type = GL_FLOAT;
143 : : break;
144 : : case ALLEGRO_PRIM_SHORT_2:
145 : : ncoord = 2;
146 : : type = GL_SHORT;
147 : : break;
148 : : }
149 : 0 : glVertexPointer(ncoord, type, decl->stride, vtxs + e->offset);
150 : : } else {
151 : 0 : glDisableClientState(GL_VERTEX_ARRAY);
152 : : }
153 : :
154 : 0 : e = &decl->elements[ALLEGRO_PRIM_TEX_COORD];
155 [ # # ]: 0 : if(!e->attribute)
156 : 0 : e = &decl->elements[ALLEGRO_PRIM_TEX_COORD_PIXEL];
157 [ # # ][ # # ]: 0 : if(texture && e->attribute) {
158 : 0 : GLenum type = 0;
159 : :
160 : 0 : glEnableClientState(GL_TEXTURE_COORD_ARRAY);
161 : :
162 [ # # ]: 0 : switch(e->storage) {
163 : : case ALLEGRO_PRIM_FLOAT_2:
164 : : case ALLEGRO_PRIM_FLOAT_3:
165 : : type = GL_FLOAT;
166 : : break;
167 : : case ALLEGRO_PRIM_SHORT_2:
168 : : type = GL_SHORT;
169 : : break;
170 : : }
171 : 0 : glTexCoordPointer(2, type, decl->stride, vtxs + e->offset);
172 : : } else {
173 : 0 : glDisableClientState(GL_TEXTURE_COORD_ARRAY);
174 : : }
175 : :
176 : 0 : e = &decl->elements[ALLEGRO_PRIM_COLOR_ATTR];
177 [ # # ]: 0 : if(e->attribute) {
178 : 0 : glEnableClientState(GL_COLOR_ARRAY);
179 : :
180 : 0 : glColorPointer(4, GL_FLOAT, decl->stride, vtxs + e->offset);
181 : : } else {
182 : 0 : glDisableClientState(GL_COLOR_ARRAY);
183 : 0 : glColor4f(1, 1, 1, 1);
184 : : }
185 : : } else {
186 : 216 : glEnableClientState(GL_COLOR_ARRAY);
187 : 216 : glEnableClientState(GL_VERTEX_ARRAY);
188 : 216 : glEnableClientState(GL_TEXTURE_COORD_ARRAY);
189 [ + - ]: 216 : if (!(display->flags & ALLEGRO_USE_PROGRAMMABLE_PIPELINE))
190 : 216 : glDisableClientState(GL_NORMAL_ARRAY);
191 : :
192 : 216 : glVertexPointer(3, GL_FLOAT, sizeof(ALLEGRO_VERTEX), vtxs + offsetof(ALLEGRO_VERTEX, x));
193 : 216 : glColorPointer(4, GL_FLOAT, sizeof(ALLEGRO_VERTEX), vtxs + offsetof(ALLEGRO_VERTEX, color));
194 : 216 : glTexCoordPointer(2, GL_FLOAT, sizeof(ALLEGRO_VERTEX), vtxs + offsetof(ALLEGRO_VERTEX, u));
195 : : }
196 : : }
197 : :
198 [ + + ]: 216 : if (texture) {
199 : 34 : GLuint gl_texture = al_get_opengl_texture(texture);
200 : : int true_w, true_h;
201 : : int tex_x, tex_y;
202 : 34 : float mat[4][4] = {
203 : : {1, 0, 0, 0},
204 : : {0, -1, 0, 0},
205 : : {0, 0, 1, 0},
206 : : {0, 0, 0, 1}
207 : : };
208 : : int height;
209 : :
210 [ + + ]: 34 : if (texture->parent)
211 : 6 : height = texture->parent->h;
212 : : else
213 : 28 : height = texture->h;
214 : :
215 : 34 : al_get_opengl_texture_size(texture, &true_w, &true_h);
216 : 34 : al_get_opengl_texture_position(texture, &tex_x, &tex_y);
217 : :
218 : 34 : mat[3][0] = (float)tex_x / true_w;
219 : 34 : mat[3][1] = (float)(height - tex_y) / true_h;
220 : :
221 [ - + ]: 34 : if(decl) {
222 [ # # ]: 0 : if(decl->elements[ALLEGRO_PRIM_TEX_COORD_PIXEL].attribute) {
223 : 0 : mat[0][0] = 1.0f / true_w;
224 : 0 : mat[1][1] = -1.0f / true_h;
225 : : } else {
226 : 0 : mat[0][0] = (float)al_get_bitmap_width(texture) / true_w;
227 : 0 : mat[1][1] = -(float)al_get_bitmap_height(texture) / true_h;
228 : : }
229 : : } else {
230 : 34 : mat[0][0] = 1.0f / true_w;
231 : 34 : mat[1][1] = -1.0f / true_h;
232 : : }
233 : :
234 [ + - ]: 34 : if (!(display->flags & ALLEGRO_USE_PROGRAMMABLE_PIPELINE)) {
235 : 34 : glBindTexture(GL_TEXTURE_2D, gl_texture);
236 : : }
237 : :
238 [ - + ]: 34 : if (display->flags & ALLEGRO_USE_PROGRAMMABLE_PIPELINE) {
239 : : #ifndef ALLEGRO_CFG_NO_GLES2
240 : : GLint handle;
241 : :
242 : 0 : handle = display->ogl_extras->tex_matrix_loc;
243 [ # # ]: 0 : if (handle >= 0)
244 : 0 : glUniformMatrix4fv(handle, 1, false, (float *)mat);
245 : :
246 : 0 : handle = display->ogl_extras->use_tex_matrix_loc;
247 [ # # ]: 0 : if (handle >= 0)
248 : 0 : glUniform1i(handle, 1);
249 : :
250 [ # # ]: 0 : if (display->ogl_extras->use_tex_loc >= 0) {
251 : 0 : glUniform1i(display->ogl_extras->use_tex_loc, 1);
252 : : }
253 [ # # ]: 0 : if (display->ogl_extras->tex_loc >= 0) {
254 : 0 : glBindTexture(GL_TEXTURE_2D, al_get_opengl_texture(texture));
255 : 0 : glActiveTexture(GL_TEXTURE0);
256 : 0 : glUniform1i(display->ogl_extras->tex_loc, 0); // 0th sampler
257 : : }
258 : 0 : glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
259 : 0 : glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
260 : : #endif
261 : : }
262 : : else {
263 : 34 : glMatrixMode(GL_TEXTURE);
264 : 34 : glLoadMatrixf(mat[0]);
265 : 34 : glMatrixMode(GL_MODELVIEW);
266 : :
267 : 34 : glEnable(GL_TEXTURE_2D);
268 : 34 : glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
269 : 34 : glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
270 : : }
271 : : } else {
272 : 182 : glBindTexture(GL_TEXTURE_2D, 0);
273 : : }
274 : 216 : }
275 : :
276 : 216 : static void revert_state(ALLEGRO_BITMAP* texture)
277 : : {
278 : 216 : ALLEGRO_DISPLAY *display = al_get_current_display();
279 : :
280 [ + + ]: 216 : if(texture) {
281 [ - + ]: 34 : if (display->flags & ALLEGRO_USE_PROGRAMMABLE_PIPELINE) {
282 : : #ifndef ALLEGRO_CFG_NO_GLES2
283 : 0 : float identity[16] = {
284 : : 1, 0, 0, 0,
285 : : 0, 1, 0, 0,
286 : : 0, 0, 1, 0,
287 : : 0, 0, 0, 1
288 : : };
289 : : GLint handle;
290 : 0 : handle = display->ogl_extras->tex_matrix_loc;
291 [ # # ]: 0 : if (handle >= 0)
292 : 0 : glUniformMatrix4fv(handle, 1, false, identity);
293 : 0 : handle = display->ogl_extras->use_tex_matrix_loc;
294 [ # # ]: 0 : if (handle >= 0)
295 : 0 : glUniform1i(handle, 0);
296 [ # # ]: 0 : if (display->ogl_extras->use_tex_loc >= 0)
297 : 0 : glUniform1i(display->ogl_extras->use_tex_loc, 0);
298 : : #endif
299 : : }
300 : : else {
301 : 34 : glDisable(GL_TEXTURE_2D);
302 : 34 : glMatrixMode(GL_TEXTURE);
303 : 34 : glLoadIdentity();
304 : 34 : glMatrixMode(GL_MODELVIEW);
305 : : }
306 : : }
307 : :
308 [ - + ]: 216 : if (display->flags & ALLEGRO_USE_PROGRAMMABLE_PIPELINE) {
309 : : #ifndef ALLEGRO_CFG_NO_GLES2
310 [ # # ]: 0 : if (display->ogl_extras->pos_loc >= 0)
311 : 0 : glDisableVertexAttribArray(display->ogl_extras->pos_loc);
312 [ # # ]: 0 : if (display->ogl_extras->color_loc >= 0)
313 : 0 : glDisableVertexAttribArray(display->ogl_extras->color_loc);
314 [ # # ]: 0 : if (display->ogl_extras->texcoord_loc >= 0)
315 : 0 : glDisableVertexAttribArray(display->ogl_extras->texcoord_loc);
316 : : #endif
317 : : }
318 : : else {
319 : 216 : glDisableClientState(GL_COLOR_ARRAY);
320 : 216 : glDisableClientState(GL_VERTEX_ARRAY);
321 : 216 : glDisableClientState(GL_TEXTURE_COORD_ARRAY);
322 : : }
323 : 216 : }
324 : :
325 : 216 : static int draw_prim_raw(ALLEGRO_BITMAP* target, ALLEGRO_BITMAP* texture,
326 : : ALLEGRO_VERTEX_BUFFER* vertex_buffer,
327 : : const void* vtx, const ALLEGRO_VERTEX_DECL* decl,
328 : : int start, int end, int type)
329 : : {
330 : 216 : int num_primitives = 0;
331 : 216 : ALLEGRO_DISPLAY *ogl_disp = target->display;
332 : 216 : ALLEGRO_BITMAP *opengl_target = target;
333 : : ALLEGRO_BITMAP_EXTRA_OPENGL *extra;
334 : 216 : int num_vtx = end - start;
335 : :
336 [ + + ]: 216 : if (target->parent) {
337 : 10 : opengl_target = target->parent;
338 : : }
339 : 216 : extra = opengl_target->extra;
340 : :
341 [ + + ][ + - ]: 216 : if ((!extra->is_backbuffer && ogl_disp->ogl_extras->opengl_target !=
342 [ - + ]: 216 : opengl_target) || al_is_bitmap_locked(target)) {
343 [ # # ]: 0 : if (vertex_buffer) {
344 [ # # ][ # # ]: 0 : ASSERT(!vertex_buffer->write_only);
[ # # ]
345 : 0 : vtx = al_lock_vertex_buffer(vertex_buffer, start, end, ALLEGRO_LOCK_READONLY);
346 [ # # ][ # # ]: 0 : ASSERT(vtx);
[ # # ]
347 : 0 : num_primitives = _al_draw_prim_soft(texture, vtx, decl, 0, num_vtx, type);
348 : 0 : al_unlock_vertex_buffer(vertex_buffer);
349 : 0 : return num_primitives;
350 : : }
351 : : else {
352 : 0 : return _al_draw_prim_soft(texture, vtx, decl, start, end, type);
353 : : }
354 : : }
355 : :
356 [ - + ]: 216 : if (vertex_buffer) {
357 : 0 : glBindBuffer(GL_ARRAY_BUFFER, (GLuint)vertex_buffer->handle);
358 : : }
359 : :
360 : 216 : _al_opengl_set_blender(ogl_disp);
361 : 216 : setup_state(vtx, decl, texture);
362 : :
363 [ + + + + : 216 : switch (type) {
+ + - - ]
364 : : case ALLEGRO_PRIM_LINE_LIST: {
365 : 13 : glDrawArrays(GL_LINES, start, num_vtx);
366 : 13 : num_primitives = num_vtx / 2;
367 : 13 : break;
368 : : };
369 : : case ALLEGRO_PRIM_LINE_STRIP: {
370 : 10 : glDrawArrays(GL_LINE_STRIP, start, num_vtx);
371 : 10 : num_primitives = num_vtx - 1;
372 : 10 : break;
373 : : };
374 : : case ALLEGRO_PRIM_LINE_LOOP: {
375 : 13 : glDrawArrays(GL_LINE_LOOP, start, num_vtx);
376 : 13 : num_primitives = num_vtx;
377 : 13 : break;
378 : : };
379 : : case ALLEGRO_PRIM_TRIANGLE_LIST: {
380 : 35 : glDrawArrays(GL_TRIANGLES, start, num_vtx);
381 : 35 : num_primitives = num_vtx / 3;
382 : 35 : break;
383 : : };
384 : : case ALLEGRO_PRIM_TRIANGLE_STRIP: {
385 : 65 : glDrawArrays(GL_TRIANGLE_STRIP, start, num_vtx);
386 : 65 : num_primitives = num_vtx - 2;
387 : 65 : break;
388 : : };
389 : : case ALLEGRO_PRIM_TRIANGLE_FAN: {
390 : 80 : glDrawArrays(GL_TRIANGLE_FAN, start, num_vtx);
391 : 80 : num_primitives = num_vtx - 2;
392 : 80 : break;
393 : : };
394 : : case ALLEGRO_PRIM_POINT_LIST: {
395 : 0 : glDrawArrays(GL_POINTS, start, num_vtx);
396 : 0 : num_primitives = num_vtx;
397 : 0 : break;
398 : : };
399 : : }
400 : :
401 : 216 : revert_state(texture);
402 : :
403 [ - + ]: 216 : if (vertex_buffer) {
404 : 0 : glBindBuffer(GL_ARRAY_BUFFER, 0);
405 : : }
406 : :
407 : 216 : return num_primitives;
408 : : }
409 : :
410 : 0 : static int draw_prim_indexed_raw(ALLEGRO_BITMAP* target, ALLEGRO_BITMAP* texture,
411 : : const void* vtx, const ALLEGRO_VERTEX_DECL* decl, const int* indices,
412 : : int num_vtx, int type)
413 : : {
414 : 0 : int num_primitives = 0;
415 : 0 : ALLEGRO_DISPLAY *ogl_disp = target->display;
416 : 0 : ALLEGRO_BITMAP *opengl_target = target;
417 : : ALLEGRO_BITMAP_EXTRA_OPENGL *extra;
418 : 0 : const void* idx = indices;
419 : : GLenum idx_size;
420 : :
421 : : #if defined ALLEGRO_IPHONE
422 : : GLushort ind[num_vtx];
423 : : int ii;
424 : : #endif
425 : :
426 [ # # ]: 0 : if (target->parent) {
427 : 0 : opengl_target = target->parent;
428 : : }
429 : 0 : extra = opengl_target->extra;
430 : :
431 [ # # ][ # # ]: 0 : if ((!extra->is_backbuffer && ogl_disp->ogl_extras->opengl_target !=
432 [ # # ]: 0 : opengl_target) || al_is_bitmap_locked(target)) {
433 : 0 : return _al_draw_prim_indexed_soft(texture, vtx, decl, indices, num_vtx, type);
434 : : }
435 : :
436 : : #if defined ALLEGRO_IPHONE
437 : : for (ii = 0; ii < num_vtx; ii++) {
438 : : ind[ii] = (GLushort)indices[ii];
439 : : }
440 : : idx = ind;
441 : : idx_size = GL_UNSIGNED_SHORT;
442 : : #else
443 : 0 : idx_size = GL_UNSIGNED_INT;
444 : : #endif
445 : :
446 : 0 : _al_opengl_set_blender(ogl_disp);
447 : 0 : setup_state(vtx, decl, texture);
448 : :
449 [ # # # # : 0 : switch (type) {
# # # # ]
450 : : case ALLEGRO_PRIM_LINE_LIST: {
451 : 0 : glDrawElements(GL_LINES, num_vtx, idx_size, idx);
452 : 0 : num_primitives = num_vtx / 2;
453 : 0 : break;
454 : : };
455 : : case ALLEGRO_PRIM_LINE_STRIP: {
456 : 0 : glDrawElements(GL_LINE_STRIP, num_vtx, idx_size, idx);
457 : 0 : num_primitives = num_vtx - 1;
458 : 0 : break;
459 : : };
460 : : case ALLEGRO_PRIM_LINE_LOOP: {
461 : 0 : glDrawElements(GL_LINE_LOOP, num_vtx, idx_size, idx);
462 : 0 : num_primitives = num_vtx;
463 : 0 : break;
464 : : };
465 : : case ALLEGRO_PRIM_TRIANGLE_LIST: {
466 : 0 : glDrawElements(GL_TRIANGLES, num_vtx, idx_size, idx);
467 : 0 : num_primitives = num_vtx / 3;
468 : 0 : break;
469 : : };
470 : : case ALLEGRO_PRIM_TRIANGLE_STRIP: {
471 : 0 : glDrawElements(GL_TRIANGLE_STRIP, num_vtx, idx_size, idx);
472 : 0 : num_primitives = num_vtx - 2;
473 : 0 : break;
474 : : };
475 : : case ALLEGRO_PRIM_TRIANGLE_FAN: {
476 : 0 : glDrawElements(GL_TRIANGLE_FAN, num_vtx, idx_size, idx);
477 : 0 : num_primitives = num_vtx - 2;
478 : 0 : break;
479 : : };
480 : : case ALLEGRO_PRIM_POINT_LIST: {
481 : 0 : glDrawElements(GL_POINTS, num_vtx, idx_size, idx);
482 : 0 : num_primitives = num_vtx;
483 : 0 : break;
484 : : };
485 : : }
486 : :
487 : 0 : revert_state(texture);
488 : :
489 : 0 : return num_primitives;
490 : : }
491 : :
492 : : #endif /* ALLEGRO_CFG_OPENGL */
493 : :
494 : 216 : int _al_draw_prim_opengl(ALLEGRO_BITMAP* target, ALLEGRO_BITMAP* texture, const void* vtxs, const ALLEGRO_VERTEX_DECL* decl, int start, int end, int type)
495 : : {
496 : : #ifdef ALLEGRO_CFG_OPENGL
497 : 216 : return draw_prim_raw(target, texture, 0, vtxs, decl, start, end, type);
498 : : #else
499 : : (void)target;
500 : : (void)texture;
501 : : (void)vtxs;
502 : : (void)start;
503 : : (void)end;
504 : : (void)type;
505 : : (void)decl;
506 : :
507 : : return 0;
508 : : #endif
509 : : }
510 : :
511 : 0 : int _al_draw_vertex_buffer_opengl(ALLEGRO_BITMAP* target, ALLEGRO_BITMAP* texture, ALLEGRO_VERTEX_BUFFER* vertex_buffer, int start, int end, int type)
512 : : {
513 : : #ifdef ALLEGRO_CFG_OPENGL
514 : 0 : return draw_prim_raw(target, texture, vertex_buffer, 0, vertex_buffer->decl, start, end, type);
515 : : #else
516 : : (void)target;
517 : : (void)texture;
518 : : (void)vertex_buffer;
519 : : (void)start;
520 : : (void)end;
521 : : (void)type;
522 : :
523 : : return 0;
524 : : #endif
525 : : }
526 : :
527 : 0 : int _al_draw_prim_indexed_opengl(ALLEGRO_BITMAP *target, ALLEGRO_BITMAP* texture, const void* vtxs, const ALLEGRO_VERTEX_DECL* decl, const int* indices, int num_vtx, int type)
528 : : {
529 : : #ifdef ALLEGRO_CFG_OPENGL
530 : 0 : return draw_prim_indexed_raw(target, texture, vtxs, decl, indices, num_vtx, type);
531 : : #else
532 : : (void)target;
533 : : (void)texture;
534 : : (void)vtxs;
535 : : (void)decl;
536 : : (void)indices;
537 : : (void)num_vtx;
538 : : (void)type;
539 : :
540 : : return 0;
541 : : #endif
542 : : }
543 : :
544 : 0 : bool _al_create_vertex_buffer_opengl(ALLEGRO_VERTEX_BUFFER* buf, const void* initial_data, size_t num_vertices, int usage_hints)
545 : : {
546 : : #ifdef ALLEGRO_CFG_OPENGL
547 : : GLuint vbo;
548 : : GLenum usage;
549 [ # # ]: 0 : int stride = buf->decl ? buf->decl->stride : (int)sizeof(ALLEGRO_VERTEX);
550 : :
551 [ # # ]: 0 : switch (usage_hints)
552 : : {
553 : : #if !defined ALLEGRO_CFG_OPENGLES
554 : : case ALLEGRO_BUFFER_STREAM | ALLEGRO_BUFFER_DRAW:
555 : : usage = GL_STREAM_DRAW;
556 : : break;
557 : : case ALLEGRO_BUFFER_STREAM | ALLEGRO_BUFFER_READ:
558 : : usage = GL_STREAM_READ;
559 : : break;
560 : : case ALLEGRO_BUFFER_STREAM | ALLEGRO_BUFFER_COPY:
561 : : usage = GL_STREAM_COPY;
562 : : break;
563 : : #endif
564 : : case ALLEGRO_BUFFER_STATIC | ALLEGRO_BUFFER_DRAW:
565 : : usage = GL_STATIC_DRAW;
566 : : break;
567 : : #if !defined ALLEGRO_CFG_OPENGLES
568 : : case ALLEGRO_BUFFER_STATIC | ALLEGRO_BUFFER_READ:
569 : : usage = GL_STATIC_READ;
570 : : break;
571 : : case ALLEGRO_BUFFER_STATIC | ALLEGRO_BUFFER_COPY:
572 : : usage = GL_STATIC_COPY;
573 : : break;
574 : : #endif
575 : : case ALLEGRO_BUFFER_DYNAMIC | ALLEGRO_BUFFER_DRAW:
576 : : usage = GL_DYNAMIC_DRAW;
577 : : break;
578 : : #if !defined ALLEGRO_CFG_OPENGLES
579 : : case ALLEGRO_BUFFER_DYNAMIC | ALLEGRO_BUFFER_READ:
580 : : usage = GL_DYNAMIC_READ;
581 : : break;
582 : : case ALLEGRO_BUFFER_DYNAMIC | ALLEGRO_BUFFER_COPY:
583 : : usage = GL_DYNAMIC_COPY;
584 : : break;
585 : : #endif
586 : : default:
587 : : usage = GL_STATIC_DRAW;
588 : : }
589 : :
590 : 0 : glGenBuffers(1, &vbo);
591 : 0 : glBindBuffer(GL_ARRAY_BUFFER, vbo);
592 : 0 : glBufferData(GL_ARRAY_BUFFER, num_vertices * stride, initial_data, usage);
593 : 0 : glBindBuffer(GL_ARRAY_BUFFER, 0);
594 : :
595 [ # # ]: 0 : if (glGetError())
596 : : return false;
597 : :
598 : 0 : buf->local_buffer_length = 0;
599 : 0 : buf->handle = vbo;
600 : :
601 : : return true;
602 : : #else
603 : : (void)buf;
604 : : (void)initial_data;
605 : : (void)num_vertices;
606 : : (void)usage_hints;
607 : :
608 : : return false;
609 : : #endif
610 : : }
611 : :
612 : 0 : void _al_destroy_vertex_buffer_opengl(ALLEGRO_VERTEX_BUFFER* buf)
613 : : {
614 : : #ifdef ALLEGRO_CFG_OPENGL
615 : 0 : glDeleteBuffers(1, (GLuint*)&buf->handle);
616 : 0 : al_free(buf->locked_memory);
617 : : #else
618 : : (void)buf;
619 : : #endif
620 : 0 : }
621 : :
622 : 0 : void* _al_lock_vertex_buffer_opengl(ALLEGRO_VERTEX_BUFFER* buf)
623 : : {
624 : : #ifdef ALLEGRO_CFG_OPENGL
625 [ # # ]: 0 : if (buf->local_buffer_length < buf->lock_length) {
626 : 0 : buf->locked_memory = al_realloc(buf->locked_memory, buf->lock_length);
627 : 0 : buf->local_buffer_length = buf->lock_length;
628 : : }
629 : :
630 [ # # ]: 0 : if (buf->lock_flags != ALLEGRO_LOCK_WRITEONLY) {
631 : : #if !defined ALLEGRO_CFG_OPENGLES
632 : 0 : glBindBuffer(GL_ARRAY_BUFFER, (GLuint)buf->handle);
633 : 0 : glGetBufferSubData(GL_ARRAY_BUFFER, buf->lock_offset, buf->lock_length, buf->locked_memory);
634 : 0 : glBindBuffer(GL_ARRAY_BUFFER, 0);
635 : :
636 [ # # ]: 0 : if (glGetError())
637 : : return 0;
638 : : #else
639 : : return 0;
640 : : #endif
641 : : }
642 : 0 : return buf->locked_memory;
643 : : #else
644 : : (void)buf;
645 : :
646 : : return 0;
647 : : #endif
648 : : }
649 : :
650 : 0 : void _al_unlock_vertex_buffer_opengl(ALLEGRO_VERTEX_BUFFER* buf)
651 : : {
652 : : #ifdef ALLEGRO_CFG_OPENGL
653 [ # # ]: 0 : if (buf->lock_flags != ALLEGRO_LOCK_READONLY) {
654 : 0 : glBindBuffer(GL_ARRAY_BUFFER, (GLuint)buf->handle);
655 : 0 : glBufferSubData(GL_ARRAY_BUFFER, buf->lock_offset, buf->lock_length, buf->locked_memory);
656 : 0 : glBindBuffer(GL_ARRAY_BUFFER, 0);
657 : : }
658 : : #else
659 : : (void)buf;
660 : : #endif
661 : 0 : }
|