Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  
  3.  * Z buffer: 16 bits Z / 16 bits color
  4.  *
  5.  */
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. /*#include <assert.h>*/
  9. #include <string.h>
  10. #include "zbuffer.h"
  11.  
  12. ZBuffer *ZB_open(int xsize, int ysize, int mode,
  13.                  int nb_colors,
  14.                  unsigned char *color_indexes,
  15.                  int *color_table,
  16.                  void *frame_buffer)
  17. {
  18.     ZBuffer *zb;
  19.     int size;
  20.  
  21.     zb = gl_malloc(sizeof(ZBuffer));
  22.     if (zb == NULL)
  23.         return NULL;
  24.  
  25.     zb->xsize = xsize;
  26.     zb->ysize = ysize;
  27.     zb->mode = mode;
  28.     zb->linesize = (xsize * PSZB + 3) & ~3;
  29.  
  30.     switch (mode) {
  31. #ifdef TGL_FEATURE_8_BITS
  32.     case ZB_MODE_INDEX:
  33.         ZB_initDither(zb, nb_colors, color_indexes, color_table);
  34.         break;
  35. #endif
  36. #ifdef TGL_FEATURE_32_BITS
  37.     case ZB_MODE_RGBA:
  38. #endif
  39. #ifdef TGL_FEATURE_24_BITS
  40.     case ZB_MODE_RGB24:
  41. #endif
  42.     case ZB_MODE_5R6G5B:
  43.         zb->nb_colors = 0;
  44.         break;
  45.     default:
  46.         goto error;
  47.     }
  48.  
  49.     size = zb->xsize * zb->ysize * sizeof(unsigned short);
  50.  
  51.     zb->zbuf = gl_malloc(size);
  52.     if (zb->zbuf == NULL)
  53.         goto error;
  54.  
  55.         zb->frame_buffer_allocated = 0;
  56.         zb->pbuf = NULL;
  57.  
  58.     zb->current_texture = NULL;
  59.  
  60.     return zb;
  61.   error:
  62.     gl_free(zb);
  63.     return NULL;
  64. }
  65.  
  66. void ZB_close(ZBuffer * zb)
  67. {
  68. #ifdef TGL_FEATURE_8_BITS
  69.     if (zb->mode == ZB_MODE_INDEX)
  70.         ZB_closeDither(zb);
  71. #endif
  72.  
  73.     if (zb->frame_buffer_allocated)
  74.         gl_free(zb->pbuf);
  75.  
  76.     gl_free(zb->zbuf);
  77.     gl_free(zb);
  78. }
  79.  
  80. void ZB_resize(ZBuffer * zb, void *frame_buffer, int xsize, int ysize)
  81. {
  82.     int size;
  83.  
  84.     /* xsize must be a multiple of 4 */
  85.     xsize = xsize & ~3;
  86.  
  87.     zb->xsize = xsize;
  88.     zb->ysize = ysize;
  89.     zb->linesize = (xsize * PSZB + 3) & ~3;
  90.  
  91.     size = zb->xsize * zb->ysize * sizeof(unsigned short);
  92.  
  93.     gl_free(zb->zbuf);
  94.     zb->zbuf = gl_malloc(size);
  95.  
  96.     if (zb->frame_buffer_allocated)
  97.         gl_free(zb->pbuf);
  98.  
  99.     if (frame_buffer == NULL) {
  100.         zb->pbuf = gl_malloc((zb->ysize+1) * (zb->linesize));
  101.         zb->frame_buffer_allocated = 1;
  102.     } else {
  103.         zb->pbuf = frame_buffer;
  104.         zb->frame_buffer_allocated = 0;
  105.     }
  106. }
  107.  
  108. static void ZB_copyBuffer(ZBuffer * zb,
  109.                           void *buf,
  110.                           int linesize)
  111. {
  112.     unsigned char *p1;
  113.     PIXEL *q;
  114.     int y, n;
  115.  
  116.     q = zb->pbuf;
  117.     p1 = buf;
  118.     n = zb->xsize * PSZB;
  119.     for (y = 0; y < zb->ysize; y++) {
  120.         memcpy(p1, q, n);
  121.         p1 += linesize;
  122.         q = (PIXEL *) ((char *) q + zb->linesize);
  123.     }
  124. }
  125.  
  126. #if TGL_FEATURE_RENDER_BITS == 16
  127.  
  128. /* 32 bpp copy */
  129.  
  130. #ifdef TGL_FEATURE_32_BITS
  131.  
  132. #define RGB16_TO_RGB32(p0,p1,v)\
  133. {\
  134.     unsigned int g,b,gb;\
  135.     g = (v & 0x07E007E0) << 5;\
  136.     b = (v & 0x001F001F) << 3;\
  137.     gb = g | b;\
  138.     p0 = (gb & 0x0000FFFF) | ((v & 0x0000F800) << 8);\
  139.     p1 = (gb >> 16) | ((v & 0xF8000000) >> 8);\
  140. }
  141.  
  142. static void ZB_copyFrameBufferRGB32(ZBuffer * zb,
  143.                                     void *buf,
  144.                                     int linesize)
  145. {
  146.     unsigned short *q;
  147.     unsigned int *p, *p1, v, w0, w1;
  148.     int y, n;
  149.  
  150.     q = zb->pbuf;
  151.     p1 = (unsigned int *) buf;
  152.  
  153.     for (y = 0; y < zb->ysize; y++) {
  154.         p = p1;
  155.         n = zb->xsize >> 2;
  156.         do {
  157.             v = *(unsigned int *) q;
  158. #if BYTE_ORDER == BIG_ENDIAN
  159.             RGB16_TO_RGB32(w1, w0, v);
  160. #else
  161.             RGB16_TO_RGB32(w0, w1, v);
  162. #endif
  163.             p[0] = w0;
  164.             p[1] = w1;
  165.  
  166.             v = *(unsigned int *) (q + 2);
  167. #if BYTE_ORDER == BIG_ENDIAN
  168.             RGB16_TO_RGB32(w1, w0, v);
  169. #else
  170.             RGB16_TO_RGB32(w0, w1, v);
  171. #endif
  172.             p[2] = w0;
  173.             p[3] = w1;
  174.  
  175.             q += 4;
  176.             p += 4;
  177.         } while (--n > 0);
  178.  
  179.         p1 += linesize;
  180.     }
  181. }
  182.  
  183. #endif
  184.  
  185. /* 24 bit packed pixel handling */
  186.  
  187. #ifdef TGL_FEATURE_24_BITS
  188.  
  189. /* order: RGBR GBRG BRGB */
  190.  
  191. /* XXX: packed pixel 24 bit support not tested */
  192. /* XXX: big endian case not optimised */
  193.  
  194. #if BYTE_ORDER == BIG_ENDIAN
  195.  
  196. #define RGB16_TO_RGB24(p0,p1,p2,v1,v2)\
  197. {\
  198.     unsigned int r1,g1,b1,gb1,g2,b2,gb2;\
  199.     v1 = (v1 << 16) | (v1 >> 16);\
  200.     v2 = (v2 << 16) | (v2 >> 16);\
  201.     r1 = (v1 & 0xF800F800);\
  202.     g1 = (v1 & 0x07E007E0) << 5;\
  203.     b1 = (v1 & 0x001F001F) << 3;\
  204.     gb1 = g1 | b1;\
  205.     p0 = ((gb1 & 0x0000FFFF) << 8) | (r1 << 16) | (r1 >> 24);\
  206.     g2 = (v2 & 0x07E007E0) << 5;\
  207.     b2 = (v2 & 0x001F001F) << 3;\
  208.     gb2 = g2 | b2;\
  209.     p1 = (gb1 & 0xFFFF0000) | (v2 & 0xF800) | ((gb2 >> 8) & 0xff);\
  210.     p2 = (gb2 << 24) | ((v2 & 0xF8000000) >> 8) | (gb2 >> 16);\
  211. }
  212.  
  213. #else
  214.  
  215. #define RGB16_TO_RGB24(p0,p1,p2,v1,v2)\
  216. {\
  217.     unsigned int r1,g1,b1,gb1,g2,b2,gb2;\
  218.     r1 = (v1 & 0xF800F800);\
  219.     g1 = (v1 & 0x07E007E0) << 5;\
  220.     b1 = (v1 & 0x001F001F) << 3;\
  221.     gb1 = g1 | b1;\
  222.     p0 = ((gb1 & 0x0000FFFF) << 8) | (r1 << 16) | (r1 >> 24);\
  223.     g2 = (v2 & 0x07E007E0) << 5;\
  224.     b2 = (v2 & 0x001F001F) << 3;\
  225.     gb2 = g2 | b2;\
  226.     p1 = (gb1 & 0xFFFF0000) | (v2 & 0xF800) | ((gb2 >> 8) & 0xff);\
  227.     p2 = (gb2 << 24) | ((v2 & 0xF8000000) >> 8) | (gb2 >> 16);\
  228. }
  229.  
  230. #endif
  231.  
  232. static void ZB_copyFrameBufferRGB24(ZBuffer * zb,
  233.                                     void *buf,
  234.                                     int linesize)
  235. {
  236.     unsigned short *q;
  237.     unsigned int *p, *p1, w0, w1, w2, v0, v1;
  238.     int y, n;
  239.  
  240.     q = zb->pbuf;
  241.     p1 = (unsigned int *) buf;
  242.     linesize = linesize * 3;
  243.  
  244.     for (y = 0; y < zb->ysize; y++) {
  245.         p = p1;
  246.         n = zb->xsize >> 2;
  247.         do {
  248.             v0 = *(unsigned int *) q;
  249.             v1 = *(unsigned int *) (q + 2);
  250.             RGB16_TO_RGB24(w0, w1, w2, v0, v1);
  251.             p[0] = w0;
  252.             p[1] = w1;
  253.             p[2] = w2;
  254.  
  255.             q += 4;
  256.             p += 3;
  257.         } while (--n > 0);
  258.  
  259.         (char *) p1 += linesize;
  260.     }
  261. }
  262.  
  263. #endif
  264.  
  265. void ZB_copyFrameBuffer(ZBuffer * zb, void *buf,
  266.                         int linesize)
  267. {
  268.     switch (zb->mode) {
  269. #ifdef TGL_FEATURE_8_BITS
  270.     case ZB_MODE_INDEX:
  271.         ZB_ditherFrameBuffer(zb, buf, linesize >> 1);
  272.         break;
  273. #endif
  274. #ifdef TGL_FEATURE_16_BITS
  275.     case ZB_MODE_5R6G5B:
  276.         ZB_copyBuffer(zb, buf, linesize);
  277.         break;
  278. #endif
  279. #ifdef TGL_FEATURE_32_BITS
  280.     case ZB_MODE_RGBA:
  281.         ZB_copyFrameBufferRGB32(zb, buf, linesize >> 1);
  282.         break;
  283. #endif
  284. #ifdef TGL_FEATURE_24_BITS
  285.     case ZB_MODE_RGB24:
  286.         ZB_copyFrameBufferRGB24(zb, buf, linesize >> 1);
  287.         break;
  288. #endif
  289.     default:
  290.         assert(0);
  291.     }
  292. }
  293.  
  294. #endif /* TGL_FEATURE_RENDER_BITS == 16 */
  295.  
  296. #if TGL_FEATURE_RENDER_BITS == 24
  297.  
  298. #define RGB24_TO_RGB16(r, g, b) \
  299.   ((((r) >> 3) << 11) | (((g) >> 2) << 5) | ((b) >> 3))
  300.  
  301. /* XXX: not optimized */
  302. static void ZB_copyFrameBuffer5R6G5B(ZBuffer * zb,
  303.                                      void *buf, int linesize)
  304. {
  305.     PIXEL *q;
  306.     unsigned short *p, *p1;
  307.     int y, n;
  308.  
  309.     q = zb->pbuf;
  310.     p1 = (unsigned short *) buf;
  311.  
  312.     for (y = 0; y < zb->ysize; y++) {
  313.         p = p1;
  314.         n = zb->xsize >> 2;
  315.         do {
  316.             p[0] = RGB24_TO_RGB16(q[0], q[1], q[2]);
  317.             p[1] = RGB24_TO_RGB16(q[3], q[4], q[5]);
  318.             p[2] = RGB24_TO_RGB16(q[6], q[7], q[8]);
  319.             p[3] = RGB24_TO_RGB16(q[9], q[10], q[11]);
  320.             q = (PIXEL *)((char *)q + 4 * PSZB);
  321.             p += 4;
  322.         } while (--n > 0);
  323.         p1 = (unsigned short *)((char *)p1 + linesize);
  324.     }
  325. }
  326.  
  327. void ZB_copyFrameBuffer(ZBuffer * zb, void *buf,
  328.                         int linesize)
  329. {
  330.     switch (zb->mode) {
  331. #ifdef TGL_FEATURE_16_BITS
  332.     case ZB_MODE_5R6G5B:
  333.         ZB_copyFrameBuffer5R6G5B(zb, buf, linesize);
  334.         break;
  335. #endif
  336. #ifdef TGL_FEATURE_24_BITS
  337.     case ZB_MODE_RGB24:
  338.         ZB_copyBuffer(zb, buf, linesize);
  339.         break;
  340. #endif
  341.     default:
  342.         assert(0);
  343.     }
  344. }
  345.  
  346. #endif /* TGL_FEATURE_RENDER_BITS == 24 */
  347.  
  348. #if TGL_FEATURE_RENDER_BITS == 32
  349.  
  350. #define RGB32_TO_RGB16(v) \
  351.   (((v >> 8) & 0xf800) | (((v) >> 5) & 0x07e0) | (((v) & 0xff) >> 3))
  352.  
  353. /* XXX: not optimized */
  354. static void ZB_copyFrameBuffer5R6G5B(ZBuffer * zb,
  355.                                      void *buf, int linesize)
  356. {
  357.     PIXEL *q;
  358.     unsigned short *p, *p1;
  359.     int y, n;
  360.  
  361.     q = zb->pbuf;
  362.     p1 = (unsigned short *) buf;
  363.  
  364.     for (y = 0; y < zb->ysize; y++) {
  365.         p = p1;
  366.         n = zb->xsize >> 2;
  367.         do {
  368.             p[0] = RGB32_TO_RGB16(q[0]);
  369.             p[1] = RGB32_TO_RGB16(q[1]);
  370.             p[2] = RGB32_TO_RGB16(q[2]);
  371.             p[3] = RGB32_TO_RGB16(q[3]);
  372.             q += 4;
  373.             p += 4;
  374.         } while (--n > 0);
  375.         p1 = (unsigned short *)((char *)p1 + linesize);
  376.     }
  377. }
  378.  
  379. void ZB_copyFrameBuffer(ZBuffer * zb, void *buf,
  380.                         int linesize)
  381. {
  382.     switch (zb->mode) {
  383. #ifdef TGL_FEATURE_16_BITS
  384.     case ZB_MODE_5R6G5B:
  385.         ZB_copyFrameBuffer5R6G5B(zb, buf, linesize);
  386.         break;
  387. #endif
  388. #ifdef TGL_FEATURE_32_BITS
  389.     case ZB_MODE_RGBA:
  390.         ZB_copyBuffer(zb, buf, linesize);
  391.         break;
  392. #endif
  393.     default:
  394.         assert(0);
  395.     }
  396. }
  397.  
  398. #endif /* TGL_FEATURE_RENDER_BITS == 32 */
  399.  
  400.  
  401. /*
  402.  * adr must be aligned on an 'int'
  403.  */
  404. void memset_s(void *adr, int val, int count)
  405. {
  406.     int i, n, v;
  407.     unsigned int *p;
  408.     unsigned short *q;
  409.  
  410.     p = adr;
  411.     v = val | (val << 16);
  412.  
  413.     n = count >> 3;
  414.     for (i = 0; i < n; i++) {
  415.         p[0] = v;
  416.         p[1] = v;
  417.         p[2] = v;
  418.         p[3] = v;
  419.         p += 4;
  420.     }
  421.  
  422.     q = (unsigned short *) p;
  423.     n = count & 7;
  424.     for (i = 0; i < n; i++)
  425.         *q++ = val;
  426. }
  427.  
  428. void memset_l(void *adr, int val, int count)
  429. {
  430.     int i, n, v;
  431.     unsigned int *p;
  432.  
  433.     p = adr;
  434.     v = val;
  435.     n = count >> 2;
  436.     for (i = 0; i < n; i++) {
  437.         p[0] = v;
  438.         p[1] = v;
  439.         p[2] = v;
  440.         p[3] = v;
  441.         p += 4;
  442.     }
  443.  
  444.     n = count & 3;
  445.     for (i = 0; i < n; i++)
  446.         *p++ = val;
  447. }
  448.  
  449. /* count must be a multiple of 4 and >= 4 */
  450. void memset_RGB24(void *adr,int r, int v, int b,long count)
  451. {
  452.     long i, n;
  453.     register long v1,v2,v3,*pt=(long *)(adr);
  454.     unsigned char *p,R=(unsigned char)r,V=(unsigned char)v,B=(unsigned char)b;
  455.  
  456.     p=(unsigned char *)adr;
  457.     *p++=R;
  458.     *p++=V;
  459.     *p++=B;
  460.     *p++=R;
  461.     *p++=V;
  462.     *p++=B;
  463.     *p++=R;
  464.     *p++=V;
  465.     *p++=B;
  466.     *p++=R;
  467.     *p++=V;
  468.     *p++=B;
  469.     v1=*pt++;
  470.     v2=*pt++;
  471.     v3=*pt++;
  472.     n = count >> 2;
  473.     for(i=1;i<n;i++) {
  474.         *pt++=v1;
  475.         *pt++=v2;
  476.         *pt++=v3;
  477.     }
  478. }
  479.  
  480. void ZB_clear(ZBuffer * zb, int clear_z, int z,
  481.               int clear_color, int r, int g, int b)
  482. {
  483. #if TGL_FEATURE_RENDER_BITS != 24
  484.     int color;
  485. #endif
  486.     int y;
  487.     PIXEL *pp;
  488.  
  489.     if (clear_z) {
  490.         memset_s(zb->zbuf, z, zb->xsize * zb->ysize);
  491.     }
  492.     if (clear_color) {
  493.         pp = zb->pbuf;
  494.         for (y = 0; y < zb->ysize; y++) {
  495. #if TGL_FEATURE_RENDER_BITS == 15 || TGL_FEATURE_RENDER_BITS == 16
  496.             color = RGB_TO_PIXEL(r, g, b);
  497.             memset_s(pp, color, zb->xsize);
  498. #elif TGL_FEATURE_RENDER_BITS == 32
  499.             color = RGB_TO_PIXEL(r, g, b);
  500.             memset_l(pp, color, zb->xsize);
  501. #elif TGL_FEATURE_RENDER_BITS == 24
  502.             memset_RGB24(pp,r>>8,g>>8,b>>8,zb->xsize);
  503. #else
  504. #error TODO
  505. #endif
  506.             pp = (PIXEL *) ((char *) pp + zb->linesize);
  507.         }
  508.     }
  509. }
  510.