Annotation of quake1/gl_warp.c, revision 1.1.1.1

1.1       root        1: // gl_warp.c -- sky and water polygons
                      2: 
                      3: #include "quakedef.h"
                      4: 
                      5: extern model_t *loadmodel;
                      6: 
                      7: int            skytexturenum;
                      8: 
                      9: int            solidskytexture;
                     10: int            alphaskytexture;
                     11: float  speedscale;             // for top sky and bottom sky
                     12: 
                     13: msurface_t     *warpface;
                     14: 
                     15: #define        SUBDIVIDE_SIZE  64
                     16: 
                     17: void BoundPoly (int numverts, float *verts, vec3_t mins, vec3_t maxs)
                     18: {
                     19:        int             i, j;
                     20:        float   *v;
                     21: 
                     22:        mins[0] = mins[1] = mins[2] = 9999;
                     23:        maxs[0] = maxs[1] = maxs[2] = -9999;
                     24:        v = verts;
                     25:        for (i=0 ; i<numverts ; i++)
                     26:                for (j=0 ; j<3 ; j++, v++)
                     27:                {
                     28:                        if (*v < mins[j])
                     29:                                mins[j] = *v;
                     30:                        if (*v > maxs[j])
                     31:                                maxs[j] = *v;
                     32:                }
                     33: }
                     34: 
                     35: void SubdividePolygon (int numverts, float *verts)
                     36: {
                     37:        int             i, j, k;
                     38:        vec3_t  mins, maxs;
                     39:        float   m;
                     40:        float   *v;
                     41:        vec3_t  front[64], back[64];
                     42:        int             f, b;
                     43:        float   dist[64];
                     44:        float   frac;
                     45:        glpoly_t        *poly;
                     46:        float   s, t;
                     47: 
                     48:        if (numverts > 60)
                     49:                Sys_Error ("numverts = %i", numverts);
                     50: 
                     51:        BoundPoly (numverts, verts, mins, maxs);
                     52: 
                     53:        for (i=0 ; i<3 ; i++)
                     54:        {
                     55:                m = (mins[i] + maxs[i]) * 0.5;
                     56:                m = SUBDIVIDE_SIZE * floor (m/SUBDIVIDE_SIZE + 0.5);
                     57:                if (maxs[i] - m < 8)
                     58:                        continue;
                     59:                if (m - mins[i] < 8)
                     60:                        continue;
                     61: 
                     62:                // cut it
                     63:                v = verts + i;
                     64:                for (j=0 ; j<numverts ; j++, v+= 3)
                     65:                        dist[j] = *v - m;
                     66: 
                     67:                // wrap cases
                     68:                dist[j] = dist[0];
                     69:                v-=i;
                     70:                VectorCopy (verts, v);
                     71: 
                     72:                f = b = 0;
                     73:                v = verts;
                     74:                for (j=0 ; j<numverts ; j++, v+= 3)
                     75:                {
                     76:                        if (dist[j] >= 0)
                     77:                        {
                     78:                                VectorCopy (v, front[f]);
                     79:                                f++;
                     80:                        }
                     81:                        if (dist[j] <= 0)
                     82:                        {
                     83:                                VectorCopy (v, back[b]);
                     84:                                b++;
                     85:                        }
                     86:                        if (dist[j] == 0 || dist[j+1] == 0)
                     87:                                continue;
                     88:                        if ( (dist[j] > 0) != (dist[j+1] > 0) )
                     89:                        {
                     90:                                // clip point
                     91:                                frac = dist[j] / (dist[j] - dist[j+1]);
                     92:                                for (k=0 ; k<3 ; k++)
                     93:                                        front[f][k] = back[b][k] = v[k] + frac*(v[3+k] - v[k]);
                     94:                                f++;
                     95:                                b++;
                     96:                        }
                     97:                }
                     98: 
                     99:                SubdividePolygon (f, front[0]);
                    100:                SubdividePolygon (b, back[0]);
                    101:                return;
                    102:        }
                    103: 
                    104:        poly = Hunk_Alloc (sizeof(glpoly_t) + (numverts-4) * VERTEXSIZE*sizeof(float));
                    105:        poly->next = warpface->polys;
                    106:        warpface->polys = poly;
                    107:        poly->numverts = numverts;
                    108:        for (i=0 ; i<numverts ; i++, verts+= 3)
                    109:        {
                    110:                VectorCopy (verts, poly->verts[i]);
                    111:                s = DotProduct (verts, warpface->texinfo->vecs[0]);
                    112:                t = DotProduct (verts, warpface->texinfo->vecs[1]);
                    113:                poly->verts[i][3] = s;
                    114:                poly->verts[i][4] = t;
                    115:        }
                    116: }
                    117: 
                    118: /*
                    119: ================
                    120: GL_SubdivideSurface
                    121: 
                    122: Breaks a polygon up along axial 64 unit
                    123: boundaries so that turbulent and sky warps
                    124: can be done reasonably.
                    125: ================
                    126: */
                    127: void GL_SubdivideSurface (msurface_t *fa)
                    128: {
                    129:        vec3_t          verts[64];
                    130:        int                     numverts;
                    131:        int                     i;
                    132:        int                     lindex;
                    133:        float           *vec;
                    134:        texture_t       *t;
                    135: 
                    136:        warpface = fa;
                    137: 
                    138:        //
                    139:        // convert edges back to a normal polygon
                    140:        //
                    141:        numverts = 0;
                    142:        for (i=0 ; i<fa->numedges ; i++)
                    143:        {
                    144:                lindex = loadmodel->surfedges[fa->firstedge + i];
                    145: 
                    146:                if (lindex > 0)
                    147:                        vec = loadmodel->vertexes[loadmodel->edges[lindex].v[0]].position;
                    148:                else
                    149:                        vec = loadmodel->vertexes[loadmodel->edges[-lindex].v[1]].position;
                    150:                VectorCopy (vec, verts[numverts]);
                    151:                numverts++;
                    152:        }
                    153: 
                    154:        SubdividePolygon (numverts, verts[0]);
                    155: }
                    156: 
                    157: //=========================================================
                    158: 
                    159: 
                    160: 
                    161: // speed up sin calculations - Ed
                    162: float  turbsin[] =
                    163: {
                    164:        #include "gl_warp_sin.h"
                    165: };
                    166: #define TURBSCALE (256.0 / (2 * M_PI))
                    167: 
                    168: /*
                    169: =============
                    170: EmitWaterPolys
                    171: 
                    172: Does a water warp on the pre-fragmented glpoly_t chain
                    173: =============
                    174: */
                    175: void EmitWaterPolys (msurface_t *fa)
                    176: {
                    177:        glpoly_t        *p;
                    178:        float           *v;
                    179:        int                     i;
                    180:        float           s, t, os, ot;
                    181: 
                    182: 
                    183:        for (p=fa->polys ; p ; p=p->next)
                    184:        {
                    185:                glBegin (GL_POLYGON);
                    186:                for (i=0,v=p->verts[0] ; i<p->numverts ; i++, v+=VERTEXSIZE)
                    187:                {
                    188:                        os = v[3];
                    189:                        ot = v[4];
                    190: 
                    191:                        s = os + turbsin[(int)((ot*0.125+realtime) * TURBSCALE) & 255];
                    192:                        s *= (1.0/64);
                    193: 
                    194:                        t = ot + turbsin[(int)((os*0.125+realtime) * TURBSCALE) & 255];
                    195:                        t *= (1.0/64);
                    196: 
                    197:                        glTexCoord2f (s, t);
                    198:                        glVertex3fv (v);
                    199:                }
                    200:                glEnd ();
                    201:        }
                    202: }
                    203: 
                    204: 
                    205: 
                    206: 
                    207: /*
                    208: =============
                    209: EmitSkyPolys
                    210: =============
                    211: */
                    212: void EmitSkyPolys (msurface_t *fa)
                    213: {
                    214:        glpoly_t        *p;
                    215:        float           *v;
                    216:        int                     i;
                    217:        float   s, t;
                    218:        vec3_t  dir;
                    219:        float   length;
                    220: 
                    221:        for (p=fa->polys ; p ; p=p->next)
                    222:        {
                    223:                glBegin (GL_POLYGON);
                    224:                for (i=0,v=p->verts[0] ; i<p->numverts ; i++, v+=VERTEXSIZE)
                    225:                {
                    226:                        VectorSubtract (v, r_origin, dir);
                    227:                        dir[2] *= 3;    // flatten the sphere
                    228: 
                    229:                        length = dir[0]*dir[0] + dir[1]*dir[1] + dir[2]*dir[2];
                    230:                        length = sqrt (length);
                    231:                        length = 6*63/length;
                    232: 
                    233:                        dir[0] *= length;
                    234:                        dir[1] *= length;
                    235: 
                    236:                        s = (speedscale + dir[0]) * (1.0/128);
                    237:                        t = (speedscale + dir[1]) * (1.0/128);
                    238: 
                    239:                        glTexCoord2f (s, t);
                    240:                        glVertex3fv (v);
                    241:                }
                    242:                glEnd ();
                    243:        }
                    244: }
                    245: 
                    246: /*
                    247: ===============
                    248: EmitBothSkyLayers
                    249: 
                    250: Does a sky warp on the pre-fragmented glpoly_t chain
                    251: This will be called for brushmodels, the world
                    252: will have them chained together.
                    253: ===============
                    254: */
                    255: void EmitBothSkyLayers (msurface_t *fa)
                    256: {
                    257:        int                     i;
                    258:        int                     lindex;
                    259:        float           *vec;
                    260: 
                    261:        GL_Bind (solidskytexture);
                    262:        speedscale = realtime*8;
                    263:        speedscale -= (int)speedscale & ~127 ;
                    264: 
                    265:        EmitSkyPolys (fa);
                    266: 
                    267:        glEnable (GL_BLEND);
                    268:        GL_Bind (alphaskytexture);
                    269:        speedscale = realtime*16;
                    270:        speedscale -= (int)speedscale & ~127 ;
                    271: 
                    272:        EmitSkyPolys (fa);
                    273: 
                    274:        glDisable (GL_BLEND);
                    275: }
                    276: 
                    277: #ifndef QUAKE2
                    278: /*
                    279: =================
                    280: R_DrawSkyChain
                    281: =================
                    282: */
                    283: void R_DrawSkyChain (msurface_t *s)
                    284: {
                    285:        msurface_t      *fa;
                    286: 
                    287:        // used when gl_texsort is on
                    288:        GL_Bind(solidskytexture);
                    289:        speedscale = realtime*8;
                    290:        speedscale -= (int)speedscale & ~127 ;
                    291: 
                    292:        for (fa=s ; fa ; fa=fa->texturechain)
                    293:                EmitSkyPolys (fa);
                    294: 
                    295:        glEnable (GL_BLEND);
                    296:        GL_Bind (alphaskytexture);
                    297:        speedscale = realtime*16;
                    298:        speedscale -= (int)speedscale & ~127 ;
                    299: 
                    300:        for (fa=s ; fa ; fa=fa->texturechain)
                    301:                EmitSkyPolys (fa);
                    302: 
                    303:        glDisable (GL_BLEND);
                    304: }
                    305: 
                    306: #endif
                    307: 
                    308: /*
                    309: =================================================================
                    310: 
                    311:   Quake 2 environment sky
                    312: 
                    313: =================================================================
                    314: */
                    315: 
                    316: #ifdef QUAKE2
                    317: 
                    318: 
                    319: #define        SKY_TEX         2000
                    320: 
                    321: /*
                    322: =================================================================
                    323: 
                    324:   PCX Loading
                    325: 
                    326: =================================================================
                    327: */
                    328: 
                    329: typedef struct
                    330: {
                    331:     char       manufacturer;
                    332:     char       version;
                    333:     char       encoding;
                    334:     char       bits_per_pixel;
                    335:     unsigned short     xmin,ymin,xmax,ymax;
                    336:     unsigned short     hres,vres;
                    337:     unsigned char      palette[48];
                    338:     char       reserved;
                    339:     char       color_planes;
                    340:     unsigned short     bytes_per_line;
                    341:     unsigned short     palette_type;
                    342:     char       filler[58];
                    343:     unsigned   data;                   // unbounded
                    344: } pcx_t;
                    345: 
                    346: byte   *pcx_rgb;
                    347: 
                    348: /*
                    349: ============
                    350: LoadPCX
                    351: ============
                    352: */
                    353: void LoadPCX (FILE *f)
                    354: {
                    355:        pcx_t   *pcx, pcxbuf;
                    356:        byte    palette[768];
                    357:        byte    *pix;
                    358:        int             x, y;
                    359:        int             dataByte, runLength;
                    360:        int             count;
                    361: 
                    362: //
                    363: // parse the PCX file
                    364: //
                    365:        fread (&pcxbuf, 1, sizeof(pcxbuf), f);
                    366: 
                    367:        pcx = &pcxbuf;
                    368: 
                    369:        if (pcx->manufacturer != 0x0a
                    370:                || pcx->version != 5
                    371:                || pcx->encoding != 1
                    372:                || pcx->bits_per_pixel != 8
                    373:                || pcx->xmax >= 320
                    374:                || pcx->ymax >= 256)
                    375:        {
                    376:                Con_Printf ("Bad pcx file\n");
                    377:                return;
                    378:        }
                    379: 
                    380:        // seek to palette
                    381:        fseek (f, -768, SEEK_END);
                    382:        fread (palette, 1, 768, f);
                    383: 
                    384:        fseek (f, sizeof(pcxbuf) - 4, SEEK_SET);
                    385: 
                    386:        count = (pcx->xmax+1) * (pcx->ymax+1);
                    387:        pcx_rgb = malloc( count * 4);
                    388: 
                    389:        for (y=0 ; y<=pcx->ymax ; y++)
                    390:        {
                    391:                pix = pcx_rgb + 4*y*(pcx->xmax+1);
                    392:                for (x=0 ; x<=pcx->ymax ; )
                    393:                {
                    394:                        dataByte = fgetc(f);
                    395: 
                    396:                        if((dataByte & 0xC0) == 0xC0)
                    397:                        {
                    398:                                runLength = dataByte & 0x3F;
                    399:                                dataByte = fgetc(f);
                    400:                        }
                    401:                        else
                    402:                                runLength = 1;
                    403: 
                    404:                        while(runLength-- > 0)
                    405:                        {
                    406:                                pix[0] = palette[dataByte*3];
                    407:                                pix[1] = palette[dataByte*3+1];
                    408:                                pix[2] = palette[dataByte*3+2];
                    409:                                pix[3] = 255;
                    410:                                pix += 4;
                    411:                                x++;
                    412:                        }
                    413:                }
                    414:        }
                    415: }
                    416: 
                    417: /*
                    418: =========================================================
                    419: 
                    420: TARGA LOADING
                    421: 
                    422: =========================================================
                    423: */
                    424: 
                    425: typedef struct _TargaHeader {
                    426:        unsigned char   id_length, colormap_type, image_type;
                    427:        unsigned short  colormap_index, colormap_length;
                    428:        unsigned char   colormap_size;
                    429:        unsigned short  x_origin, y_origin, width, height;
                    430:        unsigned char   pixel_size, attributes;
                    431: } TargaHeader;
                    432: 
                    433: 
                    434: TargaHeader            targa_header;
                    435: byte                   *targa_rgba;
                    436: 
                    437: int fgetLittleShort (FILE *f)
                    438: {
                    439:        byte    b1, b2;
                    440: 
                    441:        b1 = fgetc(f);
                    442:        b2 = fgetc(f);
                    443: 
                    444:        return (short)(b1 + b2*256);
                    445: }
                    446: 
                    447: int fgetLittleLong (FILE *f)
                    448: {
                    449:        byte    b1, b2, b3, b4;
                    450: 
                    451:        b1 = fgetc(f);
                    452:        b2 = fgetc(f);
                    453:        b3 = fgetc(f);
                    454:        b4 = fgetc(f);
                    455: 
                    456:        return b1 + (b2<<8) + (b3<<16) + (b4<<24);
                    457: }
                    458: 
                    459: 
                    460: /*
                    461: =============
                    462: LoadTGA
                    463: =============
                    464: */
                    465: void LoadTGA (FILE *fin)
                    466: {
                    467:        int                             columns, rows, numPixels;
                    468:        byte                    *pixbuf;
                    469:        int                             row, column;
                    470: 
                    471:        targa_header.id_length = fgetc(fin);
                    472:        targa_header.colormap_type = fgetc(fin);
                    473:        targa_header.image_type = fgetc(fin);
                    474:        
                    475:        targa_header.colormap_index = fgetLittleShort(fin);
                    476:        targa_header.colormap_length = fgetLittleShort(fin);
                    477:        targa_header.colormap_size = fgetc(fin);
                    478:        targa_header.x_origin = fgetLittleShort(fin);
                    479:        targa_header.y_origin = fgetLittleShort(fin);
                    480:        targa_header.width = fgetLittleShort(fin);
                    481:        targa_header.height = fgetLittleShort(fin);
                    482:        targa_header.pixel_size = fgetc(fin);
                    483:        targa_header.attributes = fgetc(fin);
                    484: 
                    485:        if (targa_header.image_type!=2 
                    486:                && targa_header.image_type!=10) 
                    487:                Sys_Error ("LoadTGA: Only type 2 and 10 targa RGB images supported\n");
                    488: 
                    489:        if (targa_header.colormap_type !=0 
                    490:                || (targa_header.pixel_size!=32 && targa_header.pixel_size!=24))
                    491:                Sys_Error ("Texture_LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n");
                    492: 
                    493:        columns = targa_header.width;
                    494:        rows = targa_header.height;
                    495:        numPixels = columns * rows;
                    496: 
                    497:        targa_rgba = malloc (numPixels*4);
                    498:        
                    499:        if (targa_header.id_length != 0)
                    500:                fseek(fin, targa_header.id_length, SEEK_CUR);  // skip TARGA image comment
                    501:        
                    502:        if (targa_header.image_type==2) {  // Uncompressed, RGB images
                    503:                for(row=rows-1; row>=0; row--) {
                    504:                        pixbuf = targa_rgba + row*columns*4;
                    505:                        for(column=0; column<columns; column++) {
                    506:                                unsigned char red,green,blue,alphabyte;
                    507:                                switch (targa_header.pixel_size) {
                    508:                                        case 24:
                    509:                                                        
                    510:                                                        blue = getc(fin);
                    511:                                                        green = getc(fin);
                    512:                                                        red = getc(fin);
                    513:                                                        *pixbuf++ = red;
                    514:                                                        *pixbuf++ = green;
                    515:                                                        *pixbuf++ = blue;
                    516:                                                        *pixbuf++ = 255;
                    517:                                                        break;
                    518:                                        case 32:
                    519:                                                        blue = getc(fin);
                    520:                                                        green = getc(fin);
                    521:                                                        red = getc(fin);
                    522:                                                        alphabyte = getc(fin);
                    523:                                                        *pixbuf++ = red;
                    524:                                                        *pixbuf++ = green;
                    525:                                                        *pixbuf++ = blue;
                    526:                                                        *pixbuf++ = alphabyte;
                    527:                                                        break;
                    528:                                }
                    529:                        }
                    530:                }
                    531:        }
                    532:        else if (targa_header.image_type==10) {   // Runlength encoded RGB images
                    533:                unsigned char red,green,blue,alphabyte,packetHeader,packetSize,j;
                    534:                for(row=rows-1; row>=0; row--) {
                    535:                        pixbuf = targa_rgba + row*columns*4;
                    536:                        for(column=0; column<columns; ) {
                    537:                                packetHeader=getc(fin);
                    538:                                packetSize = 1 + (packetHeader & 0x7f);
                    539:                                if (packetHeader & 0x80) {        // run-length packet
                    540:                                        switch (targa_header.pixel_size) {
                    541:                                                case 24:
                    542:                                                                blue = getc(fin);
                    543:                                                                green = getc(fin);
                    544:                                                                red = getc(fin);
                    545:                                                                alphabyte = 255;
                    546:                                                                break;
                    547:                                                case 32:
                    548:                                                                blue = getc(fin);
                    549:                                                                green = getc(fin);
                    550:                                                                red = getc(fin);
                    551:                                                                alphabyte = getc(fin);
                    552:                                                                break;
                    553:                                        }
                    554:        
                    555:                                        for(j=0;j<packetSize;j++) {
                    556:                                                *pixbuf++=red;
                    557:                                                *pixbuf++=green;
                    558:                                                *pixbuf++=blue;
                    559:                                                *pixbuf++=alphabyte;
                    560:                                                column++;
                    561:                                                if (column==columns) { // run spans across rows
                    562:                                                        column=0;
                    563:                                                        if (row>0)
                    564:                                                                row--;
                    565:                                                        else
                    566:                                                                goto breakOut;
                    567:                                                        pixbuf = targa_rgba + row*columns*4;
                    568:                                                }
                    569:                                        }
                    570:                                }
                    571:                                else {                            // non run-length packet
                    572:                                        for(j=0;j<packetSize;j++) {
                    573:                                                switch (targa_header.pixel_size) {
                    574:                                                        case 24:
                    575:                                                                        blue = getc(fin);
                    576:                                                                        green = getc(fin);
                    577:                                                                        red = getc(fin);
                    578:                                                                        *pixbuf++ = red;
                    579:                                                                        *pixbuf++ = green;
                    580:                                                                        *pixbuf++ = blue;
                    581:                                                                        *pixbuf++ = 255;
                    582:                                                                        break;
                    583:                                                        case 32:
                    584:                                                                        blue = getc(fin);
                    585:                                                                        green = getc(fin);
                    586:                                                                        red = getc(fin);
                    587:                                                                        alphabyte = getc(fin);
                    588:                                                                        *pixbuf++ = red;
                    589:                                                                        *pixbuf++ = green;
                    590:                                                                        *pixbuf++ = blue;
                    591:                                                                        *pixbuf++ = alphabyte;
                    592:                                                                        break;
                    593:                                                }
                    594:                                                column++;
                    595:                                                if (column==columns) { // pixel packet run spans across rows
                    596:                                                        column=0;
                    597:                                                        if (row>0)
                    598:                                                                row--;
                    599:                                                        else
                    600:                                                                goto breakOut;
                    601:                                                        pixbuf = targa_rgba + row*columns*4;
                    602:                                                }                                               
                    603:                                        }
                    604:                                }
                    605:                        }
                    606:                        breakOut:;
                    607:                }
                    608:        }
                    609:        
                    610:        fclose(fin);
                    611: }
                    612: 
                    613: /*
                    614: ==================
                    615: R_LoadSkys
                    616: ==================
                    617: */
                    618: char   *suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"};
                    619: void R_LoadSkys (void)
                    620: {
                    621:        int             i;
                    622:        FILE    *f;
                    623:        char    name[64];
                    624: 
                    625:        for (i=0 ; i<6 ; i++)
                    626:        {
                    627:                GL_Bind (SKY_TEX + i);
                    628:                sprintf (name, "gfx/env/bkgtst%s.tga", suf[i]);
                    629:                COM_FOpenFile (name, &f);
                    630:                if (!f)
                    631:                {
                    632:                        Con_Printf ("Couldn't load %s\n", name);
                    633:                        continue;
                    634:                }
                    635:                LoadTGA (f);
                    636: //             LoadPCX (f);
                    637: 
                    638:                glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, targa_rgba);
                    639: //             glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, pcx_rgb);
                    640: 
                    641:                free (targa_rgba);
                    642: //             free (pcx_rgb);
                    643: 
                    644:                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
                    645:                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
                    646:        }
                    647: }
                    648: 
                    649: 
                    650: vec3_t skyclip[6] = {
                    651:        {1,1,0},
                    652:        {1,-1,0},
                    653:        {0,-1,1},
                    654:        {0,1,1},
                    655:        {1,0,1},
                    656:        {-1,0,1} 
                    657: };
                    658: int    c_sky;
                    659: 
                    660: // 1 = s, 2 = t, 3 = 2048
                    661: int    st_to_vec[6][3] =
                    662: {
                    663:        {3,-1,2},
                    664:        {-3,1,2},
                    665: 
                    666:        {1,3,2},
                    667:        {-1,-3,2},
                    668: 
                    669:        {-2,-1,3},              // 0 degrees yaw, look straight up
                    670:        {2,-1,-3}               // look straight down
                    671: 
                    672: //     {-1,2,3},
                    673: //     {1,2,-3}
                    674: };
                    675: 
                    676: // s = [0]/[2], t = [1]/[2]
                    677: int    vec_to_st[6][3] =
                    678: {
                    679:        {-2,3,1},
                    680:        {2,3,-1},
                    681: 
                    682:        {1,3,2},
                    683:        {-1,3,-2},
                    684: 
                    685:        {-2,-1,3},
                    686:        {-2,1,-3}
                    687: 
                    688: //     {-1,2,3},
                    689: //     {1,2,-3}
                    690: };
                    691: 
                    692: float  skymins[2][6], skymaxs[2][6];
                    693: 
                    694: void DrawSkyPolygon (int nump, vec3_t vecs)
                    695: {
                    696:        int             i,j;
                    697:        vec3_t  v, av;
                    698:        float   s, t, dv;
                    699:        int             axis;
                    700:        float   *vp;
                    701: 
                    702:        c_sky++;
                    703: #if 0
                    704: glBegin (GL_POLYGON);
                    705: for (i=0 ; i<nump ; i++, vecs+=3)
                    706: {
                    707:        VectorAdd(vecs, r_origin, v);
                    708:        glVertex3fv (v);
                    709: }
                    710: glEnd();
                    711: return;
                    712: #endif
                    713:        // decide which face it maps to
                    714:        VectorCopy (vec3_origin, v);
                    715:        for (i=0, vp=vecs ; i<nump ; i++, vp+=3)
                    716:        {
                    717:                VectorAdd (vp, v, v);
                    718:        }
                    719:        av[0] = fabs(v[0]);
                    720:        av[1] = fabs(v[1]);
                    721:        av[2] = fabs(v[2]);
                    722:        if (av[0] > av[1] && av[0] > av[2])
                    723:        {
                    724:                if (v[0] < 0)
                    725:                        axis = 1;
                    726:                else
                    727:                        axis = 0;
                    728:        }
                    729:        else if (av[1] > av[2] && av[1] > av[0])
                    730:        {
                    731:                if (v[1] < 0)
                    732:                        axis = 3;
                    733:                else
                    734:                        axis = 2;
                    735:        }
                    736:        else
                    737:        {
                    738:                if (v[2] < 0)
                    739:                        axis = 5;
                    740:                else
                    741:                        axis = 4;
                    742:        }
                    743: 
                    744:        // project new texture coords
                    745:        for (i=0 ; i<nump ; i++, vecs+=3)
                    746:        {
                    747:                j = vec_to_st[axis][2];
                    748:                if (j > 0)
                    749:                        dv = vecs[j - 1];
                    750:                else
                    751:                        dv = -vecs[-j - 1];
                    752: 
                    753:                j = vec_to_st[axis][0];
                    754:                if (j < 0)
                    755:                        s = -vecs[-j -1] / dv;
                    756:                else
                    757:                        s = vecs[j-1] / dv;
                    758:                j = vec_to_st[axis][1];
                    759:                if (j < 0)
                    760:                        t = -vecs[-j -1] / dv;
                    761:                else
                    762:                        t = vecs[j-1] / dv;
                    763: 
                    764:                if (s < skymins[0][axis])
                    765:                        skymins[0][axis] = s;
                    766:                if (t < skymins[1][axis])
                    767:                        skymins[1][axis] = t;
                    768:                if (s > skymaxs[0][axis])
                    769:                        skymaxs[0][axis] = s;
                    770:                if (t > skymaxs[1][axis])
                    771:                        skymaxs[1][axis] = t;
                    772:        }
                    773: }
                    774: 
                    775: #define        MAX_CLIP_VERTS  64
                    776: void ClipSkyPolygon (int nump, vec3_t vecs, int stage)
                    777: {
                    778:        float   *norm;
                    779:        float   *v;
                    780:        qboolean        front, back;
                    781:        float   d, e;
                    782:        float   dists[MAX_CLIP_VERTS];
                    783:        int             sides[MAX_CLIP_VERTS];
                    784:        vec3_t  newv[2][MAX_CLIP_VERTS];
                    785:        int             newc[2];
                    786:        int             i, j;
                    787: 
                    788:        if (nump > MAX_CLIP_VERTS-2)
                    789:                Sys_Error ("ClipSkyPolygon: MAX_CLIP_VERTS");
                    790:        if (stage == 6)
                    791:        {       // fully clipped, so draw it
                    792:                DrawSkyPolygon (nump, vecs);
                    793:                return;
                    794:        }
                    795: 
                    796:        front = back = false;
                    797:        norm = skyclip[stage];
                    798:        for (i=0, v = vecs ; i<nump ; i++, v+=3)
                    799:        {
                    800:                d = DotProduct (v, norm);
                    801:                if (d > ON_EPSILON)
                    802:                {
                    803:                        front = true;
                    804:                        sides[i] = SIDE_FRONT;
                    805:                }
                    806:                else if (d < ON_EPSILON)
                    807:                {
                    808:                        back = true;
                    809:                        sides[i] = SIDE_BACK;
                    810:                }
                    811:                else
                    812:                        sides[i] = SIDE_ON;
                    813:                dists[i] = d;
                    814:        }
                    815: 
                    816:        if (!front || !back)
                    817:        {       // not clipped
                    818:                ClipSkyPolygon (nump, vecs, stage+1);
                    819:                return;
                    820:        }
                    821: 
                    822:        // clip it
                    823:        sides[i] = sides[0];
                    824:        dists[i] = dists[0];
                    825:        VectorCopy (vecs, (vecs+(i*3)) );
                    826:        newc[0] = newc[1] = 0;
                    827: 
                    828:        for (i=0, v = vecs ; i<nump ; i++, v+=3)
                    829:        {
                    830:                switch (sides[i])
                    831:                {
                    832:                case SIDE_FRONT:
                    833:                        VectorCopy (v, newv[0][newc[0]]);
                    834:                        newc[0]++;
                    835:                        break;
                    836:                case SIDE_BACK:
                    837:                        VectorCopy (v, newv[1][newc[1]]);
                    838:                        newc[1]++;
                    839:                        break;
                    840:                case SIDE_ON:
                    841:                        VectorCopy (v, newv[0][newc[0]]);
                    842:                        newc[0]++;
                    843:                        VectorCopy (v, newv[1][newc[1]]);
                    844:                        newc[1]++;
                    845:                        break;
                    846:                }
                    847: 
                    848:                if (sides[i] == SIDE_ON || sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
                    849:                        continue;
                    850: 
                    851:                d = dists[i] / (dists[i] - dists[i+1]);
                    852:                for (j=0 ; j<3 ; j++)
                    853:                {
                    854:                        e = v[j] + d*(v[j+3] - v[j]);
                    855:                        newv[0][newc[0]][j] = e;
                    856:                        newv[1][newc[1]][j] = e;
                    857:                }
                    858:                newc[0]++;
                    859:                newc[1]++;
                    860:        }
                    861: 
                    862:        // continue
                    863:        ClipSkyPolygon (newc[0], newv[0][0], stage+1);
                    864:        ClipSkyPolygon (newc[1], newv[1][0], stage+1);
                    865: }
                    866: 
                    867: /*
                    868: =================
                    869: R_DrawSkyChain
                    870: =================
                    871: */
                    872: void R_DrawSkyChain (msurface_t *s)
                    873: {
                    874:        msurface_t      *fa;
                    875: 
                    876:        int             i;
                    877:        vec3_t  verts[MAX_CLIP_VERTS];
                    878:        glpoly_t        *p;
                    879: 
                    880:        c_sky = 0;
                    881:        GL_Bind(solidskytexture);
                    882: 
                    883:        // calculate vertex values for sky box
                    884: 
                    885:        for (fa=s ; fa ; fa=fa->texturechain)
                    886:        {
                    887:                for (p=fa->polys ; p ; p=p->next)
                    888:                {
                    889:                        for (i=0 ; i<p->numverts ; i++)
                    890:                        {
                    891:                                VectorSubtract (p->verts[i], r_origin, verts[i]);
                    892:                        }
                    893:                        ClipSkyPolygon (p->numverts, verts[0], 0);
                    894:                }
                    895:        }
                    896: }
                    897: 
                    898: 
                    899: /*
                    900: ==============
                    901: R_ClearSkyBox
                    902: ==============
                    903: */
                    904: void R_ClearSkyBox (void)
                    905: {
                    906:        int             i;
                    907: 
                    908:        for (i=0 ; i<6 ; i++)
                    909:        {
                    910:                skymins[0][i] = skymins[1][i] = 9999;
                    911:                skymaxs[0][i] = skymaxs[1][i] = -9999;
                    912:        }
                    913: }
                    914: 
                    915: 
                    916: void MakeSkyVec (float s, float t, int axis)
                    917: {
                    918:        vec3_t          v, b;
                    919:        int                     j, k;
                    920: 
                    921:        b[0] = s*2048;
                    922:        b[1] = t*2048;
                    923:        b[2] = 2048;
                    924: 
                    925:        for (j=0 ; j<3 ; j++)
                    926:        {
                    927:                k = st_to_vec[axis][j];
                    928:                if (k < 0)
                    929:                        v[j] = -b[-k - 1];
                    930:                else
                    931:                        v[j] = b[k - 1];
                    932:                v[j] += r_origin[j];
                    933:        }
                    934: 
                    935:        // avoid bilerp seam
                    936:        s = (s+1)*0.5;
                    937:        t = (t+1)*0.5;
                    938: 
                    939:        if (s < 1.0/512)
                    940:                s = 1.0/512;
                    941:        else if (s > 511.0/512)
                    942:                s = 511.0/512;
                    943:        if (t < 1.0/512)
                    944:                t = 1.0/512;
                    945:        else if (t > 511.0/512)
                    946:                t = 511.0/512;
                    947: 
                    948:        t = 1.0 - t;
                    949:        glTexCoord2f (s, t);
                    950:        glVertex3fv (v);
                    951: }
                    952: 
                    953: /*
                    954: ==============
                    955: R_DrawSkyBox
                    956: ==============
                    957: */
                    958: int    skytexorder[6] = {0,2,1,3,4,5};
                    959: void R_DrawSkyBox (void)
                    960: {
                    961:        int             i, j, k;
                    962:        vec3_t  v;
                    963:        float   s, t;
                    964: 
                    965: #if 0
                    966: glEnable (GL_BLEND);
                    967: glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
                    968: glColor4f (1,1,1,0.5);
                    969: glDisable (GL_DEPTH_TEST);
                    970: #endif
                    971:        for (i=0 ; i<6 ; i++)
                    972:        {
                    973:                if (skymins[0][i] >= skymaxs[0][i]
                    974:                || skymins[1][i] >= skymaxs[1][i])
                    975:                        continue;
                    976: 
                    977:                GL_Bind (SKY_TEX+skytexorder[i]);
                    978: #if 0
                    979: skymins[0][i] = -1;
                    980: skymins[1][i] = -1;
                    981: skymaxs[0][i] = 1;
                    982: skymaxs[1][i] = 1;
                    983: #endif
                    984:                glBegin (GL_QUADS);
                    985:                MakeSkyVec (skymins[0][i], skymins[1][i], i);
                    986:                MakeSkyVec (skymins[0][i], skymaxs[1][i], i);
                    987:                MakeSkyVec (skymaxs[0][i], skymaxs[1][i], i);
                    988:                MakeSkyVec (skymaxs[0][i], skymins[1][i], i);
                    989:                glEnd ();
                    990:        }
                    991: #if 0
                    992: glDisable (GL_BLEND);
                    993: glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
                    994: glColor4f (1,1,1,0.5);
                    995: glEnable (GL_DEPTH_TEST);
                    996: #endif
                    997: }
                    998: 
                    999: 
                   1000: #endif
                   1001: 
                   1002: //===============================================================
                   1003: 
                   1004: /*
                   1005: =============
                   1006: R_InitSky
                   1007: 
                   1008: A sky texture is 256*128, with the right side being a masked overlay
                   1009: ==============
                   1010: */
                   1011: void R_InitSky (texture_t *mt)
                   1012: {
                   1013:        int                     i, j, p;
                   1014:        byte            *src;
                   1015:        unsigned        trans[128*128];
                   1016:        unsigned        transpix;
                   1017:        int                     r, g, b;
                   1018:        unsigned        *rgba;
                   1019:        extern  int                     skytexturenum;
                   1020: 
                   1021:        src = (byte *)mt + mt->offsets[0];
                   1022: 
                   1023:        // make an average value for the back to avoid
                   1024:        // a fringe on the top level
                   1025: 
                   1026:        r = g = b = 0;
                   1027:        for (i=0 ; i<128 ; i++)
                   1028:                for (j=0 ; j<128 ; j++)
                   1029:                {
                   1030:                        p = src[i*256 + j + 128];
                   1031:                        rgba = &d_8to24table[p];
                   1032:                        trans[(i*128) + j] = *rgba;
                   1033:                        r += ((byte *)rgba)[0];
                   1034:                        g += ((byte *)rgba)[1];
                   1035:                        b += ((byte *)rgba)[2];
                   1036:                }
                   1037: 
                   1038:        ((byte *)&transpix)[0] = r/(128*128);
                   1039:        ((byte *)&transpix)[1] = g/(128*128);
                   1040:        ((byte *)&transpix)[2] = b/(128*128);
                   1041:        ((byte *)&transpix)[3] = 0;
                   1042: 
                   1043: 
                   1044:        if (!solidskytexture)
                   1045:                solidskytexture = texture_extension_number++;
                   1046:        GL_Bind (solidskytexture );
                   1047:        glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans);
                   1048:        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
                   1049:        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
                   1050: 
                   1051: 
                   1052:        for (i=0 ; i<128 ; i++)
                   1053:                for (j=0 ; j<128 ; j++)
                   1054:                {
                   1055:                        p = src[i*256 + j];
                   1056:                        if (p == 0)
                   1057:                                trans[(i*128) + j] = transpix;
                   1058:                        else
                   1059:                                trans[(i*128) + j] = d_8to24table[p];
                   1060:                }
                   1061: 
                   1062:        if (!alphaskytexture)
                   1063:                alphaskytexture = texture_extension_number++;
                   1064:        GL_Bind(alphaskytexture);
                   1065:        glTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans);
                   1066:        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
                   1067:        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
                   1068: }
                   1069: 

unix.superglobalmegacorp.com

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