vkQuake2 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  ((intptr_t)(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
673  edge_sentinel.u = 32767 << 16; // qb: FS: Sezero - integer shift overflow fix
675 
676 //
677 // process all scan lines
678 //
680 
681  for (iv=r_refdef.vrect.y ; iv<bottom ; iv++)
682  {
683  current_iv = iv;
684  fv = (float)iv;
685 
686  // mark that the head (background start) span is pre-included
687  surfaces[1].spanstate = 1;
688 
689  if (newedges[iv])
690  {
692  }
693 
694  (*pdrawfunc) ();
695 
696  // flush the span list if we can't be sure we have enough spans left for
697  // the next scan
698  if (span_p > max_span_p)
699  {
700  D_DrawSurfaces ();
701 
702  // clear the surface span pointers
703  for (s = &surfaces[1] ; s<surface_p ; s++)
704  s->spans = NULL;
705 
706  span_p = basespan_p;
707  }
708 
709  if (removeedges[iv])
711 
712  if (edge_head.next != &edge_tail)
714  }
715 
716 // do the last scan (no need to step or sort or remove on the last scan)
717 
718  current_iv = iv;
719  fv = (float)iv;
720 
721 // mark that the head (background start) span is pre-included
722  surfaces[1].spanstate = 1;
723 
724  if (newedges[iv])
726 
727  (*pdrawfunc) ();
728 
729 // draw whatever's left in the span list
730  D_DrawSurfaces ();
731 }
732 
733 
734 /*
735 =========================================================================
736 
737 SURFACE FILLING
738 
739 =========================================================================
740 */
741 
747 
748 /*
749 =============
750 D_MipLevelForScale
751 =============
752 */
753 int D_MipLevelForScale (float scale)
754 {
755  int lmiplevel;
756 
757  if (scale >= d_scalemip[0] )
758  lmiplevel = 0;
759  else if (scale >= d_scalemip[1] )
760  lmiplevel = 1;
761  else if (scale >= d_scalemip[2] )
762  lmiplevel = 2;
763  else
764  lmiplevel = 3;
765 
766  if (lmiplevel < d_minmip)
767  lmiplevel = d_minmip;
768 
769  return lmiplevel;
770 }
771 
772 
773 /*
774 ==============
775 D_FlatFillSurface
776 
777 Simple single color fill with no texture mapping
778 ==============
779 */
780 void D_FlatFillSurface (surf_t *surf, int color)
781 {
782  espan_t *span;
783  byte *pdest;
784  int u, u2;
785 
786  for (span=surf->spans ; span ; span=span->pnext)
787  {
788  pdest = (byte *)d_viewbuffer + r_screenwidth*span->v;
789  u = span->u;
790  u2 = span->u + span->count - 1;
791  for ( ; u <= u2 ; u++)
792  pdest[u] = color;
793  }
794 }
795 
796 
797 /*
798 ==============
799 D_CalcGradients
800 ==============
801 */
803 {
804  float mipscale;
805  vec3_t p_temp1;
806  vec3_t p_saxis, p_taxis;
807  float t;
808 
809  mipscale = 1.0 / (float)(1 << miplevel);
810 
811  TransformVector (pface->texinfo->vecs[0], p_saxis);
812  TransformVector (pface->texinfo->vecs[1], p_taxis);
813 
814  t = xscaleinv * mipscale;
815  d_sdivzstepu = p_saxis[0] * t;
816  d_tdivzstepu = p_taxis[0] * t;
817 
818  t = yscaleinv * mipscale;
819  d_sdivzstepv = -p_saxis[1] * t;
820  d_tdivzstepv = -p_taxis[1] * t;
821 
822  d_sdivzorigin = p_saxis[2] * mipscale - xcenter * d_sdivzstepu -
824  d_tdivzorigin = p_taxis[2] * mipscale - xcenter * d_tdivzstepu -
826 
827  VectorScale (transformed_modelorg, mipscale, p_temp1);
828 
829  t = 0x10000*mipscale;
830  sadjust = ((fixed16_t)(DotProduct (p_temp1, p_saxis) * 0x10000 + 0.5)) -
831  ((pface->texturemins[0] << 16) >> miplevel)
832  + pface->texinfo->vecs[0][3]*t;
833  tadjust = ((fixed16_t)(DotProduct (p_temp1, p_taxis) * 0x10000 + 0.5)) -
834  ((pface->texturemins[1] << 16) >> miplevel)
835  + pface->texinfo->vecs[1][3]*t;
836 
837  // PGM - changing flow speed for non-warping textures.
839  {
840  if(pface->texinfo->flags & SURF_WARP)
841  sadjust += 0x10000 * (-128 * ( (r_newrefdef.time * 0.25) - (int)(r_newrefdef.time * 0.25) ));
842  else
843  sadjust += 0x10000 * (-128 * ( (r_newrefdef.time * 0.77) - (int)(r_newrefdef.time * 0.77) ));
844  }
845  // PGM
846 
847 //
848 // -1 (-epsilon) so we never wander off the edge of the texture
849 //
850  bbextents = ((pface->extents[0] << 16) >> miplevel) - 1;
851  bbextentt = ((pface->extents[1] << 16) >> miplevel) - 1;
852 }
853 
854 
855 /*
856 ==============
857 D_BackgroundSurf
858 
859 The grey background filler seen when there is a hole in the map
860 ==============
861 */
863 {
864 // set up a gradient for the background surface that places it
865 // effectively at infinity distance from the viewpoint
866  d_zistepu = 0;
867  d_zistepv = 0;
868  d_ziorigin = -0.9;
869 
870  D_FlatFillSurface (s, (int)sw_clearcolor->value & 0xFF);
871  D_DrawZSpans (s->spans);
872 }
873 
874 /*
875 =================
876 D_TurbulentSurf
877 =================
878 */
880 {
881  d_zistepu = s->d_zistepu;
882  d_zistepv = s->d_zistepv;
883  d_ziorigin = s->d_ziorigin;
884 
885  pface = s->msurf;
886  miplevel = 0;
888  cachewidth = 64;
889 
890  if (s->insubmodel)
891  {
892  // FIXME: we don't want to do all this for every polygon!
893  // TODO: store once at start of frame
894  currententity = s->entity; //FIXME: make this passed in to
895  // R_RotateBmodel ()
899 
900  R_RotateBmodel (); // FIXME: don't mess with the frustum,
901  // make entity passed in
902  }
903 
905 
906 //============
907 //PGM
908  // textures that aren't warping are just flowing. Use NonTurbulent8 instead
909  if(!(pface->texinfo->flags & SURF_WARP))
910  NonTurbulent8 (s->spans);
911  else
912  Turbulent8 (s->spans);
913 //PGM
914 //============
915 
916  D_DrawZSpans (s->spans);
917 
918  if (s->insubmodel)
919  {
920  //
921  // restore the old drawing state
922  // FIXME: we don't want to do this every time!
923  // TODO: speed up
924  //
925  currententity = NULL; // &r_worldentity;
932  }
933 }
934 
935 /*
936 ==============
937 D_SkySurf
938 ==============
939 */
941 {
942  pface = s->msurf;
943  miplevel = 0;
944  if (!pface->texinfo->image)
945  return;
947  cachewidth = 256;
948 
949  d_zistepu = s->d_zistepu;
950  d_zistepv = s->d_zistepv;
951  d_ziorigin = s->d_ziorigin;
952 
954 
955  D_DrawSpans16 (s->spans);
956 
957 // set up a gradient for the background surface that places it
958 // effectively at infinity distance from the viewpoint
959  d_zistepu = 0;
960  d_zistepv = 0;
961  d_ziorigin = -0.9;
962 
963  D_DrawZSpans (s->spans);
964 }
965 
966 /*
967 ==============
968 D_SolidSurf
969 
970 Normal surface cached, texture mapped surface
971 ==============
972 */
974 {
975  d_zistepu = s->d_zistepu;
976  d_zistepv = s->d_zistepv;
977  d_ziorigin = s->d_ziorigin;
978 
979  if (s->insubmodel)
980  {
981  // FIXME: we don't want to do all this for every polygon!
982  // TODO: store once at start of frame
983  currententity = s->entity; //FIXME: make this passed in to
984  // R_RotateBmodel ()
987 
988  R_RotateBmodel (); // FIXME: don't mess with the frustum,
989  // make entity passed in
990  }
991  else
993 
994  pface = s->msurf;
995 #if 1
997 #else
998  {
999  float dot;
1000  float normal[3];
1001 
1002  if ( s->insubmodel )
1003  {
1004  VectorCopy( pface->plane->normal, normal );
1005 // TransformVector( pface->plane->normal, normal);
1006  dot = DotProduct( normal, vpn );
1007  }
1008  else
1009  {
1010  VectorCopy( pface->plane->normal, normal );
1011  dot = DotProduct( normal, vpn );
1012  }
1013 
1014  if ( pface->flags & SURF_PLANEBACK )
1015  dot = -dot;
1016 
1017  if ( dot > 0 )
1018  printf( "blah" );
1019 
1021  }
1022 #endif
1023 
1024 // FIXME: make this passed in to D_CacheSurface
1026 
1029 
1031 
1032  D_DrawSpans16 (s->spans);
1033 
1034  D_DrawZSpans (s->spans);
1035 
1036  if (s->insubmodel)
1037  {
1038  //
1039  // restore the old drawing state
1040  // FIXME: we don't want to do this every time!
1041  // TODO: speed up
1042  //
1045  VectorCopy (base_vpn, vpn);
1046  VectorCopy (base_vup, vup);
1048  R_TransformFrustum ();
1049  currententity = NULL; //&r_worldentity;
1050  }
1051 }
1052 
1053 /*
1054 =============
1055 D_DrawflatSurfaces
1056 
1057 To allow developers to see the polygon carving of the world
1058 =============
1059 */
1061 {
1062  surf_t *s;
1063 
1064  for (s = &surfaces[1] ; s<surface_p ; s++)
1065  {
1066  if (!s->spans)
1067  continue;
1068 
1069  d_zistepu = s->d_zistepu;
1070  d_zistepv = s->d_zistepv;
1071  d_ziorigin = s->d_ziorigin;
1072 
1073  // make a stable color for each surface by taking the low
1074  // bits of the msurface pointer
1075  D_FlatFillSurface (s, (intptr_t)s->msurf & 0xFF);
1076  D_DrawZSpans (s->spans);
1077  }
1078 }
1079 
1080 /*
1081 ==============
1082 D_DrawSurfaces
1083 
1084 Rasterize all the span lists. Guaranteed zero overdraw.
1085 May be called more than once a frame if the surf list overflows (higher res)
1086 ==============
1087 */
1088 void D_DrawSurfaces (void)
1089 {
1090  surf_t *s;
1091 
1092 // currententity = NULL; //&r_worldentity;
1096 
1097  if (!sw_drawflat->value)
1098  {
1099  for (s = &surfaces[1] ; s<surface_p ; s++)
1100  {
1101  if (!s->spans)
1102  continue;
1103 
1104  r_drawnpolycount++;
1105 
1106  if (! (s->flags & (SURF_DRAWSKYBOX|SURF_DRAWBACKGROUND|SURF_DRAWTURB) ) )
1107  D_SolidSurf (s);
1108  else if (s->flags & SURF_DRAWSKYBOX)
1109  D_SkySurf (s);
1110  else if (s->flags & SURF_DRAWBACKGROUND)
1111  D_BackgroundSurf (s);
1112  else if (s->flags & SURF_DRAWTURB)
1113  D_TurbulentSurf (s);
1114  }
1115  }
1116  else
1117  D_DrawflatSurfaces ();
1118 
1119  currententity = NULL; //&r_worldentity;
1121  R_TransformFrustum ();
1122 }
1123 
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:195
espan_s
Definition: r_local.h:404
errorterm
int errorterm
Definition: r_edge.c:80
msurface_s::plane
mplane_t * plane
Definition: r_model.h:100
d_sdivzorigin
float d_sdivzorigin
Definition: r_main.c:190
transformed_modelorg
vec3_t transformed_modelorg
Definition: r_edge.c:744
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:163
surfcache_s
Definition: r_local.h:389
D_BackgroundSurf
void D_BackgroundSurf(surf_t *s)
Definition: r_edge.c:862
bottom
GLdouble GLdouble bottom
Definition: qgl_win.c:159
surf_s::next
struct surf_s * next
Definition: r_local.h:430
R_SurfacePatch
void R_SurfacePatch(void)
Definition: r_misc.c:532
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:753
yscaleinv
float yscaleinv
Definition: r_local.h:576
d_tdivzstepv
float d_tdivzstepv
Definition: r_local.h:518
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:638
MAXHEIGHT
#define MAXHEIGHT
Definition: d_ifacea.h:19
vright
vec3_t vright
Definition: r_main.c:74
surf_s::flags
int flags
Definition: r_local.h:439
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:196
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:519
espan_s::pnext
struct espan_s * pnext
Definition: r_local.h:407
fv
float fv
Definition: r_edge.c:75
local_modelorg
vec3_t local_modelorg
Definition: r_edge.c:746
r_origin
vec3_t r_origin
Definition: r_main.c:75
xscaleinv
float xscaleinv
Definition: r_main.c:83
edge_s::surfs
unsigned short surfs[2]
Definition: r_local.h:455
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:940
sw_draworder
cvar_t * sw_draworder
Definition: r_main.c:122
vup
vec3_t vup
Definition: r_main.c:72
surf_s::spans
struct espan_s * spans
Definition: r_local.h:432
R_LeadingEdgeBackwards
void R_LeadingEdgeBackwards(edge_t *edge)
Definition: r_edge.c:318
r_numallocatededges
int r_numallocatededges
Definition: r_main.c:55
espan_s::count
int count
Definition: r_local.h:406
edge_p
edge_t * edge_p
Definition: r_edge.c:49
edge_s::next
struct edge_s * next
Definition: r_local.h:454
SURF_PLANEBACK
#define SURF_PLANEBACK
Definition: r_model.h:68
u
static int u
Definition: r_part.c:472
D_DrawSurfaces
void D_DrawSurfaces(void)
Definition: r_edge.c:1088
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:557
d_ziorigin
float d_ziorigin
Definition: r_local.h:519
base_vpn
vec3_t base_vpn
Definition: r_local.h:558
r_edges
edge_t * r_edges
Definition: r_edge.c:49
sw_drawflat
cvar_t * sw_drawflat
Definition: r_main.c:121
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:559
D_FlatFillSurface
void D_FlatFillSurface(surf_t *surf, int color)
Definition: r_edge.c:780
bbextentt
fixed16_t bbextentt
Definition: r_local.h:522
edge_s::u_step
fixed16_t u_step
Definition: r_local.h:453
D_TurbulentSurf
void D_TurbulentSurf(surf_t *s)
Definition: r_edge.c:879
espan_s::v
int v
Definition: r_local.h:406
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
pixel_t
unsigned char pixel_t
Definition: r_local.h:84
pface
msurface_t * pface
Definition: r_edge.c:742
SURF_FLOWING
#define SURF_FLOWING
Definition: qfiles.h:375
sadjust
fixed16_t sadjust
Definition: r_local.h:732
d_tdivzstepu
float d_tdivzstepu
Definition: r_local.h:517
r_newrefdef
refdef_t r_newrefdef
Definition: r_main.c:38
edge_max
edge_t * edge_max
Definition: r_edge.c:49
DotProduct
#define DotProduct(x, y)
Definition: q_shared.h:162
D_DrawSpans16
void D_DrawSpans16(espan_t *pspans)
Definition: r_scan.c:429
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:331
D_DrawflatSurfaces
void D_DrawflatSurfaces(void)
Definition: r_edge.c:1060
R_RotateBmodel
void R_RotateBmodel(void)
Definition: r_bsp.c:75
espan_s::u
int u
Definition: r_local.h:406
SURF_DRAWTURB
#define SURF_DRAWTURB
Definition: r_model.h:70
edge_s::u
fixed16_t u
Definition: r_local.h:452
NULL
#define NULL
Definition: q_shared.h:67
r_drawnpolycount
int r_drawnpolycount
Definition: r_main.c:101
bbextents
fixed16_t bbextents
Definition: r_local.h:733
refdef_t::time
float time
Definition: ref.h:109
edge_s::nextremove
struct edge_s * nextremove
Definition: r_local.h:456
Turbulent8
void Turbulent8(espan_t *pspan)
Definition: r_scan.c:150
vrect_s::x
int x
Definition: vid.h:24
d_zistepv
float d_zistepv
Definition: r_local.h:518
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:78
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:87
d_zistepu
float d_zistepu
Definition: r_local.h:517
edge_sentinel
edge_t edge_sentinel
Definition: r_edge.c:73
ycenter
float ycenter
Definition: r_local.h:574
SURF_DRAWSKYBOX
#define SURF_DRAWSKYBOX
Definition: r_model.h:72
surf_s::key
int key
Definition: r_local.h:433
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:444
surf_s::d_zistepu
float d_zistepu
Definition: r_local.h:444
s
static fixed16_t s
Definition: r_scan.c:30
span_p
espan_t * span_p
Definition: r_edge.c:60
VectorCopy
#define VectorCopy(a, b)
Definition: q_shared.h:165
R_EdgeCodeStart
void R_EdgeCodeStart(void)
surf_s::d_ziorigin
float d_ziorigin
Definition: r_local.h:444
mtexinfo_s::vecs
float vecs[2][4]
Definition: r_model.h:85
oldrefdef_t::vrect
vrect_t vrect
Definition: r_local.h:118
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:139
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:208
current_iv
int current_iv
Definition: r_edge.c:64
edge_s::prev
struct edge_s * prev
Definition: r_local.h:454
surf_s::last_u
int last_u
Definition: r_local.h:434
D_SolidSurf
void D_SolidSurf(surf_t *s)
Definition: r_edge.c:973
u2
GLdouble GLdouble u2
Definition: qgl_win.c:225
pdest
static byte * pdest
Definition: r_part.c:470
surf_s::insubmodel
qboolean insubmodel
Definition: r_local.h:443
surfcache_s::data
byte data[4]
Definition: r_local.h:400
newedges
edge_t * newedges[MAXHEIGHT]
Definition: r_edge.c:57
world_transformed_modelorg
vec3_t world_transformed_modelorg
Definition: r_edge.c:745
SURF_DRAWBACKGROUND
#define SURF_DRAWBACKGROUND
Definition: r_model.h:71
NonTurbulent8
void NonTurbulent8(espan_t *pspan)
Definition: r_scan.c:281
msurface_s
Definition: r_model.h:93
D_DrawZSpans
void D_DrawZSpans(espan_t *pspans)
Definition: r_scan.c:574
oldrefdef_t::vrectright
int vrectright
Definition: r_local.h:121
max_span_p
espan_t * max_span_p
Definition: r_edge.c:60
d_sdivzstepu
float d_sdivzstepu
Definition: r_main.c:188
R_TransformFrustum
void R_TransformFrustum(void)
Definition: r_misc.c:187
mtexinfo_s::flags
int flags
Definition: r_model.h:88
surf_s::prev
struct surf_s * prev
Definition: r_local.h:431
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:396
R_ScanEdges
void R_ScanEdges(void)
Definition: r_edge.c:635
pcurrentcache
surfcache_t * pcurrentcache
Definition: r_edge.c:743
edge_head_u_shift20
int edge_head_u_shift20
Definition: r_edge.c:66
d_sdivzstepv
float d_sdivzstepv
Definition: r_main.c:189
sw_clearcolor
cvar_t * sw_clearcolor
Definition: r_main.c:120
cacheblock
pixel_t * cacheblock
Definition: r_main.c:194
r_worldentity
entity_t r_worldentity
Definition: r_main.c:30
tadjust
fixed16_t tadjust
Definition: r_local.h:521
R_LeadingEdge
void R_LeadingEdge(edge_t *edge)
Definition: r_edge.c:439
xcenter
float xcenter
Definition: r_main.c:81
vpn
vec3_t vpn
Definition: r_main.c:73
erroradjustdown
int erroradjustdown
Definition: r_edge.c:80
TransformVector
void TransformVector(vec3_t in, vec3_t out)
Definition: r_misc.c:216
vec3_t
vec_t vec3_t[3]
Definition: q_shared.h:134
surf_s
Definition: r_local.h:428
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:80
void
void(APIENTRY *qglAccum)(GLenum op
oldrefdef_t::vrectbottom
int vrectbottom
Definition: r_local.h:121
edge_s
Definition: r_local.h:450
surf_s::spanstate
int spanstate
Definition: r_local.h:435
D_CalcGradients
void D_CalcGradients(msurface_t *pface)
Definition: r_edge.c:802
vrect_s::y
int y
Definition: vid.h:24