FS2_Open
Open source remastering of the Freespace 2 engine
grbatch.cpp
Go to the documentation of this file.
1 /*
2  * Code created by Thomas Whittaker (RT) for a FreeSpace 2 source code project
3  *
4  * You may not sell or otherwise commercially exploit the source or things you
5  * created based on the source.
6  *
7 */
8 
9 #include "bmpman/bmpman.h"
10 #include "cmdline/cmdline.h"
11 #include "globalincs/pstypes.h"
12 #include "graphics/2d.h"
13 #include "graphics/grbatch.h"
14 #include "graphics/gropengldraw.h"
15 #include "graphics/gropenglstate.h"
16 #include "render/3d.h"
17 
19 {
20  if (vert != NULL) {
21  vm_free(vert);
22  vert = NULL;
23  }
24 
25  if (radius_list != NULL) {
26  vm_free(radius_list);
27  radius_list = NULL;
28  }
29 }
30 
36 void geometry_batcher::allocate_internal(int n_verts)
37 {
38 
39  if (n_verts > n_allocated) {
40  if (vert != NULL) {
41  vm_free(vert);
42  vert = NULL;
43  }
44 
45  if (radius_list != NULL) {
46  vm_free(radius_list);
47  radius_list = NULL;
48  }
49 
50  vert = (vertex *) vm_malloc( sizeof(vertex) * n_verts );
51  radius_list = (float *) vm_malloc( sizeof(float) * n_verts );
52 
53  Verify( (vert != NULL) );
54  Verify( (radius_list != NULL) );
55 
56  memset( vert, 0, sizeof(vertex) * n_verts );
57  memset( radius_list, 0, sizeof(float) * n_verts );
58 
59  n_allocated = n_verts;
60  }
61 
62  n_to_render = 0;
63  use_radius = true;
64 }
65 
66 void geometry_batcher::allocate(int quad, int n_tri)
67 {
68  int to_alloc = 0;
69 
70  // quads have two triangles, therefore six verts
71  if (quad > 0 ) {
72  to_alloc += (quad * 6);
73  }
74 
75  // a single triangle has a mere 3 verts
76  if ( n_tri > 0 ) {
77  to_alloc += (n_tri * 3);
78  }
79 
80  allocate_internal(to_alloc);
81 }
82 
83 void geometry_batcher::add_allocate(int quad, int n_tri)
84 {
85  int to_alloc = (n_to_render * 3);
86 
87  // quads have two triangles, therefore six verts
88  if ( quad > 0 ) {
89  to_alloc += (quad * 6);
90  }
91 
92  // a single triangle has a mere 3 verts
93  if (n_tri > 0) {
94  to_alloc += (n_tri * 3);
95  }
96 
97  vertex *old_vert = vert;
98  float *old_radius_list = radius_list;
99 
100  if (to_alloc > n_allocated) {
101  vert = (vertex *) vm_malloc( sizeof(vertex) * to_alloc );
102  radius_list = (float *) vm_malloc( sizeof(float) * to_alloc );
103 
104  Verify( (vert != NULL) );
105  Verify( (radius_list != NULL) );
106 
107  memset( vert, 0, sizeof(vertex) * to_alloc );
108  memset( radius_list, 0, sizeof(float) * to_alloc );
109 
110  if (old_vert != NULL) {
111  memcpy( vert, old_vert, sizeof(vertex) * n_to_render * 3 );
112  vm_free(old_vert);
113  }
114 
115  if (old_radius_list != NULL) {
116  memcpy( radius_list, old_radius_list, sizeof(float) * n_to_render * 3 );
117  vm_free(old_radius_list);
118  }
119 
120  n_allocated = to_alloc;
121  }
122 }
123 
124 void geometry_batcher::clone(const geometry_batcher &geo)
125 {
126  n_to_render = geo.n_to_render;
127  n_allocated = geo.n_allocated;
128  use_radius = geo.use_radius;
129 
130  if (n_allocated > 0) {
131  vert = (vertex *) vm_malloc( sizeof(vertex) * n_allocated );
132  radius_list = (float *) vm_malloc( sizeof(float) * n_allocated );
133 
134  memcpy( vert, geo.vert, sizeof(vertex) * n_allocated );
135  memcpy( radius_list, geo.radius_list, sizeof(float) * n_allocated);
136  } else {
137  vert = NULL;
138  radius_list = NULL;
139  }
140 }
141 
143 {
144  if (this != &geo) {
145  clone(geo);
146  }
147 
148  return *this;
149 }
150 
151 /*
152 0----1
153 |\ |
154 | \ |
155 3----2
156 */
157 void geometry_batcher::draw_bitmap(vertex *pnt, int orient, float rad, float depth)
158 {
159  float radius = rad;
160  rad *= 1.41421356f;//1/0.707, becase these are the points of a square or width and height rad
161 
162  vec3d PNT(pnt->world);
163  vec3d p[4];
164  vec3d fvec, rvec, uvec;
165  vertex *P = &vert[n_to_render * 3];
166  float *R = &radius_list[n_to_render * 3];
167 
168  // get the direction from the point to the eye
169  vm_vec_sub(&fvec, &View_position, &PNT);
170  vm_vec_normalize_safe(&fvec);
171 
172  // get an up vector in the general direction of what we want
173  uvec = View_matrix.vec.uvec;
174 
175  // make a right vector from the f and up vector, this r vec is exactly what we want, so...
176  vm_vec_cross(&rvec, &View_matrix.vec.fvec, &uvec);
177  vm_vec_normalize_safe(&rvec);
178 
179  // fix the u vec with it
180  vm_vec_cross(&uvec, &View_matrix.vec.fvec, &rvec);
181 
182  // move the center of the sprite based on the depth parameter
183  if ( depth != 0.0f )
184  vm_vec_scale_add(&PNT, &PNT, &fvec, depth);
185 
186  // move one of the verts to the left
187  vm_vec_scale_add(&p[0], &PNT, &rvec, rad);
188 
189  // and one to the right
190  vm_vec_scale_add(&p[2], &PNT, &rvec, -rad);
191 
192  // now move all oof the verts to were they need to be
193  vm_vec_scale_add(&p[1], &p[2], &uvec, rad);
194  vm_vec_scale_add(&p[3], &p[0], &uvec, -rad);
195  vm_vec_scale_add(&p[0], &p[0], &uvec, rad);
196  vm_vec_scale_add(&p[2], &p[2], &uvec, -rad);
197 
198 
199  //move all the data from the vecs into the verts
200  //tri 1
201  g3_transfer_vertex(&P[5], &p[3]);
202  g3_transfer_vertex(&P[4], &p[2]);
203  g3_transfer_vertex(&P[3], &p[1]);
204 
205  //tri 2
206  g3_transfer_vertex(&P[2], &p[3]);
207  g3_transfer_vertex(&P[1], &p[1]);
208  g3_transfer_vertex(&P[0], &p[0]);
209 
210  // set up the UV coords
211  if ( orient & 1 ) {
212  // tri 1
213  P[5].texture_position.u = 1.0f;
214  P[4].texture_position.u = 0.0f;
215  P[3].texture_position.u = 0.0f;
216  // tri 2
217  P[2].texture_position.u = 1.0f;
218  P[1].texture_position.u = 0.0f;
219  P[0].texture_position.u = 1.0f;
220  } else {
221  // tri 1
222  P[5].texture_position.u = 0.0f;
223  P[4].texture_position.u = 1.0f;
224  P[3].texture_position.u = 1.0f;
225  // tri 2
226  P[2].texture_position.u = 0.0f;
227  P[1].texture_position.u = 1.0f;
228  P[0].texture_position.u = 0.0f;
229  }
230 
231  if ( orient & 2 ) {
232  // tri 1
233  P[5].texture_position.v = 1.0f;
234  P[4].texture_position.v = 1.0f;
235  P[3].texture_position.v = 0.0f;
236  // tri 2
237  P[2].texture_position.v = 1.0f;
238  P[1].texture_position.v = 0.0f;
239  P[0].texture_position.v = 0.0f;
240  } else {
241  // tri 1
242  P[5].texture_position.v = 0.0f;
243  P[4].texture_position.v = 0.0f;
244  P[3].texture_position.v = 1.0f;
245  // tri 2
246  P[2].texture_position.v = 0.0f;
247  P[1].texture_position.v = 1.0f;
248  P[0].texture_position.v = 1.0f;
249  }
250 
251  for (int i = 0; i < 6 ; i++) {
252  P[i].r = pnt->r;
253  P[i].g = pnt->g;
254  P[i].b = pnt->b;
255  P[i].a = pnt->a;
256 
257  R[i] = radius;
258  }
259 
260  n_to_render += 2;
261 }
262 
263 void geometry_batcher::draw_bitmap(vertex *pnt, float rad, float angle, float depth)
264 {
265  float radius = rad;
266  rad *= 1.41421356f;//1/0.707, becase these are the points of a square or width and height rad
267 
268  extern float Physics_viewer_bank;
269  angle -= Physics_viewer_bank;
270 
271  if ( angle < 0.0f )
272  angle += PI2;
273  else if ( angle > PI2 )
274  angle -= PI2;
275 
276  vec3d PNT(pnt->world);
277  vec3d p[4];
278  vec3d fvec, rvec, uvec;
279  vertex *P = &vert[n_to_render * 3];
280  float *R = &radius_list[n_to_render * 3];
281 
282  vm_vec_sub(&fvec, &View_position, &PNT);
283  vm_vec_normalize_safe(&fvec);
284 
286 
287  vm_vec_cross(&rvec, &View_matrix.vec.fvec, &uvec);
288  vm_vec_normalize_safe(&rvec);
289  vm_vec_cross(&uvec, &View_matrix.vec.fvec, &rvec);
290 
291  vm_vec_scale_add(&PNT, &PNT, &fvec, depth);
292  vm_vec_scale_add(&p[0], &PNT, &rvec, rad);
293  vm_vec_scale_add(&p[2], &PNT, &rvec, -rad);
294 
295  vm_vec_scale_add(&p[1], &p[2], &uvec, rad);
296  vm_vec_scale_add(&p[3], &p[0], &uvec, -rad);
297  vm_vec_scale_add(&p[0], &p[0], &uvec, rad);
298  vm_vec_scale_add(&p[2], &p[2], &uvec, -rad);
299 
300 
301  //move all the data from the vecs into the verts
302  //tri 1
303  g3_transfer_vertex(&P[5], &p[3]);
304  g3_transfer_vertex(&P[4], &p[2]);
305  g3_transfer_vertex(&P[3], &p[1]);
306 
307  //tri 2
308  g3_transfer_vertex(&P[2], &p[3]);
309  g3_transfer_vertex(&P[1], &p[1]);
310  g3_transfer_vertex(&P[0], &p[0]);
311 
312  //tri 1
313  P[5].texture_position.u = 0.0f; P[5].texture_position.v = 0.0f;
314  P[4].texture_position.u = 1.0f; P[4].texture_position.v = 0.0f;
315  P[3].texture_position.u = 1.0f; P[3].texture_position.v = 1.0f;
316 
317  //tri 2
318  P[2].texture_position.u = 0.0f; P[2].texture_position.v = 0.0f;
319  P[1].texture_position.u = 1.0f; P[1].texture_position.v = 1.0f;
320  P[0].texture_position.u = 0.0f; P[0].texture_position.v = 1.0f;
321 
322  for (int i = 0; i < 6 ; i++) {
323  P[i].r = pnt->r;
324  P[i].g = pnt->g;
325  P[i].b = pnt->b;
326  P[i].a = pnt->a;
327 
328  R[i] = radius;
329  }
330 
331  n_to_render += 2;
332 }
333 
335 {
336  vertex *P = &vert[n_to_render *3 ];
337 
338  for (int i = 0; i < 3; i++)
339  P[i] = verts[i];
340 
341  n_to_render += 1;
342  use_radius = false;
343 }
344 
346 {
347  vertex *P = &vert[n_to_render * 3];
348 
349  P[0] = verts[0];
350  P[1] = verts[1];
351  P[2] = verts[2];
352 
353  P[3] = verts[0];
354  P[4] = verts[2];
355  P[5] = verts[3];
356 
357  n_to_render += 2;
358  use_radius = false;
359 }
360 
361 
362 void geometry_batcher::draw_beam(vec3d *start, vec3d *end, float width, float intensity, float offset)
363 {
364  vec3d p[4];
365  vertex *P = &vert[n_to_render * 3];
366  float *R = &radius_list[n_to_render * 3];
367 
368  vec3d fvec, uvecs, uvece, evec;
369 
370  vm_vec_sub(&fvec, start, end);
371  vm_vec_normalize_safe(&fvec);
372 
373  vm_vec_sub(&evec, &View_position, start);
374  vm_vec_normalize_safe(&evec);
375 
376  vm_vec_cross(&uvecs, &fvec, &evec);
377  vm_vec_normalize_safe(&uvecs);
378 
379  vm_vec_sub(&evec, &View_position, end);
380  vm_vec_normalize_safe(&evec);
381 
382  vm_vec_cross(&uvece, &fvec, &evec);
383  vm_vec_normalize_safe(&uvece);
384 
385 
386  vm_vec_scale_add(&p[0], start, &uvecs, width);
387  vm_vec_scale_add(&p[1], end, &uvece, width);
388  vm_vec_scale_add(&p[2], end, &uvece, -width);
389  vm_vec_scale_add(&p[3], start, &uvecs, -width);
390 
391 
392  //move all the data from the vecs into the verts
393  //tri 1
394  g3_transfer_vertex(&P[0], &p[3]);
395  g3_transfer_vertex(&P[1], &p[2]);
396  g3_transfer_vertex(&P[2], &p[1]);
397 
398  //tri 2
399  g3_transfer_vertex(&P[3], &p[3]);
400  g3_transfer_vertex(&P[4], &p[1]);
401  g3_transfer_vertex(&P[5], &p[0]);
402 
403  //set up the UV coords
404  //tri 1
405  P[0].texture_position.u = 0.0f; P[0].texture_position.v = 0.0f;
406  P[1].texture_position.u = 1.0f; P[1].texture_position.v = 0.0f;
407  P[2].texture_position.u = 1.0f; P[2].texture_position.v = 1.0f;
408 
409  //tri 2
410  P[3].texture_position.u = 0.0f; P[3].texture_position.v = 0.0f;
411  P[4].texture_position.u = 1.0f; P[4].texture_position.v = 1.0f;
412  P[5].texture_position.u = 0.0f; P[5].texture_position.v = 1.0f;
413 
414  ubyte _color = (ubyte)(255.0f * intensity);
415 
416  for(int i = 0; i < 6; i++){
417  P[i].r = P[i].g = P[i].b = P[i].a = _color;
418  if(offset > 0.0f) {
419  R[i] = offset;
420  } else {
421  R[i] = width;
422  }
423  }
424 
425  n_to_render += 2;
426  use_radius = true;
427 }
428 
429 float geometry_batcher::draw_laser(vec3d *p0, float width1, vec3d *p1, float width2, int r, int g, int b)
430 {
431  width1 *= 0.5f;
432  width2 *= 0.5f;
433 
434  vec3d uvec, fvec, rvec, center, reye;
435 
436  vm_vec_sub( &fvec, p0, p1 );
437  vm_vec_normalize_safe( &fvec );
438 
439  vm_vec_avg( &center, p0, p1 ); // needed for the return value only
440  vm_vec_sub(&reye, &Eye_position, &center);
441  vm_vec_normalize(&reye);
442 
443  // compute the up vector
444  vm_vec_cross(&uvec, &fvec, &reye);
445  vm_vec_normalize_safe(&uvec);
446  // ... the forward vector
447  vm_vec_cross(&fvec, &uvec, &reye);
448  vm_vec_normalize_safe(&fvec);
449  // now recompute right vector, in case it wasn't entirely perpendiclar
450  vm_vec_cross(&rvec, &uvec, &fvec);
451 
452  // Now have uvec, which is up vector and rvec which is the normal
453  // of the face.
454 
455  vec3d start, end;
456 
457  vm_vec_scale_add(&start, p0, &fvec, -width1);
458  vm_vec_scale_add(&end, p1, &fvec, width2);
459 
460  vec3d vecs[4];
461 
462  vertex *pts = &vert[n_to_render * 3];
463 
464  vm_vec_scale_add( &vecs[0], &end, &uvec, width2 );
465  vm_vec_scale_add( &vecs[1], &start, &uvec, width1 );
466  vm_vec_scale_add( &vecs[2], &start, &uvec, -width1 );
467  vm_vec_scale_add( &vecs[3], &end, &uvec, -width2 );
468 
469  g3_transfer_vertex( &pts[0], &vecs[0] );
470  g3_transfer_vertex( &pts[1], &vecs[1] );
471  g3_transfer_vertex( &pts[2], &vecs[2] );
472 
473  g3_transfer_vertex( &pts[3], &vecs[0] );
474  g3_transfer_vertex( &pts[4], &vecs[2] );
475  g3_transfer_vertex( &pts[5], &vecs[3] );
476 
477  pts[0].texture_position.u = 1.0f;
478  pts[0].texture_position.v = 0.0f;
479  pts[1].texture_position.u = 0.0f;
480  pts[1].texture_position.v = 0.0f;
481  pts[2].texture_position.u = 0.0f;
482  pts[2].texture_position.v = 1.0f;
483 
484  pts[3].texture_position.u = 1.0f;
485  pts[3].texture_position.v = 0.0f;
486  pts[4].texture_position.u = 0.0f;
487  pts[4].texture_position.v = 1.0f;
488  pts[5].texture_position.u = 1.0f;
489  pts[5].texture_position.v = 1.0f;
490 
491  pts[0].r = (ubyte)r;
492  pts[0].g = (ubyte)g;
493  pts[0].b = (ubyte)b;
494  pts[0].a = 255;
495  pts[1].r = (ubyte)r;
496  pts[1].g = (ubyte)g;
497  pts[1].b = (ubyte)b;
498  pts[1].a = 255;
499  pts[2].r = (ubyte)r;
500  pts[2].g = (ubyte)g;
501  pts[2].b = (ubyte)b;
502  pts[2].a = 255;
503  pts[3].r = (ubyte)r;
504  pts[3].g = (ubyte)g;
505  pts[3].b = (ubyte)b;
506  pts[3].a = 255;
507  pts[4].r = (ubyte)r;
508  pts[4].g = (ubyte)g;
509  pts[4].b = (ubyte)b;
510  pts[4].a = 255;
511  pts[5].r = (ubyte)r;
512  pts[5].g = (ubyte)g;
513  pts[5].b = (ubyte)b;
514  pts[5].a = 255;
515 
516 
517  n_to_render += 2;
518  use_radius = false;
519 
520  return center.xyz.z;
521 }
522 
523 void geometry_batcher::render(int flags, float radius)
524 {
525  if (n_to_render) {
526  if ( Use_Shaders_for_effect_rendering && (flags & TMAP_FLAG_SOFT_QUAD || flags & TMAP_FLAG_DISTORTION || flags & TMAP_FLAG_DISTORTION_THRUSTER) && use_radius ) {
527  gr_render_effect(n_to_render * 3, vert, radius_list, flags | TMAP_FLAG_TRILIST);
528  } else {
529  gr_render(n_to_render * 3, vert, flags | TMAP_FLAG_TRILIST);
530  }
531 
532  use_radius = true;
533  n_to_render = 0;
534  }
535 }
536 
538 {
539  int verts_to_render = n_to_render * 3;
540  int i;
541 
542  buffer_offset = *n_verts;
543 
544  for ( i = 0; i < verts_to_render; ++i) {
545  buffer[buffer_offset+i].position = vert[i].world;
546  buffer[buffer_offset+i].tex_coord = vert[i].texture_position;
547 
548  if ( use_radius && radius_list != NULL ) {
549  buffer[buffer_offset+i].radius = radius_list[i];
550  } else {
551  buffer[buffer_offset+i].radius = 0.0f;
552  }
553 
554  buffer[buffer_offset+i].r = vert[i].r;
555  buffer[buffer_offset+i].g = vert[i].g;
556  buffer[buffer_offset+i].b = vert[i].b;
557  buffer[buffer_offset+i].a = vert[i].a;
558  }
559 
560  *n_verts = *n_verts + verts_to_render;
561 }
562 
563 void geometry_batcher::render_buffer(int buffer_handle, int flags)
564 {
565  if ( buffer_offset < 0 ) {
566  return;
567  }
568 
569  if ( !n_to_render ) {
570  return;
571  }
572 
573  if ( buffer_handle < 0 ) {
574  return;
575  }
576 
577  gr_render_stream_buffer(buffer_handle, buffer_offset, n_to_render * 3, flags | TMAP_FLAG_TRILIST);
578 
579  use_radius = true;
580  n_to_render = 0;
581  buffer_offset = -1;
582 }
583 
584 void geometry_shader_batcher::render_buffer(int buffer_handle, int flags)
585 {
586  if ( buffer_offset < 0 ) {
587  return;
588  }
589 
590  if ( !vertices.size() ) {
591  return;
592  }
593 
594  if ( buffer_handle < 0 ) {
595  return;
596  }
597 
598  gr_render_stream_buffer(buffer_handle, buffer_offset, vertices.size(), flags | TMAP_FLAG_POINTLIST);
599 
600  vertices.clear();
601  buffer_offset = -1;
602 }
603 
605 {
606  int verts_to_render = vertices.size();
607  int i;
608 
609  buffer_offset = *n_verts;
610 
611  for ( i = 0; i < verts_to_render; ++i) {
612  buffer[buffer_offset+i] = vertices[i];
613  }
614 
615  *n_verts = *n_verts + verts_to_render;
616 }
617 
618 void geometry_shader_batcher::draw_bitmap(vertex *position, int orient, float rad, float depth)
619 {
620  rad *= 1.41421356f;//1/0.707, becase these are the points of a square or width and height rad
621 
622  vec3d PNT(position->world);
623  vec3d fvec;
624 
625  // get the direction from the point to the eye
626  vm_vec_sub(&fvec, &View_position, &PNT);
627  vm_vec_normalize_safe(&fvec);
628 
629  // move the center of the sprite based on the depth parameter
630  if ( depth != 0.0f )
631  vm_vec_scale_add(&PNT, &PNT, &fvec, depth);
632 
633  particle_pnt new_particle;
634  vec3d up = {{{0.0f, 1.0f, 0.0f}}};
635 
636  new_particle.position = position->world;
637  new_particle.size = rad;
638 
639  int direction = orient % 4;
640 
641  if ( direction == 1 ) {
642  up.xyz.x = 0.0f;
643  up.xyz.y = -1.0f;
644  up.xyz.z = 0.0f;
645  } else if ( direction == 2 ) {
646  up.xyz.x = -1.0f;
647  up.xyz.y = 0.0f;
648  up.xyz.z = 0.0f;
649  } else if ( direction == 3 ) {
650  up.xyz.x = 1.0f;
651  up.xyz.y = 0.0f;
652  up.xyz.z = 0.0f;
653  }
654 
655  new_particle.up = up;
656 
657  vertices.push_back(new_particle);
658 }
659 
663 struct batch_item {
665 
667 
668  int texture;
670  float alpha;
671 
672  bool laser;
673 };
674 
677 
679 
680  int texture;
682  float alpha;
683 
684  bool laser;
685 };
686 
687 static SCP_map<int, g_sdr_batch_item> geometry_shader_map;
688 static SCP_map<int, batch_item> geometry_map;
689 static SCP_map<int, batch_item> distortion_map;
690 
691 // Used for sending verts to the vertex buffer
692 void *Batch_buffer = NULL;
693 size_t Batch_buffer_size = 0;
694 
697 
698 float batch_add_laser(int texture, vec3d *p0, float width1, vec3d *p1, float width2, int r, int g, int b)
699 {
700  if (texture < 0) {
701  Int3();
702  return 1;
703  }
704 
705  batch_item *item = NULL;
706  SCP_map<int, batch_item>::iterator it = geometry_map.find(texture);
707 
708  if ( !geometry_map.empty() && it != geometry_map.end() ) {
709  item = &it->second;
710  } else {
711  item = &geometry_map[texture];
712  item->texture = texture;
713  }
714 
715  item->laser = true;
716 
717  item->batch.add_allocate(1);
718 
719  float num = item->batch.draw_laser(p0, width1, p1, width2, r, g, b);
720 
721  return num;
722 }
723 
724 int batch_add_bitmap(int texture, int tmap_flags, vertex *pnt, int orient, float rad, float alpha, float depth)
725 {
726  if (texture < 0) {
727  Int3();
728  return 1;
729  }
730 
731  if ( tmap_flags & TMAP_FLAG_SOFT_QUAD && ( !Cmdline_softparticles || GLSL_version <= 120 ) ) {
732  // don't render this as a soft particle if we don't support soft particles
733  tmap_flags &= ~(TMAP_FLAG_SOFT_QUAD);
734  }
735 
737  geometry_batch_add_bitmap(texture, tmap_flags, pnt, orient, rad, alpha, depth);
738  return 0;
739  } else if ( tmap_flags & TMAP_FLAG_VERTEX_GEN ) {
740  tmap_flags &= ~(TMAP_FLAG_VERTEX_GEN);
741  }
742 
743  batch_item *item = NULL;
744 
745  SCP_map<int, batch_item>::iterator it = geometry_map.find(texture);
746 
747  if ( !geometry_map.empty() && it != geometry_map.end() ) {
748  item = &it->second;
749  } else {
750  item = &geometry_map[texture];
751  item->texture = texture;
752  }
753 
754  Assertion( (item->laser == false), "Particle effect %s used as laser glow or laser bitmap\n", bm_get_filename(texture) );
755 
756  item->tmap_flags = tmap_flags;
757  item->alpha = alpha;
758 
759  item->batch.add_allocate(1);
760 
761  item->batch.draw_bitmap(pnt, orient, rad, depth);
762 
763  return 0;
764 }
765 
766 int geometry_batch_add_bitmap(int texture, int tmap_flags, vertex *pnt, int orient, float rad, float alpha, float depth)
767 {
768  if (texture < 0) {
769  Int3();
770  return 1;
771  }
772 
773  g_sdr_batch_item *item = NULL;
774  SCP_map<int, g_sdr_batch_item>::iterator it = geometry_shader_map.find(texture);
775 
776  if ( !geometry_shader_map.empty() && it != geometry_shader_map.end() ) {
777  item = &it->second;
778  } else {
779  item = &geometry_shader_map[texture];
780  item->texture = texture;
781  }
782 
783  Assertion( (item->laser == false), "Particle effect %s used as laser glow or laser bitmap\n", bm_get_filename(texture) );
784 
785  item->tmap_flags = tmap_flags;
786  item->alpha = alpha;
787 
788  item->batch.draw_bitmap(pnt, orient, rad, depth);
789 
790  return 0;
791 }
792 
793 int batch_add_bitmap_rotated(int texture, int tmap_flags, vertex *pnt, float angle, float rad, float alpha, float depth)
794 {
795  if (texture < 0) {
796  Int3();
797  return 1;
798  }
799 
800  if ( tmap_flags & TMAP_FLAG_SOFT_QUAD && ( !Cmdline_softparticles || GLSL_version <= 120 ) ) {
801  // don't render this as a soft particle if we don't support soft particles
802  tmap_flags &= ~(TMAP_FLAG_SOFT_QUAD);
803  }
804 
805  batch_item *item = NULL;
806 
807  SCP_map<int, batch_item>::iterator it = geometry_map.find(texture);
808 
809  if ( !geometry_map.empty() && it != geometry_map.end() ) {
810  item = &it->second;
811  } else {
812  item = &geometry_map[texture];
813  item->texture = texture;
814  }
815 
816  Assertion( (item->laser == false), "Particle effect %s used as laser glow or laser bitmap\n", bm_get_filename(texture) );
817 
818  item->tmap_flags = tmap_flags;
819  item->alpha = alpha;
820 
821  item->batch.add_allocate(1);
822 
823  item->batch.draw_bitmap(pnt, rad, angle, depth);
824 
825  return 0;
826 }
827 
828 int batch_add_tri(int texture, int tmap_flags, vertex *verts, float alpha)
829 {
830  if (texture < 0) {
831  Int3();
832  return 1;
833  }
834 
835  batch_item *item = NULL;
836 
837  SCP_map<int, batch_item>::iterator it = geometry_map.find(texture);
838 
839  if ( !geometry_map.empty() && it != geometry_map.end() ) {
840  item = &it->second;
841  } else {
842  item = &geometry_map[texture];
843  item->texture = texture;
844  }
845 
846  Assertion( (item->laser == false), "Particle effect %s used as laser glow or laser bitmap\n", bm_get_filename(texture) );
847 
848  item->tmap_flags = tmap_flags;
849  item->alpha = alpha;
850 
851  item->batch.add_allocate(0, 1); // just allocating for one triangle
852 
853  item->batch.draw_tri(verts);
854 
855  return 0;
856 }
857 
858 int batch_add_quad(int texture, int tmap_flags, vertex *verts, float alpha)
859 {
860  if (texture < 0) {
861  Int3();
862  return 1;
863  }
864 
865  batch_item *item = NULL;
866 
867  SCP_map<int, batch_item>::iterator it = geometry_map.find(texture);
868 
869  if ( !geometry_map.empty() && it != geometry_map.end() ) {
870  item = &it->second;
871  } else {
872  item = &geometry_map[texture];
873  item->texture = texture;
874  }
875 
876  Assertion( (item->laser == false), "Particle effect %s used as laser glow or laser bitmap\n", bm_get_filename(texture) );
877 
878  item->tmap_flags = tmap_flags;
879  item->alpha = alpha;
880 
881  item->batch.add_allocate(1);
882 
883  item->batch.draw_quad(verts);
884 
885  return 0;
886 }
887 
888 int batch_add_polygon(int texture, int tmap_flags, vec3d *pos, matrix *orient, float width, float height, float alpha)
889 {
890  //idiot-proof
891  if(width == 0 || height == 0)
892  return 0;
893 
894  Assert(pos != NULL);
895  Assert(orient != NULL);
896 
897  //Let's begin.
898 
899  const int NUM_VERTICES = 4;
900  vec3d p[NUM_VERTICES] = { ZERO_VECTOR };
901  vertex v[NUM_VERTICES] = { vertex() };
902 
903  p[0].xyz.x = width;
904  p[0].xyz.y = height;
905 
906  p[1].xyz.x = -width;
907  p[1].xyz.y = height;
908 
909  p[2].xyz.x = -width;
910  p[2].xyz.y = -height;
911 
912  p[3].xyz.x = width;
913  p[3].xyz.y = -height;
914 
915  for(int i = 0; i < NUM_VERTICES; i++)
916  {
917  vec3d tmp = vmd_zero_vector;
918 
919  //Rotate correctly
920  vm_vec_unrotate(&tmp, &p[i], orient);
921  //Move to point in space
922  vm_vec_add2(&tmp, pos);
923 
924  //Convert to vertex
925  g3_transfer_vertex(&v[i], &tmp);
926  }
927 
928  v[0].texture_position.u = 1.0f;
929  v[0].texture_position.v = 0.0f;
930 
931  v[1].texture_position.u = 0.0f;
932  v[1].texture_position.v = 0.0f;
933 
934  v[2].texture_position.u = 0.0f;
935  v[2].texture_position.v = 1.0f;
936 
937  v[3].texture_position.u = 1.0f;
938  v[3].texture_position.v = 1.0f;
939 
940  if (texture < 0) {
941  Int3();
942  return 1;
943  }
944 
945  batch_item *item = NULL;
946 
947  SCP_map<int, batch_item>::iterator it = geometry_map.find(texture);
948 
949  if ( !geometry_map.empty() && it != geometry_map.end() ) {
950  item = &it->second;
951  } else {
952  item = &geometry_map[texture];
953  item->texture = texture;
954  }
955 
956  Assertion( (item->laser == false), "Particle effect %s used as laser glow or laser bitmap\n", bm_get_filename(texture) );
957 
958  item->tmap_flags = tmap_flags;
959  item->alpha = alpha;
960 
961  item->batch.add_allocate(1);
962 
963  item->batch.draw_quad(v);
964 
965  return 0;
966 }
967 
968 int batch_add_beam(int texture, int tmap_flags, vec3d *start, vec3d *end, float width, float intensity)
969 {
970  if (texture < 0) {
971  Int3();
972  return 1;
973  }
974 
975  batch_item *item = NULL;
976 
977  SCP_map<int, batch_item>::iterator it = geometry_map.find(texture);
978 
979  if ( !geometry_map.empty() && it != geometry_map.end() ) {
980  item = &it->second;
981  } else {
982  item = &geometry_map[texture];
983  item->texture = texture;
984  }
985 
986  Assertion( (item->laser == false), "Particle effect %s used as laser glow or laser bitmap\n", bm_get_filename(texture) );
987 
988  item->tmap_flags = tmap_flags;
989  item->alpha = intensity;
990 
991  item->batch.add_allocate(1);
992 
993  item->batch.draw_beam(start, end, width, intensity);
994 
995  return 0;
996 }
997 
998 void batch_render_lasers(int buffer_handle)
999 {
1000  for (SCP_map<int, batch_item>::iterator bi = geometry_map.begin(); bi != geometry_map.end(); ++bi) {
1001 
1002  if ( !bi->second.laser )
1003  continue;
1004 
1005  if ( !bi->second.batch.need_to_render() )
1006  continue;
1007 
1008  Assert( bi->second.texture >= 0 );
1009  gr_set_bitmap(bi->second.texture, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 0.99999f);
1010  if ( buffer_handle >= 0 ) {
1011  bi->second.batch.render_buffer(buffer_handle, TMAP_FLAG_TEXTURED | TMAP_FLAG_XPARENT | TMAP_HTL_3D_UNLIT | TMAP_FLAG_RGB | TMAP_FLAG_GOURAUD | TMAP_FLAG_CORRECT);
1012  } else {
1014  }
1015  }
1016 }
1017 
1019 {
1020  for (SCP_map<int, batch_item>::iterator bi = geometry_map.begin(); bi != geometry_map.end(); ++bi) {
1021 
1022  if ( !bi->second.laser )
1023  continue;
1024 
1025  if ( !bi->second.batch.need_to_render() )
1026  continue;
1027 
1028  Assert( bi->second.texture >= 0 );
1029  bi->second.batch.load_buffer(buffer, n_verts);
1030  }
1031 }
1032 
1033 void batch_render_geometry_map_bitmaps(int buffer_handle)
1034 {
1035  for (SCP_map<int, batch_item>::iterator bi = geometry_map.begin(); bi != geometry_map.end(); ++bi) {
1036 
1037  if ( bi->second.laser )
1038  continue;
1039 
1040  if ( !bi->second.batch.need_to_render() )
1041  continue;
1042 
1043  Assert( bi->second.texture >= 0 );
1044  gr_set_bitmap(bi->second.texture, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, bi->second.alpha);
1045  if ( buffer_handle >= 0 ) {
1046  bi->second.batch.render_buffer(buffer_handle, bi->second.tmap_flags);
1047  } else {
1048  bi->second.batch.render( bi->second.tmap_flags);
1049  }
1050  }
1051 }
1052 
1054 {
1055  for (SCP_map<int, g_sdr_batch_item>::iterator bi = geometry_shader_map.begin(); bi != geometry_shader_map.end(); ++bi) {
1056 
1057  if ( bi->second.laser )
1058  continue;
1059 
1060  if ( !bi->second.batch.need_to_render() )
1061  continue;
1062 
1063  Assert( bi->second.texture >= 0 );
1064  gr_set_bitmap(bi->second.texture, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, bi->second.alpha);
1065  bi->second.batch.render_buffer(buffer_handle, bi->second.tmap_flags);
1066  }
1067 }
1068 
1070 {
1071  for (SCP_map<int, batch_item>::iterator bi = geometry_map.begin(); bi != geometry_map.end(); ++bi) {
1072 
1073  if ( bi->second.laser )
1074  continue;
1075 
1076  if ( !bi->second.batch.need_to_render() )
1077  continue;
1078 
1079  Assert( bi->second.texture >= 0 );
1080  bi->second.batch.load_buffer(buffer, n_verts);
1081  }
1082 }
1083 
1085 {
1086  for (SCP_map<int, g_sdr_batch_item>::iterator bi = geometry_shader_map.begin(); bi != geometry_shader_map.end(); ++bi) {
1087 
1088  if ( bi->second.laser )
1089  continue;
1090 
1091  if ( !bi->second.batch.need_to_render() )
1092  continue;
1093 
1094  Assert( bi->second.texture >= 0 );
1095  bi->second.batch.load_buffer(buffer, n_verts);
1096  }
1097 }
1098 
1099 void geometry_batch_render(int stream_buffer)
1100 {
1101  if ( stream_buffer < 0 ) {
1102  return;
1103  }
1104 
1105  int n_to_render = geometry_batch_get_size();
1106  int n_verts = 0;
1107 
1108  if ( Batch_geometry_buffer_size < (n_to_render * sizeof(particle_pnt)) ) {
1109  if ( Batch_geometry_buffer != NULL ) {
1110  vm_free(Batch_geometry_buffer);
1111  }
1112 
1113  Batch_geometry_buffer_size = n_to_render * sizeof(particle_pnt);
1114  Batch_geometry_buffer = vm_malloc(Batch_geometry_buffer_size);
1115  }
1116 
1117  batch_load_buffer_geometry_shader_map_bitmaps((particle_pnt*)Batch_geometry_buffer, &n_verts);
1118 
1119  gr_update_buffer_object(stream_buffer, Batch_geometry_buffer_size, Batch_geometry_buffer);
1120 
1122 }
1123 
1124 void batch_render_all(int stream_buffer)
1125 {
1126  if ( stream_buffer >= 0 ) {
1127  // need to get vertex size
1128  int n_to_render = batch_get_size();
1129  int n_verts = 0;
1130 
1131  if ( ( Batch_buffer_size < (n_to_render * sizeof(effect_vertex)) ) ) {
1132  if ( Batch_buffer != NULL ) {
1133  vm_free(Batch_buffer);
1134  }
1135 
1136  Batch_buffer_size = n_to_render * sizeof(effect_vertex);
1137  Batch_buffer = vm_malloc(Batch_buffer_size);
1138  }
1139 
1140  batch_load_buffer_lasers((effect_vertex*)Batch_buffer, &n_verts);
1141  batch_load_buffer_geometry_map_bitmaps((effect_vertex*)Batch_buffer, &n_verts);
1142  batch_load_buffer_distortion_map_bitmaps((effect_vertex*)Batch_buffer, &n_verts);
1143  gr_update_buffer_object(stream_buffer, Batch_buffer_size, Batch_buffer);
1144 
1145  Assert(n_verts <= n_to_render);
1146 
1147  batch_render_lasers(stream_buffer);
1148  batch_render_geometry_map_bitmaps(stream_buffer);
1149  //batch_render_distortion_map_bitmaps(true);
1150  } else {
1153  //batch_render_distortion_map_bitmaps();
1154  }
1155 
1156  gr_clear_states();
1157 }
1158 
1160 {
1161  geometry_map.clear();
1162  distortion_map.clear();
1163 }
1164 
1166 {
1167  if ( Batch_buffer != NULL ) {
1168  vm_free(Batch_buffer);
1169  Batch_buffer = NULL;
1170  }
1171 
1172  Batch_buffer_size = 0;
1173 }
1174 
1175 int distortion_add_bitmap_rotated(int texture, int tmap_flags, vertex *pnt, float angle, float rad, float alpha, float depth)
1176 {
1177  if (texture < 0) {
1178  Int3();
1179  return 1;
1180  }
1181 
1183  // don't render distortions if we can't support them.
1184  return 0;
1185  }
1186 
1187  batch_item *item = NULL;
1188 
1189  SCP_map<int, batch_item>::iterator it = distortion_map.find(texture);
1190 
1191  if ( !distortion_map.empty() && it != distortion_map.end() ) {
1192  item = &it->second;
1193  } else {
1194  item = &distortion_map[texture];
1195  item->texture = texture;
1196  }
1197 
1198  Assertion( (item->laser == false), "Distortion particle effect %s used as laser glow or laser bitmap\n", bm_get_filename(texture) );
1199 
1200  item->tmap_flags = tmap_flags;
1201  item->alpha = alpha;
1202 
1203  item->batch.add_allocate(1);
1204 
1205  item->batch.draw_bitmap(pnt, rad, angle, depth);
1206 
1207  return 0;
1208 }
1209 
1210 int distortion_add_beam(int texture, int tmap_flags, vec3d *start, vec3d *end, float width, float intensity, float offset)
1211 {
1212  if (texture < 0) {
1213  Int3();
1214  return 1;
1215  }
1216 
1218  // don't render distortions if we can't support them.
1219  return 0;
1220  }
1221 
1222  batch_item *item = NULL;
1223 
1224  SCP_map<int, batch_item>::iterator it = distortion_map.find(texture);
1225 
1226  if ( !distortion_map.empty() && it != distortion_map.end() ) {
1227  item = &it->second;
1228  } else {
1229  item = &distortion_map[texture];
1230  item->texture = texture;
1231  }
1232 
1233  Assertion( (item->laser == false), "Distortion particle effect %s used as laser glow or laser bitmap\n", bm_get_filename(texture) );
1234 
1235  item->tmap_flags = tmap_flags;
1236  item->alpha = intensity;
1237 
1238  item->batch.add_allocate(1);
1239 
1240  item->batch.draw_beam(start,end,width,intensity,offset);
1241 
1242  return 0;
1243 }
1244 
1246 {
1247  for (SCP_map<int,batch_item>::iterator bi = distortion_map.begin(); bi != distortion_map.end(); ++bi) {
1248 
1249  if ( bi->second.laser )
1250  continue;
1251 
1252  if ( !bi->second.batch.need_to_render() )
1253  continue;
1254 
1255  Assert( bi->second.texture >= 0 );
1256  gr_set_bitmap(bi->second.texture, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, bi->second.alpha);
1257 
1258  if ( buffer_handle >= 0 ) {
1259  bi->second.batch.render_buffer(buffer_handle, bi->second.tmap_flags);
1260  } else {
1261  bi->second.batch.render( bi->second.tmap_flags);
1262  }
1263  }
1264 }
1265 
1267 {
1268  for (SCP_map<int, batch_item>::iterator bi = distortion_map.begin(); bi != distortion_map.end(); ++bi) {
1269 
1270  if ( bi->second.laser )
1271  continue;
1272 
1273  if ( !bi->second.batch.need_to_render() )
1274  continue;
1275 
1276  Assert( bi->second.texture >= 0 );
1277  bi->second.batch.load_buffer(buffer, n_verts);
1278  }
1279 }
1280 
1282 {
1283  int n_to_render = 0;
1285 
1286  for (bi = geometry_map.begin(); bi != geometry_map.end(); ++bi) {
1287  n_to_render += bi->second.batch.need_to_render();
1288  }
1289 
1290  for (bi = distortion_map.begin(); bi != distortion_map.end(); ++bi) {
1291  if ( bi->second.laser )
1292  continue;
1293 
1294  n_to_render += bi->second.batch.need_to_render();
1295  }
1296 
1297  return n_to_render * 3;
1298 }
1299 
1301 {
1302  int n_to_render = 0;
1304 
1305  for (bi = geometry_shader_map.begin(); bi != geometry_shader_map.end(); ++bi) {
1306  n_to_render += bi->second.batch.need_to_render();
1307  }
1308 
1309  return n_to_render;
1310 }
#define OGL_EXT_GEOMETRY_SHADER4
#define TMAP_FLAG_POINTLIST
Definition: tmapper.h:89
int i
Definition: multi_pxo.cpp:466
#define vm_free(ptr)
Definition: pstypes.h:548
int batch_add_quad(int texture, int tmap_flags, vertex *verts, float alpha)
Definition: grbatch.cpp:858
#define OGL_EXT_FRAMEBUFFER_OBJECT
#define TMAP_FLAG_XPARENT
Definition: tmapper.h:44
#define Verify(x)
Definition: pstypes.h:272
struct vertex vertex
void batch_reset()
Definition: grbatch.cpp:1159
#define TMAP_FLAG_SOFT_QUAD
Definition: tmapper.h:79
vec3d View_position
Definition: 3dsetup.cpp:20
void vm_vec_scale_add(vec3d *dest, const vec3d *src1, const vec3d *src2, float k)
Definition: vecmat.cpp:266
bool laser
Definition: grbatch.cpp:672
int batch_add_beam(int texture, int tmap_flags, vec3d *start, vec3d *end, float width, float intensity)
Definition: grbatch.cpp:968
float v
Definition: pstypes.h:135
void batch_render_close()
Definition: grbatch.cpp:1165
ubyte g
Definition: pstypes.h:175
ubyte g3_transfer_vertex(vertex *dest, const vec3d *src)
Definition: 3dmath.cpp:84
geometry_batcher batch
Definition: grbatch.cpp:666
Assert(pm!=NULL)
Definition: pstypes.h:88
GLint GLint GLsizei GLsizei GLsizei depth
Definition: Glext.h:5180
void render_buffer(int buffer_handle, int flags)
Definition: grbatch.cpp:563
int Cmdline_softparticles
Definition: cmdline.cpp:334
hull_check p0
Definition: lua.cpp:5051
geometry_shader_batcher batch
Definition: grbatch.cpp:676
#define gr_render
Definition: 2d.h:805
struct vec3d::@225::@227 xyz
#define TMAP_HTL_3D_UNLIT
Definition: tmapper.h:63
GLclampf f
Definition: Glext.h:7097
#define gr_update_buffer_object
Definition: 2d.h:882
GLenum GLuint texture
Definition: Glext.h:5872
#define Assertion(expr, msg,...)
Definition: clang.h:41
float alpha
Definition: grbatch.cpp:670
#define TMAP_FLAG_VERTEX_GEN
Definition: tmapper.h:92
void draw_bitmap(vertex *position, int orient, float rad, float depth=0)
Definition: grbatch.cpp:618
float batch_add_laser(int texture, vec3d *p0, float width1, vec3d *p1, float width2, int r, int g, int b)
Definition: grbatch.cpp:698
hull_check orient
Definition: lua.cpp:5049
int batch_add_bitmap_rotated(int texture, int tmap_flags, vertex *pnt, float angle, float rad, float alpha, float depth)
Definition: grbatch.cpp:793
void gr_set_bitmap(int bitmap_num, int alphablend_mode, int bitblt_mode, float alpha)
Definition: 2d.cpp:2105
#define Int3()
Definition: pstypes.h:292
int geometry_batch_get_size()
Definition: grbatch.cpp:1300
#define TMAP_FLAG_DISTORTION
Definition: tmapper.h:85
GLint GLsizei width
Definition: Gl.h:1505
int distortion_add_bitmap_rotated(int texture, int tmap_flags, vertex *pnt, float angle, float rad, float alpha, float depth)
Definition: grbatch.cpp:1175
GLfloat angle
Definition: Glext.h:10324
void batch_render_lasers(int buffer_handle)
Definition: grbatch.cpp:998
uv_pair texture_position
Definition: pstypes.h:174
ubyte a
Definition: pstypes.h:175
GLintptr offset
Definition: Glext.h:5497
void batch_render_all(int stream_buffer)
Definition: grbatch.cpp:1124
void vm_vec_add2(vec3d *dest, const vec3d *src)
Definition: vecmat.cpp:178
void * Batch_buffer
Definition: grbatch.cpp:692
#define GR_ALPHABLEND_FILTER
Definition: 2d.h:349
const float PI2
Definition: pstypes.h:305
void batch_render_geometry_shader_map_bitmaps(int buffer_handle)
Definition: grbatch.cpp:1053
GLdouble GLdouble GLdouble r
Definition: Glext.h:5337
struct matrix::@228::@230 vec
GLboolean GLboolean g
Definition: Glext.h:5781
#define TMAP_FLAG_GOURAUD
Definition: tmapper.h:40
void draw_quad(vertex *verts)
Definition: grbatch.cpp:345
vec3d position
Definition: pstypes.h:183
int batch_get_size()
Definition: grbatch.cpp:1281
void load_buffer(particle_pnt *buffer, int *n_verts)
Definition: grbatch.cpp:604
void vm_rot_point_around_line(vec3d *out, const vec3d *in, float angle, const vec3d *line_point, const vec3d *line_dir)
Definition: vecmat.cpp:1395
const char * bm_get_filename(int handle)
Gets the filename of the bitmap indexed by handle, which must exist.
Definition: bmpman.cpp:727
hull_check p1
Definition: lua.cpp:5052
void add_allocate(int quad, int n_tri=0)
Definition: grbatch.cpp:83
GLuint buffer
Definition: Glext.h:5492
float u
Definition: pstypes.h:135
void batch_load_buffer_distortion_map_bitmaps(effect_vertex *buffer, int *n_verts)
Definition: grbatch.cpp:1266
float vm_vec_normalize_safe(vec3d *v)
Definition: vecmat.cpp:471
float size
Definition: pstypes.h:191
vec3d * vm_vec_unrotate(vec3d *dest, const vec3d *src, const matrix *m)
Definition: vecmat.cpp:959
#define Is_Extension_Enabled(x)
unsigned char ubyte
Definition: pstypes.h:62
int GLSL_version
Definition: gropengl.cpp:58
#define ZERO_VECTOR
Definition: vecmat.h:60
#define TMAP_FLAG_RGB
Definition: tmapper.h:39
GLuint start
Definition: Gl.h:1502
ubyte b
Definition: pstypes.h:175
#define TMAP_FLAG_CORRECT
Definition: tmapper.h:37
GLbitfield flags
Definition: Glext.h:6722
#define vm_malloc(size)
Definition: pstypes.h:547
void allocate(int quad, int n_tri=0)
Definition: grbatch.cpp:66
vec3d up
Definition: pstypes.h:192
vec3d position
Definition: pstypes.h:190
void vm_vec_sub(vec3d *dest, const vec3d *src0, const vec3d *src1)
Definition: vecmat.cpp:168
vec3d Eye_position
Definition: 3dsetup.cpp:27
GLboolean GLboolean GLboolean b
Definition: Glext.h:5781
float radius
Definition: pstypes.h:185
#define TMAP_FLAG_TRILIST
Definition: tmapper.h:68
GLuint GLuint num
Definition: Glext.h:9089
GLint GLsizei GLsizei height
Definition: Gl.h:1505
void render_buffer(int buffer_handle, int flags)
Definition: grbatch.cpp:584
int texture
Definition: grbatch.cpp:668
float Physics_viewer_bank
Definition: physics.cpp:128
void draw_tri(vertex *verts)
Definition: grbatch.cpp:334
void batch_load_buffer_geometry_shader_map_bitmaps(particle_pnt *buffer, int *n_verts)
Definition: grbatch.cpp:1084
int batch_add_bitmap(int texture, int tmap_flags, vertex *pnt, int orient, float rad, float alpha, float depth)
Definition: grbatch.cpp:724
void batch_load_buffer_lasers(effect_vertex *buffer, int *n_verts)
Definition: grbatch.cpp:1018
void * Batch_geometry_buffer
Definition: grbatch.cpp:695
#define gr_clear_states
Definition: 2d.h:946
GLfloat GLfloat p
Definition: Glext.h:8373
size_t Batch_buffer_size
Definition: grbatch.cpp:693
void batch_load_buffer_geometry_map_bitmaps(effect_vertex *buffer, int *n_verts)
Definition: grbatch.cpp:1069
vec3d * vm_vec_avg(vec3d *dest, const vec3d *src0, const vec3d *src1)
Definition: vecmat.cpp:217
float draw_laser(vec3d *p0, float width1, vec3d *p1, float width2, int r, int g, int b)
Definition: grbatch.cpp:429
#define TMAP_FLAG_TEXTURED
Definition: tmapper.h:36
void batch_render_geometry_map_bitmaps(int buffer_handle)
Definition: grbatch.cpp:1033
void load_buffer(effect_vertex *buffer, int *n_verts)
Definition: grbatch.cpp:537
void draw_beam(vec3d *start, vec3d *end, float width, float intensity=1.0f, float offset=0.0f)
Definition: grbatch.cpp:362
hull_check pos
Definition: lua.cpp:5050
struct effect_vertex effect_vertex
int batch_add_tri(int texture, int tmap_flags, vertex *verts, float alpha)
Definition: grbatch.cpp:828
int geometry_batch_add_bitmap(int texture, int tmap_flags, vertex *pnt, int orient, float rad, float alpha, float depth)
Definition: grbatch.cpp:766
#define gr_render_stream_buffer
Definition: 2d.h:887
void geometry_batch_render(int stream_buffer)
Definition: grbatch.cpp:1099
#define GR_BITBLT_MODE_NORMAL
Definition: 2d.h:351
matrix View_matrix
Definition: 3dsetup.cpp:19
vec3d world
Definition: pstypes.h:172
void render(int flags, float radius=0.0f)
Definition: grbatch.cpp:523
bool Cmdline_no_geo_sdr_effects
Definition: cmdline.cpp:451
#define gr_render_effect
Definition: 2d.h:806
int batch_add_polygon(int texture, int tmap_flags, vec3d *pos, matrix *orient, float width, float height, float alpha)
Definition: grbatch.cpp:888
void batch_render_distortion_map_bitmaps(int buffer_handle)
Definition: grbatch.cpp:1245
vec3d * vm_vec_cross(vec3d *dest, const vec3d *src0, const vec3d *src1)
Definition: vecmat.cpp:645
#define TMAP_FLAG_DISTORTION_THRUSTER
Definition: tmapper.h:82
#define GR_ALPHABLEND_NONE
Definition: 2d.h:348
false
Definition: lua.cpp:6789
int tmap_flags
Definition: grbatch.cpp:669
int distortion_add_beam(int texture, int tmap_flags, vec3d *start, vec3d *end, float width, float intensity, float offset)
Definition: grbatch.cpp:1210
void draw_bitmap(vertex *position, int orient, float rad, float depth=0)
Definition: grbatch.cpp:157
size_t Batch_geometry_buffer_size
Definition: grbatch.cpp:696
GLclampf GLclampf GLclampf alpha
Definition: Glext.h:5177
const geometry_batcher & operator=(const geometry_batcher &geo)
Definition: grbatch.cpp:142
vec3d vmd_zero_vector
Definition: vecmat.cpp:24
const GLdouble * v
Definition: Glext.h:5322
bool Use_Shaders_for_effect_rendering
GLuint GLuint end
Definition: Gl.h:1502
uv_pair tex_coord
Definition: pstypes.h:184
ubyte r
Definition: pstypes.h:175
float vm_vec_normalize(vec3d *v)
Definition: vecmat.cpp:460