FS2_Open
Open source remastering of the Freespace 2 engine
3ddraw.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) Volition, Inc. 1999. All rights reserved.
3  *
4  * All source code herein is the property of Volition, Inc. You may not sell
5  * or otherwise commercially exploit the source or things you created based on the
6  * source.
7  *
8 */
9 
10 
11 
12 #include "bmpman/bmpman.h"
13 #include "cmdline/cmdline.h"
14 #include "globalincs/alphacolors.h"
15 #include "graphics/grbatch.h"
16 #include "graphics/tmapper.h"
17 #include "io/key.h"
18 #include "physics/physics.h" // For Physics_viewer_bank for g3_draw_rotated_bitmap
19 #include "render/3dinternal.h"
20 
21 
22 //vertex buffers for polygon drawing and clipping
23 static vertex **Vbuf0 = NULL;
24 static vertex **Vbuf1 = NULL;
25 static int Num_vbufs_allocated = 0;
26 
27 
28 static void g3_deallocate_vbufs()
29 {
30  if (Vbuf0 != NULL) {
31  vm_free(Vbuf0);
32  Vbuf0 = NULL;
33  }
34 
35  if (Vbuf1 != NULL) {
36  vm_free(Vbuf1);
37  Vbuf1 = NULL;
38  }
39 }
40 
41 static void g3_allocate_vbufs(int nv)
42 {
43  static ubyte dealloc = 0;
44 
45  Assert( nv >= 0 );
46  Assert( nv || Num_vbufs_allocated );
47 
48  if (!dealloc) {
49  atexit(g3_deallocate_vbufs);
50  dealloc = 1;
51  }
52 
53  if (nv > Num_vbufs_allocated) {
54  g3_deallocate_vbufs();
55 
56  Vbuf0 = (vertex**) vm_malloc( nv * sizeof(vertex) );
57  Vbuf1 = (vertex**) vm_malloc( nv * sizeof(vertex) );
58 
59  Num_vbufs_allocated = nv;
60  }
61 
62  // make sure everything is valid
63  Verify( Vbuf0 != NULL );
64  Verify( Vbuf1 != NULL );
65 }
66 
67 
72 {
73  int ret = 0;
74 
75  clip_line(&p0, &p1, codes_or, flags);
76 
77  if (p0->codes & p1->codes) goto free_points;
78 
79  codes_or = (unsigned char)(p0->codes | p1->codes);
80 
81  if (codes_or & CC_BEHIND) goto free_points;
82 
83  if (!(p0->flags&PF_PROJECTED))
85 
86  if (p0->flags&PF_OVERFLOW) goto free_points;
87 
88  if (!(p1->flags&PF_PROJECTED))
90 
91  if (p1->flags&PF_OVERFLOW) goto free_points;
92 
93  gr_aaline( p0, p1 );
94 
95  ret = 1;
96 
97  //frees temp points
99 
100  if (p0->flags & PF_TEMP_POINT)
101  free_temp_point(p0);
102 
103  if (p1->flags & PF_TEMP_POINT)
104  free_temp_point(p1);
105 
106  return ret;
107 }
108 
113 {
114 #ifdef FRED_OGL_COMMENT_OUT_FOR_NOW
116  {
117  gr_aaline( p0, p1 );
118  return 0;
119  }
120 #endif
121 
122  ubyte codes_or;
123 
124  Assert( G3_count == 1 );
125 
126  if (p0->codes & p1->codes)
127  return 0;
128 
129  codes_or = (unsigned char)(p0->codes | p1->codes);
130 
131  if (codes_or & CC_BEHIND)
132  return must_clip_line(p0,p1,codes_or,0);
133 
134  if (!(p0->flags&PF_PROJECTED))
135  g3_project_vertex(p0);
136 
137  if (p0->flags&PF_OVERFLOW)
138  return must_clip_line(p0,p1,codes_or,0);
139 
140 
141  if (!(p1->flags&PF_PROJECTED))
142  g3_project_vertex(p1);
143 
144  if (p1->flags&PF_OVERFLOW)
145  return must_clip_line(p0,p1,codes_or,0);
146 
147  gr_aaline( p0, p1 );
148 
149  return 0;
150 }
151 
152 
153 //returns true if a plane is facing the viewer. takes the unrotated surface
154 //normal of the plane, and a point on it. The normal need not be normalized
155 int g3_check_normal_facing(const vec3d *v, const vec3d *norm)
156 {
157  vec3d tempv;
158 
159  Assert( G3_count == 1 );
160 
161  vm_vec_sub(&tempv,&View_position,v);
162 
163  return (vm_vec_dot(&tempv,norm) > 0.0f);
164 }
165 
166 int do_facing_check(const vec3d *norm, vertex **vertlist, const vec3d *p)
167 {
168  Assert( G3_count == 1 );
169 
170  if (norm) { //have normal
171 
172  Assert(norm->xyz.x || norm->xyz.y || norm->xyz.z);
173 
174  return g3_check_normal_facing(p,norm);
175  }
176  else { //normal not specified, so must compute
177 
178  vec3d tempv;
179 
180  //get three points (rotated) and compute normal
181 
182  vm_vec_perp(&tempv,&vertlist[0]->world,&vertlist[1]->world,&vertlist[2]->world);
183 
184  return (vm_vec_dot(&tempv,&vertlist[1]->world ) < 0.0);
185  }
186 }
187 
188 //like g3_draw_poly(), but checks to see if facing. If surface normal is
189 //NULL, this routine must compute it, which will be slow. It is better to
190 //pre-compute the normal, and pass it to this function. When the normal
191 //is passed, this function works like g3_check_normal_facing() plus
192 //g3_draw_poly().
193 //returns -1 if not facing, 1 if off screen, 0 if drew
194 int g3_draw_poly_if_facing(int nv, vertex **pointlist, uint tmap_flags, const vec3d *norm, const vec3d *pnt)
195 {
196  Assert( G3_count == 1 );
197 
198  if (do_facing_check(norm,pointlist,pnt))
199  return g3_draw_poly(nv,pointlist,tmap_flags);
200  else
201  return 255;
202 }
203 
204 //draw a polygon.
205 //Set TMAP_FLAG_TEXTURED in the tmap_flags to texture map it with current texture.
206 //returns 1 if off screen, 0 if drew
207 int g3_draw_poly(int nv, vertex **pointlist, uint tmap_flags)
208 {
209  int i;
210  vertex **bufptr;
211  ccodes cc;
212 
213  Assert( G3_count == 1 );
214 
215  if(!Cmdline_nohtl && (tmap_flags & TMAP_HTL_3D_UNLIT)) {
216  gr_tmapper( nv, pointlist, tmap_flags );
217  return 0;
218  }
219  //don't clip in HT&L mode, the card does it for us
220  if(!Cmdline_nohtl && (tmap_flags & TMAP_FLAG_TRISTRIP)) {
221  gr_tmapper( nv, pointlist, tmap_flags );
222  return 0;
223  }
224  if(Cmdline_nohtl && (tmap_flags & TMAP_FLAG_TRISTRIP)){
225  bool starting = true;
226  int offset = 0;
227  for (i=0;i<nv;i++){
228  if (!(pointlist[i]->flags&PF_PROJECTED))g3_project_vertex(pointlist[i]);
229  if (pointlist[i]->flags&PF_OVERFLOW){
230  if(starting)
231  offset++;
232  nv--;
233  }else
234  starting = false;
235  if(nv<3)return 1;
236  }
237  if(nv<3)return 1;
238  pointlist += offset;
239  gr_tmapper( nv, pointlist, tmap_flags );
240  return 0;
241  }
242 
243  g3_allocate_vbufs(nv);
244 
245  cc.cc_or = 0;
246  cc.cc_and = 0xff;
247 
248  bufptr = Vbuf0;
249 
250  for (i=0;i<nv;i++) {
251  vertex *p;
252 
253  p = bufptr[i] = pointlist[i];
254 
255  cc.cc_and &= p->codes;
256  cc.cc_or |= p->codes;
257  }
258 
259  if (cc.cc_and)
260  return 1; //all points off screen
261 
262  if (cc.cc_or) {
263  Assert( G3_count == 1 );
264 
265  bufptr = clip_polygon(Vbuf0,Vbuf1,&nv,&cc,tmap_flags);
266 
267  if (nv && !(cc.cc_or & CC_BEHIND) && !cc.cc_and) {
268 
269  for (i=0;i<nv;i++) {
270  vertex *p = bufptr[i];
271 
272  if (!(p->flags&PF_PROJECTED))
274 
275  if (p->flags&PF_OVERFLOW) {
276  goto free_points;
277  }
278  }
279 
280  gr_tmapper( nv, bufptr, tmap_flags );
281  }
282 
284  ;
285 
286  for (i=0;i<nv;i++)
287  if (bufptr[i]->flags & PF_TEMP_POINT)
288  free_temp_point(bufptr[i]);
289 
290  } else {
291  //now make list of 2d coords (& check for overflow)
292 
293  for (i=0;i<nv;i++) {
294  vertex *p = bufptr[i];
295 
296  if (!(p->flags&PF_PROJECTED))
298 
299  if (p->flags&PF_OVERFLOW) {
300  return 255;
301  }
302 
303  }
304 
305  gr_tmapper( nv, bufptr, tmap_flags );
306  }
307  return 0; //say it drew
308 }
309 
310 int g3_draw_polygon(const vec3d *pos, const matrix *ori, float width, float height, int tmap_flags)
311 {
312  //idiot-proof
313  if(width == 0 || height == 0)
314  return 0;
315 
316  Assert(pos != NULL);
317  Assert(ori != NULL);
318 
319  //Let's begin.
320 
321  const int NUM_VERTICES = 4;
322  vec3d p[NUM_VERTICES] = { ZERO_VECTOR };
323  vertex v[NUM_VERTICES];
324 
325  memset(v, 0, sizeof(v));
326 
327  p[0].xyz.x = width;
328  p[0].xyz.y = height;
329 
330  p[1].xyz.x = -width;
331  p[1].xyz.y = height;
332 
333  p[2].xyz.x = -width;
334  p[2].xyz.y = -height;
335 
336  p[3].xyz.x = width;
337  p[3].xyz.y = -height;
338 
339  for(int i = 0; i < NUM_VERTICES; i++)
340  {
341  vec3d tmp = vmd_zero_vector;
342 
343  //Rotate correctly
344  vm_vec_unrotate(&tmp, &p[i], ori);
345  //Move to point in space
346  vm_vec_add2(&tmp, pos);
347 
348  //Convert to vertex
349  g3_transfer_vertex(&v[i], &tmp);
350  }
351 
352  v[0].texture_position.u = 1.0f;
353  v[0].texture_position.v = 0.0f;
354 
355  v[1].texture_position.u = 0.0f;
356  v[1].texture_position.v = 0.0f;
357 
358  v[2].texture_position.u = 0.0f;
359  v[2].texture_position.v = 1.0f;
360 
361  v[3].texture_position.u = 1.0f;
362  v[3].texture_position.v = 1.0f;
363 
364  gr_render(NUM_VERTICES, v, tmap_flags);
365 
366  return 0;
367 }
368 
369 int g3_draw_polygon(const vec3d *pos, const vec3d *norm, float width, float height, int tmap_flags)
370 {
371  matrix m;
372  vm_vector_2_matrix(&m, norm, NULL, NULL);
373 
374  return g3_draw_polygon(pos, &m, width, height, tmap_flags);
375 }
376 
377 // Draw a polygon. Same as g3_draw_poly, but it bashes sw to a constant value
378 // for all vertexes. Needs to be done after clipping to get them all.
379 //Set TMAP_FLAG_TEXTURED in the tmap_flags to texture map it with current texture.
380 //returns 1 if off screen, 0 if drew
381 int g3_draw_poly_constant_sw(int nv, vertex **pointlist, uint tmap_flags, float constant_sw)
382 {
383  int i;
384  vertex **bufptr;
385  ccodes cc;
386 
387  Assert( G3_count == 1 );
388 
389  if(!Cmdline_nohtl && (tmap_flags & TMAP_HTL_3D_UNLIT)) {
390  gr_tmapper( nv, pointlist, tmap_flags );
391  return 0;
392  }
393  if(tmap_flags & TMAP_FLAG_TRISTRIP || tmap_flags & TMAP_FLAG_TRILIST){
394  for (i=0;i<nv;i++){
395  if (!(pointlist[i]->flags&PF_PROJECTED))g3_project_vertex(pointlist[i]);
396  }
397  gr_tmapper( nv, pointlist, tmap_flags );
398  return 0;
399  }
400 
401  g3_allocate_vbufs(nv);
402 
403  cc.cc_or = 0; cc.cc_and = 0xff;
404 
405  bufptr = Vbuf0;
406 
407  for (i=0;i<nv;i++) {
408  vertex *p;
409 
410  p = bufptr[i] = pointlist[i];
411 
412  cc.cc_and &= p->codes;
413  cc.cc_or |= p->codes;
414  }
415 
416  if (cc.cc_and)
417  return 1; //all points off screen
418 
419 
420  if (cc.cc_or) {
421  Assert( G3_count == 1 );
422 
423  bufptr = clip_polygon(Vbuf0, Vbuf1, &nv, &cc, tmap_flags);
424 
425  if (nv && !(cc.cc_or & CC_BEHIND) && !cc.cc_and) {
426 
427  for (i=0;i<nv;i++) {
428  vertex *p = bufptr[i];
429 
430  if (!(p->flags&PF_PROJECTED))
432 
433  if (p->flags&PF_OVERFLOW) {
434  goto free_points;
435  }
436 
437  p->screen.xyw.w = constant_sw;
438  }
439 
440  gr_tmapper( nv, bufptr, tmap_flags );
441  }
442 
444  ;
445 
446  for (i=0;i<nv;i++){
447  if (bufptr[i]->flags & PF_TEMP_POINT){
448  free_temp_point(bufptr[i]);
449  }
450  }
451  } else {
452  //now make list of 2d coords (& check for overflow)
453 
454  for (i=0;i<nv;i++) {
455  vertex *p = bufptr[i];
456 
457  if (!(p->flags&PF_PROJECTED))
459 
460  if (p->flags&PF_OVERFLOW) {
461  return 255;
462  }
463 
464  p->screen.xyw.w = constant_sw;
465 
466  }
467 
468  gr_tmapper( nv, bufptr, tmap_flags );
469  }
470  return 0; //say it drew
471 }
472 
473 //draw a sortof sphere - i.e., the 2d radius is proportional to the 3d
474 //radius, but not to the distance from the eye
475 int g3_draw_sphere(vertex *pnt, float rad)
476 {
477  Assert( G3_count == 1 );
478 
479  if (! (pnt->codes & CC_BEHIND)) {
480 
481  if (! (pnt->flags & PF_PROJECTED))
482  g3_project_vertex(pnt);
483 
484  if (! (pnt->codes & PF_OVERFLOW)) {
485  float r2,t;
486 
487  r2 = rad*Matrix_scale.xyz.x;
488 
489  t=r2*Canv_w2/pnt->world.xyz.z;
490 
491  gr_circle(fl2i(pnt->screen.xyw.x),fl2i(pnt->screen.xyw.y),fl2i(t*2.0f),GR_RESIZE_NONE);
492  }
493  }
494 
495  return 0;
496 }
497 
498 int g3_draw_sphere_ez(const vec3d *pnt, float rad)
499 {
500  vertex pt;
501  ubyte flags;
502 
503  Assert( G3_count == 1 );
504 
505  flags = g3_rotate_vertex(&pt, pnt);
506 
507  if (flags == 0) {
508 
509  g3_project_vertex(&pt);
510 
511  if (!(pt.flags & PF_OVERFLOW)) {
512 
513  g3_draw_sphere( &pt, rad );
514  }
515  }
516 
517  return 0;
518 }
519 
520 //alternate method
521 int g3_draw_bitmap_3d(vertex *pnt, int orient, float rad, uint tmap_flags, float depth)
522 {
523  rad *= 1.41421356f;//1/0.707, becase these are the points of a square or width and hieght rad
524 
525  vec3d PNT(pnt->world);
526  vec3d p[4];
527  vertex P[4];
528  vec3d fvec, rvec, uvec;
529 
530  vm_vec_sub(&fvec, &View_position, &PNT);
531  vm_vec_normalize(&fvec);
532 
533  uvec = View_matrix.vec.uvec;
534  vm_vec_normalize(&uvec);
535  rvec = View_matrix.vec.rvec;
536  vm_vec_normalize(&rvec);
537 
538  vertex *ptlist[4] = { &P[3], &P[2], &P[1], &P[0] };
539 
540  vm_vec_scale_add(&PNT, &PNT, &fvec, depth);
541  vm_vec_scale_add(&p[0], &PNT, &rvec, rad);
542  vm_vec_scale_add(&p[2], &PNT, &rvec, -rad);
543 
544  vm_vec_scale_add(&p[1], &p[2], &uvec, rad);
545  vm_vec_scale_add(&p[3], &p[0], &uvec, -rad);
546  vm_vec_scale_add(&p[0], &p[0], &uvec, rad);
547  vm_vec_scale_add(&p[2], &p[2], &uvec, -rad);
548 
549  //move all the data from the vecs into the verts
550  g3_transfer_vertex(&P[0], &p[3]);
551  g3_transfer_vertex(&P[1], &p[2]);
552  g3_transfer_vertex(&P[2], &p[1]);
553  g3_transfer_vertex(&P[3], &p[0]);
554 
555  // set up the UV coords
556  if ( orient & 1 ) {
557  P[0].texture_position.u = 1.0f;
558  P[1].texture_position.u = 0.0f;
559  P[2].texture_position.u = 0.0f;
560  P[3].texture_position.u = 1.0f;
561  } else {
562  P[0].texture_position.u = 0.0f;
563  P[1].texture_position.u = 1.0f;
564  P[2].texture_position.u = 1.0f;
565  P[3].texture_position.u = 0.0f;
566  }
567 
568  if ( orient & 2 ) {
569  P[0].texture_position.v = 1.0f;
570  P[1].texture_position.v = 1.0f;
571  P[2].texture_position.v = 0.0f;
572  P[3].texture_position.v = 0.0f;
573  } else {
574  P[0].texture_position.v = 0.0f;
575  P[1].texture_position.v = 0.0f;
576  P[2].texture_position.v = 1.0f;
577  P[3].texture_position.v = 1.0f;
578  }
579 
580  int cull = gr_set_cull(0);
581  g3_draw_poly(4,ptlist,tmap_flags);
582  gr_set_cull(cull);
583 
584  return 0;
585 }
586 
587 int g3_draw_bitmap_3d_v(vertex *pnt, int orient, float rad, uint tmap_flags, float depth, float c)
588 {
589  vec3d PNT(pnt->world);
590  vec3d p[4];
591  vertex P[4];
592  int i;
593 
594  vertex *ptlist[4] = { &P[3], &P[2], &P[1], &P[0] };
595  float aspect = gr_screen.aspect*(float)gr_screen.clip_width/(float)gr_screen.clip_height;//seems that we have to corect for the aspect ratio
596 
597  p[0].xyz.x = rad * aspect; p[0].xyz.y = rad; p[0].xyz.z = -depth;
598  p[1].xyz.x = -rad * aspect; p[1].xyz.y = rad; p[1].xyz.z = -depth;
599  p[2].xyz.x = -rad * aspect; p[2].xyz.y = -rad; p[2].xyz.z = -depth;
600  p[3].xyz.x = rad * aspect; p[3].xyz.y = -rad; p[3].xyz.z = -depth;
601 
602  for(i = 0; i<4; i++){
603  vec3d t = p[i];
604  vm_vec_unrotate(&p[i],&t,&View_matrix);//point it at the eye
605  vm_vec_add2(&p[i],&PNT);//move it
606  }
607 
608  //move all the data from the vecs into the verts
609  g3_transfer_vertex(&P[0], &p[3]);
610  g3_transfer_vertex(&P[1], &p[2]);
611  g3_transfer_vertex(&P[2], &p[1]);
612  g3_transfer_vertex(&P[3], &p[0]);
613 
614  for( i = 0; i<4; i++){
615  P[i].r = (ubyte)(255.0f * c);
616  P[i].g = (ubyte)(255.0f * c);
617  P[i].b = (ubyte)(255.0f * c);
618  }
619 
620  //set up the UV coords
621  P[0].texture_position.u = 0.0f; P[0].texture_position.v = 0.0f;
622  P[1].texture_position.u = 1.0f; P[1].texture_position.v = 0.0f;
623  P[2].texture_position.u = 1.0f; P[2].texture_position.v = 1.0f;
624  P[3].texture_position.u = 0.0f; P[3].texture_position.v = 1.0f;
625 
626  int cull = gr_set_cull(0);
627  g3_draw_poly(4,ptlist,tmap_flags | TMAP_FLAG_RGB | TMAP_FLAG_GOURAUD);
628  gr_set_cull(cull);
629 
630  return 0;
631 }
632 
633 int g3_draw_bitmap_3d_volume(vertex *pnt, int orient, float rad, uint tmap_flags, float depth, int resolution)
634 {
635  float s = 1.0f;
636  float res = float(resolution);
637  for(int i = 0; i <resolution; i++){
638  s = (1.0f - (float(i-1)/res))/6.5f;
639  float d = (float(i)/res);
640  g3_draw_bitmap_3d_v(pnt,orient, rad, tmap_flags, depth * d, s);
641  }
642  return 0;
643 }
644 
645 
646 //draws a bitmap with the specified 3d width & height
647 //returns 1 if off screen, 0 if drew
648 // Orient
649 int g3_draw_bitmap(vertex *pnt, int orient, float rad, uint tmap_flags, float depth)
650 {
651  if ( !Cmdline_nohtl && (tmap_flags & TMAP_HTL_3D_UNLIT) ) {
652  return g3_draw_bitmap_3d(pnt, orient, rad, tmap_flags, depth);
653  }
654 
655  vertex va, vb;
656  float t,w,h;
657  float width, height;
658  bool bw_bitmap = false;
659 
660  if ( tmap_flags & TMAP_FLAG_BW_TEXTURE ) {
661  bw_bitmap = true;
662  }
663 
664  if ( tmap_flags & TMAP_FLAG_TEXTURED ) {
665  int bw, bh;
666 
667  bm_get_info( gr_screen.current_bitmap, &bw, &bh, NULL );
668 
669  if ( bw < bh ) {
670  width = rad*2.0f;
671  height = width*i2fl(bh)/i2fl(bw);
672  } else if ( bw > bh ) {
673  height = rad*2.0f;
674  width = height*i2fl(bw)/i2fl(bh);
675  } else {
676  width = height = rad*2.0f;
677  }
678  } else {
679  width = height = rad*2.0f;
680  }
681 
682  Assert( G3_count == 1 );
683 
684  if ( pnt->codes & (CC_BEHIND|CC_OFF_USER) )
685  return 1;
686 
687  if (!(pnt->flags&PF_PROJECTED))
688  g3_project_vertex(pnt);
689 
690  if (pnt->flags & PF_OVERFLOW)
691  return 1;
692 
693  t = (width*Canv_w2)/pnt->world.xyz.z;
694  w = t*Matrix_scale.xyz.x;
695 
696  t = (height*Canv_h2)/pnt->world.xyz.z;
697  h = t*Matrix_scale.xyz.y;
698 
699  float z,sw;
700  z = pnt->world.xyz.z - rad/2.0f;
701  if ( z <= 0.0f ) {
702  z = 0.0f;
703  sw = 0.0f;
704  } else {
705  sw = 1.0f / z;
706  }
707 
708  va.screen.xyw.x = pnt->screen.xyw.x - w/2.0f;
709  va.screen.xyw.y = pnt->screen.xyw.y - h/2.0f;
710  va.screen.xyw.w = sw;
711  va.world.xyz.z = z;
712 
713  vb.screen.xyw.x = va.screen.xyw.x + w;
714  vb.screen.xyw.y = va.screen.xyw.y + h;
715  vb.screen.xyw.w = sw;
716  vb.world.xyz.z = z;
717 
718  if ( orient & 1 ) {
719  va.texture_position.u = 1.0f;
720  vb.texture_position.u = 0.0f;
721  } else {
722  va.texture_position.u = 0.0f;
723  vb.texture_position.u = 1.0f;
724  }
725 
726  if ( orient & 2 ) {
727  va.texture_position.v = 1.0f;
728  vb.texture_position.v = 0.0f;
729  } else {
730  va.texture_position.v = 0.0f;
731  vb.texture_position.v = 1.0f;
732  }
733 
734  gr_scaler(&va, &vb, bw_bitmap);
735 
736  return 0;
737 }
738 
739 // get bitmap dims onscreen as if g3_draw_bitmap() had been called
740 int g3_get_bitmap_dims(int bitmap, vertex *pnt, float rad, int *x, int *y, int *w, int *h, int *size)
741 {
742  float t;
743  float width, height;
744 
745  int bw, bh;
746 
747  bm_get_info( bitmap, &bw, &bh, NULL );
748 
749  if ( bw < bh ) {
750  width = rad*2.0f;
751  height = width*i2fl(bh)/i2fl(bw);
752  } else if ( bw > bh ) {
753  height = rad*2.0f;
754  width = height*i2fl(bw)/i2fl(bh);
755  } else {
756  width = height = rad*2.0f;
757  }
758 
759  Assert( G3_count == 1 );
760 
761  if ( pnt->codes & (CC_BEHIND|CC_OFF_USER) ) {
762  return 1;
763  }
764 
765  if (!(pnt->flags&PF_PROJECTED)){
766  g3_project_vertex(pnt);
767  }
768 
769  if (pnt->flags & PF_OVERFLOW){
770  return 1;
771  }
772 
773  t = (width*Canv_w2)/pnt->world.xyz.z;
774  *w = (int)(t*Matrix_scale.xyz.x);
775 
776  t = (height*Canv_h2)/pnt->world.xyz.z;
777  *h = (int)(t*Matrix_scale.xyz.y);
778 
779  *x = (int)(pnt->screen.xyw.x - *w/2.0f);
780  *y = (int)(pnt->screen.xyw.y - *h/2.0f);
781 
782  *size = MAX(bw, bh);
783 
784  return 0;
785 }
786 
787 //alternate method
788 int g3_draw_rotated_bitmap_3d(vertex *pnt,float angle, float rad,uint tmap_flags, float depth)
789 {
790  rad *= 1.41421356f;//1/0.707, becase these are the points of a square or width and hieght rad
791 
792  angle-=Physics_viewer_bank;
793  if ( angle < 0.0f )
794  angle += PI2;
795  else if ( angle > PI2 )
796  angle -= PI2;
797 
798  vec3d PNT(pnt->world);
799  vec3d p[4];
800  vertex P[4];
801  vec3d fvec, rvec, uvec;
802 
803  vm_vec_sub(&fvec, &View_position, &PNT);
804  vm_vec_normalize_safe(&fvec);
805 
807  vm_vec_normalize(&uvec);
808 
809  vm_vec_cross(&rvec, &View_matrix.vec.fvec, &uvec);
810  vm_vec_normalize(&rvec);
811 
812  vertex *ptlist[4] = { &P[3], &P[2], &P[1], &P[0] };
813 
814  vm_vec_scale_add(&PNT, &PNT, &fvec, depth);
815  vm_vec_scale_add(&p[0], &PNT, &rvec, rad);
816  vm_vec_scale_add(&p[2], &PNT, &rvec, -rad);
817 
818  vm_vec_scale_add(&p[1], &p[2], &uvec, rad);
819  vm_vec_scale_add(&p[3], &p[0], &uvec, -rad);
820  vm_vec_scale_add(&p[0], &p[0], &uvec, rad);
821  vm_vec_scale_add(&p[2], &p[2], &uvec, -rad);
822 
823  //move all the data from the vecs into the verts
824  g3_transfer_vertex(&P[0], &p[3]);
825  g3_transfer_vertex(&P[1], &p[2]);
826  g3_transfer_vertex(&P[2], &p[1]);
827  g3_transfer_vertex(&P[3], &p[0]);
828 
829  //set up the UV coords
830  P[0].texture_position.u = 0.0f; P[0].texture_position.v = 0.0f;
831  P[1].texture_position.u = 1.0f; P[1].texture_position.v = 0.0f;
832  P[2].texture_position.u = 1.0f; P[2].texture_position.v = 1.0f;
833  P[3].texture_position.u = 0.0f; P[3].texture_position.v = 1.0f;
834 
835  int cull = gr_set_cull(0);
836  g3_draw_poly(4,ptlist,tmap_flags);
837  gr_set_cull(cull);
838 
839  return 0;
840 }
841 
842 //draws a bitmap with the specified 3d width & height
843 //returns 1 if off screen, 0 if drew
844 int g3_draw_rotated_bitmap(vertex *pnt,float angle, float rad,uint tmap_flags, float depth)
845 {
846  if(!Cmdline_nohtl && (tmap_flags & TMAP_HTL_3D_UNLIT)) {
847  return g3_draw_rotated_bitmap_3d(pnt, angle, rad, tmap_flags, depth);
848  }
849  vertex v[4];
850  vertex *vertlist[4] = { &v[3], &v[2], &v[1], &v[0] };
851  float sa, ca;
852  int i;
853 
854  memset(v,0,sizeof(vertex)*4);
855 
856  Assert( G3_count == 1 );
857 
858  angle+=Physics_viewer_bank;
859  if ( angle < 0.0f )
860  angle += PI2;
861  else if ( angle > PI2 )
862  angle -= PI2;
863 
864  sa = sinf(angle);
865  ca = cosf(angle);
866 
867  float width, height;
868 
869  if ( tmap_flags & TMAP_FLAG_TEXTURED ) {
870  int bw, bh;
871 
872  bm_get_info( gr_screen.current_bitmap, &bw, &bh, NULL );
873 
874  if ( bw < bh ) {
875  width = rad;
876  height = width*i2fl(bh)/i2fl(bw);
877  } else if ( bw > bh ) {
878  height = rad;
879  width = height*i2fl(bw)/i2fl(bh);
880  } else {
881  width = height = rad;
882  }
883  } else {
884  width = height = rad;
885  }
886 
887  v[0].world.xyz.x = (-width*ca + height*sa)*Matrix_scale.xyz.x + pnt->world.xyz.x;
888  v[0].world.xyz.y = (-width*sa - height*ca)*Matrix_scale.xyz.y + pnt->world.xyz.y;
889  v[0].world.xyz.z = pnt->world.xyz.z;
890  v[0].screen.xyw.w = 0.0f;
891  v[0].texture_position.u = 0.0f;
892  v[0].texture_position.v = 1.0f;
893 
894  v[1].world.xyz.x = (width*ca + height*sa)*Matrix_scale.xyz.x + pnt->world.xyz.x;
895  v[1].world.xyz.y = (width*sa - height*ca)*Matrix_scale.xyz.y + pnt->world.xyz.y;
896  v[1].world.xyz.z = pnt->world.xyz.z;
897  v[1].screen.xyw.w = 0.0f;
898  v[1].texture_position.u = 1.0f;
899  v[1].texture_position.v = 1.0f;
900 
901  v[2].world.xyz.x = (width*ca - height*sa)*Matrix_scale.xyz.x + pnt->world.xyz.x;
902  v[2].world.xyz.y = (width*sa + height*ca)*Matrix_scale.xyz.y + pnt->world.xyz.y;
903  v[2].world.xyz.z = pnt->world.xyz.z;
904  v[2].screen.xyw.w = 0.0f;
905  v[2].texture_position.u = 1.0f;
906  v[2].texture_position.v = 0.0f;
907 
908  v[3].world.xyz.x = (-width*ca - height*sa)*Matrix_scale.xyz.x + pnt->world.xyz.x;
909  v[3].world.xyz.y = (-width*sa + height*ca)*Matrix_scale.xyz.y + pnt->world.xyz.y;
910  v[3].world.xyz.z = pnt->world.xyz.z;
911  v[3].screen.xyw.w = 0.0f;
912  v[3].texture_position.u = 0.0f;
913  v[3].texture_position.v = 0.0f;
914 
915  ubyte codes_and=0xff;
916 
917  float sw,z;
918  z = pnt->world.xyz.z - rad / 4.0f;
919  if ( z < 0.0f ) z = 0.0f;
920  sw = 1.0f / z;
921 
922  for (i=0; i<4; i++ ) {
923  //now code the four points
924  codes_and &= g3_code_vertex(&v[i]);
925  v[i].flags = 0; // mark as not yet projected
926  }
927 
928  if (codes_and)
929  return 1; //1 means off screen
930 
931  // clip and draw it
932  g3_draw_poly_constant_sw(4, vertlist, tmap_flags, sw );
933 
934  return 0;
935 }
936 
938 #define TRIANGLE_AREA(_p, _q, _r) do {\
939  vec3d a, b, cross;\
940  \
941  a.xyz.x = _q->world.xyz.x - _p->world.xyz.x;\
942  a.xyz.y = _q->world.xyz.y - _p->world.xyz.y;\
943  a.xyz.z = 0.0f;\
944  \
945  b.xyz.x = _r->world.xyz.x - _p->world.xyz.x;\
946  b.xyz.y = _r->world.xyz.y - _p->world.xyz.y;\
947  b.xyz.z = 0.0f;\
948  \
949  vm_vec_cross(&cross, &a, &b);\
950  total_area += vm_vec_mag(&cross) * 0.5f;\
951 } while(0);
952 
953 float g3_get_poly_area(int nv, vertex **pointlist)
954 {
955  int idx;
956  float total_area = 0.0f;
957 
958  // each triangle
959  for(idx=1; idx<nv-1; idx++){
960  TRIANGLE_AREA(pointlist[0], pointlist[idx], pointlist[idx+1]);
961  }
962 
963  // done
964  return total_area;
965 }
966 
967 // Draw a polygon. Same as g3_draw_poly, but it bashes sw to a constant value
968 // for all vertexes. Needs to be done after clipping to get them all.
969 //Set TMAP_FLAG_TEXTURED in the tmap_flags to texture map it with current texture.
970 //returns 1 if off screen, 0 if drew
971 float g3_draw_poly_constant_sw_area(int nv, vertex **pointlist, uint tmap_flags, float constant_sw, float area)
972 {
973  int i;
974  vertex **bufptr;
975  ccodes cc;
976  float p_area = 0.0f;
977 
978  Assert( G3_count == 1 );
979 
980  g3_allocate_vbufs(nv);
981 
982  cc.cc_or = 0;
983  cc.cc_and = 0xff;
984 
985  bufptr = Vbuf0;
986 
987  for (i=0;i<nv;i++) {
988  vertex *p;
989 
990  p = bufptr[i] = pointlist[i];
991 
992  cc.cc_and &= p->codes;
993  cc.cc_or |= p->codes;
994  }
995 
996  if (cc.cc_and){
997  return 0.0f; //all points off screen
998  }
999 
1000  if (cc.cc_or) {
1001  Assert( G3_count == 1 );
1002 
1003  bufptr = clip_polygon(Vbuf0, Vbuf1, &nv, &cc, tmap_flags);
1004 
1005  if (nv && !(cc.cc_or & CC_BEHIND) && !cc.cc_and) {
1006 
1007  for (i=0;i<nv;i++) {
1008  vertex *p = bufptr[i];
1009 
1010  if (!(p->flags&PF_PROJECTED))
1011  g3_project_vertex(p);
1012 
1013  if (p->flags&PF_OVERFLOW) {
1014  goto free_points;
1015  }
1016 
1017  p->screen.xyw.w = constant_sw;
1018  }
1019 
1020  // check area
1021  p_area = g3_get_poly_area(nv, bufptr);
1022  if(p_area > area){
1023  return 0.0f;
1024  }
1025 
1026  gr_tmapper( nv, bufptr, tmap_flags );
1027  }
1028 
1029 free_points:
1030  ;
1031 
1032  for (i=0;i<nv;i++){
1033  if (bufptr[i]->flags & PF_TEMP_POINT){
1034  free_temp_point(bufptr[i]);
1035  }
1036  }
1037  } else {
1038  //now make list of 2d coords (& check for overflow)
1039 
1040  for (i=0;i<nv;i++) {
1041  vertex *p = bufptr[i];
1042 
1043  if (!(p->flags&PF_PROJECTED))
1044  g3_project_vertex(p);
1045 
1046  if (p->flags&PF_OVERFLOW) {
1047  return 0.0f;
1048  }
1049 
1050  p->screen.xyw.w = constant_sw;
1051  }
1052 
1053  // check area
1054  p_area = g3_get_poly_area(nv, bufptr);
1055  if(p_area > area){
1056  return 0.0f;
1057  }
1058 
1059  gr_tmapper( nv, bufptr, tmap_flags );
1060  }
1061 
1062  // how much area we drew
1063  return p_area;
1064 }
1065 
1066 
1067 //draws a bitmap with the specified 3d width & height
1068 //returns 1 if off screen, 0 if drew
1069 float g3_draw_rotated_bitmap_area(vertex *pnt,float angle, float rad,uint tmap_flags, float area)
1070 {
1071  vertex v[4];
1072  vertex *vertlist[4] = { &v[3], &v[2], &v[1], &v[0] };
1073  float sa, ca;
1074  int i;
1075 
1076  memset(v,0,sizeof(vertex)*4);
1077 
1078  Assert( G3_count == 1 );
1079 
1080  angle+=Physics_viewer_bank;
1081  if ( angle < 0.0f ){
1082  angle += PI2;
1083  } else if ( angle > PI2 ) {
1084  angle -= PI2;
1085  }
1086 
1087  sa = sinf(angle);
1088  ca = cosf(angle);
1089 
1090  float width, height;
1091 
1092  if ( tmap_flags & TMAP_FLAG_TEXTURED ) {
1093  int bw, bh;
1094 
1095  bm_get_info( gr_screen.current_bitmap, &bw, &bh, NULL );
1096 
1097  if ( bw < bh ) {
1098  width = rad;
1099  height = width*i2fl(bh)/i2fl(bw);
1100  } else if ( bw > bh ) {
1101  height = rad;
1102  width = height*i2fl(bw)/i2fl(bh);
1103  } else {
1104  width = height = rad;
1105  }
1106  } else {
1107  width = height = rad;
1108  }
1109 
1110  v[0].world.xyz.x = (-width*ca + height*sa)*Matrix_scale.xyz.x + pnt->world.xyz.x;
1111  v[0].world.xyz.y = (-width*sa - height*ca)*Matrix_scale.xyz.y + pnt->world.xyz.y;
1112  v[0].world.xyz.z = pnt->world.xyz.z;
1113  v[0].screen.xyw.w = 0.0f;
1114  v[0].texture_position.u = 0.0f;
1115  v[0].texture_position.v = 1.0f;
1116 
1117  v[1].world.xyz.x = (width*ca + height*sa)*Matrix_scale.xyz.x + pnt->world.xyz.x;
1118  v[1].world.xyz.y = (width*sa - height*ca)*Matrix_scale.xyz.y + pnt->world.xyz.y;
1119  v[1].world.xyz.z = pnt->world.xyz.z;
1120  v[1].screen.xyw.w = 0.0f;
1121  v[1].texture_position.u = 1.0f;
1122  v[1].texture_position.v = 1.0f;
1123 
1124  v[2].world.xyz.x = (width*ca - height*sa)*Matrix_scale.xyz.x + pnt->world.xyz.x;
1125  v[2].world.xyz.y = (width*sa + height*ca)*Matrix_scale.xyz.y + pnt->world.xyz.y;
1126  v[2].world.xyz.z = pnt->world.xyz.z;
1127  v[2].screen.xyw.w = 0.0f;
1128  v[2].texture_position.u = 1.0f;
1129  v[2].texture_position.v = 0.0f;
1130 
1131  v[3].world.xyz.x = (-width*ca - height*sa)*Matrix_scale.xyz.x + pnt->world.xyz.x;
1132  v[3].world.xyz.y = (-width*sa + height*ca)*Matrix_scale.xyz.y + pnt->world.xyz.y;
1133  v[3].world.xyz.z = pnt->world.xyz.z;
1134  v[3].screen.xyw.w = 0.0f;
1135  v[3].texture_position.u = 0.0f;
1136  v[3].texture_position.v = 0.0f;
1137 
1138  ubyte codes_and=0xff;
1139 
1140  float sw,z;
1141  z = pnt->world.xyz.z - rad / 4.0f;
1142  if ( z < 0.0f ) z = 0.0f;
1143  sw = 1.0f / z;
1144 
1145  for (i=0; i<4; i++ ) {
1146  //now code the four points
1147  codes_and &= g3_code_vertex(&v[i]);
1148  v[i].flags = 0; // mark as not yet projected
1149  }
1150 
1151  if (codes_and){
1152  return 0.0f;
1153  }
1154 
1155  // clip and draw it
1156  return g3_draw_poly_constant_sw_area(4, vertlist, tmap_flags, sw, area );
1157 }
1158 
1159 
1160 
1161 #include "graphics/2d.h"
1162 typedef struct horz_pt {
1163  float x, y;
1164  int edge;
1165 } horz_pt;
1166 
1167 //draws a horizon. takes eax=sky_color, edx=ground_color
1169 {
1170  int s1, s2;
1171  int cpnt;
1172  horz_pt horz_pts[4]; // 0 = left, 1 = right
1173  vec3d horizon_vec;
1174  float up_right, down_right,down_left,up_left;
1175 
1176  Assert( G3_count == 1 );
1177 
1178  //compute horizon_vector
1179  horizon_vec.xyz.x = Unscaled_matrix.vec.rvec.xyz.y*Matrix_scale.xyz.y*Matrix_scale.xyz.z;
1180  horizon_vec.xyz.y = Unscaled_matrix.vec.uvec.xyz.y*Matrix_scale.xyz.x*Matrix_scale.xyz.z;
1181  horizon_vec.xyz.z = Unscaled_matrix.vec.fvec.xyz.y*Matrix_scale.xyz.x*Matrix_scale.xyz.y;
1182 
1183  // now compute values & flag for 4 corners.
1184  up_right = horizon_vec.xyz.x + horizon_vec.xyz.y + horizon_vec.xyz.z;
1185  down_right = horizon_vec.xyz.x - horizon_vec.xyz.y + horizon_vec.xyz.z;
1186  down_left = -horizon_vec.xyz.x - horizon_vec.xyz.y + horizon_vec.xyz.z;
1187  up_left = -horizon_vec.xyz.x + horizon_vec.xyz.y + horizon_vec.xyz.z;
1188 
1189  //check flags for all sky or all ground.
1190  if ( (up_right<0.0f)&&(down_right<0.0f)&&(down_left<0.0f)&&(up_left<0.0f) ) {
1191  return;
1192  }
1193 
1194  if ( (up_right>0.0f)&&(down_right>0.0f)&&(down_left>0.0f)&&(up_left>0.0f) ) {
1195  return;
1196  }
1197 
1198  // check for intesection with each of four edges & compute horizon line
1199  cpnt = 0;
1200 
1201  // check intersection with left edge
1202  s1 = up_left > 0.0f;
1203  s2 = down_left > 0.0f;
1204  if ( s1 != s2 ) {
1205  horz_pts[cpnt].x = 0.0f;
1206  horz_pts[cpnt].y = fl_abs(up_left * Canv_h2 / horizon_vec.xyz.y);
1207  horz_pts[cpnt].edge = 0;
1208  cpnt++;
1209  }
1210 
1211  // check intersection with top edge
1212  s1 = up_left > 0.0f;
1213  s2 = up_right > 0.0f;
1214  if ( s1 != s2 ) {
1215  horz_pts[cpnt].x = fl_abs(up_left * Canv_w2 / horizon_vec.xyz.x);
1216  horz_pts[cpnt].y = 0.0f;
1217  horz_pts[cpnt].edge = 1;
1218  cpnt++;
1219  }
1220 
1221  // check intersection with right edge
1222  s1 = up_right > 0.0f;
1223  s2 = down_right > 0.0f;
1224  if ( s1 != s2 ) {
1225  horz_pts[cpnt].x = i2fl(Canvas_width)-1;
1226  horz_pts[cpnt].y = fl_abs(up_right * Canv_h2 / horizon_vec.xyz.y);
1227  horz_pts[cpnt].edge = 2;
1228  cpnt++;
1229  }
1230 
1231  //check intersection with bottom edge
1232  s1 = down_right > 0.0f;
1233  s2 = down_left > 0.0f;
1234  if ( s1 != s2 ) {
1235  horz_pts[cpnt].x = fl_abs(down_left * Canv_w2 / horizon_vec.xyz.x);
1236  horz_pts[cpnt].y = i2fl(Canvas_height)-1;
1237  horz_pts[cpnt].edge = 3;
1238  cpnt++;
1239  }
1240 
1241  if ( cpnt != 2 ) {
1242  mprintf(( "HORZ: Wrong number of points (%d)\n", cpnt ));
1243  return;
1244  }
1245 
1246  //make sure first edge is left
1247  if ( horz_pts[0].x > horz_pts[1].x ) {
1248  horz_pt tmp;
1249  tmp = horz_pts[0];
1250  horz_pts[0] = horz_pts[1];
1251  horz_pts[1] = tmp;
1252  }
1253 
1254  // draw from left to right.
1255  gr_line( fl2i(horz_pts[0].x),fl2i(horz_pts[0].y),fl2i(horz_pts[1].x),fl2i(horz_pts[1].y), GR_RESIZE_NONE );
1256 
1257 }
1258 
1259 // Draws a polygon always facing the viewer.
1260 // compute the corners of a rod. fills in vertbuf.
1261 // Verts has any needs uv's or l's or can be NULL if none needed.
1262 int g3_draw_rod(const vec3d *p0, float width1, const vec3d *p1, float width2, vertex *verts, uint tmap_flags)
1263 {
1264  vec3d uvec, fvec, rvec, center;
1265 
1266  vm_vec_sub( &fvec, p0, p1 );
1267  vm_vec_normalize_safe( &fvec );
1268 
1269  vm_vec_avg( &center, p0, p1 );
1270  vm_vec_sub( &rvec, &Eye_position, &center );
1271  vm_vec_normalize( &rvec );
1272 
1273  vm_vec_cross(&uvec,&fvec,&rvec);
1274 
1275  //normalize new perpendicular vector
1276  vm_vec_normalize(&uvec);
1277 
1278  //now recompute right vector, in case it wasn't entirely perpendiclar
1279  vm_vec_cross(&rvec,&uvec,&fvec);
1280 
1281  // Now have uvec, which is up vector and rvec which is the normal
1282  // of the face.
1283 
1284  int i;
1285  vec3d vecs[4];
1286  vertex pts[4];
1287  vertex *ptlist[4] = { &pts[3], &pts[2], &pts[1], &pts[0] };
1288 
1289  vm_vec_scale_add( &vecs[0], p0, &uvec, width1/2.0f );
1290  vm_vec_scale_add( &vecs[1], p1, &uvec, width2/2.0f );
1291  vm_vec_scale_add( &vecs[2], p1, &uvec, -width2/2.0f );
1292  vm_vec_scale_add( &vecs[3], p0, &uvec, -width1/2.0f );
1293 
1294  for (i=0; i<4; i++ ) {
1295  if ( verts ) {
1296  pts[i] = verts[i];
1297  }
1298  if(Cmdline_nohtl)
1299  g3_rotate_vertex( &pts[i], &vecs[i] );
1300  else
1301  g3_transfer_vertex( &pts[i], &vecs[i] );
1302  }
1303  ptlist[0]->texture_position.u = 0.0f;
1304  ptlist[0]->texture_position.v = 0.0f;
1305  ptlist[0]->r = gr_screen.current_color.red;
1306  ptlist[0]->g = gr_screen.current_color.green;
1307  ptlist[0]->b = gr_screen.current_color.blue;
1308  ptlist[0]->a = gr_screen.current_color.alpha;
1309 
1310  ptlist[1]->texture_position.u = 1.0f;
1311  ptlist[1]->texture_position.v = 0.0f;
1312  ptlist[1]->r = gr_screen.current_color.red;
1313  ptlist[1]->g = gr_screen.current_color.green;
1314  ptlist[1]->b = gr_screen.current_color.blue;
1315  ptlist[1]->a = gr_screen.current_color.alpha;
1316 
1317  ptlist[2]->texture_position.u = 1.0f;
1318  ptlist[2]->texture_position.v = 1.0f;
1319  ptlist[2]->r = gr_screen.current_color.red;
1320  ptlist[2]->g = gr_screen.current_color.green;
1321  ptlist[2]->b = gr_screen.current_color.blue;
1322  ptlist[2]->a = gr_screen.current_color.alpha;
1323 
1324  ptlist[3]->texture_position.u = 0.0f;
1325  ptlist[3]->texture_position.v = 1.0f;
1326  ptlist[3]->r = gr_screen.current_color.red;
1327  ptlist[3]->g = gr_screen.current_color.green;
1328  ptlist[3]->b = gr_screen.current_color.blue;
1329  ptlist[3]->a = gr_screen.current_color.alpha;
1330 
1331  return g3_draw_poly(4,ptlist,tmap_flags);
1332 }
1333 
1334 #define MAX_ROD_VECS 100
1335 int g3_draw_rod(int num_points, const vec3d *pvecs, float width, uint tmap_flags)
1336 {
1337  vec3d uvec, fvec, rvec;
1338  vec3d vecs[2];
1339  vertex pts[MAX_ROD_VECS];
1340  vertex *ptlist[MAX_ROD_VECS];
1341  int i, nv = 0;
1342 
1343  Assert( num_points >= 2 );
1344  Assert( (num_points * 2) <= MAX_ROD_VECS );
1345 
1346  for (i = 0; i < num_points; i++) {
1347  vm_vec_sub(&fvec, &View_position, &pvecs[i]);
1348  vm_vec_normalize_safe(&fvec);
1349 
1350  int first = i+1;
1351  int second = i-1;
1352 
1353  if (i == 0) {
1354  first = 1;
1355  second = 0;
1356  } else if (i == num_points-1) {
1357  first = i;
1358  }
1359 
1360  vm_vec_sub(&rvec, &pvecs[first], &pvecs[second]);
1361  vm_vec_normalize_safe(&rvec);
1362 
1363  vm_vec_cross(&uvec, &rvec, &fvec);
1364 
1365  vm_vec_scale_add(&vecs[0], &pvecs[i], &uvec, width * 0.5f);
1366  vm_vec_scale_add(&vecs[1], &pvecs[i], &uvec, -width * 0.5f);
1367 
1368  if (nv > MAX_ROD_VECS-2) {
1369  Warning(LOCATION, "Hit high-water mark (%i) in g3_draw_rod()!!\n", MAX_ROD_VECS);
1370  break;
1371  }
1372 
1373  ptlist[nv] = &pts[nv];
1374  ptlist[nv+1] = &pts[nv+1];
1375 
1376  if (Cmdline_nohtl) {
1377  g3_rotate_vertex( &pts[nv], &vecs[0] );
1378  g3_rotate_vertex( &pts[nv+1], &vecs[1] );
1379  } else {
1380  g3_transfer_vertex( &pts[nv], &vecs[0] );
1381  g3_transfer_vertex( &pts[nv+1], &vecs[1] );
1382  }
1383 
1384  ptlist[nv]->texture_position.u = 1.0f;
1385  ptlist[nv]->texture_position.v = i2fl(i);
1386  ptlist[nv]->r = gr_screen.current_color.red;
1387  ptlist[nv]->g = gr_screen.current_color.green;
1388  ptlist[nv]->b = gr_screen.current_color.blue;
1389  ptlist[nv]->a = gr_screen.current_color.alpha;
1390 
1391  ptlist[nv+1]->texture_position.u = 0.0f;
1392  ptlist[nv+1]->texture_position.v = i2fl(i);
1393  ptlist[nv+1]->r = gr_screen.current_color.red;
1394  ptlist[nv+1]->g = gr_screen.current_color.green;
1395  ptlist[nv+1]->b = gr_screen.current_color.blue;
1396  ptlist[nv+1]->a = gr_screen.current_color.alpha;
1397 
1398  nv += 2;
1399  }
1400 
1401  // we should always have at least 4 verts, and there should always be an even number
1402  Assert( (nv >= 4) && !(nv % 2) );
1403 
1404  int rc = g3_draw_poly(nv, ptlist, tmap_flags);
1405 
1406  return rc;
1407 }
1408 
1409 // draw a perspective bitmap based on angles and radius
1411  { { { -1.0f, -1.0f, 20.0f } } },
1412  { { { -1.0f, 1.0f, 20.0f } } },
1413  { { { 1.0f, 1.0f, 20.0f } } },
1414  { { { 1.0f, -1.0f, 20.0f } } }
1415 };
1416 
1417 #define MAX_PERSPECTIVE_DIVISIONS 5 // should never even come close to this limit
1418 
1419 void stars_project_2d_onto_sphere( vec3d *pnt, float rho, float phi, float theta )
1420 {
1421  float a = PI * phi;
1422  float b = PI2 * theta;
1423  float sin_a = sinf(a);
1424 
1425  // coords
1426  pnt->xyz.z = rho * sin_a * cosf(b);
1427  pnt->xyz.y = rho * sin_a * sinf(b);
1428  pnt->xyz.x = rho * cosf(a);
1429 }
1430 
1431 // draw a perspective bitmap based on angles and radius
1432 float p_phi = 10.0f;
1433 float p_theta = 10.0f;
1434 int g3_draw_perspective_bitmap(const angles *a, float scale_x, float scale_y, int div_x, int div_y, uint tmap_flags)
1435 {
1438  vertex v[4];
1439  vertex *verts[4];
1440  matrix m, m_bank;
1441  int idx, s_idx;
1442  int saved_zbuffer_mode;
1443  float ui, vi;
1444  angles bank_first;
1445 
1446  // cap division values
1447  // div_x = div_x > MAX_PERSPECTIVE_DIVISIONS ? MAX_PERSPECTIVE_DIVISIONS : div_x;
1448  div_x = 1;
1449  div_y = div_y > MAX_PERSPECTIVE_DIVISIONS ? MAX_PERSPECTIVE_DIVISIONS : div_y;
1450 
1451  // texture increment values
1452  ui = 1.0f / (float)div_x;
1453  vi = 1.0f / (float)div_y;
1454 
1455  // adjust for aspect ratio
1456  scale_x *= ((float)gr_screen.max_w / (float)gr_screen.max_h) + 0.55f; // fudge factor
1457 
1458  float s_phi = 0.5f + (((p_phi * scale_x) / 360.0f) / 2.0f);
1459  float s_theta = (((p_theta * scale_y) / 360.0f) / 2.0f);
1460  float d_phi = -(((p_phi * scale_x) / 360.0f) / (float)(div_x));
1461  float d_theta = -(((p_theta * scale_y) / 360.0f) / (float)(div_y));
1462 
1463  // bank matrix
1464  bank_first.p = 0.0f;
1465  bank_first.b = a->b;
1466  bank_first.h = 0.0f;
1467  vm_angles_2_matrix(&m_bank, &bank_first);
1468 
1469  // convert angles to matrix
1470  angles a_temp = *a;
1471  a_temp.b = 0.0f;
1472  vm_angles_2_matrix(&m, &a_temp);
1473 
1474  // generate the bitmap points
1475  for(idx=0; idx<=div_x; idx++){
1476  for(s_idx=0; s_idx<=div_y; s_idx++){
1477  // get world spherical coords
1478  stars_project_2d_onto_sphere(&s_points[idx][s_idx], 1000.0f, s_phi + ((float)idx*d_phi), s_theta + ((float)s_idx*d_theta));
1479 
1480  // bank the bitmap first
1481  vm_vec_rotate(&t_points[idx][s_idx], &s_points[idx][s_idx], &m_bank);
1482 
1483  // rotate on the sphere
1484  vm_vec_rotate(&s_points[idx][s_idx], &t_points[idx][s_idx], &m);
1485  }
1486  }
1487 
1488  // turn off zbuffering
1489  saved_zbuffer_mode = gr_zbuffer_get();
1491 
1492  // turn off culling
1493  int cull = gr_set_cull(0);
1494 
1495  // render all polys
1496  for(idx=0; idx<div_x; idx++){
1497  for(s_idx=0; s_idx<div_y; s_idx++){
1498  // stuff texture coords
1499  v[0].texture_position.u = ui * float(idx);
1500  v[0].texture_position.v = vi * float(s_idx);
1501  v[0].spec_r=v[0].spec_g=v[0].spec_b=0;
1502 
1503  v[1].texture_position.u = ui * float(idx+1);
1504  v[1].texture_position.v = vi * float(s_idx);
1505  v[1].spec_r=v[1].spec_g=v[1].spec_b=0;
1506 
1507  v[2].texture_position.u = ui * float(idx+1);
1508  v[2].texture_position.v = vi * float(s_idx+1);
1509  v[2].spec_r=v[2].spec_g=v[2].spec_b=0;
1510 
1511  v[3].texture_position.u = ui * float(idx);
1512  v[3].texture_position.v = vi * float(s_idx+1);
1513  v[3].spec_r=v[3].spec_g=v[3].spec_b=0;
1514 
1515  // poly 1
1516  v[0].flags = 0;
1517  v[1].flags = 0;
1518  v[2].flags = 0;
1519  verts[0] = &v[0];
1520  verts[1] = &v[1];
1521  verts[2] = &v[2];
1522  g3_rotate_faraway_vertex(verts[0], &s_points[idx][s_idx]);
1523  g3_rotate_faraway_vertex(verts[1], &s_points[idx+1][s_idx]);
1524  g3_rotate_faraway_vertex(verts[2], &s_points[idx+1][s_idx+1]);
1525  g3_draw_poly(3, verts, tmap_flags);
1526 
1527  // poly 2
1528  v[0].flags = 0;
1529  v[2].flags = 0;
1530  v[3].flags = 0;
1531  verts[0] = &v[0];
1532  verts[1] = &v[2];
1533  verts[2] = &v[3];
1534  g3_rotate_faraway_vertex(verts[0], &s_points[idx][s_idx]);
1535  g3_rotate_faraway_vertex(verts[1], &s_points[idx+1][s_idx+1]);
1536  g3_rotate_faraway_vertex(verts[2], &s_points[idx][s_idx+1]);
1537  g3_draw_poly(3, verts, tmap_flags);
1538  }
1539  }
1540 
1541  // turn on culling
1542  gr_set_cull(cull);
1543 
1544  // restore zbuffer
1545  gr_zbuffer_set(saved_zbuffer_mode);
1546 
1547  // return
1548  return 1;
1549 }
1550 
1551 void g3_draw_2d_shield_icon(const coord2d coords[6], const int r, const int g, const int b, const int a)
1552 {
1553  int saved_zbuf;
1554  vertex v[6];
1555  vertex *verts[6] = {&v[0], &v[1], &v[2], &v[3], &v[4], &v[5]};
1556 
1557  memset(v,0,sizeof(vertex)*6);
1558  saved_zbuf = gr_zbuffer_get();
1559 
1560  // start the frame, no zbuffering, no culling
1561  if (!Fred_running)
1562  g3_start_frame(1);
1563 
1565  int cull = gr_set_cull(0);
1566 
1567  // stuff coords
1568  v[0].screen.xyw.x = i2fl(coords[0].x);
1569  v[0].screen.xyw.y = i2fl(coords[0].y);
1570  v[0].screen.xyw.w = 0.0f;
1571  v[0].texture_position.u = 0.0f;
1572  v[0].texture_position.v = 0.0f;
1573  v[0].flags = PF_PROJECTED;
1574  v[0].codes = 0;
1575  v[0].r = (ubyte)r;
1576  v[0].g = (ubyte)g;
1577  v[0].b = (ubyte)b;
1578  v[0].a = 0;
1579 
1580  v[1].screen.xyw.x = i2fl(coords[1].x);
1581  v[1].screen.xyw.y = i2fl(coords[1].y);
1582  v[1].screen.xyw.w = 0.0f;
1583  v[1].texture_position.u = 0.0f;
1584  v[1].texture_position.v = 0.0f;
1585  v[1].flags = PF_PROJECTED;
1586  v[1].codes = 0;
1587  v[1].r = (ubyte)r;
1588  v[1].g = (ubyte)g;
1589  v[1].b = (ubyte)b;
1590  v[1].a = (ubyte)a;
1591 
1592  v[2].screen.xyw.x = i2fl(coords[2].x);
1593  v[2].screen.xyw.y = i2fl(coords[2].y);
1594  v[2].screen.xyw.w = 0.0f;
1595  v[2].texture_position.u = 0.0f;
1596  v[2].texture_position.v = 0.0f;
1597  v[2].flags = PF_PROJECTED;
1598  v[2].codes = 0;
1599  v[2].r = (ubyte)r;
1600  v[2].g = (ubyte)g;
1601  v[2].b = (ubyte)b;
1602  v[2].a = 0;
1603 
1604  v[3].screen.xyw.x = i2fl(coords[3].x);
1605  v[3].screen.xyw.y = i2fl(coords[3].y);
1606  v[3].screen.xyw.w = 0.0f;
1607  v[3].texture_position.u = 0.0f;
1608  v[3].texture_position.v = 0.0f;
1609  v[3].flags = PF_PROJECTED;
1610  v[3].codes = 0;
1611  v[3].r = (ubyte)r;
1612  v[3].g = (ubyte)g;
1613  v[3].b = (ubyte)b;
1614  v[3].a = (ubyte)a;
1615 
1616  v[4].screen.xyw.x = i2fl(coords[4].x);
1617  v[4].screen.xyw.y = i2fl(coords[4].y);
1618  v[4].screen.xyw.w = 0.0f;
1619  v[4].texture_position.u = 0.0f;
1620  v[4].texture_position.v = 0.0f;
1621  v[4].flags = PF_PROJECTED;
1622  v[4].codes = 0;
1623  v[4].r = (ubyte)r;
1624  v[4].g = (ubyte)g;
1625  v[4].b = (ubyte)b;
1626  v[4].a = 0;
1627 
1628  v[5].screen.xyw.x = i2fl(coords[5].x);
1629  v[5].screen.xyw.y = i2fl(coords[5].y);
1630  v[5].screen.xyw.w = 0.0f;
1631  v[5].texture_position.u = 0.0f;
1632  v[5].texture_position.v = 0.0f;
1633  v[5].flags = PF_PROJECTED;
1634  v[5].codes = 0;
1635  v[5].r = (ubyte)r;
1636  v[5].g = (ubyte)g;
1637  v[5].b = (ubyte)b;
1638  v[5].a = 0;
1639 
1640  // draw the polys
1642 
1643  if (!Fred_running)
1644  g3_end_frame();
1645 
1646  // restore zbuffer and culling
1647  gr_zbuffer_set(saved_zbuf);
1648  gr_set_cull(cull);
1649 }
1650 
1651 void g3_draw_2d_rect(int x, int y, int w, int h, int r, int g, int b, int a)
1652 {
1653  int saved_zbuf;
1654  vertex v[4];
1655  vertex *verts[4] = {&v[0], &v[1], &v[2], &v[3]};
1656 
1657  memset(v,0,sizeof(vertex)*4);
1658  saved_zbuf = gr_zbuffer_get();
1659 
1660  // start the frame, no zbuffering, no culling
1661  if (!Fred_running)
1662  g3_start_frame(1);
1663 
1665  int cull = gr_set_cull(0);
1666 
1667  // stuff coords
1668  v[0].screen.xyw.x = i2fl(x);
1669  v[0].screen.xyw.y = i2fl(y);
1670  v[0].screen.xyw.w = 0.0f;
1671  v[0].texture_position.u = 0.0f;
1672  v[0].texture_position.v = 0.0f;
1673  v[0].flags = PF_PROJECTED;
1674  v[0].codes = 0;
1675  v[0].r = (ubyte)r;
1676  v[0].g = (ubyte)g;
1677  v[0].b = (ubyte)b;
1678  v[0].a = (ubyte)a;
1679 
1680  v[1].screen.xyw.x = i2fl(x + w);
1681  v[1].screen.xyw.y = i2fl(y);
1682  v[1].screen.xyw.w = 0.0f;
1683  v[1].texture_position.u = 0.0f;
1684  v[1].texture_position.v = 0.0f;
1685  v[1].flags = PF_PROJECTED;
1686  v[1].codes = 0;
1687  v[1].r = (ubyte)r;
1688  v[1].g = (ubyte)g;
1689  v[1].b = (ubyte)b;
1690  v[1].a = (ubyte)a;
1691 
1692  v[2].screen.xyw.x = i2fl(x + w);
1693  v[2].screen.xyw.y = i2fl(y + h);
1694  v[2].screen.xyw.w = 0.0f;
1695  v[2].texture_position.u = 0.0f;
1696  v[2].texture_position.v = 0.0f;
1697  v[2].flags = PF_PROJECTED;
1698  v[2].codes = 0;
1699  v[2].r = (ubyte)r;
1700  v[2].g = (ubyte)g;
1701  v[2].b = (ubyte)b;
1702  v[2].a = (ubyte)a;
1703 
1704  v[3].screen.xyw.x = i2fl(x);
1705  v[3].screen.xyw.y = i2fl(y + h);
1706  v[3].screen.xyw.w = 0.0f;
1707  v[3].texture_position.u = 0.0f;
1708  v[3].texture_position.v = 0.0f;
1709  v[3].flags = PF_PROJECTED;
1710  v[3].codes = 0;
1711  v[3].r = (ubyte)r;
1712  v[3].g = (ubyte)g;
1713  v[3].b = (ubyte)b;
1714  v[3].a = (ubyte)a;
1715 
1716  // draw the polys
1718 
1719  if (!Fred_running)
1720  g3_end_frame();
1721 
1722  // restore zbuffer and culling
1723  gr_zbuffer_set(saved_zbuf);
1724  gr_set_cull(cull);
1725 }
1726 
1727 // draw a 2d bitmap on a poly
1728 int g3_draw_2d_poly_bitmap(float x, float y, float w, float h, uint additional_tmap_flags)
1729 {
1730  int ret;
1731  int saved_zbuffer_mode;
1732  vertex v[4];
1733  vertex *vertlist[4] = { &v[0], &v[1], &v[2], &v[3] };
1734  memset(v,0,sizeof(vertex)*4);
1735 
1736  g3_start_frame(1);
1737 
1738  // turn off zbuffering
1739  saved_zbuffer_mode = gr_zbuffer_get();
1741 
1742  // stuff coords
1743  v[0].screen.xyw.x = x;
1744  v[0].screen.xyw.y = y;
1745  v[0].screen.xyw.w = 0.0f;
1746  v[0].texture_position.u = 0.0f;
1747  v[0].texture_position.v = 0.0f;
1748  v[0].flags = PF_PROJECTED;
1749  v[0].codes = 0;
1750 
1751  v[1].screen.xyw.x = (x + w);
1752  v[1].screen.xyw.y = y;
1753  v[1].screen.xyw.w = 0.0f;
1754  v[1].texture_position.u = 1.0f;
1755  v[1].texture_position.v = 0.0f;
1756  v[1].flags = PF_PROJECTED;
1757  v[1].codes = 0;
1758 
1759  v[2].screen.xyw.x = (x + w);
1760  v[2].screen.xyw.y = (y + h);
1761  v[2].screen.xyw.w = 0.0f;
1762  v[2].texture_position.u = 1.0f;
1763  v[2].texture_position.v = 1.0f;
1764  v[2].flags = PF_PROJECTED;
1765  v[2].codes = 0;
1766 
1767  v[3].screen.xyw.x = x;
1768  v[3].screen.xyw.y = (y + h);
1769  v[3].screen.xyw.w = 0.0f;
1770  v[3].texture_position.u = 0.0f;
1771  v[3].texture_position.v = 1.0f;
1772  v[3].flags = PF_PROJECTED;
1773  v[3].codes = 0;
1774 
1775  // set debrief
1776  ret = g3_draw_poly_constant_sw(4, vertlist, TMAP_FLAG_TEXTURED | additional_tmap_flags, 0.1f);
1777 
1778  g3_end_frame();
1779 
1780  gr_zbuffer_set(saved_zbuffer_mode);
1781 
1782  return ret;
1783 }
1784 
1788 
1790  if(bitmap_2d_poly_list)delete[]bitmap_2d_poly_list;
1791  if(bitmap_2d_poly_vertlist)delete[]bitmap_2d_poly_vertlist;
1792 }
1793 
1794 int g3_draw_2d_poly_bitmap_list(bitmap_2d_list* b_list, int n_bm, uint additional_tmap_flags)
1795 {
1796  int ret;
1797  int saved_zbuffer_mode;
1798  if(n_bm>bitmap_2d_poly_list_size){
1799  if(bitmap_2d_poly_list)delete[]bitmap_2d_poly_list;
1800  if(bitmap_2d_poly_vertlist)delete[]bitmap_2d_poly_vertlist;
1801  bitmap_2d_poly_list = new vertex[6* n_bm];
1802  bitmap_2d_poly_vertlist = new vertex*[6*n_bm];
1803  for(int i = 0; i<6*n_bm; i++)bitmap_2d_poly_vertlist[i] = &bitmap_2d_poly_list[i];
1804  memset(bitmap_2d_poly_list,0,sizeof(vertex)*6*n_bm);
1805  }
1806 
1807  g3_start_frame(1);
1808 
1809  // turn off zbuffering
1810  saved_zbuffer_mode = gr_zbuffer_get();
1812 
1813  for(int i = 0; i<n_bm;i++){
1814  // stuff coords
1815 
1816  //tri one
1817  vertex *V = &bitmap_2d_poly_list[i*6];
1818  V->screen.xyw.x = (float)b_list[i].x;
1819  V->screen.xyw.y = (float)b_list[i].y;
1820  V->screen.xyw.w = 0.0f;
1821  V->texture_position.u = 0.0f;
1822  V->texture_position.v = 0.0f;
1823  V->flags = PF_PROJECTED;
1824  V->codes = 0;
1825 
1826  V++;
1827  V->screen.xyw.x = (float)(b_list[i].x + b_list[i].w);
1828  V->screen.xyw.y = (float)b_list[i].y;
1829  V->screen.xyw.w = 0.0f;
1830  V->texture_position.u = 1.0f;
1831  V->texture_position.v = 0.0f;
1832  V->flags = PF_PROJECTED;
1833  V->codes = 0;
1834 
1835  V++;
1836  V->screen.xyw.x = (float)(b_list[i].x + b_list[i].w);
1837  V->screen.xyw.y = (float)(b_list[i].y + b_list[i].h);
1838  V->screen.xyw.w = 0.0f;
1839  V->texture_position.u = 1.0f;
1840  V->texture_position.v = 1.0f;
1841  V->flags = PF_PROJECTED;
1842  V->codes = 0;
1843 
1844  //tri two
1845  V++;
1846  V->screen.xyw.x = (float)b_list[i].x;
1847  V->screen.xyw.y = (float)b_list[i].y;
1848  V->screen.xyw.w = 0.0f;
1849  V->texture_position.u = 0.0f;
1850  V->texture_position.v = 0.0f;
1851  V->flags = PF_PROJECTED;
1852  V->codes = 0;
1853 
1854  V++;
1855  V->screen.xyw.x = (float)(b_list[i].x + b_list[i].w);
1856  V->screen.xyw.y = (float)(b_list[i].y + b_list[i].h);
1857  V->screen.xyw.w = 0.0f;
1858  V->texture_position.u = 1.0f;
1859  V->texture_position.v = 1.0f;
1860  V->flags = PF_PROJECTED;
1861  V->codes = 0;
1862 
1863  V++;
1864  V->screen.xyw.x = (float)b_list[i].x;
1865  V->screen.xyw.y = (float)(b_list[i].y + b_list[i].h);
1866  V->screen.xyw.w = 0.0f;
1867  V->texture_position.u = 0.0f;
1868  V->texture_position.v = 1.0f;
1869  V->flags = PF_PROJECTED;
1870  V->codes = 0;
1871  }
1872 
1873  // set debrief
1874  ret = g3_draw_poly_constant_sw(6*n_bm, bitmap_2d_poly_vertlist, TMAP_FLAG_TEXTURED | TMAP_FLAG_TRILIST | additional_tmap_flags, 0.1f);
1875 
1876  g3_end_frame();
1877 
1878  gr_zbuffer_set(saved_zbuffer_mode);
1879 
1880  return ret;
1881 }
1882 
1883 //draws an array of bitmap_rect_list objects
1884 //see tmapper.h for explaination of structure bitmap_rect_list
1885 int g3_draw_2d_poly_bitmap_rect_list(bitmap_rect_list* b_list, int n_bm, uint additional_tmap_flags)
1886 {
1887  int ret;
1888  int saved_zbuffer_mode;
1889  if(n_bm>bitmap_2d_poly_list_size){
1890  if(bitmap_2d_poly_list)delete[]bitmap_2d_poly_list;
1891  if(bitmap_2d_poly_vertlist)delete[]bitmap_2d_poly_vertlist;
1892  bitmap_2d_poly_list = new vertex[6* n_bm];
1893  bitmap_2d_poly_vertlist = new vertex*[6*n_bm];
1894  for(int i = 0; i<6*n_bm; i++)bitmap_2d_poly_vertlist[i] = &bitmap_2d_poly_list[i];
1895  }
1896 
1897  g3_start_frame(1);
1898 
1899  // turn off zbuffering
1900  saved_zbuffer_mode = gr_zbuffer_get();
1902 
1903  for(int i = 0; i<n_bm;i++){
1904  // stuff coords
1905 
1906  bitmap_2d_list* b = &b_list[i].screen_rect;
1907  texture_rect_list* t = &b_list[i].texture_rect;
1908  //tri one
1909  vertex *V = &bitmap_2d_poly_list[i*6];
1910  V->screen.xyw.x = (float)b->x;
1911  V->screen.xyw.y = (float)b->y;
1912  V->screen.xyw.w = 0.0f;
1913  V->texture_position.u = (float)t->u0;
1914  V->texture_position.v = (float)t->v0;
1915  V->flags = PF_PROJECTED;
1916  V->codes = 0;
1917 
1918  V++;
1919  V->screen.xyw.x = (float)(b->x + b->w);
1920  V->screen.xyw.y = (float)b->y;
1921  V->screen.xyw.w = 0.0f;
1922  V->texture_position.u = (float)t->u1;
1923  V->texture_position.v = (float)t->v0;
1924  V->flags = PF_PROJECTED;
1925  V->codes = 0;
1926 
1927  V++;
1928  V->screen.xyw.x = (float)(b->x + b->w);
1929  V->screen.xyw.y = (float)(b->y + b->h);
1930  V->screen.xyw.w = 0.0f;
1931  V->texture_position.u = (float)t->u1;
1932  V->texture_position.v = (float)t->v1;
1933  V->flags = PF_PROJECTED;
1934  V->codes = 0;
1935 
1936  //tri two
1937  V++;
1938  V->screen.xyw.x = (float)b->x;
1939  V->screen.xyw.y = (float)b->y;
1940  V->screen.xyw.w = 0.0f;
1941  V->texture_position.u = (float)t->u0;
1942  V->texture_position.v = (float)t->v0;
1943  V->flags = PF_PROJECTED;
1944  V->codes = 0;
1945 
1946  V++;
1947  V->screen.xyw.x = (float)(b->x + b->w);
1948  V->screen.xyw.y = (float)(b->y + b->h);
1949  V->screen.xyw.w = 0.0f;
1950  V->texture_position.u = (float)t->u1;
1951  V->texture_position.v = (float)t->v1;
1952  V->flags = PF_PROJECTED;
1953  V->codes = 0;
1954 
1955  V++;
1956  V->screen.xyw.x = (float)b->x;
1957  V->screen.xyw.y = (float)(b->y + b->h);
1958  V->screen.xyw.w = 0.0f;
1959  V->texture_position.u = (float)t->u0;
1960  V->texture_position.v = (float)t->v1;
1961  V->flags = PF_PROJECTED;
1962  V->codes = 0;
1963  }
1964 
1965  // set debrief
1966  ret = g3_draw_poly_constant_sw(6*n_bm, bitmap_2d_poly_vertlist, TMAP_FLAG_TEXTURED | TMAP_FLAG_TRILIST | additional_tmap_flags, 0.1f);
1967 
1968  g3_end_frame();
1969 
1970  gr_zbuffer_set(saved_zbuffer_mode);
1971 
1972  return ret;
1973 }
1974 
1975 void g3_draw_htl_line(const vec3d *start, const vec3d *end)
1976 {
1977  if (Cmdline_nohtl) {
1978  return;
1979  }
1980 
1981  gr_line_htl(start, end);
1982 }
1983 
1984 void g3_draw_htl_sphere(const vec3d* position, float radius)
1985 {
1986  if (Cmdline_nohtl) {
1987  return;
1988  }
1989 
1991 
1992  gr_sphere_htl(radius);
1993 
1994  g3_done_instance(true);
1995 }
1996 
1997 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
1998 //flash ball stuff
1999 
2000 void flash_ball::initialize(int number, float min_ray_width, float max_ray_width, const vec3d* dir, const vec3d* pcenter, float outer, float inner, ubyte max_r, ubyte max_g, ubyte max_b, ubyte min_r, ubyte min_g, ubyte min_b)
2001 {
2002  if(number < 1)
2003  return;
2004 
2005  center = *pcenter;
2006 
2007  if(n_rays < number){
2008  if(ray)vm_free(ray);
2009  ray = (flash_beam*)vm_malloc(sizeof(flash_beam)*number);
2010  n_rays = number;
2011  }
2012 
2013  int i;
2014  for(i = 0; i<n_rays; i++){
2015  //colors
2016  if(min_r != 255){
2017  ray[i].start.r = (rand()%(max_r-min_r))+min_r;
2018  }else{
2019  ray[i].start.r = 255;
2020  }
2021  if(min_g != 255){
2022  ray[i].start.g = (rand()%(max_g-min_g))+min_g;
2023  }else{
2024  ray[i].start.g = 255;
2025  }
2026  if(min_b != 255){
2027  ray[i].start.b = (rand()%(max_b-min_b))+min_b;
2028  }else{
2029  ray[i].start.b = 255;
2030  }
2031 
2032  //rays
2033  if(dir == &vmd_zero_vector || outer >= PI2){
2034  //random sphere
2035  vec3d start, end;
2036 
2037  vm_vec_rand_vec_quick(&start);
2038  vm_vec_rand_vec_quick(&end);
2039 
2040  ray[i].start.world = start;
2041  ray[i].end.world = end;
2042  }else{
2043  //random cones
2044  vec3d start, end;
2045 
2046  vm_vec_random_cone(&start, dir, outer, inner);
2047  vm_vec_random_cone(&end, dir, outer, inner);
2048 
2049  ray[i].start.world = start;
2050  ray[i].end.world = end;
2051  }
2052  if(max_ray_width == 0.0f)ray[i].width=min_ray_width;
2053  else ray[i].width = frand_range(min_ray_width, max_ray_width);
2054  }
2055 
2056 
2057 }
2058 
2059 #define uw(p) (*((uint *) (p)))
2060 #define w(p) (*((int *) (p)))
2061 #define wp(p) ((int *) (p))
2062 #define vp(p) ((vec3d *) (p))
2063 #define fl(p) (*((float *) (p)))
2064 
2065 void flash_ball::defpoint(int off, ubyte *bsp_data)
2066 {
2067  int n;
2068  int nverts = w(off+bsp_data+8);
2069  int offset = w(off+bsp_data+16);
2070  ubyte * normcount = off+bsp_data+20;
2071  vec3d *src = vp(off+bsp_data+offset);
2072 
2073  if(n_rays < nverts){
2074  if(ray)vm_free(ray);
2075  ray = (flash_beam*)vm_malloc(sizeof(flash_beam)*nverts);
2076  n_rays = nverts;
2077  }
2078 
2079  {
2080  vec3d temp;
2081  for (n=0; n<nverts; n++ ) {
2082 
2083  temp = *src;
2084  vm_vec_sub2(&temp, &center);
2085  vm_vec_normalize(&temp);
2086  ray[n].start.world = temp;
2087 
2088  src++; // move to normal
2089 
2090  src+=normcount[n];
2091  }
2092  }
2093 }
2094 
2095 #define OP_EOF 0
2096 #define OP_DEFPOINTS 1
2097 #define OP_FLATPOLY 2
2098 #define OP_TMAPPOLY 3
2099 #define OP_SORTNORM 4
2100 #define OP_BOUNDBOX 5
2101 
2102 
2103 void flash_ball::parse_bsp(int offset, ubyte *bsp_data){
2104  int ID, SIZE;
2105 
2106  memcpy(&ID, &bsp_data[offset], sizeof(int));
2107  memcpy(&SIZE, &bsp_data[offset+sizeof(int)], sizeof(int));
2108 
2109  while(ID!=0){
2110  switch(ID){
2111  case OP_EOF:
2112  return;
2113  break;
2114  case OP_DEFPOINTS: defpoint(offset, bsp_data);
2115  break;
2116  case OP_SORTNORM:
2117  break;
2118  case OP_FLATPOLY:
2119  break;
2120  case OP_TMAPPOLY:
2121  break;
2122  case OP_BOUNDBOX:
2123  break;
2124  default:
2125  return;
2126  }
2127  offset += SIZE;
2128  memcpy(&ID, &bsp_data[offset], sizeof(int));
2129  memcpy(&SIZE, &bsp_data[offset+sizeof(int)], sizeof(int));
2130 
2131  if(SIZE < 1)ID=OP_EOF;
2132  }
2133 }
2134 
2135 
2136 void flash_ball::initialize(ubyte *bsp_data, float min_ray_width, float max_ray_width, const vec3d* dir, const vec3d* pcenter, float outer, float inner, ubyte max_r, ubyte max_g, ubyte max_b, ubyte min_r, ubyte min_g, ubyte min_b)
2137 {
2138  center = *pcenter;
2139  vm_vec_negate(&center);
2140  parse_bsp(0,bsp_data);
2141  center = vmd_zero_vector;
2142 
2143  int i;
2144  for(i = 0; i<n_rays; i++){
2145  //colors
2146  if(min_r != 255){
2147  ray[i].start.r = (rand()%(max_r-min_r))+min_r;
2148  }else{
2149  ray[i].start.r = 255;
2150  }
2151  if(min_g != 255){
2152  ray[i].start.g = (rand()%(max_g-min_g))+min_g;
2153  }else{
2154  ray[i].start.g = 255;
2155  }
2156  if(min_b != 255){
2157  ray[i].start.b = (rand()%(max_b-min_b))+min_b;
2158  }else{
2159  ray[i].start.b = 255;
2160  }
2161 
2162  //rays
2163  if(dir == &vmd_zero_vector || outer >= PI2){
2164  //random sphere
2165  vec3d end;
2166 
2167  vm_vec_rand_vec_quick(&end);
2168 
2169  ray[i].end.world = end;
2170  }else{
2171  //random cones
2172  vec3d end;
2173 
2174  vm_vec_random_cone(&end, dir, outer, inner);
2175 
2176  ray[i].end.world = end;
2177  }
2178  if(max_ray_width == 0.0f)ray[i].width=min_ray_width;
2179  else ray[i].width = frand_range(min_ray_width, max_ray_width);
2180  }
2181 }
2182 
2183 //rad how wide the ball should be
2184 //intinsity how visable it should be
2185 //life how far along from start to end should it be
2186 void flash_ball::render(float rad, float intinsity, float life){
2187  flash_ball::batcher.allocate(n_rays);
2188  for(int i = 0; i<n_rays; i++){
2189  vec3d end;
2190  vm_vec_interp_constant(&end, &ray[i].start.world, &ray[i].end.world, life);
2191  vm_vec_scale(&end, rad);
2192  vm_vec_add2(&end, &center);
2193  flash_ball::batcher.draw_beam(&center, &end, ray[i].width*rad, intinsity);
2194  }
2196 }
2197 
2198 void flash_ball::render(int texture, float rad, float intinsity, float life){
2199  flash_ball::batcher.allocate(n_rays);
2200  for(int i = 0; i<n_rays; i++){
2201  vec3d end;
2202  vm_vec_interp_constant(&end, &ray[i].start.world, &ray[i].end.world, life);
2203  vm_vec_scale(&end, rad);
2204  vm_vec_add2(&end, &center);
2205 
2207  }
2208 }
2209 
2210 geometry_batcher flash_ball::batcher;
int g3_draw_rotated_bitmap_3d(vertex *pnt, float angle, float rad, uint tmap_flags, float depth)
Definition: 3ddraw.cpp:788
int g3_draw_sphere_ez(const vec3d *pnt, float rad)
Definition: 3ddraw.cpp:498
#define gr_tmapper
Definition: 2d.h:804
void initialize(int number, float min_ray_width, float max_ray_width=0, const vec3d *dir=&vmd_zero_vector, const vec3d *pcenter=&vmd_zero_vector, float outer=PI2, float inner=0.0f, ubyte max_r=255, ubyte max_g=255, ubyte max_b=255, ubyte min_r=255, ubyte min_g=255, ubyte min_b=255)
Definition: 3ddraw.cpp:2000
#define gr_zbuffer_set
Definition: 2d.h:817
struct screen3d::@234::@236 xyw
void render(float rad, float intinsity, float life)
Definition: 3ddraw.cpp:2186
int i
Definition: multi_pxo.cpp:466
#define vm_free(ptr)
Definition: pstypes.h:548
float p
Definition: pstypes.h:111
#define OP_BOUNDBOX
Definition: 3ddraw.cpp:2100
#define TMAP_FLAG_XPARENT
Definition: tmapper.h:44
#define Verify(x)
Definition: pstypes.h:272
int g3_draw_poly_if_facing(int nv, vertex **pointlist, uint tmap_flags, const vec3d *norm, const vec3d *pnt)
Definition: 3ddraw.cpp:194
#define OP_EOF
Definition: 3ddraw.cpp:2095
ubyte spec_g
Definition: pstypes.h:176
float g3_draw_rotated_bitmap_area(vertex *pnt, float angle, float rad, uint tmap_flags, float area)
Definition: 3ddraw.cpp:1069
vec3d View_position
Definition: 3dsetup.cpp:20
GLfloat GLfloat GLfloat GLfloat h
Definition: Glext.h:7280
void vm_vec_scale_add(vec3d *dest, const vec3d *src1, const vec3d *src2, float k)
Definition: vecmat.cpp:266
ubyte cc_or
Definition: pstypes.h:71
float frand_range(float min, float max)
Return a floating point number in the range min..max.
Definition: floating.cpp:50
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
int g3_draw_polygon(const vec3d *pos, const matrix *ori, float width, float height, int tmap_flags)
Definition: 3ddraw.cpp:310
ubyte g
Definition: pstypes.h:175
int g3_check_normal_facing(const vec3d *v, const vec3d *norm)
Definition: 3ddraw.cpp:155
#define MAX_ROD_VECS
Definition: 3ddraw.cpp:1334
int Fred_running
Definition: fred.cpp:44
matrix * vm_angles_2_matrix(matrix *m, const angles *a)
Definition: vecmat.cpp:752
float g3_get_poly_area(int nv, vertex **pointlist)
Definition: 3ddraw.cpp:953
__inline void gr_circle(int xc, int yc, int d, int resize_mode=GR_RESIZE_FULL)
Definition: 2d.h:774
float Canv_h2
Definition: 3dsetup.cpp:40
int g3_get_bitmap_dims(int bitmap, vertex *pnt, float rad, int *x, int *y, int *w, int *h, int *size)
Definition: 3ddraw.cpp:740
ubyte g3_transfer_vertex(vertex *dest, const vec3d *src)
Definition: 3dmath.cpp:84
void g3_draw_2d_rect(int x, int y, int w, int h, int r, int g, int b, int a)
Definition: 3ddraw.cpp:1651
void _cdecl void void _cdecl void _cdecl Warning(char *filename, int line, SCP_FORMAT_STRING const char *format,...) SCP_FORMAT_STRING_ARGS(3
Assert(pm!=NULL)
bitmap_2d_list screen_rect
Definition: tmapper.h:127
Definition: pstypes.h:88
#define mprintf(args)
Definition: pstypes.h:238
GLint GLint GLsizei GLsizei GLsizei depth
Definition: Glext.h:5180
hull_check p0
Definition: lua.cpp:5051
int g3_draw_bitmap_3d_volume(vertex *pnt, int orient, float rad, uint tmap_flags, float depth, int resolution)
Definition: 3ddraw.cpp:633
matrix Unscaled_matrix
Definition: 3dsetup.cpp:21
#define gr_render
Definition: 2d.h:805
int g3_draw_bitmap_3d(vertex *pnt, int orient, float rad, uint tmap_flags, float depth)
Definition: 3ddraw.cpp:521
int bm_get_info(int handle, int *w, int *h, ubyte *flags, int *nframes, int *fps)
Gets info on the bitmap indexed by handle.
Definition: bmpman.cpp:769
vertex start
Definition: 3d.h:378
struct vec3d::@225::@227 xyz
#define TMAP_HTL_3D_UNLIT
Definition: tmapper.h:63
GLclampf f
Definition: Glext.h:7097
#define GR_ZBUFF_NONE
Definition: 2d.h:672
GLenum GLuint texture
Definition: Glext.h:5872
void free_temp_point(vertex *p)
Definition: 3dclipper.cpp:42
ubyte spec_b
Definition: pstypes.h:176
vec3d * vm_vec_rotate(vec3d *dest, const vec3d *src, const matrix *m)
Definition: vecmat.cpp:933
vertex * bitmap_2d_poly_list
Definition: 3ddraw.cpp:1785
ubyte g3_code_vertex(vertex *point)
Definition: 3dmath.cpp:54
void vm_vec_random_cone(vec3d *out, const vec3d *in, float max_angle, const matrix *orient)
Definition: vecmat.cpp:2418
float x
Definition: 3ddraw.cpp:1163
float y
Definition: 3ddraw.cpp:1163
int g3_draw_rotated_bitmap(vertex *pnt, float angle, float rad, uint tmap_flags, float depth)
Definition: 3ddraw.cpp:844
int g3_draw_2d_poly_bitmap_rect_list(bitmap_rect_list *b_list, int n_bm, uint additional_tmap_flags)
Definition: 3ddraw.cpp:1885
float p_theta
Definition: 3ddraw.cpp:1433
ubyte blue
Definition: 2d.h:102
hull_check orient
Definition: lua.cpp:5049
GLsizeiptr size
Definition: Glext.h:5496
int g3_draw_2d_poly_bitmap(float x, float y, float w, float h, uint additional_tmap_flags)
Definition: 3ddraw.cpp:1728
#define CC_OFF_USER
Definition: 3d.h:30
#define MAX_PERSPECTIVE_DIVISIONS
Definition: 3ddraw.cpp:1417
#define TMAP_FLAG_BW_TEXTURE
Definition: tmapper.h:73
#define GR_RESIZE_NONE
Definition: 2d.h:681
int g3_draw_2d_poly_bitmap_list(bitmap_2d_list *b_list, int n_bm, uint additional_tmap_flags)
Definition: 3ddraw.cpp:1794
vertex * free_points[TMAP_MAX_VERTS]
Definition: 3dclipper.cpp:19
int clip_height
Definition: 2d.h:378
GLint GLsizei width
Definition: Gl.h:1505
ubyte green
Definition: 2d.h:101
ubyte spec_r
Definition: pstypes.h:176
int g3_draw_bitmap_3d_v(vertex *pnt, int orient, float rad, uint tmap_flags, float depth, float c)
Definition: 3ddraw.cpp:587
void g3_done_instance(bool set_api=false)
Definition: 3dsetup.cpp:341
#define OP_TMAPPOLY
Definition: 3ddraw.cpp:2098
GLfloat angle
Definition: Glext.h:10324
#define OP_FLATPOLY
Definition: 3ddraw.cpp:2097
#define OP_DEFPOINTS
Definition: 3ddraw.cpp:2096
#define vp(p)
Definition: 3ddraw.cpp:2062
uv_pair texture_position
Definition: pstypes.h:174
ubyte a
Definition: pstypes.h:175
typedef int(SCP_EXT_CALLCONV *SCPDLL_PFVERSION)(SCPDLL_Version *)
matrix * vm_vector_2_matrix(matrix *m, const vec3d *fvec, const vec3d *uvec, const vec3d *rvec)
Definition: vecmat.cpp:850
GLintptr offset
Definition: Glext.h:5497
#define PF_OVERFLOW
Definition: 3d.h:22
void vm_vec_add2(vec3d *dest, const vec3d *src)
Definition: vecmat.cpp:178
int Cmdline_nohtl
Definition: cmdline.cpp:438
const float PI2
Definition: pstypes.h:305
GLdouble GLdouble GLdouble r
Definition: Glext.h:5337
struct matrix::@228::@230 vec
Definition: pstypes.h:70
unsigned int uint
Definition: pstypes.h:64
screen3d screen
Definition: pstypes.h:173
GLboolean GLboolean g
Definition: Glext.h:5781
vec3d g3_square[4]
Definition: 3ddraw.cpp:1410
void vm_vec_scale(vec3d *dest, float s)
Definition: vecmat.cpp:248
GLuint coords
Definition: Glext.h:6925
#define TMAP_FLAG_GOURAUD
Definition: tmapper.h:40
#define gr_scaler
Definition: 2d.h:802
int g3_draw_line(vertex *p0, vertex *p1)
Definition: 3ddraw.cpp:112
GLboolean GLboolean GLboolean GLboolean a
Definition: Glext.h:5781
int g3_draw_bitmap(vertex *pnt, int orient, float rad, uint tmap_flags, float depth)
Definition: 3ddraw.cpp:649
#define PF_TEMP_POINT
Definition: 3d.h:23
void vm_vec_sub2(vec3d *dest, const vec3d *src)
Definition: vecmat.cpp:187
int must_clip_line(vertex *p0, vertex *p1, ubyte codes_or, uint flags)
Definition: 3ddraw.cpp:71
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
GLdouble GLdouble z
Definition: Glext.h:5451
#define w(p)
Definition: 3ddraw.cpp:2060
#define gr_sphere_htl
Definition: 2d.h:941
ubyte red
Definition: 2d.h:100
#define vm_vec_negate(v)
Definition: vecmat.h:70
int edge
Definition: 3ddraw.cpp:1164
float g3_draw_poly_constant_sw_area(int nv, vertex **pointlist, uint tmap_flags, float constant_sw, float area)
Definition: 3ddraw.cpp:971
ubyte g3_rotate_vertex(vertex *dest, const vec3d *src)
Definition: 3dmath.cpp:97
hull_check p1
Definition: lua.cpp:5052
Definition: bmpman.h:101
#define fl_abs(fl)
Definition: floating.h:31
int Canvas_width
Definition: 3dsetup.cpp:36
GLdouble s
Definition: Glext.h:5321
float u
Definition: pstypes.h:135
float width
Definition: 3d.h:380
int g3_draw_rod(const vec3d *p0, float width1, const vec3d *p1, float width2, vertex *verts, uint tmap_flags)
Definition: 3ddraw.cpp:1262
float vm_vec_normalize_safe(vec3d *v)
Definition: vecmat.cpp:471
int idx
Definition: multiui.cpp:761
int g3_project_vertex(vertex *point)
Definition: 3dmath.cpp:202
GLdouble GLdouble t
Definition: Glext.h:5329
vec3d Matrix_scale
Definition: 3dsetup.cpp:34
vec3d * vm_vec_unrotate(vec3d *dest, const vec3d *src, const matrix *m)
Definition: vecmat.cpp:959
void g3_draw_htl_line(const vec3d *start, const vec3d *end)
Definition: 3ddraw.cpp:1975
GLint GLint GLint GLint GLint x
Definition: Glext.h:5182
ubyte alpha
Definition: 2d.h:103
GLclampd n
Definition: Glext.h:7286
unsigned char ubyte
Definition: pstypes.h:62
#define ZERO_VECTOR
Definition: vecmat.h:60
int g3_draw_poly_constant_sw(int nv, vertex **pointlist, uint tmap_flags, float constant_sw)
Definition: 3ddraw.cpp:381
void vm_vec_interp_constant(vec3d *out, const vec3d *v0, const vec3d *v1, float t)
Definition: vecmat.cpp:2401
vertex ** clip_polygon(vertex **src, vertex **dest, int *nv, ccodes *cc, uint flags)
Clips a polygon to the viewing pyramid.
Definition: 3dclipper.cpp:274
ubyte cc_and
Definition: pstypes.h:71
#define gr_set_cull
Definition: 2d.h:838
int max_w
Definition: 2d.h:360
void stars_project_2d_onto_sphere(vec3d *pnt, float rho, float phi, float theta)
Definition: 3ddraw.cpp:1419
#define TMAP_FLAG_RGB
Definition: tmapper.h:39
GLuint start
Definition: Gl.h:1502
ubyte b
Definition: pstypes.h:175
int do_facing_check(const vec3d *norm, vertex **vertlist, const vec3d *p)
Definition: 3ddraw.cpp:166
#define TMAP_FLAG_CORRECT
Definition: tmapper.h:37
ubyte flags
Definition: pstypes.h:178
GLbitfield flags
Definition: Glext.h:6722
void vm_vec_rand_vec_quick(vec3d *rvec)
Definition: vecmat.cpp:1379
#define gr_aaline
Definition: 2d.h:796
#define vm_malloc(size)
Definition: pstypes.h:547
void allocate(int quad, int n_tri=0)
Definition: grbatch.cpp:66
void bm_list_shutdown()
Definition: 3ddraw.cpp:1789
__inline void gr_line(int x1, int y1, int x2, int y2, int resize_mode=GR_RESIZE_FULL)
Definition: 2d.h:791
void vm_vec_sub(vec3d *dest, const vec3d *src0, const vec3d *src1)
Definition: vecmat.cpp:168
struct horz_pt horz_pt
vec3d Eye_position
Definition: 3dsetup.cpp:27
int g3_draw_sphere(vertex *pnt, float rad)
Definition: 3ddraw.cpp:475
void g3_draw_2d_shield_icon(const coord2d coords[6], const int r, const int g, const int b, const int a)
Definition: 3ddraw.cpp:1551
#define gr_line_htl
Definition: 2d.h:940
GLboolean GLboolean GLboolean b
Definition: Glext.h:5781
#define TRIANGLE_AREA(_p, _q, _r)
Definition: 3ddraw.cpp:938
#define CC_BEHIND
Definition: 3d.h:31
#define TMAP_FLAG_TRILIST
Definition: tmapper.h:68
typedef float(SCP_EXT_CALLCONV *SCPTRACKIR_PFFLOATVOID)()
void g3_draw_horizon_line()
Definition: 3ddraw.cpp:1168
ubyte g3_rotate_faraway_vertex(vertex *dest, const vec3d *src)
Definition: 3dmath.cpp:156
int g3_draw_poly(int nv, vertex **pointlist, uint tmap_flags)
Definition: 3ddraw.cpp:207
GLint GLsizei GLsizei height
Definition: Gl.h:1505
GLubyte GLubyte GLubyte GLubyte w
Definition: Glext.h:5679
int g3_draw_perspective_bitmap(const angles *a, float scale_x, float scale_y, int div_x, int div_y, uint tmap_flags)
Definition: 3ddraw.cpp:1434
float Physics_viewer_bank
Definition: physics.cpp:128
#define fl2i(fl)
Definition: floating.h:33
vertex ** bitmap_2d_poly_vertlist
Definition: 3ddraw.cpp:1786
#define g3_end_frame()
Definition: 3d.h:49
int clip_width
Definition: 2d.h:378
screen gr_screen
Definition: 2d.cpp:46
GLint first
Definition: Gl.h:1491
GLfloat GLfloat p
Definition: Glext.h:8373
GLenum src
Definition: Glext.h:5917
#define TMAP_FLAG_ALPHA
Definition: tmapper.h:53
#define LOCATION
Definition: pstypes.h:245
int max_h
Definition: 2d.h:360
vec3d * vm_vec_avg(vec3d *dest, const vec3d *src0, const vec3d *src1)
Definition: vecmat.cpp:217
void g3_start_instance_matrix(const vec3d *pos, const matrix *orient, bool set_api=true)
Definition: 3dsetup.cpp:249
#define TMAP_FLAG_TEXTURED
Definition: tmapper.h:36
void draw_beam(vec3d *start, vec3d *end, float width, float intensity=1.0f, float offset=0.0f)
Definition: grbatch.cpp:362
color current_color
Definition: 2d.h:396
Definition: 3d.h:377
#define PI
Definition: pstypes.h:303
hull_check pos
Definition: lua.cpp:5050
const GLfloat * m
Definition: Glext.h:10319
float vm_vec_dot(const vec3d *v0, const vec3d *v1)
Definition: vecmat.cpp:312
#define TMAP_FLAG_TRISTRIP
Definition: tmapper.h:67
#define i2fl(i)
Definition: floating.h:32
#define PF_PROJECTED
Definition: 3d.h:21
vec3d * vm_vec_perp(vec3d *dest, const vec3d *p0, const vec3d *p1, const vec3d *p2)
Definition: vecmat.cpp:667
matrix View_matrix
Definition: 3dsetup.cpp:19
vec3d world
Definition: pstypes.h:172
int temp
Definition: lua.cpp:4996
float Canv_w2
Definition: 3dsetup.cpp:39
void render(int flags, float radius=0.0f)
Definition: grbatch.cpp:523
#define MAX(a, b)
Definition: pstypes.h:299
int G3_count
Definition: 3dsetup.cpp:59
ubyte codes
Definition: pstypes.h:177
vec3d * vm_vec_cross(vec3d *dest, const vec3d *src0, const vec3d *src1)
Definition: vecmat.cpp:645
#define gr_zbuffer_get
Definition: 2d.h:816
texture_rect_list texture_rect
Definition: tmapper.h:128
float p_phi
Definition: 3ddraw.cpp:1432
float h
Definition: pstypes.h:111
void g3_draw_htl_sphere(const vec3d *position, float radius)
Definition: 3ddraw.cpp:1984
vec3d vmd_zero_vector
Definition: vecmat.cpp:24
void clip_line(vertex **p0, vertex **p1, ubyte codes_or, uint flags)
Clips a line to the viewing pyramid.
Definition: 3dclipper.cpp:197
int Canvas_height
Definition: 3dsetup.cpp:37
#define OP_SORTNORM
Definition: 3ddraw.cpp:2099
vertex end
Definition: 3d.h:379
const GLdouble * v
Definition: Glext.h:5322
matrix vmd_identity_matrix
Definition: vecmat.cpp:28
float aspect
Definition: 2d.h:372
const GLubyte * c
Definition: Glext.h:8376
GLuint GLuint end
Definition: Gl.h:1502
ubyte r
Definition: pstypes.h:175
float b
Definition: pstypes.h:111
GLint y
Definition: Gl.h:1505
GLuint res
Definition: Glext.h:9084
#define g3_start_frame(zbuffer_flag)
Definition: 3d.h:39
float vm_vec_normalize(vec3d *v)
Definition: vecmat.cpp:460
int current_bitmap
Definition: 2d.h:395
int bitmap_2d_poly_list_size
Definition: 3ddraw.cpp:1787