source: trunk/sys/TinyGL/src/zbuffer.c @ 264

Last change on this file since 264 was 1, checked in by alain, 8 years ago

First import

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