Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5098 clevermous 1
/*
2
 
3
 * Z buffer: 16 bits Z / 16 bits color
4
 *
5
 */
6
#include 
7
#include 
8
/*#include */
9
#include 
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
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
}