Annotation of quake2/ref_soft/r_edge.c, revision 1.1.1.2

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.