[AD] gouraud sprites, blits

[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]


Attached is the code todo gouraud blits, rgb gouraud blits and rgb
gouraud sprites.

Timing info (none to impressive)

Color depth: 8 bpp
                     blit_gouraud:   8379.121 per second
                 blit_gouraud_rgb:   8516.484 per second
                 draw_gouraud_rgb:   8653.846 per second
Color depth: 15 bpp
                     blit_gouraud:   7829.670 per second
                 blit_gouraud_rgb:   8104.396 per second
                 draw_gouraud_rgb:   6318.681 per second
Color depth: 16 bpp
                     blit_gouraud:   7829.670 per second
                 blit_gouraud_rgb:   8104.396 per second
                 draw_gouraud_rgb:   6318.681 per second
Color depth: 24 bpp
                     blit_gouraud:   7692.308 per second
                 blit_gouraud_rgb:   7554.945 per second
                 draw_gouraud_rgb:   6043.956 per second
Color depth: 32 bpp
                     blit_gouraud:   7829.670 per second
                 blit_gouraud_rgb:   7692.308 per second
                 draw_gouraud_rgb:   6181.319 per second


__________________________________________________
Do You Yahoo!?
Get personalized email addresses from Yahoo! Mail - only $35 
a year!  http://personal.mail.yahoo.com/
/* Gouraud blitting routines */
#include <allegro.h>
#include <stdlib.h>
#include <time.h>
#include <stdio.h>

/* c1 ---- c2
 *  |      |
 * c3 ---- c4
 */
#define HELPER_BLIT_GOURAUD(depth)                                          \
    for (y = 0; y < height; y++) {                                          \
        /* find scanline points */                                          \
        C = C1;                                                             \
        dx = (C2 - C1) / width;                                             \
        for (x = 0; x < width; x++) {                                       \
            /* calc the new shade value as we go across */                  \
            C += dx;                                                        \
            temp = C>>16;                                                   \
            /* get pixel and shade it */                                    \
            c = getpixel(src, src_x+x, src_y+y);                            \
            r = (getr##depth(c) * temp) >> 8;                               \
            g = (getg##depth(c) * temp) >> 8;                               \
            b = (getb##depth(c) * temp) >> 8;                               \
            putpixel(dest, dest_x+x, dest_y+y, makecol##depth(r, g, b));    \
        }                                                                   \
        C1 += d1;                                                           \
        C2 += d2;                                                           \
    }                                                                       

#define HELPER_BLIT_GOURAUD_RGB(depth)                                      \
    for (y = 0; y < height; y++) {                                          \
        /* find scanline points */                                          \
        C[0] = C1[0];C[1] = C1[1];C[2] = C1[2];                             \
        dx[0] = (C2[0] - C1[0]) / width;                                    \
        dx[1] = (C2[1] - C1[1]) / width;                                    \
        dx[2] = (C2[2] - C1[2]) / width;                                    \
        for (x = 0; x < width; x++) {                                       \
            /* calc the new shade value as we go across */                  \
            C[0] += dx[0];C[1] += dx[1];C[2] += dx[2];                      \
            temp[0] = C[0]>>16;temp[1] = C[1]>>16;temp[2] = C[2]>>16;       \
            /* get pixel and shade it */                                    \
            c = getpixel(src, src_x+x, src_y+y);                            \
            r = (getr##depth(c) * temp[0]) >> 8;                            \
            g = (getg##depth(c) * temp[1]) >> 8;                            \
            b = (getb##depth(c) * temp[2]) >> 8;                            \
            putpixel(dest, dest_x+x, dest_y+y, makecol##depth(r, g, b));    \
        }                                                                   \
        C1[0] += d1[0];C1[1] += d1[1];C1[2] += d1[2];                       \
        C2[0] += d2[0];C2[1] += d2[1];C2[2] += d2[2];                       \
    }                                                                       

#define HELPER_BLIT_GOURAUD_RGB_SPRITE(depth)                               \
    for (y = 0; y < height; y++) {                                          \
        /* find scanline points */                                          \
        C[0] = C1[0];C[1] = C1[1];C[2] = C1[2];                             \
        dx[0] = (C2[0] - C1[0]) / width;                                    \
        dx[1] = (C2[1] - C1[1]) / width;                                    \
        dx[2] = (C2[2] - C1[2]) / width;                                    \
        for (x = 0; x < width; x++) {                                       \
            /* calc the new shade value as we go across */                  \
            C[0] += dx[0];C[1] += dx[1];C[2] += dx[2];                      \
            temp[0] = C[0]>>16;temp[1] = C[1]>>16;temp[2] = C[2]>>16;       \
            /* get pixel and shade it */                                    \
            c = getpixel(src, x, y);                                        \
            if (c != MASK_COLOR_##depth){                                   \
                r = (getr##depth(c) * temp[0]) >> 8;                        \
                g = (getg##depth(c) * temp[1]) >> 8;                        \
                b = (getb##depth(c) * temp[2]) >> 8;                        \
                putpixel(dest, dest_x+x, dest_y+y, makecol##depth(r, g, b));\
            }                                                               \
        }                                                                   \
        C1[0] += d1[0];C1[1] += d1[1];C1[2] += d1[2];                       \
        C2[0] += d2[0];C2[1] += d2[1];C2[2] += d2[2];                       \
    }                                                                       

void blit_gouraud(BITMAP *src, BITMAP *dest, int src_x, int src_y,
                  int dest_x, int dest_y, int width, int height,
                  int c1, int c2, int c3, int c4)
{
    int x, y, d1, d2, dx, C, C1, C2;                                        
    int c, r, g, b, temp;                                         
                                                                            
    /* find deltas */                                                       
    d1 = ((c3 - c1) << 16) / height;                                        
    d2 = ((c4 - c2) << 16) / height;                                        
    C1 = c1<<16;                                                            
    C2 = c2<<16;

    switch (bitmap_color_depth(src)) {
        case 8: HELPER_BLIT_GOURAUD(8); break;
        case 15: HELPER_BLIT_GOURAUD(15); break;
        case 16: HELPER_BLIT_GOURAUD(16); break;
        case 24: HELPER_BLIT_GOURAUD(24); break;
        case 32: HELPER_BLIT_GOURAUD(32); break;
    }
}

void blit_gouraud_rgb(BITMAP *src, BITMAP *dest, int src_x, int src_y,
                  int dest_x, int dest_y, int width, int height,
                  int *c1, int *c2, int *c3, int *c4)
{
    int x, y, d1[3], d2[3], dx[3], C[3], C1[3], C2[3];
    int c, r, g, b, temp[3];

    for (x = 0; x < 3; x++) {
        /* find deltas */                                                       
        d1[x] = ((c3[x] - c1[x]) << 16) / height;                                        
        d2[x] = ((c4[x] - c2[x]) << 16) / height;                                        
        C1[x] = c1[x]<<16;                                                            
        C2[x] = c2[x]<<16;
    }
    switch (bitmap_color_depth(src)) {
        case 8: HELPER_BLIT_GOURAUD_RGB(8); break;
        case 15: HELPER_BLIT_GOURAUD_RGB(15); break;
        case 16: HELPER_BLIT_GOURAUD_RGB(16); break;
        case 24: HELPER_BLIT_GOURAUD_RGB(24); break;
        case 32: HELPER_BLIT_GOURAUD_RGB(32); break;
    }
}

void draw_gouraud_rgb_sprite(BITMAP *dest, BITMAP *src, int dest_x,
                             int dest_y, int *c1, int *c2, int *c3, int *c4)
{
    int x, y, d1[3], d2[3], dx[3], C[3], C1[3], C2[3], width, height;
    unsigned long c, r, g, b, temp[3];

    width = src->w;
    height = src->h;
    for (x = 0; x < 3; x++) {
        /* find deltas */                                                       
        d1[x] = ((c3[x] - c1[x]) << 16) / height;                                        
        d2[x] = ((c4[x] - c2[x]) << 16) / height;                                        
        C1[x] = c1[x]<<16;                                                            
        C2[x] = c2[x]<<16;
    }
    switch (bitmap_color_depth(src)) {
        case 8: HELPER_BLIT_GOURAUD_RGB_SPRITE(8); break;
        case 15: HELPER_BLIT_GOURAUD_RGB_SPRITE(15); break;
        case 16: HELPER_BLIT_GOURAUD_RGB_SPRITE(16); break;
        case 24: HELPER_BLIT_GOURAUD_RGB_SPRITE(24); break;
        case 32: HELPER_BLIT_GOURAUD_RGB_SPRITE(32); break;
    }
}

/*dummy example */
#define TESTS 2500
RGB_MAP rgbmap;
int main(void)
{
    BITMAP *bmp, *dest;
    static int modes[5] = { 8, 15, 16, 24, 32 }, c[4], c2[4][3], x, y, s, z;
    static int time[5][3] = { 0 };
    static char *txt[] = { "blit_gouraud", "blit_gouraud_rgb", "draw_gouraud_rgb" };
    PALETTE pal;

    allegro_init();

    for (x = 0; x < 5; x++) {
        set_color_depth(modes[x]);
        bmp = load_bitmap("test.bmp", (RGB *)pal);
        dest = create_bitmap(64, 64);
        if (modes[x] == 8) {
            create_rgb_table(&rgbmap, pal, NULL);
            rgb_map = &rgbmap;
        }
        for (y = 0; y < 3; y++) {
            printf("Test: %s\n", txt[y]);fflush(stdout);
            switch (y) {
                case 0:
                    s = clock();
                    for (z = 0; z < TESTS; z++) 
                        blit_gouraud(bmp, dest, 0, 0, 0, 0, 64, 64, c[0], c[1], c[2], c[3]);
                    s = clock() - s;
                    time[x][y] = s;
                    break;
                case 1:
                    s = clock();
                    for (z = 0; z < TESTS; z++)
                        blit_gouraud_rgb(bmp, dest, 0, 0, 0, 0, 64, 64, c2[0], c2[1], c2[2], c2[3]);
                    s = clock() - s;
                    time[x][y] = s;
                    break;
                case 2:
                    s = clock();
                    for (z = 0; z < TESTS; z++)
                        draw_gouraud_rgb_sprite(dest, bmp, 0, 0, c2[0], c2[1], c2[2], c2[3]);
                    s = clock() - s;
                    time[x][y] = s;
                    break;
            }
        }
        destroy_bitmap(bmp);
        destroy_bitmap(dest);
    }
    for (x = 0; x < 5; x++) {
        printf("Color depth: %d bpp\n", modes[x]);
        for (y = 0; y < 3; y++)
            printf("\t%25s: %10.3f per second\n", txt[y], (float)TESTS * (float)time[x][y] / (float)CLK_TCK);
    }

    return 0;
}



Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/