Annotation of quake1/gl_draw.c, revision 1.1.1.1

1.1       root        1: 
                      2: // draw.c -- this is the only file outside the refresh that touches the
                      3: // vid buffer
                      4: 
                      5: #include "quakedef.h"
                      6: 
                      7: cvar_t         gl_nobind = {"gl_nobind", "0"};
                      8: cvar_t         gl_max_size = {"gl_max_size", "1024"};
                      9: cvar_t         gl_round_down = {"gl_round_down", "1"};
                     10: cvar_t         gl_picmip = {"gl_picmip", "0"};
                     11: 
                     12: byte           *draw_chars;                            // 8*8 graphic characters
                     13: qpic_t         *draw_disc;
                     14: qpic_t         *draw_backtile;
                     15: 
                     16: int                    translate_texture;
                     17: int                    char_texture;
                     18: 
                     19: typedef struct
                     20: {
                     21:        int             texnum;
                     22:        float   sl, tl, sh, th;
                     23: } glpic_t;
                     24: 
                     25: byte           conback_buffer[sizeof(qpic_t) + sizeof(glpic_t)];
                     26: qpic_t         *conback = (qpic_t *)&conback_buffer;
                     27: 
                     28: int            gl_lightmap_format = 4;
                     29: int            gl_solid_format = 3;
                     30: int            gl_alpha_format = 4;
                     31: 
                     32: int            gl_filter_min = GL_LINEAR_MIPMAP_NEAREST;
                     33: int            gl_filter_max = GL_LINEAR;
                     34: 
                     35: 
                     36: int            texels;
                     37: 
                     38: typedef struct
                     39: {
                     40:        int             texnum;
                     41:        char    identifier[64];
                     42:        int             width, height;
                     43:        qboolean        mipmap;
                     44: } gltexture_t;
                     45: 
                     46: #define        MAX_GLTEXTURES  1024
                     47: gltexture_t    gltextures[MAX_GLTEXTURES];
                     48: int                    numgltextures;
                     49: 
                     50: 
                     51: void GL_Bind (int texnum)
                     52: {
                     53:        if (gl_nobind.value)
                     54:                texnum = char_texture;
                     55:        if (currenttexture == texnum)
                     56:                return;
                     57:        currenttexture = texnum;
                     58:        bindTexFunc (GL_TEXTURE_2D, texnum);
                     59: }
                     60: 
                     61: void GL_Texels_f (void)
                     62: {
                     63:        Con_Printf ("Current uploaded texels: %i\n", texels);
                     64: }
                     65: 
                     66: /*
                     67: =============================================================================
                     68: 
                     69:   scrap allocation
                     70: 
                     71:   Allocate all the little status bar obejcts into a single texture
                     72:   to crutch up stupid hardware / drivers
                     73: 
                     74: =============================================================================
                     75: */
                     76: 
                     77: #define        MAX_SCRAPS              1
                     78: #define        BLOCK_WIDTH             256
                     79: #define        BLOCK_HEIGHT    256
                     80: 
                     81: int                    scrap_allocated[MAX_SCRAPS][BLOCK_WIDTH];
                     82: byte           scrap_texels[MAX_SCRAPS][BLOCK_WIDTH*BLOCK_HEIGHT*4];
                     83: qboolean       scrap_dirty;
                     84: int                    scrap_texnum;
                     85: 
                     86: // returns a texture number and the position inside it
                     87: int Scrap_AllocBlock (int w, int h, int *x, int *y)
                     88: {
                     89:        int             i, j;
                     90:        int             best, best2;
                     91:        int             bestx;
                     92:        int             texnum;
                     93: 
                     94:        for (texnum=0 ; texnum<MAX_SCRAPS ; texnum++)
                     95:        {
                     96:                best = BLOCK_HEIGHT;
                     97: 
                     98:                for (i=0 ; i<BLOCK_WIDTH-w ; i++)
                     99:                {
                    100:                        best2 = 0;
                    101: 
                    102:                        for (j=0 ; j<w ; j++)
                    103:                        {
                    104:                                if (scrap_allocated[texnum][i+j] >= best)
                    105:                                        break;
                    106:                                if (scrap_allocated[texnum][i+j] > best2)
                    107:                                        best2 = scrap_allocated[texnum][i+j];
                    108:                        }
                    109:                        if (j == w)
                    110:                        {       // this is a valid spot
                    111:                                *x = i;
                    112:                                *y = best = best2;
                    113:                        }
                    114:                }
                    115: 
                    116:                if (best + h > BLOCK_HEIGHT)
                    117:                        continue;
                    118: 
                    119:                for (i=0 ; i<w ; i++)
                    120:                        scrap_allocated[texnum][*x + i] = best + h;
                    121: 
                    122:                return texnum;
                    123:        }
                    124: 
                    125:        return -1;
                    126: //     Sys_Error ("Scrap_AllocBlock: full");
                    127: }
                    128: 
                    129: int    scrap_uploads;
                    130: 
                    131: void Scrap_Upload (void)
                    132: {
                    133:        scrap_uploads++;
                    134:        GL_Bind(scrap_texnum);
                    135:        GL_Upload8 (scrap_texels[0], BLOCK_WIDTH, BLOCK_HEIGHT, false, true);
                    136:        scrap_dirty = false;
                    137: }
                    138: 
                    139: //=============================================================================
                    140: /* Support Routines */
                    141: 
                    142: typedef struct cachepic_s
                    143: {
                    144:        char            name[MAX_QPATH];
                    145:        qpic_t          pic;
                    146:        byte            padding[32];    // for appended glpic
                    147: } cachepic_t;
                    148: 
                    149: #define        MAX_CACHED_PICS         128
                    150: cachepic_t     menu_cachepics[MAX_CACHED_PICS];
                    151: int                    menu_numcachepics;
                    152: 
                    153: byte           menuplyr_pixels[4096];
                    154: 
                    155: int            pic_texels;
                    156: int            pic_count;
                    157: 
                    158: qpic_t *Draw_PicFromWad (char *name)
                    159: {
                    160:        qpic_t  *p;
                    161:        glpic_t *gl;
                    162: 
                    163:        p = W_GetLumpName (name);
                    164:        gl = (glpic_t *)p->data;
                    165: 
                    166:        // load little ones into the scrap
                    167:        if (p->width < 64 && p->height < 64)
                    168:        {
                    169:                int             x, y;
                    170:                int             i, j, k;
                    171:                int             texnum;
                    172: 
                    173:                texnum = Scrap_AllocBlock (p->width, p->height, &x, &y);
                    174:                if (texnum == -1)
                    175:                        goto nonscrap;
                    176:                scrap_dirty = true;
                    177:                k = 0;
                    178:                for (i=0 ; i<p->height ; i++)
                    179:                        for (j=0 ; j<p->width ; j++, k++)
                    180:                                scrap_texels[texnum][(y+i)*BLOCK_WIDTH + x + j] = p->data[k];
                    181:                texnum += scrap_texnum;
                    182:                gl->texnum = texnum;
                    183:                gl->sl = (x+0.01)/(float)BLOCK_WIDTH;
                    184:                gl->sh = (x+p->width-0.01)/(float)BLOCK_WIDTH;
                    185:                gl->tl = (y+0.01)/(float)BLOCK_WIDTH;
                    186:                gl->th = (y+p->height-0.01)/(float)BLOCK_WIDTH;
                    187: 
                    188:                pic_count++;
                    189:                pic_texels += p->width*p->height;
                    190:        }
                    191:        else
                    192:        {
                    193: nonscrap:
                    194:                gl->texnum = GL_LoadPicTexture (p);
                    195:                gl->sl = 0;
                    196:                gl->sh = 1;
                    197:                gl->tl = 0;
                    198:                gl->th = 1;
                    199:        }
                    200:        return p;
                    201: }
                    202: 
                    203: 
                    204: /*
                    205: ================
                    206: Draw_CachePic
                    207: ================
                    208: */
                    209: qpic_t *Draw_CachePic (char *path)
                    210: {
                    211:        cachepic_t      *pic;
                    212:        int                     i;
                    213:        qpic_t          *dat;
                    214:        glpic_t         *gl;
                    215: 
                    216:        for (pic=menu_cachepics, i=0 ; i<menu_numcachepics ; pic++, i++)
                    217:                if (!strcmp (path, pic->name))
                    218:                        return &pic->pic;
                    219: 
                    220:        if (menu_numcachepics == MAX_CACHED_PICS)
                    221:                Sys_Error ("menu_numcachepics == MAX_CACHED_PICS");
                    222:        menu_numcachepics++;
                    223:        strcpy (pic->name, path);
                    224: 
                    225: //
                    226: // load the pic from disk
                    227: //
                    228:        dat = (qpic_t *)COM_LoadTempFile (path);        
                    229:        if (!dat)
                    230:                Sys_Error ("Draw_CachePic: failed to load %s", path);
                    231:        SwapPic (dat);
                    232: 
                    233:        // HACK HACK HACK --- we need to keep the bytes for
                    234:        // the translatable player picture just for the menu
                    235:        // configuration dialog
                    236:        if (!strcmp (path, "gfx/menuplyr.lmp"))
                    237:                memcpy (menuplyr_pixels, dat->data, dat->width*dat->height);
                    238: 
                    239:        pic->pic.width = dat->width;
                    240:        pic->pic.height = dat->height;
                    241: 
                    242:        gl = (glpic_t *)pic->pic.data;
                    243:        gl->texnum = GL_LoadPicTexture (dat);
                    244:        gl->sl = 0;
                    245:        gl->sh = 1;
                    246:        gl->tl = 0;
                    247:        gl->th = 1;
                    248: 
                    249:        return &pic->pic;
                    250: }
                    251: 
                    252: 
                    253: void Draw_CharToConback (int num, byte *dest)
                    254: {
                    255:        int             row, col;
                    256:        byte    *source;
                    257:        int             drawline;
                    258:        int             x;
                    259: 
                    260:        row = num>>4;
                    261:        col = num&15;
                    262:        source = draw_chars + (row<<10) + (col<<3);
                    263: 
                    264:        drawline = 8;
                    265: 
                    266:        while (drawline--)
                    267:        {
                    268:                for (x=0 ; x<8 ; x++)
                    269:                        if (source[x] != 255)
                    270:                                dest[x] = 0x60 + source[x];
                    271:                source += 128;
                    272:                dest += 320;
                    273:        }
                    274: 
                    275: }
                    276: 
                    277: typedef struct
                    278: {
                    279:        char *name;
                    280:        int     minimize, maximize;
                    281: } mode_t;
                    282: 
                    283: mode_t modes[] = {
                    284:        {"GL_NEAREST", GL_NEAREST, GL_NEAREST},
                    285:        {"GL_LINEAR", GL_LINEAR, GL_LINEAR},
                    286:        {"GL_NEAREST_MIPMAP_NEAREST", GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST},
                    287:        {"GL_LINEAR_MIPMAP_NEAREST", GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR},
                    288:        {"GL_NEAREST_MIPMAP_LINEAR", GL_NEAREST_MIPMAP_LINEAR, GL_NEAREST},
                    289:        {"GL_LINEAR_MIPMAP_LINEAR", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR}
                    290: };
                    291: 
                    292: /*
                    293: ===============
                    294: Draw_TextureMode_f
                    295: ===============
                    296: */
                    297: void Draw_TextureMode_f (void)
                    298: {
                    299:        int             i;
                    300:        gltexture_t     *glt;
                    301: 
                    302:        if (Cmd_Argc() == 1)
                    303:        {
                    304:                for (i=0 ; i< 6 ; i++)
                    305:                        if (gl_filter_min == modes[i].minimize)
                    306:                        {
                    307:                                Con_Printf ("%s\n", modes[i].name);
                    308:                                return;
                    309:                        }
                    310:                Con_Printf ("current filter is unknown???\n");
                    311:                return;
                    312:        }
                    313: 
                    314:        for (i=0 ; i< 6 ; i++)
                    315:        {
                    316:                if (!Q_strcasecmp (modes[i].name, Cmd_Argv(1) ) )
                    317:                        break;
                    318:        }
                    319:        if (i == 6)
                    320:        {
                    321:                Con_Printf ("bad filter name\n");
                    322:                return;
                    323:        }
                    324: 
                    325:        gl_filter_min = modes[i].minimize;
                    326:        gl_filter_max = modes[i].maximize;
                    327: 
                    328:        // change all the existing mipmap texture objects
                    329:        for (i=0, glt=gltextures ; i<numgltextures ; i++, glt++)
                    330:        {
                    331:                if (glt->mipmap)
                    332:                {
                    333:                        GL_Bind (glt->texnum);
                    334:                        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
                    335:                        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
                    336:                }
                    337:        }
                    338: }
                    339: 
                    340: /*
                    341: ===============
                    342: Draw_Init
                    343: ===============
                    344: */
                    345: void Draw_Init (void)
                    346: {
                    347:        int             i;
                    348:        qpic_t  *cb;
                    349:        byte    *dest;
                    350:        int             x, y;
                    351:        char    ver[40];
                    352:        glpic_t *gl;
                    353: 
                    354:        Cvar_RegisterVariable (&gl_nobind);
                    355:        Cvar_RegisterVariable (&gl_max_size);
                    356:        Cvar_RegisterVariable (&gl_round_down);
                    357:        Cvar_RegisterVariable (&gl_picmip);
                    358: 
                    359:        // 3dfx can only handle 256 wide textures
                    360:        if (!Q_strncasecmp ((char *)gl_renderer, "3dfx",4))
                    361:                Cvar_Set ("gl_max_size", "256");
                    362: 
                    363:        Cmd_AddCommand ("gl_texturemode", &Draw_TextureMode_f);
                    364:        Cmd_AddCommand ("gl_texels", &GL_Texels_f);
                    365: 
                    366: 
                    367:        // load the console background and the charset
                    368:        // by hand, because we need to write the version
                    369:        // string into the background before turning
                    370:        // it into a texture
                    371:        draw_chars = W_GetLumpName ("conchars");
                    372:        for (i=0 ; i<256*64 ; i++)
                    373:                if (draw_chars[i] == 0)
                    374:                        draw_chars[i] = 255;    // proper transparent color
                    375: 
                    376:        cb = (qpic_t *)COM_LoadTempFile ("gfx/conback.lmp");    
                    377:        if (!cb)
                    378:                Sys_Error ("Couldn't load gfx/conback.lmp");
                    379:        SwapPic (cb);
                    380: 
                    381:        // hack the version number directly into the pic
                    382:        sprintf (ver, "(gl %4.2f) %4.2f", (float)GLQUAKE_VERSION, (float)VERSION);
                    383:        dest = cb->data + 320*186 + 320 - 11 - 8*strlen(ver);
                    384:        y = strlen(ver);
                    385:        for (x=0 ; x<y ; x++)
                    386:                Draw_CharToConback (ver[x], dest+(x<<3));
                    387: 
                    388:        // now turn them into textures
                    389:        char_texture = GL_LoadTexture ("charset", 128, 128, draw_chars, false, true);
                    390:        conback->width = cb->width;
                    391:        conback->height = cb->height;
                    392:        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
                    393:        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
                    394: 
                    395:        gl = (glpic_t *)conback->data;
                    396:        gl->texnum = GL_LoadTexture ("conback", 320, 200, cb->data, false, false);
                    397:        gl->sl = 0;
                    398:        gl->sh = 1;
                    399:        gl->tl = 0;
                    400:        gl->th = 1;
                    401: 
                    402:        // save a texture slot for translated picture
                    403:        translate_texture = texture_extension_number++;
                    404: 
                    405:        // save slots for scraps
                    406:        scrap_texnum = texture_extension_number;
                    407:        texture_extension_number += MAX_SCRAPS;
                    408: 
                    409:        //
                    410:        // get the other pics we need
                    411:        //
                    412:        draw_disc = Draw_PicFromWad ("disc");
                    413:        draw_backtile = Draw_PicFromWad ("backtile");
                    414: }
                    415: 
                    416: 
                    417: 
                    418: /*
                    419: ================
                    420: Draw_Character
                    421: 
                    422: Draws one 8*8 graphics character with 0 being transparent.
                    423: It can be clipped to the top of the screen to allow the console to be
                    424: smoothly scrolled off.
                    425: ================
                    426: */
                    427: void Draw_Character (int x, int y, int num)
                    428: {
                    429:        byte                    *dest;
                    430:        byte                    *source;
                    431:        unsigned short  *pusdest;
                    432:        int                             drawline;       
                    433:        int                             row, col;
                    434:        float                   frow, fcol, size;
                    435: 
                    436:        if (num == 32)
                    437:                return;         // space
                    438: 
                    439:        num &= 255;
                    440:        
                    441:        if (y <= -8)
                    442:                return;                 // totally off screen
                    443: 
                    444:        row = num>>4;
                    445:        col = num&15;
                    446: 
                    447:        frow = row*0.0625;
                    448:        fcol = col*0.0625;
                    449:        size = 0.0625;
                    450: 
                    451:        GL_Bind (char_texture);
                    452: 
                    453:        glBegin (GL_QUADS);
                    454:        glTexCoord2f (fcol, frow);
                    455:        glVertex2f (x, y);
                    456:        glTexCoord2f (fcol + size, frow);
                    457:        glVertex2f (x+8, y);
                    458:        glTexCoord2f (fcol + size, frow + size);
                    459:        glVertex2f (x+8, y+8);
                    460:        glTexCoord2f (fcol, frow + size);
                    461:        glVertex2f (x, y+8);
                    462:        glEnd ();
                    463: }
                    464: 
                    465: /*
                    466: ================
                    467: Draw_String
                    468: ================
                    469: */
                    470: void Draw_String (int x, int y, char *str)
                    471: {
                    472:        while (*str)
                    473:        {
                    474:                Draw_Character (x, y, *str);
                    475:                str++;
                    476:                x += 8;
                    477:        }
                    478: }
                    479: 
                    480: /*
                    481: ================
                    482: Draw_DebugChar
                    483: 
                    484: Draws a single character directly to the upper right corner of the screen.
                    485: This is for debugging lockups by drawing different chars in different parts
                    486: of the code.
                    487: ================
                    488: */
                    489: void Draw_DebugChar (char num)
                    490: {
                    491: }
                    492: 
                    493: /*
                    494: =============
                    495: Draw_Pic
                    496: =============
                    497: */
                    498: void Draw_Pic (int x, int y, qpic_t *pic)
                    499: {
                    500:        byte                    *dest, *source;
                    501:        unsigned short  *pusdest;
                    502:        int                             v, u;
                    503:        glpic_t                 *gl;
                    504: 
                    505:        if (scrap_dirty)
                    506:                Scrap_Upload ();
                    507:        gl = (glpic_t *)pic->data;
                    508:        glColor4f (1,1,1,1);
                    509:        GL_Bind (gl->texnum);
                    510:        glBegin (GL_QUADS);
                    511:        glTexCoord2f (gl->sl, gl->tl);
                    512:        glVertex2f (x, y);
                    513:        glTexCoord2f (gl->sh, gl->tl);
                    514:        glVertex2f (x+pic->width, y);
                    515:        glTexCoord2f (gl->sh, gl->th);
                    516:        glVertex2f (x+pic->width, y+pic->height);
                    517:        glTexCoord2f (gl->sl, gl->th);
                    518:        glVertex2f (x, y+pic->height);
                    519:        glEnd ();
                    520: }
                    521: 
                    522: 
                    523: /*
                    524: =============
                    525: Draw_TransPic
                    526: =============
                    527: */
                    528: void Draw_TransPic (int x, int y, qpic_t *pic)
                    529: {
                    530:        byte    *dest, *source, tbyte;
                    531:        unsigned short  *pusdest;
                    532:        int                             v, u;
                    533: 
                    534:        if (x < 0 || (unsigned)(x + pic->width) > vid.width || y < 0 ||
                    535:                 (unsigned)(y + pic->height) > vid.height)
                    536:        {
                    537:                Sys_Error ("Draw_TransPic: bad coordinates");
                    538:        }
                    539:                
                    540:        Draw_Pic (x, y, pic);
                    541: }
                    542: 
                    543: 
                    544: /*
                    545: =============
                    546: Draw_TransPicTranslate
                    547: 
                    548: Only used for the player color selection menu
                    549: =============
                    550: */
                    551: void Draw_TransPicTranslate (int x, int y, qpic_t *pic, byte *translation)
                    552: {
                    553:        int                             v, u, c;
                    554:        unsigned                trans[64*64], *dest;
                    555:        byte                    *src;
                    556:        int                             p;
                    557: 
                    558:        GL_Bind (translate_texture);
                    559: 
                    560:        c = pic->width * pic->height;
                    561: 
                    562:        dest = trans;
                    563:        for (v=0 ; v<64 ; v++, dest += 64)
                    564:        {
                    565:                src = &menuplyr_pixels[ ((v*pic->height)>>6) *pic->width];
                    566:                for (u=0 ; u<64 ; u++)
                    567:                {
                    568:                        p = src[(u*pic->width)>>6];
                    569:                        if (p == 255)
                    570:                                dest[u] = p;
                    571:                        else
                    572:                                dest[u] =  d_8to24table[translation[p]];
                    573:                }
                    574:        }
                    575: 
                    576:        glTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans);
                    577: 
                    578:        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
                    579:        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
                    580: 
                    581:        glColor3f (1,1,1);
                    582:        glBegin (GL_QUADS);
                    583:        glTexCoord2f (0, 0);
                    584:        glVertex2f (x, y);
                    585:        glTexCoord2f (1, 0);
                    586:        glVertex2f (x+pic->width, y);
                    587:        glTexCoord2f (1, 1);
                    588:        glVertex2f (x+pic->width, y+pic->height);
                    589:        glTexCoord2f (0, 1);
                    590:        glVertex2f (x, y+pic->height);
                    591:        glEnd ();
                    592: }
                    593: 
                    594: 
                    595: /*
                    596: ================
                    597: Draw_ConsoleBackground
                    598: 
                    599: ================
                    600: */
                    601: void Draw_ConsoleBackground (int lines)
                    602: {
                    603:        Draw_Pic (0, lines-200, conback);
                    604: }
                    605: 
                    606: 
                    607: /*
                    608: =============
                    609: Draw_TileClear
                    610: 
                    611: This repeats a 64*64 tile graphic to fill the screen around a sized down
                    612: refresh window.
                    613: =============
                    614: */
                    615: void Draw_TileClear (int x, int y, int w, int h)
                    616: {
                    617:        glColor3f (1,1,1);
                    618:        GL_Bind (*(int *)draw_backtile->data);
                    619:        glBegin (GL_QUADS);
                    620:        glTexCoord2f (x/64.0, y/64.0);
                    621:        glVertex2f (x, y);
                    622:        glTexCoord2f ( (x+w)/64.0, y/64.0);
                    623:        glVertex2f (x+w, y);
                    624:        glTexCoord2f ( (x+w)/64.0, (y+h)/64.0);
                    625:        glVertex2f (x+w, y+h);
                    626:        glTexCoord2f ( x/64.0, (y+h)/64.0 );
                    627:        glVertex2f (x, y+h);
                    628:        glEnd ();
                    629: }
                    630: 
                    631: 
                    632: /*
                    633: =============
                    634: Draw_Fill
                    635: 
                    636: Fills a box of pixels with a single color
                    637: =============
                    638: */
                    639: void Draw_Fill (int x, int y, int w, int h, int c)
                    640: {
                    641:        glDisable (GL_TEXTURE_2D);
                    642:        glColor3f (host_basepal[c*3]/255.0,
                    643:                host_basepal[c*3+1]/255.0,
                    644:                host_basepal[c*3+2]/255.0);
                    645: 
                    646:        glBegin (GL_QUADS);
                    647: 
                    648:        glVertex2f (x,y);
                    649:        glVertex2f (x+w, y);
                    650:        glVertex2f (x+w, y+h);
                    651:        glVertex2f (x, y+h);
                    652: 
                    653:        glEnd ();
                    654:        glColor3f (1,1,1);
                    655:        glEnable (GL_TEXTURE_2D);
                    656: }
                    657: //=============================================================================
                    658: 
                    659: /*
                    660: ================
                    661: Draw_FadeScreen
                    662: 
                    663: ================
                    664: */
                    665: void Draw_FadeScreen (void)
                    666: {
                    667:        glEnable (GL_BLEND);
                    668:        glDisable (GL_TEXTURE_2D);
                    669:        glColor4f (0, 0, 0, 0.8);
                    670:        glBegin (GL_QUADS);
                    671: 
                    672:        glVertex2f (0,0);
                    673:        glVertex2f (320, 0);
                    674:        glVertex2f (320, 200);
                    675:        glVertex2f (0, 200);
                    676: 
                    677:        glEnd ();
                    678:        glColor4f (1,1,1,1);
                    679:        glEnable (GL_TEXTURE_2D);
                    680:        glDisable (GL_BLEND);
                    681: 
                    682:        Sbar_Changed();
                    683: }
                    684: 
                    685: //=============================================================================
                    686: 
                    687: /*
                    688: ================
                    689: Draw_BeginDisc
                    690: 
                    691: Draws the little blue disc in the corner of the screen.
                    692: Call before beginning any disc IO.
                    693: ================
                    694: */
                    695: void Draw_BeginDisc (void)
                    696: {
                    697:        if (!draw_disc)
                    698:                return;
                    699:        glDrawBuffer  (GL_FRONT);
                    700:        Draw_Pic (320 - 24, 0, draw_disc);
                    701:        glDrawBuffer  (GL_BACK);
                    702: }
                    703: 
                    704: 
                    705: /*
                    706: ================
                    707: Draw_EndDisc
                    708: 
                    709: Erases the disc icon.
                    710: Call after completing any disc IO
                    711: ================
                    712: */
                    713: void Draw_EndDisc (void)
                    714: {
                    715: }
                    716: 
                    717: /*
                    718: ================
                    719: GL_Set2D
                    720: 
                    721: Setup as if the screen was 320*200
                    722: ================
                    723: */
                    724: void GL_Set2D (void)
                    725: {
                    726:        glViewport (glx, gly, glwidth, glheight);
                    727: 
                    728:        glMatrixMode(GL_PROJECTION);
                    729:     glLoadIdentity ();
                    730:        glOrtho  (0, 320, 200, 0, -99999, 99999);
                    731: 
                    732:        glMatrixMode(GL_MODELVIEW);
                    733:     glLoadIdentity ();
                    734: 
                    735:        glDisable (GL_DEPTH_TEST);
                    736:        glDisable (GL_CULL_FACE);
                    737:        glDisable (GL_BLEND);
                    738:        glEnable (GL_ALPHA_TEST);
                    739: //     glDisable (GL_ALPHA_TEST);
                    740: 
                    741:        glColor4f (1,1,1,1);
                    742: }
                    743: 
                    744: //====================================================================
                    745: 
                    746: /*
                    747: ================
                    748: GL_FindTexture
                    749: ================
                    750: */
                    751: int GL_FindTexture (char *identifier)
                    752: {
                    753:        int             i;
                    754:        gltexture_t     *glt;
                    755: 
                    756:        for (i=0, glt=gltextures ; i<numgltextures ; i++, glt++)
                    757:        {
                    758:                if (!strcmp (identifier, glt->identifier))
                    759:                        return gltextures[i].texnum;
                    760:        }
                    761: 
                    762:        return -1;
                    763: }
                    764: 
                    765: /*
                    766: ================
                    767: GL_ResampleTexture
                    768: ================
                    769: */
                    770: void GL_ResampleTexture (unsigned *in, int inwidth, int inheight, unsigned *out,  int outwidth, int outheight)
                    771: {
                    772:        int             i, j;
                    773:        unsigned        *inrow, *inrow2;
                    774:        unsigned        frac, fracstep;
                    775:        unsigned        p1[1024], p2[1024];
                    776:        byte            *pix1, *pix2, *pix3, *pix4;
                    777: 
                    778:        fracstep = inwidth*0x10000/outwidth;
                    779: 
                    780:        frac = fracstep>>2;
                    781:        for (i=0 ; i<outwidth ; i++)
                    782:        {
                    783:                p1[i] = 4*(frac>>16);
                    784:                frac += fracstep;
                    785:        }
                    786:        frac = 3*(fracstep>>2);
                    787:        for (i=0 ; i<outwidth ; i++)
                    788:        {
                    789:                p2[i] = 4*(frac>>16);
                    790:                frac += fracstep;
                    791:        }
                    792: 
                    793:        for (i=0 ; i<outheight ; i++, out += outwidth)
                    794:        {
                    795:                inrow = in + inwidth*(int)((i+0.25)*inheight/outheight);
                    796:                inrow2 = in + inwidth*(int)((i+0.75)*inheight/outheight);
                    797:                frac = fracstep >> 1;
                    798:                for (j=0 ; j<outwidth ; j++)
                    799:                {
                    800:                        pix1 = (byte *)inrow + p1[j];
                    801:                        pix2 = (byte *)inrow + p2[j];
                    802:                        pix3 = (byte *)inrow2 + p1[j];
                    803:                        pix4 = (byte *)inrow2 + p2[j];
                    804:                        ((byte *)(out+j))[0] = (pix1[0] + pix2[0] + pix3[0] + pix4[0])>>2;
                    805:                        ((byte *)(out+j))[1] = (pix1[1] + pix2[1] + pix3[1] + pix4[1])>>2;
                    806:                        ((byte *)(out+j))[2] = (pix1[2] + pix2[2] + pix3[2] + pix4[2])>>2;
                    807:                        ((byte *)(out+j))[3] = (pix1[3] + pix2[3] + pix3[3] + pix4[3])>>2;
                    808:                }
                    809:        }
                    810: }
                    811: 
                    812: /*
                    813: ================
                    814: GL_MipMap
                    815: 
                    816: Operates in place, quartering the size of the texture
                    817: ================
                    818: */
                    819: void GL_MipMap (byte *in, int width, int height)
                    820: {
                    821:        int             i, j;
                    822:        byte    *out;
                    823: 
                    824:        width <<=2;
                    825:        height >>= 1;
                    826:        out = in;
                    827:        for (i=0 ; i<height ; i++, in+=width)
                    828:        {
                    829:                for (j=0 ; j<width ; j+=8, out+=4, in+=8)
                    830:                {
                    831:                        out[0] = (in[0] + in[4] + in[width+0] + in[width+4])>>2;
                    832:                        out[1] = (in[1] + in[5] + in[width+1] + in[width+5])>>2;
                    833:                        out[2] = (in[2] + in[6] + in[width+2] + in[width+6])>>2;
                    834:                        out[3] = (in[3] + in[7] + in[width+3] + in[width+7])>>2;
                    835:                }
                    836:        }
                    837: }
                    838: 
                    839: /*
                    840: ===============
                    841: GL_Upload32
                    842: ===============
                    843: */
                    844: void GL_Upload32 (unsigned *data, int width, int height,  qboolean mipmap, qboolean alpha)
                    845: {
                    846:        int                     samples;
                    847: static unsigned        scaled[1024*512];       // [512*256];
                    848:        int                     scaled_width, scaled_height;
                    849: 
                    850:        for (scaled_width = 1 ; scaled_width < width ; scaled_width<<=1)
                    851:                ;
                    852:        if (gl_round_down.value && scaled_width > width)
                    853:                scaled_width >>= 1;
                    854:        for (scaled_height = 1 ; scaled_height < height ; scaled_height<<=1)
                    855:                ;
                    856:        if (gl_round_down.value && scaled_height > height)
                    857:                scaled_height >>= 1;
                    858: 
                    859:        scaled_width >>= (int)gl_picmip.value;
                    860:        scaled_height >>= (int)gl_picmip.value;
                    861: 
                    862:        if (scaled_width > gl_max_size.value)
                    863:                scaled_width = gl_max_size.value;
                    864:        if (scaled_height > gl_max_size.value)
                    865:                scaled_height = gl_max_size.value;
                    866: 
                    867:        if (scaled_width * scaled_height > sizeof(scaled)/4)
                    868:                Sys_Error ("GL_LoadTexture: too big");
                    869: 
                    870:        samples = alpha ? gl_alpha_format : gl_solid_format;
                    871: 
                    872: #if 0
                    873:        if (mipmap)
                    874:                gluBuild2DMipmaps (GL_TEXTURE_2D, samples, width, height, GL_RGBA, GL_UNSIGNED_BYTE, trans);
                    875:        else if (scaled_width == width && scaled_height == height)
                    876:                glTexImage2D (GL_TEXTURE_2D, 0, samples, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans);
                    877:        else
                    878:        {
                    879:                gluScaleImage (GL_RGBA, width, height, GL_UNSIGNED_BYTE, trans,
                    880:                        scaled_width, scaled_height, GL_UNSIGNED_BYTE, scaled);
                    881:                glTexImage2D (GL_TEXTURE_2D, 0, samples, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled);
                    882:        }
                    883: #else
                    884: 
                    885:        if (scaled_width == width && scaled_height == height)
                    886:        {
                    887:                if (!mipmap)
                    888:                {
                    889:                        glTexImage2D (GL_TEXTURE_2D, 0, samples, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
                    890:                        goto done;
                    891:                }
                    892:                memcpy (scaled, data, width*height*4);
                    893:        }
                    894:        else
                    895:                GL_ResampleTexture (data, width, height, scaled, scaled_width, scaled_height);
                    896: 
                    897: texels += scaled_width * scaled_height;
                    898:        glTexImage2D (GL_TEXTURE_2D, 0, samples, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled);
                    899:        if (mipmap)
                    900:        {
                    901:                int             miplevel;
                    902: 
                    903:                miplevel = 0;
                    904:                while (scaled_width > 1 || scaled_height > 1)
                    905:                {
                    906:                        GL_MipMap ((byte *)scaled, scaled_width, scaled_height);
                    907:                        scaled_width >>= 1;
                    908:                        scaled_height >>= 1;
                    909:                        if (scaled_width < 1)
                    910:                                scaled_width = 1;
                    911:                        if (scaled_height < 1)
                    912:                                scaled_height = 1;
                    913:                        miplevel++;
                    914: texels += scaled_width * scaled_height;
                    915:                        glTexImage2D (GL_TEXTURE_2D, miplevel, samples, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled);
                    916:                }
                    917:        }
                    918: done: ;
                    919: #endif
                    920: 
                    921: 
                    922:        if (mipmap)
                    923:        {
                    924:                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
                    925:                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
                    926:        }
                    927:        else
                    928:        {
                    929:                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max);
                    930:                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
                    931:        }
                    932: }
                    933: 
                    934: /*
                    935: ===============
                    936: GL_Upload8
                    937: ===============
                    938: */
                    939: void GL_Upload8 (byte *data, int width, int height,  qboolean mipmap, qboolean alpha)
                    940: {
                    941: static unsigned        trans[640*480];         // FIXME, temporary
                    942:        int                     i, s;
                    943:        qboolean        noalpha;
                    944:        int                     p;
                    945: 
                    946:        s = width*height;
                    947:        // if there are no transparent pixels, make it a 3 component
                    948:        // texture even if it was specified as otherwise
                    949:        if (alpha)
                    950:        {
                    951:                noalpha = true;
                    952:                for (i=0 ; i<s ; i++)
                    953:                {
                    954:                        p = data[i];
                    955:                        if (p == 255)
                    956:                                noalpha = false;
                    957:                        trans[i] = d_8to24table[p];
                    958:                }
                    959: 
                    960:                if (alpha && noalpha)
                    961:                        alpha = false;
                    962:        }
                    963:        else
                    964:        {
                    965:                if (s&3)
                    966:                        Sys_Error ("GL_Upload8: s&3");
                    967:                for (i=0 ; i<s ; i+=4)
                    968:                {
                    969:                        trans[i] = d_8to24table[data[i]];
                    970:                        trans[i+1] = d_8to24table[data[i+1]];
                    971:                        trans[i+2] = d_8to24table[data[i+2]];
                    972:                        trans[i+3] = d_8to24table[data[i+3]];
                    973:                }
                    974:        }
                    975: 
                    976:        GL_Upload32 (trans, width, height, mipmap, alpha);
                    977: }
                    978: 
                    979: /*
                    980: ================
                    981: GL_LoadTexture
                    982: ================
                    983: */
                    984: int GL_LoadTexture (char *identifier, int width, int height, byte *data, qboolean mipmap, qboolean alpha)
                    985: {
                    986:        qboolean        noalpha;
                    987:        int                     i, p, s;
                    988:        gltexture_t     *glt;
                    989: 
                    990:        // see if the texture is allready present
                    991:        if (identifier[0])
                    992:        {
                    993:                for (i=0, glt=gltextures ; i<numgltextures ; i++, glt++)
                    994:                {
                    995:                        if (!strcmp (identifier, glt->identifier))
                    996:                        {
                    997:                                if (width != glt->width || height != glt->height)
                    998:                                        Sys_Error ("GL_LoadTexture: cache mismatch");
                    999:                                return gltextures[i].texnum;
                   1000:                        }
                   1001:                }
                   1002:        }
                   1003:        else
                   1004:                glt = &gltextures[numgltextures];
                   1005:        numgltextures++;
                   1006: 
                   1007:        strcpy (glt->identifier, identifier);
                   1008:        glt->texnum = texture_extension_number;
                   1009:        glt->width = width;
                   1010:        glt->height = height;
                   1011:        glt->mipmap = mipmap;
                   1012: 
                   1013:        GL_Bind(texture_extension_number );
                   1014: 
                   1015:        GL_Upload8 (data, width, height, mipmap, alpha);
                   1016: 
                   1017:        texture_extension_number++;
                   1018: 
                   1019:        return texture_extension_number-1;
                   1020: }
                   1021: 
                   1022: /*
                   1023: ================
                   1024: GL_LoadPicTexture
                   1025: ================
                   1026: */
                   1027: int GL_LoadPicTexture (qpic_t *pic)
                   1028: {
                   1029:        return GL_LoadTexture ("", pic->width, pic->height, pic->data, false, true);
                   1030: }
                   1031: 

unix.superglobalmegacorp.com

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