icculus quake2 doxygen  1.0 dev
r_edge.c
Go to the documentation of this file.
1 /*
2 Copyright (C) 1997-2001 Id Software, Inc.
3 
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 
13 See the GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 
19 */
20 // r_edge.c
21 
22 #include "r_local.h"
23 
24 #ifndef id386
25 void R_SurfacePatch (void)
26 {
27 }
28 
29 void R_EdgeCodeStart (void)
30 {
31 }
32 
33 void R_EdgeCodeEnd (void)
34 {
35 }
36 #endif
37 
38 
39 #if 0
40 the complex cases add new polys on most lines, so dont optimize for keeping them the same
41 have multiple free span lists to try to get better coherence?
42 low depth complexity -- 1 to 3 or so
43 
44 have a sentinal at both ends?
45 #endif
46 
47 
50 
52 
53 // surfaces are generated in back to front order by the bsp, so if a surf
54 // pointer is greater than another one, it should be drawn in front
55 // surfaces[1] is the background, and is used as the active surface stack
56 
59 
61 
63 
65 
67 
68 static void (*pdrawfunc)(void);
69 
74 
75 float fv;
76 
77 static int miplevel;
78 
81 
82 // FIXME: should go away
83 extern void R_RotateBmodel (void);
84 extern void R_TransformFrustum (void);
85 
86 
87 
88 void R_GenerateSpans (void);
89 void R_GenerateSpansBackward (void);
90 
91 void R_LeadingEdge (edge_t *edge);
92 void R_LeadingEdgeBackwards (edge_t *edge);
93 void R_TrailingEdge (surf_t *surf, edge_t *edge);
94 
95 
96 /*
97 ===============================================================================
98 
99 EDGE SCANNING
100 
101 ===============================================================================
102 */
103 
104 /*
105 ==============
106 R_BeginEdgeFrame
107 ==============
108 */
109 void R_BeginEdgeFrame (void)
110 {
111  int v;
112 
113  edge_p = r_edges;
115 
116  surface_p = &surfaces[2]; // background is surface 1,
117  // surface 0 is a dummy
118  surfaces[1].spans = NULL; // no background spans yet
120 
121 // put the background behind everything in the world
122  if (sw_draworder->value)
123  {
125  surfaces[1].key = 0;
126  r_currentkey = 1;
127  }
128  else
129  {
131  surfaces[1].key = 0x7FFfFFFF;
132  r_currentkey = 0;
133  }
134 
135 // FIXME: set with memset
136  for (v=r_refdef.vrect.y ; v<r_refdef.vrectbottom ; v++)
137  {
138  newedges[v] = removeedges[v] = NULL;
139  }
140 }
141 
142 
143 #if !id386
144 
145 /*
146 ==============
147 R_InsertNewEdges
148 
149 Adds the edges in the linked list edgestoadd, adding them to the edges in the
150 linked list edgelist. edgestoadd is assumed to be sorted on u, and non-empty (this is actually newedges[v]). edgelist is assumed to be sorted on u, with a
151 sentinel at the end (actually, this is the active edge table starting at
152 edge_head.next).
153 ==============
154 */
155 void R_InsertNewEdges (edge_t *edgestoadd, edge_t *edgelist)
156 {
157  edge_t *next_edge;
158 
159  do
160  {
161  next_edge = edgestoadd->next;
162 edgesearch:
163  if (edgelist->u >= edgestoadd->u)
164  goto addedge;
165  edgelist=edgelist->next;
166  if (edgelist->u >= edgestoadd->u)
167  goto addedge;
168  edgelist=edgelist->next;
169  if (edgelist->u >= edgestoadd->u)
170  goto addedge;
171  edgelist=edgelist->next;
172  if (edgelist->u >= edgestoadd->u)
173  goto addedge;
174  edgelist=edgelist->next;
175  goto edgesearch;
176 
177  // insert edgestoadd before edgelist
178 addedge:
179  edgestoadd->next = edgelist;
180  edgestoadd->prev = edgelist->prev;
181  edgelist->prev->next = edgestoadd;
182  edgelist->prev = edgestoadd;
183  } while ((edgestoadd = next_edge) != NULL);
184 }
185 
186 #endif // !id386
187 
188 
189 #if !id386
190 
191 /*
192 ==============
193 R_RemoveEdges
194 ==============
195 */
196 void R_RemoveEdges (edge_t *pedge)
197 {
198 
199  do
200  {
201  pedge->next->prev = pedge->prev;
202  pedge->prev->next = pedge->next;
203  } while ((pedge = pedge->nextremove) != NULL);
204 }
205 
206 #endif // !id386
207 
208 
209 #if !id386
210 
211 /*
212 ==============
213 R_StepActiveU
214 ==============
215 */
216 void R_StepActiveU (edge_t *pedge)
217 {
218  edge_t *pnext_edge, *pwedge;
219 
220  while (1)
221  {
222 nextedge:
223  pedge->u += pedge->u_step;
224  if (pedge->u < pedge->prev->u)
225  goto pushback;
226  pedge = pedge->next;
227 
228  pedge->u += pedge->u_step;
229  if (pedge->u < pedge->prev->u)
230  goto pushback;
231  pedge = pedge->next;
232 
233  pedge->u += pedge->u_step;
234  if (pedge->u < pedge->prev->u)
235  goto pushback;
236  pedge = pedge->next;
237 
238  pedge->u += pedge->u_step;
239  if (pedge->u < pedge->prev->u)
240  goto pushback;
241  pedge = pedge->next;
242 
243  goto nextedge;
244 
245 pushback:
246  if (pedge == &edge_aftertail)
247  return;
248 
249  // push it back to keep it sorted
250  pnext_edge = pedge->next;
251 
252  // pull the edge out of the edge list
253  pedge->next->prev = pedge->prev;
254  pedge->prev->next = pedge->next;
255 
256  // find out where the edge goes in the edge list
257  pwedge = pedge->prev->prev;
258 
259  while (pwedge->u > pedge->u)
260  {
261  pwedge = pwedge->prev;
262  }
263 
264  // put the edge back into the edge list
265  pedge->next = pwedge->next;
266  pedge->prev = pwedge;
267  pedge->next->prev = pedge;
268  pwedge->next = pedge;
269 
270  pedge = pnext_edge;
271  if (pedge == &edge_tail)
272  return;
273  }
274 }
275 
276 #endif // !id386
277 
278 
279 /*
280 ==============
281 R_CleanupSpan
282 ==============
283 */
284 void R_CleanupSpan (void)
285 {
286  surf_t *surf;
287  int iu;
288  espan_t *span;
289 
290 // now that we've reached the right edge of the screen, we're done with any
291 // unfinished surfaces, so emit a span for whatever's on top
292  surf = surfaces[1].next;
293  iu = edge_tail_u_shift20;
294  if (iu > surf->last_u)
295  {
296  span = span_p++;
297  span->u = surf->last_u;
298  span->count = iu - span->u;
299  span->v = current_iv;
300  span->pnext = surf->spans;
301  surf->spans = span;
302  }
303 
304 // reset spanstate for all surfaces in the surface stack
305  do
306  {
307  surf->spanstate = 0;
308  surf = surf->next;
309  } while (surf != &surfaces[1]);
310 }
311 
312 
313 /*
314 ==============
315 R_LeadingEdgeBackwards
316 ==============
317 */
319 {
320  espan_t *span;
321  surf_t *surf, *surf2;
322  int iu;
323 
324 // it's adding a new surface in, so find the correct place
325  surf = &surfaces[edge->surfs[1]];
326 
327 // don't start a span if this is an inverted span, with the end
328 // edge preceding the start edge (that is, we've already seen the
329 // end edge)
330  if (++surf->spanstate == 1)
331  {
332  surf2 = surfaces[1].next;
333 
334  if (surf->key > surf2->key)
335  goto newtop;
336 
337  // if it's two surfaces on the same plane, the one that's already
338  // active is in front, so keep going unless it's a bmodel
339  if (surf->insubmodel && (surf->key == surf2->key))
340  {
341  // must be two bmodels in the same leaf; don't care, because they'll
342  // never be farthest anyway
343  goto newtop;
344  }
345 
346 continue_search:
347 
348  do
349  {
350  surf2 = surf2->next;
351  } while (surf->key < surf2->key);
352 
353  if (surf->key == surf2->key)
354  {
355  // if it's two surfaces on the same plane, the one that's already
356  // active is in front, so keep going unless it's a bmodel
357  if (!surf->insubmodel)
358  goto continue_search;
359 
360  // must be two bmodels in the same leaf; don't care which is really
361  // in front, because they'll never be farthest anyway
362  }
363 
364  goto gotposition;
365 
366 newtop:
367  // emit a span (obscures current top)
368  iu = edge->u >> 20;
369 
370  if (iu > surf2->last_u)
371  {
372  span = span_p++;
373  span->u = surf2->last_u;
374  span->count = iu - span->u;
375  span->v = current_iv;
376  span->pnext = surf2->spans;
377  surf2->spans = span;
378  }
379 
380  // set last_u on the new span
381  surf->last_u = iu;
382 
383 gotposition:
384  // insert before surf2
385  surf->next = surf2;
386  surf->prev = surf2->prev;
387  surf2->prev->next = surf;
388  surf2->prev = surf;
389  }
390 }
391 
392 
393 /*
394 ==============
395 R_TrailingEdge
396 ==============
397 */
398 void R_TrailingEdge (surf_t *surf, edge_t *edge)
399 {
400  espan_t *span;
401  int iu;
402 
403 // don't generate a span if this is an inverted span, with the end
404 // edge preceding the start edge (that is, we haven't seen the
405 // start edge yet)
406  if (--surf->spanstate == 0)
407  {
408  if (surf == surfaces[1].next)
409  {
410  // emit a span (current top going away)
411  iu = edge->u >> 20;
412  if (iu > surf->last_u)
413  {
414  span = span_p++;
415  span->u = surf->last_u;
416  span->count = iu - span->u;
417  span->v = current_iv;
418  span->pnext = surf->spans;
419  surf->spans = span;
420  }
421 
422  // set last_u on the surface below
423  surf->next->last_u = iu;
424  }
425 
426  surf->prev->next = surf->next;
427  surf->next->prev = surf->prev;
428  }
429 }
430 
431 
432 #if !id386
433 
434 /*
435 ==============
436 R_LeadingEdge
437 ==============
438 */
439 void R_LeadingEdge (edge_t *edge)
440 {
441  espan_t *span;
442  surf_t *surf, *surf2;
443  int iu;
444  float fu, newzi, testzi, newzitop, newzibottom;
445 
446  if (edge->surfs[1])
447  {
448  // it's adding a new surface in, so find the correct place
449  surf = &surfaces[edge->surfs[1]];
450 
451  // don't start a span if this is an inverted span, with the end
452  // edge preceding the start edge (that is, we've already seen the
453  // end edge)
454  if (++surf->spanstate == 1)
455  {
456  surf2 = surfaces[1].next;
457 
458  if (surf->key < surf2->key)
459  goto newtop;
460 
461  // if it's two surfaces on the same plane, the one that's already
462  // active is in front, so keep going unless it's a bmodel
463  if (surf->insubmodel && (surf->key == surf2->key))
464  {
465  // must be two bmodels in the same leaf; sort on 1/z
466  fu = (float)(edge->u - 0xFFFFF) * (1.0 / 0x100000);
467  newzi = surf->d_ziorigin + fv*surf->d_zistepv +
468  fu*surf->d_zistepu;
469  newzibottom = newzi * 0.99;
470 
471  testzi = surf2->d_ziorigin + fv*surf2->d_zistepv +
472  fu*surf2->d_zistepu;
473 
474  if (newzibottom >= testzi)
475  {
476  goto newtop;
477  }
478 
479  newzitop = newzi * 1.01;
480  if (newzitop >= testzi)
481  {
482  if (surf->d_zistepu >= surf2->d_zistepu)
483  {
484  goto newtop;
485  }
486  }
487  }
488 
489 continue_search:
490 
491  do
492  {
493  surf2 = surf2->next;
494  } while (surf->key > surf2->key);
495 
496  if (surf->key == surf2->key)
497  {
498  // if it's two surfaces on the same plane, the one that's already
499  // active is in front, so keep going unless it's a bmodel
500  if (!surf->insubmodel)
501  goto continue_search;
502 
503  // must be two bmodels in the same leaf; sort on 1/z
504  fu = (float)(edge->u - 0xFFFFF) * (1.0 / 0x100000);
505  newzi = surf->d_ziorigin + fv*surf->d_zistepv +
506  fu*surf->d_zistepu;
507  newzibottom = newzi * 0.99;
508 
509  testzi = surf2->d_ziorigin + fv*surf2->d_zistepv +
510  fu*surf2->d_zistepu;
511 
512  if (newzibottom >= testzi)
513  {
514  goto gotposition;
515  }
516 
517  newzitop = newzi * 1.01;
518  if (newzitop >= testzi)
519  {
520  if (surf->d_zistepu >= surf2->d_zistepu)
521  {
522  goto gotposition;
523  }
524  }
525 
526  goto continue_search;
527  }
528 
529  goto gotposition;
530 
531 newtop:
532  // emit a span (obscures current top)
533  iu = edge->u >> 20;
534 
535  if (iu > surf2->last_u)
536  {
537  span = span_p++;
538  span->u = surf2->last_u;
539  span->count = iu - span->u;
540  span->v = current_iv;
541  span->pnext = surf2->spans;
542  surf2->spans = span;
543  }
544 
545  // set last_u on the new span
546  surf->last_u = iu;
547 
548 gotposition:
549  // insert before surf2
550  surf->next = surf2;
551  surf->prev = surf2->prev;
552  surf2->prev->next = surf;
553  surf2->prev = surf;
554  }
555  }
556 }
557 
558 
559 /*
560 ==============
561 R_GenerateSpans
562 ==============
563 */
564 void R_GenerateSpans (void)
565 {
566  edge_t *edge;
567  surf_t *surf;
568 
569 // clear active surfaces to just the background surface
570  surfaces[1].next = surfaces[1].prev = &surfaces[1];
572 
573 // generate spans
574  for (edge=edge_head.next ; edge != &edge_tail; edge=edge->next)
575  {
576  if (edge->surfs[0])
577  {
578  // it has a left surface, so a surface is going away for this span
579  surf = &surfaces[edge->surfs[0]];
580 
581  R_TrailingEdge (surf, edge);
582 
583  if (!edge->surfs[1])
584  continue;
585  }
586 
587  R_LeadingEdge (edge);
588  }
589 
590  R_CleanupSpan ();
591 }
592 
593 #endif // !id386
594 
595 
596 /*
597 ==============
598 R_GenerateSpansBackward
599 ==============
600 */
602 {
603  edge_t *edge;
604 
605 // clear active surfaces to just the background surface
606  surfaces[1].next = surfaces[1].prev = &surfaces[1];
608 
609 // generate spans
610  for (edge=edge_head.next ; edge != &edge_tail; edge=edge->next)
611  {
612  if (edge->surfs[0])
613  R_TrailingEdge (&surfaces[edge->surfs[0]], edge);
614 
615  if (edge->surfs[1])
616  R_LeadingEdgeBackwards (edge);
617  }
618 
619  R_CleanupSpan ();
620 }
621 
622 
623 /*
624 ==============
625 R_ScanEdges
626 
627 Input:
628 newedges[] array
629  this has links to edges, which have links to surfaces
630 
631 Output:
632 Each surface has a linked list of its visible spans
633 ==============
634 */
635 void R_ScanEdges (void)
636 {
637  int iv, bottom;
638  byte basespans[MAXSPANS*sizeof(espan_t)+CACHE_SIZE];
639  espan_t *basespan_p;
640  surf_t *s;
641 
642  basespan_p = (espan_t *)
643  ((long)(basespans + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
644  max_span_p = &basespan_p[MAXSPANS - r_refdef.vrect.width];
645 
646  span_p = basespan_p;
647 
648 // clear active edges to just the background edges around the whole screen
649 // FIXME: most of this only needs to be set up once
650  edge_head.u = r_refdef.vrect.x << 20;
652  edge_head.u_step = 0;
653  edge_head.prev = NULL;
655  edge_head.surfs[0] = 0;
656  edge_head.surfs[1] = 1;
657 
658  edge_tail.u = (r_refdef.vrectright << 20) + 0xFFFFF;
660  edge_tail.u_step = 0;
663  edge_tail.surfs[0] = 1;
664  edge_tail.surfs[1] = 0;
665 
666  edge_aftertail.u = -1; // force a move
670 
671 // FIXME: do we need this now that we clamp x in r_draw.c?
672  edge_sentinel.u = 2000 << 24; // make sure nothing sorts past this
674 
675 //
676 // process all scan lines
677 //
679 
680  for (iv=r_refdef.vrect.y ; iv<bottom ; iv++)
681  {
682  current_iv = iv;
683  fv = (float)iv;
684 
685  // mark that the head (background start) span is pre-included
686  surfaces[1].spanstate = 1;
687 
688  if (newedges[iv])
689  {
691  }
692 
693  (*pdrawfunc) ();
694 
695  // flush the span list if we can't be sure we have enough spans left for
696  // the next scan
697  if (span_p > max_span_p)
698  {
699  D_DrawSurfaces ();
700 
701  // clear the surface span pointers
702  for (s = &surfaces[1] ; s<surface_p ; s++)
703  s->spans = NULL;
704 
705  span_p = basespan_p;
706  }
707 
708  if (removeedges[iv])
710 
711  if (edge_head.next != &edge_tail)
713  }
714 
715 // do the last scan (no need to step or sort or remove on the last scan)
716 
717  current_iv = iv;
718  fv = (float)iv;
719 
720 // mark that the head (background start) span is pre-included
721  surfaces[1].spanstate = 1;
722 
723  if (newedges[iv])
725 
726  (*pdrawfunc) ();
727 
728 // draw whatever's left in the span list
729  D_DrawSurfaces ();
730 }
731 
732 
733 /*
734 =========================================================================
735 
736 SURFACE FILLING
737 
738 =========================================================================
739 */
740 
746 
747 /*
748 =============
749 D_MipLevelForScale
750 =============
751 */
752 int D_MipLevelForScale (float scale)
753 {
754  int lmiplevel;
755 
756  if (scale >= d_scalemip[0] )
757  lmiplevel = 0;
758  else if (scale >= d_scalemip[1] )
759  lmiplevel = 1;
760  else if (scale >= d_scalemip[2] )
761  lmiplevel = 2;
762  else
763  lmiplevel = 3;
764 
765  if (lmiplevel < d_minmip)
766  lmiplevel = d_minmip;
767 
768  return lmiplevel;
769 }
770 
771 
772 /*
773 ==============
774 D_FlatFillSurface
775 
776 Simple single color fill with no texture mapping
777 ==============
778 */
779 void D_FlatFillSurface (surf_t *surf, int color)
780 {
781  espan_t *span;
782  byte *pdest;
783  int u, u2;
784 
785  for (span=surf->spans ; span ; span=span->pnext)
786  {
787  pdest = (byte *)d_viewbuffer + r_screenwidth*span->v;
788  u = span->u;
789  u2 = span->u + span->count - 1;
790  for ( ; u <= u2 ; u++)
791  pdest[u] = color;
792  }
793 }
794 
795 
796 /*
797 ==============
798 D_CalcGradients
799 ==============
800 */
802 {
803  mplane_t *pplane;
804  float mipscale;
805  vec3_t p_temp1;
806  vec3_t p_saxis, p_taxis;
807  float t;
808 
809  pplane = pface->plane;
810 
811  mipscale = 1.0 / (float)(1 << miplevel);
812 
813  TransformVector (pface->texinfo->vecs[0], p_saxis);
814  TransformVector (pface->texinfo->vecs[1], p_taxis);
815 
816  t = xscaleinv * mipscale;
817  d_sdivzstepu = p_saxis[0] * t;
818  d_tdivzstepu = p_taxis[0] * t;
819 
820  t = yscaleinv * mipscale;
821  d_sdivzstepv = -p_saxis[1] * t;
822  d_tdivzstepv = -p_taxis[1] * t;
823 
824  d_sdivzorigin = p_saxis[2] * mipscale - xcenter * d_sdivzstepu -
826  d_tdivzorigin = p_taxis[2] * mipscale - xcenter * d_tdivzstepu -
828 
829  VectorScale (transformed_modelorg, mipscale, p_temp1);
830 
831  t = 0x10000*mipscale;
832  sadjust = ((fixed16_t)(DotProduct (p_temp1, p_saxis) * 0x10000 + 0.5)) -
833  ((pface->texturemins[0] << 16) >> miplevel)
834  + pface->texinfo->vecs[0][3]*t;
835  tadjust = ((fixed16_t)(DotProduct (p_temp1, p_taxis) * 0x10000 + 0.5)) -
836  ((pface->texturemins[1] << 16) >> miplevel)
837  + pface->texinfo->vecs[1][3]*t;
838 
839  // PGM - changing flow speed for non-warping textures.
841  {
842  if(pface->texinfo->flags & SURF_WARP)
843  sadjust += 0x10000 * (-128 * ( (r_newrefdef.time * 0.25) - (int)(r_newrefdef.time * 0.25) ));
844  else
845  sadjust += 0x10000 * (-128 * ( (r_newrefdef.time * 0.77) - (int)(r_newrefdef.time * 0.77) ));
846  }
847  // PGM
848 
849 //
850 // -1 (-epsilon) so we never wander off the edge of the texture
851 //
852  bbextents = ((pface->extents[0] << 16) >> miplevel) - 1;
853  bbextentt = ((pface->extents[1] << 16) >> miplevel) - 1;
854 }
855 
856 
857 /*
858 ==============
859 D_BackgroundSurf
860 
861 The grey background filler seen when there is a hole in the map
862 ==============
863 */
865 {
866 // set up a gradient for the background surface that places it
867 // effectively at infinity distance from the viewpoint
868  d_zistepu = 0;
869  d_zistepv = 0;
870  d_ziorigin = -0.9;
871 
872  D_FlatFillSurface (s, (int)sw_clearcolor->value & 0xFF);
873  D_DrawZSpans (s->spans);
874 }
875 
876 /*
877 =================
878 D_TurbulentSurf
879 =================
880 */
882 {
883  d_zistepu = s->d_zistepu;
884  d_zistepv = s->d_zistepv;
885  d_ziorigin = s->d_ziorigin;
886 
887  pface = s->msurf;
888  miplevel = 0;
890  cachewidth = 64;
891 
892  if (s->insubmodel)
893  {
894  // FIXME: we don't want to do all this for every polygon!
895  // TODO: store once at start of frame
896  currententity = s->entity; //FIXME: make this passed in to
897  // R_RotateBmodel ()
901 
902  R_RotateBmodel (); // FIXME: don't mess with the frustum,
903  // make entity passed in
904  }
905 
907 
908 //============
909 //PGM
910  // textures that aren't warping are just flowing. Use NonTurbulent8 instead
911  if(!(pface->texinfo->flags & SURF_WARP))
912  NonTurbulent8 (s->spans);
913  else
914  Turbulent8 (s->spans);
915 //PGM
916 //============
917 
918  D_DrawZSpans (s->spans);
919 
920  if (s->insubmodel)
921  {
922  //
923  // restore the old drawing state
924  // FIXME: we don't want to do this every time!
925  // TODO: speed up
926  //
927  currententity = NULL; // &r_worldentity;
934  }
935 }
936 
937 /*
938 ==============
939 D_SkySurf
940 ==============
941 */
942 void D_SkySurf (surf_t *s)
943 {
944  pface = s->msurf;
945  miplevel = 0;
946  if (!pface->texinfo->image)
947  return;
949  cachewidth = 256;
950 
951  d_zistepu = s->d_zistepu;
952  d_zistepv = s->d_zistepv;
953  d_ziorigin = s->d_ziorigin;
954 
956 
957  D_DrawSpans16 (s->spans);
958 
959 // set up a gradient for the background surface that places it
960 // effectively at infinity distance from the viewpoint
961  d_zistepu = 0;
962  d_zistepv = 0;
963  d_ziorigin = -0.9;
964 
965  D_DrawZSpans (s->spans);
966 }
967 
968 /*
969 ==============
970 D_SolidSurf
971 
972 Normal surface cached, texture mapped surface
973 ==============
974 */
976 {
977  d_zistepu = s->d_zistepu;
978  d_zistepv = s->d_zistepv;
979  d_ziorigin = s->d_ziorigin;
980 
981  if (s->insubmodel)
982  {
983  // FIXME: we don't want to do all this for every polygon!
984  // TODO: store once at start of frame
985  currententity = s->entity; //FIXME: make this passed in to
986  // R_RotateBmodel ()
989 
990  R_RotateBmodel (); // FIXME: don't mess with the frustum,
991  // make entity passed in
992  }
993  else
995 
996  pface = s->msurf;
997 #if 1
999 #else
1000  {
1001  float dot;
1002  float normal[3];
1003 
1004  if ( s->insubmodel )
1005  {
1006  VectorCopy( pface->plane->normal, normal );
1007 // TransformVector( pface->plane->normal, normal);
1008  dot = DotProduct( normal, vpn );
1009  }
1010  else
1011  {
1012  VectorCopy( pface->plane->normal, normal );
1013  dot = DotProduct( normal, vpn );
1014  }
1015 
1016  if ( pface->flags & SURF_PLANEBACK )
1017  dot = -dot;
1018 
1019  if ( dot > 0 )
1020  printf( "blah" );
1021 
1023  }
1024 #endif
1025 
1026 // FIXME: make this passed in to D_CacheSurface
1028 
1031 
1033 
1034  D_DrawSpans16 (s->spans);
1035 
1036  D_DrawZSpans (s->spans);
1037 
1038  if (s->insubmodel)
1039  {
1040  //
1041  // restore the old drawing state
1042  // FIXME: we don't want to do this every time!
1043  // TODO: speed up
1044  //
1047  VectorCopy (base_vpn, vpn);
1048  VectorCopy (base_vup, vup);
1050  R_TransformFrustum ();
1051  currententity = NULL; //&r_worldentity;
1052  }
1053 }
1054 
1055 /*
1056 =============
1057 D_DrawflatSurfaces
1058 
1059 To allow developers to see the polygon carving of the world
1060 =============
1061 */
1063 {
1064  surf_t *s;
1065 
1066  for (s = &surfaces[1] ; s<surface_p ; s++)
1067  {
1068  if (!s->spans)
1069  continue;
1070 
1071  d_zistepu = s->d_zistepu;
1072  d_zistepv = s->d_zistepv;
1073  d_ziorigin = s->d_ziorigin;
1074 
1075  // make a stable color for each surface by taking the low
1076  // bits of the msurface pointer
1077  D_FlatFillSurface (s, (int)s->msurf & 0xFF);
1078  D_DrawZSpans (s->spans);
1079  }
1080 }
1081 
1082 /*
1083 ==============
1084 D_DrawSurfaces
1085 
1086 Rasterize all the span lists. Guaranteed zero overdraw.
1087 May be called more than once a frame if the surf list overflows (higher res)
1088 ==============
1089 */
1090 void D_DrawSurfaces (void)
1091 {
1092  surf_t *s;
1093 
1094 // currententity = NULL; //&r_worldentity;
1098 
1099  if (!sw_drawflat->value)
1100  {
1101  for (s = &surfaces[1] ; s<surface_p ; s++)
1102  {
1103  if (!s->spans)
1104  continue;
1105 
1106  r_drawnpolycount++;
1107 
1109  D_SolidSurf (s);
1110  else if (s->flags & SURF_DRAWSKYBOX)
1111  D_SkySurf (s);
1112  else if (s->flags & SURF_DRAWBACKGROUND)
1113  D_BackgroundSurf (s);
1114  else if (s->flags & SURF_DRAWTURB)
1115  D_TurbulentSurf (s);
1116  }
1117  }
1118  else
1119  D_DrawflatSurfaces ();
1120 
1121  currententity = NULL; //&r_worldentity;
1123  R_TransformFrustum ();
1124 }
1125 
edge_tail_u_shift20
int edge_tail_u_shift20
Definition: r_edge.c:66
d_scalemip
float d_scalemip[3]
Definition: r_misc.c:32
cachewidth
int cachewidth
Definition: r_main.c:180
espan_s
Definition: r_local.h:375
errorterm
int errorterm
Definition: r_edge.c:80
d_sdivzorigin
float d_sdivzorigin
Definition: r_main.c:175
transformed_modelorg
vec3_t transformed_modelorg
Definition: r_edge.c:743
R_BeginEdgeFrame
void R_BeginEdgeFrame(void)
Definition: r_edge.c:109
entity_s::origin
float origin[3]
Definition: ref.h:57
int
CONST PIXELFORMATDESCRIPTOR int
Definition: qgl_win.c:35
VectorSubtract
#define VectorSubtract(a, b, c)
Definition: q_shared.h:156
surfcache_s
Definition: r_local.h:360
D_BackgroundSurf
void D_BackgroundSurf(surf_t *s)
Definition: r_edge.c:864
bottom
GLdouble GLdouble bottom
Definition: qgl_win.c:159
surf_s::next
struct surf_s * next
Definition: r_local.h:401
R_SurfacePatch
void R_SurfacePatch(void)
Definition: r_misc.c:524
espan_t
struct espan_s espan_t
v
GLdouble v
Definition: qgl_win.c:143
D_MipLevelForScale
int D_MipLevelForScale(float scale)
Definition: r_edge.c:752
yscaleinv
float yscaleinv
Definition: r_local.h:540
d_tdivzstepv
float d_tdivzstepv
Definition: r_local.h:482
CACHE_SIZE
#define CACHE_SIZE
Definition: d_ifacea.h:22
D_CacheSurface
surfcache_t * D_CacheSurface(msurface_t *surface, int miplevel)
Definition: r_surf.c:575
MAXHEIGHT
#define MAXHEIGHT
Definition: d_ifacea.h:19
vright
vec3_t vright
Definition: r_main.c:68
surf_s::flags
int flags
Definition: r_local.h:410
R_TrailingEdge
void R_TrailingEdge(surf_t *surf, edge_t *edge)
Definition: r_edge.c:398
VectorScale
void VectorScale(vec3_t in, vec_t scale, vec3_t out)
Definition: q_shared.c:782
d_viewbuffer
pixel_t * d_viewbuffer
Definition: r_main.c:181
surf_max
surf_t * surf_max
Definition: r_edge.c:51
modelorg
vec3_t modelorg
Definition: r_bsp.c:29
r_currentkey
int r_currentkey
Definition: r_edge.c:62
d_tdivzorigin
float d_tdivzorigin
Definition: r_local.h:483
espan_s::pnext
struct espan_s * pnext
Definition: r_local.h:378
fv
float fv
Definition: r_edge.c:75
local_modelorg
vec3_t local_modelorg
Definition: r_edge.c:745
r_origin
vec3_t r_origin
Definition: r_main.c:69
xscaleinv
float xscaleinv
Definition: r_main.c:77
edge_s::surfs
unsigned short surfs[2]
Definition: r_local.h:426
pdrawfunc
static void(* pdrawfunc)(void)
Definition: r_edge.c:68
currententity
entity_t * currententity
Definition: r_bsp.c:28
SURF_WARP
#define SURF_WARP
Definition: qfiles.h:372
r_local.h
mplane_s::normal
vec3_t normal
Definition: r_model.h:59
erroradjustup
int erroradjustup
Definition: r_edge.c:80
msurface_s::extents
short extents[2]
Definition: r_model.h:110
D_SkySurf
void D_SkySurf(surf_t *s)
Definition: r_edge.c:942
sw_draworder
cvar_t * sw_draworder
Definition: r_main.c:116
vup
vec3_t vup
Definition: r_main.c:66
msurface_s::plane
mplane_t * plane
Definition: r_model.h:100
surf_s::spans
struct espan_s * spans
Definition: r_local.h:403
R_LeadingEdgeBackwards
void R_LeadingEdgeBackwards(edge_t *edge)
Definition: r_edge.c:318
r_numallocatededges
int r_numallocatededges
Definition: r_main.c:49
espan_s::count
int count
Definition: r_local.h:377
edge_p
edge_t * edge_p
Definition: r_edge.c:49
edge_s::next
struct edge_s * next
Definition: r_local.h:425
SURF_PLANEBACK
#define SURF_PLANEBACK
Definition: r_model.h:68
D_DrawSurfaces
void D_DrawSurfaces(void)
Definition: r_edge.c:1090
mtexinfo_s::image
image_t * image
Definition: r_model.h:87
lists
GLenum const GLvoid * lists
Definition: qgl_win.c:72
base_vup
vec3_t base_vup
Definition: r_local.h:521
d_ziorigin
float d_ziorigin
Definition: r_local.h:483
base_vpn
vec3_t base_vpn
Definition: r_local.h:522
r_edges
edge_t * r_edges
Definition: r_edge.c:49
sw_drawflat
cvar_t * sw_drawflat
Definition: r_main.c:115
auxedges
edge_t * auxedges
Definition: r_edge.c:48
miplevel
static int miplevel
Definition: r_edge.c:77
base_vright
vec3_t base_vright
Definition: r_local.h:523
surf_s::entity
entity_t * entity
Definition: r_local.h:412
D_FlatFillSurface
void D_FlatFillSurface(surf_t *surf, int color)
Definition: r_edge.c:779
bbextentt
fixed16_t bbextentt
Definition: r_local.h:486
edge_s::u_step
fixed16_t u_step
Definition: r_local.h:424
D_TurbulentSurf
void D_TurbulentSurf(surf_t *s)
Definition: r_edge.c:881
espan_s::v
int v
Definition: r_local.h:377
msurface_s::texinfo
mtexinfo_t * texinfo
Definition: r_model.h:112
scale_for_mip
float scale_for_mip
Definition: r_edge.c:79
edge_tail
edge_t edge_tail
Definition: r_edge.c:71
t
GLdouble t
Definition: qgl_win.c:328
R_RemoveEdges
void R_RemoveEdges(edge_t *pedge)
Definition: r_edge.c:196
edge_aftertail
edge_t edge_aftertail
Definition: r_edge.c:72
surf_s::nearzi
float nearzi
Definition: r_local.h:413
pixel_t
unsigned char pixel_t
Definition: r_local.h:78
pface
msurface_t * pface
Definition: r_edge.c:741
SURF_FLOWING
#define SURF_FLOWING
Definition: qfiles.h:375
sadjust
fixed16_t sadjust
Definition: r_local.h:672
surf_s::msurf
msurface_t * msurf
Definition: r_local.h:411
d_tdivzstepu
float d_tdivzstepu
Definition: r_local.h:481
r_newrefdef
refdef_t r_newrefdef
Definition: r_main.c:36
edge_max
edge_t * edge_max
Definition: r_edge.c:49
DotProduct
#define DotProduct(x, y)
Definition: q_shared.h:155
D_DrawSpans16
void D_DrawSpans16(espan_t *pspans)
Definition: r_scan.c:399
R_CleanupSpan
void R_CleanupSpan(void)
Definition: r_edge.c:284
edge_head
edge_t edge_head
Definition: r_edge.c:70
cvar_s::value
float value
Definition: q_shared.h:324
D_DrawflatSurfaces
void D_DrawflatSurfaces(void)
Definition: r_edge.c:1062
R_RotateBmodel
void R_RotateBmodel(void)
Definition: r_bsp.c:75
espan_s::u
int u
Definition: r_local.h:377
SURF_DRAWTURB
#define SURF_DRAWTURB
Definition: r_model.h:70
edge_s::u
fixed16_t u
Definition: r_local.h:423
NULL
#define NULL
Definition: q_shared.h:60
r_drawnpolycount
int r_drawnpolycount
Definition: r_main.c:95
bbextents
fixed16_t bbextents
Definition: r_local.h:673
refdef_t::time
float time
Definition: ref.h:127
edge_s::nextremove
struct edge_s * nextremove
Definition: r_local.h:427
Turbulent8
void Turbulent8(espan_t *pspan)
Definition: r_scan.c:124
vrect_s::x
int x
Definition: vid.h:24
d_zistepv
float d_zistepv
Definition: r_local.h:482
R_GenerateSpansBackward
void R_GenerateSpansBackward(void)
Definition: r_edge.c:601
surface_p
surf_t * surface_p
Definition: r_edge.c:51
image_s::pixels
byte * pixels[4]
Definition: r_local.h:72
R_InsertNewEdges
void R_InsertNewEdges(edge_t *edgestoadd, edge_t *edgelist)
Definition: r_edge.c:155
r_screenwidth
int r_screenwidth
Definition: r_main.c:81
d_zistepu
float d_zistepu
Definition: r_local.h:481
edge_sentinel
edge_t edge_sentinel
Definition: r_edge.c:73
ycenter
float ycenter
Definition: r_local.h:538
SURF_DRAWSKYBOX
#define SURF_DRAWSKYBOX
Definition: r_model.h:72
surf_s::key
int key
Definition: r_local.h:404
mtexinfo_s::mipadjust
float mipadjust
Definition: r_model.h:86
msurface_s::flags
int flags
Definition: r_model.h:101
d_minmip
int d_minmip
Definition: r_misc.c:31
R_GenerateSpans
void R_GenerateSpans(void)
Definition: r_edge.c:564
surf_s::d_zistepv
float d_zistepv
Definition: r_local.h:415
surf_s::d_zistepu
float d_zistepu
Definition: r_local.h:415
span_p
espan_t * span_p
Definition: r_edge.c:60
VectorCopy
#define VectorCopy(a, b)
Definition: q_shared.h:158
R_EdgeCodeStart
void R_EdgeCodeStart(void)
surf_s::d_ziorigin
float d_ziorigin
Definition: r_local.h:415
mtexinfo_s::vecs
float vecs[2][4]
Definition: r_model.h:85
oldrefdef_t::vrect
vrect_t vrect
Definition: r_local.h:112
R_StepActiveU
void R_StepActiveU(edge_t *pedge)
Definition: r_edge.c:216
removeedges
edge_t * removeedges[MAXHEIGHT]
Definition: r_edge.c:58
fixed16_t
int fixed16_t
Definition: q_shared.h:132
vec3_origin
vec3_t vec3_origin
Definition: q_shared.c:24
vrect_s::width
int width
Definition: vid.h:24
MAXSPANS
#define MAXSPANS
Definition: r_local.h:200
current_iv
int current_iv
Definition: r_edge.c:64
edge_s::prev
struct edge_s * prev
Definition: r_local.h:425
surf_s::last_u
int last_u
Definition: r_local.h:405
D_SolidSurf
void D_SolidSurf(surf_t *s)
Definition: r_edge.c:975
u2
GLdouble GLdouble u2
Definition: qgl_win.c:225
surf_s::insubmodel
qboolean insubmodel
Definition: r_local.h:414
surfcache_s::data
byte data[4]
Definition: r_local.h:371
newedges
edge_t * newedges[MAXHEIGHT]
Definition: r_edge.c:57
world_transformed_modelorg
vec3_t world_transformed_modelorg
Definition: r_edge.c:744
SURF_DRAWBACKGROUND
#define SURF_DRAWBACKGROUND
Definition: r_model.h:71
NonTurbulent8
void NonTurbulent8(espan_t *pspan)
Definition: r_scan.c:259
msurface_s
Definition: r_model.h:93
D_DrawZSpans
void D_DrawZSpans(espan_t *pspans)
Definition: r_scan.c:537
oldrefdef_t::vrectright
int vrectright
Definition: r_local.h:115
max_span_p
espan_t * max_span_p
Definition: r_edge.c:60
d_sdivzstepu
float d_sdivzstepu
Definition: r_main.c:173
R_TransformFrustum
void R_TransformFrustum(void)
Definition: r_misc.c:187
mplane_s
Definition: r_model.h:57
mtexinfo_s::flags
int flags
Definition: r_model.h:88
surf_s::prev
struct surf_s * prev
Definition: r_local.h:402
R_EdgeCodeEnd
void R_EdgeCodeEnd(void)
msurface_s::texturemins
short texturemins[2]
Definition: r_model.h:109
surfcache_s::width
unsigned width
Definition: r_local.h:367
R_ScanEdges
void R_ScanEdges(void)
Definition: r_edge.c:635
pcurrentcache
surfcache_t * pcurrentcache
Definition: r_edge.c:742
edge_head_u_shift20
int edge_head_u_shift20
Definition: r_edge.c:66
d_sdivzstepv
float d_sdivzstepv
Definition: r_main.c:174
sw_clearcolor
cvar_t * sw_clearcolor
Definition: r_main.c:114
cacheblock
pixel_t * cacheblock
Definition: r_main.c:179
r_worldentity
entity_t r_worldentity
Definition: r_main.c:29
tadjust
fixed16_t tadjust
Definition: r_local.h:485
R_LeadingEdge
void R_LeadingEdge(edge_t *edge)
Definition: r_edge.c:439
xcenter
float xcenter
Definition: r_main.c:75
vpn
vec3_t vpn
Definition: r_main.c:67
erroradjustdown
int erroradjustdown
Definition: r_edge.c:80
TransformVector
void TransformVector(vec3_t in, vec3_t out)
Definition: r_misc.c:215
vec3_t
vec_t vec3_t[3]
Definition: q_shared.h:127
surf_s
Definition: r_local.h:399
surfaces
surf_t * surfaces
Definition: r_edge.c:51
ubasestep
int ubasestep
Definition: r_edge.c:80
r_refdef
oldrefdef_t r_refdef
Definition: r_main.c:74
void
void(APIENTRY *qglAccum)(GLenum op
oldrefdef_t::vrectbottom
int vrectbottom
Definition: r_local.h:115
edge_s
Definition: r_local.h:421
surf_s::spanstate
int spanstate
Definition: r_local.h:406
D_CalcGradients
void D_CalcGradients(msurface_t *pface)
Definition: r_edge.c:801
vrect_s::y
int y
Definition: vid.h:24