[AD] Yet again updated the gouraud/rgb blitters |
[ Thread Index |
Date Index
| More lists.liballeg.org/allegro-developers Archives
]
I added "fast" versions that do not perform clipping. Here are the
speeds I got.
Color depth: 8 bpp
blit_gouraud: 745.902 per second
blit_gouraud_rgb: 733.871 per second
draw_gouraud_rgb: 722.222 per second
blit_gouraud_fast: 1137.500 per second
blit_gouraud_rgb_fast: 1083.333 per second
draw_gouraud_rgb_fast: 1083.333 per second
Color depth: 15 bpp
blit_gouraud: 798.246 per second
blit_gouraud_rgb: 771.186 per second
draw_gouraud_rgb: 989.130 per second
blit_gouraud_fast: 1421.875 per second
blit_gouraud_rgb_fast: 1229.730 per second
draw_gouraud_rgb_fast: 1421.875 per second
Color depth: 16 bpp
blit_gouraud: 798.246 per second
blit_gouraud_rgb: 771.186 per second
draw_gouraud_rgb: 989.130 per second
blit_gouraud_fast: 1421.875 per second
blit_gouraud_rgb_fast: 1263.889 per second
draw_gouraud_rgb_fast: 1421.875 per second
Color depth: 24 bpp
blit_gouraud: 798.246 per second
blit_gouraud_rgb: 798.246 per second
draw_gouraud_rgb: 1011.111 per second
blit_gouraud_fast: 1263.889 per second
blit_gouraud_rgb_fast: 1109.756 per second
draw_gouraud_rgb_fast: 1421.875 per second
Color depth: 32 bpp
blit_gouraud: 784.483 per second
blit_gouraud_rgb: 827.273 per second
draw_gouraud_rgb: 1011.111 per second
blit_gouraud_fast: 1378.788 per second
blit_gouraud_rgb_fast: 1197.368 per second
draw_gouraud_rgb_fast: 1378.788 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>
#define _getpixel8(bmp, x, y) _getpixel(bmp, x, y)
#define _putpixel8(bmp, x, y, c) _putpixel(bmp, x, y, c)
/* c1 ---- c2
* | |
* c3 ---- c4
*/
#define HELPER_BLIT_GOURAUD_FAST(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##depth(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##depth(dest, dest_x+x, dest_y+y, makecol##depth(r, g, b));\
} \
C1 += d1; \
C2 += d2; \
}
#define HELPER_BLIT_GOURAUD_RGB_FAST(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##depth(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##depth(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_FAST(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##depth(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##depth(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]; \
}
/* 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;
/* clip */
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;
int 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;
}
}
void blit_gouraud_fast(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;
/* clip */
switch (bitmap_color_depth(src)) {
case 8: HELPER_BLIT_GOURAUD_FAST(8); break;
case 15: HELPER_BLIT_GOURAUD_FAST(15); break;
case 16: HELPER_BLIT_GOURAUD_FAST(16); break;
case 24: HELPER_BLIT_GOURAUD_FAST(24); break;
case 32: HELPER_BLIT_GOURAUD_FAST(32); break;
}
}
void blit_gouraud_rgb_fast(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_FAST(8); break;
case 15: HELPER_BLIT_GOURAUD_RGB_FAST(15); break;
case 16: HELPER_BLIT_GOURAUD_RGB_FAST(16); break;
case 24: HELPER_BLIT_GOURAUD_RGB_FAST(24); break;
case 32: HELPER_BLIT_GOURAUD_RGB_FAST(32); break;
}
}
void draw_gouraud_rgb_sprite_fast(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;
int 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_FAST(8); break;
case 15: HELPER_BLIT_GOURAUD_RGB_SPRITE_FAST(15); break;
case 16: HELPER_BLIT_GOURAUD_RGB_SPRITE_FAST(16); break;
case 24: HELPER_BLIT_GOURAUD_RGB_SPRITE_FAST(24); break;
case 32: HELPER_BLIT_GOURAUD_RGB_SPRITE_FAST(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][6] = { 0 };
static char *txt[] = { "blit_gouraud", "blit_gouraud_rgb", "draw_gouraud_rgb",
"blit_gouraud_fast", "blit_gouraud_rgb_fast", "draw_gouraud_rgb_fast" };
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 < 6; 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, 255, 192, 128, 64);
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;
case 3:
s = clock();
for (z = 0; z < TESTS; z++)
blit_gouraud_fast(bmp, dest, 0, 0, 0, 0, 64, 64, 255, 192, 128, 64);
s = clock() - s;
time[x][y] = s;
break;
case 4:
s = clock();
for (z = 0; z < TESTS; z++)
blit_gouraud_rgb_fast(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 5:
s = clock();
for (z = 0; z < TESTS; z++)
draw_gouraud_rgb_sprite_fast(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 < 6; y++)
printf("\t%25s: %10.3f per second\n", txt[y], ((float)TESTS) / ((float)time[x][y] / (float)CLK_TCK));
}
return 0;
}