TinyGL 0.4.1 for MinGW
zbuffer.c
Go to the documentation of this file.
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 }
62 } else {
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)
80#endif
81
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
106 gl_free(zb->pbuf);
107
108 if (frame_buffer == NULL) {
109 zb->pbuf = gl_malloc(zb->ysize * zb->linesize);
111 } else {
112 zb->pbuf = frame_buffer;
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 = (unsigned int *)((char *)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);
291 break;
292#endif
293#ifdef TGL_FEATURE_24_BITS
294 case ZB_MODE_RGB24:
295 ZB_copyFrameBufferRGB24(zb, buf, linesize);
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}
void gl_free(void *p)
Definition: memory.c:8
void * gl_malloc(int size)
Definition: memory.c:13
int nb_colors
Definition: zbuffer.h:83
unsigned short * zbuf
Definition: zbuffer.h:79
int mode
Definition: zbuffer.h:77
int frame_buffer_allocated
Definition: zbuffer.h:81
PIXEL * current_texture
Definition: zbuffer.h:86
int linesize
Definition: zbuffer.h:76
PIXEL * pbuf
Definition: zbuffer.h:80
int ysize
Definition: zbuffer.h:75
int xsize
Definition: zbuffer.h:75
void memset_l(void *adr, int val, int count)
Definition: zbuffer.c:437
#define RGB16_TO_RGB32(p0, p1, v)
Definition: zbuffer.c:141
void ZB_close(ZBuffer *zb)
Definition: zbuffer.c:75
void ZB_clear(ZBuffer *zb, int clear_z, int z, int clear_color, int r, int g, int b)
Definition: zbuffer.c:489
void memset_s(void *adr, int val, int count)
Definition: zbuffer.c:413
void ZB_copyFrameBuffer(ZBuffer *zb, void *buf, int linesize)
Definition: zbuffer.c:274
#define RGB16_TO_RGB24(p0, p1, p2, v1, v2)
Definition: zbuffer.c:205
void memset_RGB24(void *adr, int r, int v, int b, long count)
Definition: zbuffer.c:459
void ZB_resize(ZBuffer *zb, void *frame_buffer, int xsize, int ysize)
Definition: zbuffer.c:89
ZBuffer * ZB_open(int xsize, int ysize, int mode, int nb_colors, unsigned char *color_indexes, int *color_table, void *frame_buffer)
Definition: zbuffer.c:12
#define RGB_TO_PIXEL(r, g, b)
Definition: zbuffer.h:46
void ZB_ditherFrameBuffer(ZBuffer *zb, unsigned char *dest, int linesize)
Definition: zdither.c:109
#define ZB_MODE_5R6G5B
Definition: zbuffer.h:27
#define PSZB
Definition: zbuffer.h:49
#define ZB_MODE_RGB24
Definition: zbuffer.h:30
void ZB_initDither(ZBuffer *zb, int nb_colors, unsigned char *color_indexes, int *color_table)
Definition: zdither.c:39
#define ZB_MODE_RGBA
Definition: zbuffer.h:29
unsigned short PIXEL
Definition: zbuffer.h:48
#define ZB_MODE_INDEX
Definition: zbuffer.h:28
void ZB_closeDither(ZBuffer *zb)
Definition: zdither.c:79
register PIXEL * pp
Definition: zline.h:4
int error
Definition: ztriangle.h:14