ref: 0d5263b0ef5c4c7077a81927590ab28813e76f37
dir: /src/zbuffer.c/
/* * Z buffer: 16 bits Z / 16 bits color * */ #include <stdlib.h> #include <stdio.h> #include <assert.h> #include <string.h> #include "../include/zbuffer.h" ZBuffer *ZB_open(int xsize, int ysize, int mode, int nb_colors, unsigned char *color_indexes, int *color_table, void *frame_buffer) { ZBuffer *zb; int size; zb = gl_malloc(sizeof(ZBuffer)); if (zb == NULL) return NULL; zb->xsize = xsize; zb->ysize = ysize; zb->mode = mode; zb->linesize = (xsize * PSZB + 3) & ~3; switch (mode) { #ifdef TGL_FEATURE_8_BITS case ZB_MODE_INDEX: ZB_initDither(zb, nb_colors, color_indexes, color_table); break; #endif #ifdef TGL_FEATURE_32_BITS case ZB_MODE_RGBA: #endif #ifdef TGL_FEATURE_24_BITS case ZB_MODE_RGB24: #endif case ZB_MODE_5R6G5B: zb->nb_colors = 0; break; default: goto error; } size = zb->xsize * zb->ysize * sizeof(unsigned short); zb->zbuf = gl_malloc(size); if (zb->zbuf == NULL) goto error; if (frame_buffer == NULL) { zb->pbuf = gl_malloc(zb->ysize * zb->linesize); if (zb->pbuf == NULL) { gl_free(zb->zbuf); goto error; } zb->frame_buffer_allocated = 1; } else { zb->frame_buffer_allocated = 0; zb->pbuf = frame_buffer; } zb->current_texture = NULL; return zb; error: gl_free(zb); return NULL; } void ZB_close(ZBuffer * zb) { #ifdef TGL_FEATURE_8_BITS if (zb->mode == ZB_MODE_INDEX) ZB_closeDither(zb); #endif if (zb->frame_buffer_allocated) gl_free(zb->pbuf); gl_free(zb->zbuf); gl_free(zb); } void ZB_resize(ZBuffer * zb, void *frame_buffer, int xsize, int ysize) { int size; /* xsize must be a multiple of 4 */ xsize = xsize & ~3; zb->xsize = xsize; zb->ysize = ysize; zb->linesize = (xsize * PSZB + 3) & ~3; size = zb->xsize * zb->ysize * sizeof(unsigned short); gl_free(zb->zbuf); zb->zbuf = gl_malloc(size); if (zb->frame_buffer_allocated) gl_free(zb->pbuf); if (frame_buffer == NULL) { zb->pbuf = gl_malloc(zb->ysize * zb->linesize); zb->frame_buffer_allocated = 1; } else { zb->pbuf = frame_buffer; zb->frame_buffer_allocated = 0; } } #if TGL_FEATURE_32_BITS == 1 inline PIXEL pxReverse32(PIXEL x) { return // Source is in format: 0xAARRGGBB ((x & 0xFF000000) >> 24) | //______AA ((x & 0x00FF0000) >> 8) | //____RR__ ((x & 0x0000FF00) << 8) | //__GG____ ((x & 0x000000FF) << 24); //BB______ // Return value is in format: 0xBBGGRRAA } #endif static void ZB_copyBuffer(ZBuffer * zb, void *buf, int linesize) { unsigned char *p1; PIXEL *q; int y; #if !TGL_FEATURE_NO_COPY_COLOR int n; #endif q = zb->pbuf; p1 = buf; #if !TGL_FEATURE_NO_COPY_COLOR n = zb->xsize * PSZB; #endif for (y = 0; y < zb->ysize; y++) { #if TGL_FEATURE_NO_COPY_COLOR for(int i = 0; i < zb->xsize; i++) { if((*(q+i) & TGL_COLOR_MASK) != TGL_NO_COPY_COLOR) *(((PIXEL*)p1) + i) = *(q+i); } #else memcpy(p1, q, n); #endif p1 += linesize; //TODO make this a predictable behavior. q = (PIXEL *) ((char *) q + zb->linesize); } } #if TGL_FEATURE_RENDER_BITS == 16 /* 32 bpp copy */ /* #ifdef TGL_FEATURE_32_BITS #define RGB16_TO_RGB32(p0,p1,v)\ {\ unsigned int g,b,gb;\ g = (v & 0x07E007E0) << 5;\ b = (v & 0x001F001F) << 3;\ gb = g | b;\ p0 = (gb & 0x0000FFFF) | ((v & 0x0000F800) << 8);\ p1 = (gb >> 16) | ((v & 0xF8000000) >> 8);\ } //This function is never called. static void ZB_copyFrameBufferRGB32(ZBuffer * zb, void *buf, int linesize) { unsigned short *q; unsigned int *p, *p1, v, w0, w1; int y, n; q = zb->pbuf; p1 = (unsigned int *) buf; //puts("\nBEING CALLED\n"); for (y = 0; y < zb->ysize; y++) { p = p1; n = zb->xsize >> 2; do { v = *(unsigned int *) q; RGB16_TO_RGB32(w1, w0, v); p[0] = w0; p[1] = w1; v = *(unsigned int *) (q + 2); RGB16_TO_RGB32(w1, w0, v); p[2] = w0; p[3] = 0; q += 4; p += 4; } while (--n > 0); p1 += linesize; } } */ #endif /* 24 bit packed pixel handling */ #ifdef TGL_FEATURE_24_BITS /* order: RGBR GBRG BRGB */ /* XXX: packed pixel 24 bit support not tested */ /* XXX: big endian case not optimised */ /* #if BYTE_ORDER == BIG_ENDIAN #define RGB16_TO_RGB24(p0,p1,p2,v1,v2)\ {\ unsigned int r1,g1,b1,gb1,g2,b2,gb2;\ v1 = (v1 << 16) | (v1 >> 16);\ v2 = (v2 << 16) | (v2 >> 16);\ r1 = (v1 & 0xF800F800);\ g1 = (v1 & 0x07E007E0) << 5;\ b1 = (v1 & 0x001F001F) << 3;\ gb1 = g1 | b1;\ p0 = ((gb1 & 0x0000FFFF) << 8) | (r1 << 16) | (r1 >> 24);\ g2 = (v2 & 0x07E007E0) << 5;\ b2 = (v2 & 0x001F001F) << 3;\ gb2 = g2 | b2;\ p1 = (gb1 & 0xFFFF0000) | (v2 & 0xF800) | ((gb2 >> 8) & 0xff);\ p2 = (gb2 << 24) | ((v2 & 0xF8000000) >> 8) | (gb2 >> 16);\ } #else #define RGB16_TO_RGB24(p0,p1,p2,v1,v2)\ {\ unsigned int r1,g1,b1,gb1,g2,b2,gb2;\ r1 = (v1 & 0xF800F800);\ g1 = (v1 & 0x07E007E0) << 5;\ b1 = (v1 & 0x001F001F) << 3;\ gb1 = g1 | b1;\ p0 = ((gb1 & 0x0000FFFF) << 8) | (r1 << 16) | (r1 >> 24);\ g2 = (v2 & 0x07E007E0) << 5;\ b2 = (v2 & 0x001F001F) << 3;\ gb2 = g2 | b2;\ p1 = (gb1 & 0xFFFF0000) | (v2 & 0xF800) | ((gb2 >> 8) & 0xff);\ p2 = (gb2 << 24) | ((v2 & 0xF8000000) >> 8) | (gb2 >> 16);\ } #endif */ /* static void ZB_copyFrameBufferRGB24(ZBuffer * zb, void *buf, int linesize) { unsigned short *q; unsigned int *p, *p1, w0, w1, w2, v0, v1; int y, n; q = zb->pbuf; p1 = (unsigned int *) buf; linesize = linesize * 3; for (y = 0; y < zb->ysize; y++) { p = p1; n = zb->xsize >> 2; do { v0 = *(unsigned int *) q; v1 = *(unsigned int *) (q + 2); RGB16_TO_RGB24(w0, w1, w2, v0, v1); p[0] = w0; p[1] = w1; p[2] = w2; q += 4; p += 3; } while (--n > 0); *((char *) p1) += linesize; } } */ #endif #if TGL_FEATURE_RENDER_BITS == 16 void ZB_copyFrameBuffer(ZBuffer * zb, void *buf, int linesize) { ZB_copyBuffer(zb, buf, linesize); //switch (zb->mode) { /* #ifdef TGL_FEATURE_8_BITS case ZB_MODE_INDEX: ZB_ditherFrameBuffer(zb, buf, linesize >> 1); break; #endif */ /*#ifdef TGL_FEATURE_16_BITS case ZB_MODE_5R6G5B: ZB_copyBuffer(zb, buf, linesize); break; #endif*/ /*#ifdef TGL_FEATURE_32_BITS case ZB_MODE_RGBA: ZB_copyFrameBufferRGB32(zb, buf, linesize >> 1); break; #endif */ // default: // assert(0); // } } #endif /* TGL_FEATURE_RENDER_BITS == 16 */ /* #if TGL_FEATURE_RENDER_BITS == 24 #define RGB24_TO_RGB16(r, g, b) \ ((((r) >> 3) << 11) | (((g) >> 2) << 5) | ((b) >> 3)) // XXX: not optimized static void ZB_copyFrameBuffer5R6G5B(ZBuffer * zb, void *buf, int linesize) { PIXEL *q; unsigned short *p, *p1; int y, n; q = zb->pbuf; p1 = (unsigned short *) buf; for (y = 0; y < zb->ysize; y++) { p = p1; n = zb->xsize >> 2; do { p[0] = RGB24_TO_RGB16(q[0], q[1], q[2]); p[1] = RGB24_TO_RGB16(q[3], q[4], q[5]); p[2] = RGB24_TO_RGB16(q[6], q[7], q[8]); p[3] = RGB24_TO_RGB16(q[9], q[10], q[11]); q = (PIXEL *)((char *)q + 4 * PSZB); p += 4; } while (--n > 0); p1 = (unsigned short *)((char *)p1 + linesize); } } void ZB_copyFrameBuffer(ZBuffer * zb, void *buf, int linesize) { switch (zb->mode) { #ifdef TGL_FEATURE_16_BITS case ZB_MODE_5R6G5B: ZB_copyFrameBuffer5R6G5B(zb, buf, linesize); break; #endif #ifdef TGL_FEATURE_24_BITS case ZB_MODE_RGB24: ZB_copyBuffer(zb, buf, linesize); break; #endif default: assert(0); } } #endif */ /* TGL_FEATURE_RENDER_BITS == 24 */ #if TGL_FEATURE_RENDER_BITS == 32 #define RGB32_TO_RGB16(v) \ (((v >> 8) & 0xf800) | (((v) >> 5) & 0x07e0) | (((v) & 0xff) >> 3)) /* XXX: not optimized */ /* static void ZB_copyFrameBuffer5R6G5B(ZBuffer * zb, void *buf, int linesize) { PIXEL *q; unsigned short *p, *p1; int y, n; q = zb->pbuf; p1 = (unsigned short *) buf; for (y = 0; y < zb->ysize; y++) { p = p1; n = zb->xsize >> 2; do { p[0] = RGB32_TO_RGB16(q[0]); p[1] = RGB32_TO_RGB16(q[1]); p[2] = RGB32_TO_RGB16(q[2]); p[3] = RGB32_TO_RGB16(q[3]); q += 4; p += 4; } while (--n > 0); p1 = (unsigned short *)((char *)p1 + linesize); } } */ void ZB_copyFrameBuffer(ZBuffer * zb, void *buf, int linesize) { ZB_copyBuffer(zb, buf, linesize); //switch (zb->mode) { /* #ifdef TGL_FEATURE_16_BITS case ZB_MODE_5R6G5B: ZB_copyFrameBuffer5R6G5B(zb, buf, linesize); break; #endif */ /* #ifdef TGL_FEATURE_32_BITS case ZB_MODE_RGBA: ZB_copyBuffer(zb, buf, linesize); break; #endif default: assert(0); } */ } #endif /* TGL_FEATURE_RENDER_BITS == 32 */ /* * adr must be aligned on an 'int' */ //Used in 16 bit mode void memset_s(void *adr, int val, int count) { int i, n, v; unsigned int *p; unsigned short *q; p = adr; v = val | (val << 16); n = count >> 3; for (i = 0; i < n; i++) { p[0] = v; p[1] = v; p[2] = v; p[3] = v; p += 4; } q = (unsigned short *) p; n = count & 7; for (i = 0; i < n; i++) *q++ = val; } //Used in 32 bit mode void memset_l(void *adr, int val, int count) { int i, n, v; unsigned int *p; p = adr; v = val; n = count >> 2; for (i = 0; i < n; i++) { p[0] = v; p[1] = v; p[2] = v; p[3] = v; p += 4; } n = count & 3; for (i = 0; i < n; i++) *p++ = val; } /* count must be a multiple of 4 and >= 4 */ //Gek's note: Should never be used. void memset_RGB24(void *adr,int r, int v, int b,long count) { long i, n; register long v1,v2,v3,*pt=(long *)(adr); unsigned char *p,R=(unsigned char)r,V=(unsigned char)v,B=(unsigned char)b; p=(unsigned char *)adr; *p++=R; *p++=V; *p++=B; *p++=R; *p++=V; *p++=B; *p++=R; *p++=V; *p++=B; *p++=R; *p++=V; *p++=B; v1=*pt++; v2=*pt++; v3=*pt++; n = count >> 2; for(i=1;i<n;i++) { *pt++=v1; *pt++=v2; *pt++=v3; } } void ZB_clear(ZBuffer * zb, int clear_z, int z, int clear_color, int r, int g, int b) { #if TGL_FEATURE_RENDER_BITS != 24 int color; #endif int y; PIXEL *pp; if (clear_z) { memset_s(zb->zbuf, z, zb->xsize * zb->ysize); } if (clear_color) { pp = zb->pbuf; for (y = 0; y < zb->ysize; y++) { #if TGL_FEATURE_RENDER_BITS == 15 || TGL_FEATURE_RENDER_BITS == 16 //color = RGB_TO_PIXEL(r, g, b); #if TGL_FEATURE_FORCE_CLEAR_NO_COPY_COLOR color = TGL_NO_COPY_COLOR; #else color = RGB_TO_PIXEL(r, g, b); #endif memset_s(pp, color, zb->xsize); #elif TGL_FEATURE_RENDER_BITS == 32 #if TGL_FEATURE_FORCE_CLEAR_NO_COPY_COLOR color = TGL_NO_COPY_COLOR; #else color = RGB_TO_PIXEL(r, g, b); #endif memset_l(pp, color, zb->xsize); #else #error BADJUJU #endif pp = (PIXEL *) ((char *) pp + zb->linesize); } } }