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