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