Subversion Repositories eduke32

Rev

Rev 4898 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4639 terminx 1
//--------------------------------------- VOX LIBRARY BEGINS ---------------------------------------
2
 
3
#ifdef USE_OPENGL
4
 
5
#include "compat.h"
6
#include "build.h"
7
#include "glbuild.h"
8
#include "pragmas.h"
9
#include "baselayer.h"
10
#include "engine_priv.h"
11
#include "hightile.h"
12
#include "polymost.h"
13
#include "texcache.h"
14
#include "mdsprite.h"
15
#include "cache1d.h"
16
#include "kplib.h"
17
 
18
#include <math.h>
19
 
4834 helixhorne 20
 
4639 terminx 21
//For loading/conversion only
22
static vec3_t voxsiz;
23
static int32_t yzsiz, *vbit = 0; //vbit: 1 bit per voxel: 0=air,1=solid
24
static vec3f_t voxpiv;
4834 helixhorne 25
 
4639 terminx 26
static int32_t *vcolhashead = 0, vcolhashsizm1;
27
typedef struct { int32_t p, c, n; } voxcol_t;
28
static voxcol_t *vcol = 0; int32_t vnum = 0, vmax = 0;
4834 helixhorne 29
 
4639 terminx 30
typedef struct { int16_t x, y; } spoint2d;
31
static spoint2d *shp;
32
static int32_t *shcntmal, *shcnt = 0, shcntp;
4834 helixhorne 33
 
4639 terminx 34
static int32_t mytexo5, *zbit, gmaxx, gmaxy, garea, pow2m1[33];
35
static voxmodel_t *gvox;
36
 
4834 helixhorne 37
 
4639 terminx 38
//pitch must equal xsiz*4
39
uint32_t gloadtex(int32_t *picbuf, int32_t xsiz, int32_t ysiz, int32_t is8bit, int32_t dapal)
40
{
41
    const char *const cptr = &britable[gammabrightness ? 0 : curbrightness][0];
42
 
43
    // Correct for GL's RGB order; also apply gamma here:
4834 helixhorne 44
    const coltype *const pic = (const coltype *)picbuf;
45
    coltype *pic2 = (coltype *)Xmalloc(xsiz*ysiz*sizeof(coltype));
4639 terminx 46
 
47
    if (!is8bit)
48
    {
4834 helixhorne 49
        for (int32_t i=xsiz*ysiz-1; i>=0; i--)
4639 terminx 50
        {
51
            pic2[i].b = cptr[pic[i].r];
52
            pic2[i].g = cptr[pic[i].g];
53
            pic2[i].r = cptr[pic[i].b];
54
            pic2[i].a = 255;
55
        }
56
    }
57
    else
58
    {
59
        if (palookup[dapal] == NULL)
60
            dapal = 0;
61
 
4834 helixhorne 62
        for (int32_t i=xsiz*ysiz-1; i>=0; i--)
4639 terminx 63
        {
64
            const int32_t ii = palookup[dapal][pic[i].a] * 3;
65
 
66
            pic2[i].b = cptr[palette[ii+2]*4];
67
            pic2[i].g = cptr[palette[ii+1]*4];
68
            pic2[i].r = cptr[palette[ii+0]*4];
69
            pic2[i].a = 255;
70
        }
71
    }
72
 
4834 helixhorne 73
    uint32_t rtexid;
74
 
4639 terminx 75
    bglGenTextures(1, (GLuint *) &rtexid);
76
    bglBindTexture(GL_TEXTURE_2D, rtexid);
77
    bglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
78
    bglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
79
    bglTexImage2D(GL_TEXTURE_2D, 0, 4, xsiz, ysiz, 0, GL_RGBA, GL_UNSIGNED_BYTE, (char *) pic2);
80
 
81
    Bfree(pic2);
82
 
83
    return rtexid;
84
}
85
 
86
static int32_t getvox(int32_t x, int32_t y, int32_t z)
87
{
88
    z += x*yzsiz + y*voxsiz.z;
4834 helixhorne 89
 
4639 terminx 90
    for (x=vcolhashead[(z*214013)&vcolhashsizm1]; x>=0; x=vcol[x].n)
4834 helixhorne 91
        if (vcol[x].p == z)
92
            return vcol[x].c;
93
 
94
    return 0x808080;
4639 terminx 95
}
96
 
97
static void putvox(int32_t x, int32_t y, int32_t z, int32_t col)
98
{
4834 helixhorne 99
    if (vnum >= vmax)
100
    {
101
        vmax = max(vmax<<1, 4096);
102
        vcol = (voxcol_t *)Xrealloc(vcol, vmax*sizeof(voxcol_t));
103
    }
4639 terminx 104
 
105
    z += x*yzsiz + y*voxsiz.z;
4834 helixhorne 106
 
107
    vcol[vnum].p = z; z = (z*214013)&vcolhashsizm1;
4639 terminx 108
    vcol[vnum].c = col;
109
    vcol[vnum].n = vcolhashead[z]; vcolhashead[z] = vnum++;
110
}
111
 
112
//Set all bits in vbit from (x,y,z0) to (x,y,z1-1) to 0's
113
#if 0
114
static void setzrange0(int32_t *lptr, int32_t z0, int32_t z1)
115
{
116
    if (!((z0^z1)&~31)) { lptr[z0>>5] &= ((~(-1<<SHIFTMOD32(z0)))|(-1<<SHIFTMOD32(z1))); return; }
4834 helixhorne 117
    int32_t z = (z0>>5), ze = (z1>>5);
4639 terminx 118
    lptr[z] &=~(-1<<SHIFTMOD32(z0)); for (z++; z<ze; z++) lptr[z] = 0;
119
    lptr[z] &= (-1<<SHIFTMOD32(z1));
120
}
121
#endif
122
//Set all bits in vbit from (x,y,z0) to (x,y,z1-1) to 1's
123
static void setzrange1(int32_t *lptr, int32_t z0, int32_t z1)
124
{
125
    if (!((z0^z1)&~31)) { lptr[z0>>5] |= ((~(-1<<SHIFTMOD32(z1)))&(-1<<SHIFTMOD32(z0))); return; }
4834 helixhorne 126
    int32_t z = (z0>>5), ze = (z1>>5);
4639 terminx 127
    lptr[z] |= (-1<<SHIFTMOD32(z0)); for (z++; z<ze; z++) lptr[z] = -1;
128
    lptr[z] |=~(-1<<SHIFTMOD32(z1));
129
}
130
 
131
static int32_t isrectfree(int32_t x0, int32_t y0, int32_t dx, int32_t dy)
132
{
133
#if 0
134
    int32_t i, j, x;
135
    i = y0*gvox->mytexx + x0;
136
    for (dy=0; dy; dy--, i+=gvox->mytexx)
137
        for (x=0; x<dx; x++) { j = i+x; if (zbit[j>>5]&(1<<SHIFTMOD32(j))) return(0); }
138
#else
4834 helixhorne 139
    int32_t i = y0*mytexo5 + (x0>>5);
140
    dx += x0-1;
141
    const int32_t c = (dx>>5) - (x0>>5);
4639 terminx 142
 
4834 helixhorne 143
    int32_t m = ~pow2m1[x0&31];
144
    const int32_t m1 = pow2m1[(dx&31)+1];
145
 
146
    if (!c)
147
    {
148
        for (m &= m1; dy; dy--, i += mytexo5)
149
            if (zbit[i]&m)
150
                return 0;
151
    }
4639 terminx 152
    else
153
    {
4834 helixhorne 154
        for (; dy; dy--, i += mytexo5)
4639 terminx 155
        {
4834 helixhorne 156
            if (zbit[i]&m)
157
                return 0;
158
 
159
            int32_t x;
160
            for (x=1; x<c; x++)
161
                if (zbit[i+x])
162
                    return 0;
163
 
164
            if (zbit[i+x]&m1)
165
                return 0;
4639 terminx 166
        }
167
    }
168
#endif
169
    return(1);
170
}
171
 
172
static void setrect(int32_t x0, int32_t y0, int32_t dx, int32_t dy)
173
{
174
#if 0
175
    int32_t i, j, y;
176
    i = y0*gvox->mytexx + x0;
177
    for (y=0; y<dy; y++, i+=gvox->mytexx)
178
        for (x=0; x<dx; x++) { j = i+x; zbit[j>>5] |= (1<<SHIFTMOD32(j)); }
179
#else
4834 helixhorne 180
    int32_t i = y0*mytexo5 + (x0>>5);
181
    dx += x0-1;
182
    const int32_t c = (dx>>5) - (x0>>5);
4639 terminx 183
 
4834 helixhorne 184
    int32_t m = ~pow2m1[x0&31];
185
    const int32_t m1 = pow2m1[(dx&31)+1];
186
 
187
    if (!c)
188
    {
189
        for (m &= m1; dy; dy--, i += mytexo5)
190
            zbit[i] |= m;
191
    }
4639 terminx 192
    else
193
    {
4834 helixhorne 194
        for (; dy; dy--, i += mytexo5)
4639 terminx 195
        {
196
            zbit[i] |= m;
4834 helixhorne 197
 
198
            int32_t x;
199
            for (x=1; x<c; x++)
200
                zbit[i+x] = -1;
201
 
4639 terminx 202
            zbit[i+x] |= m1;
203
        }
204
    }
205
#endif
206
}
207
 
4834 helixhorne 208
static void cntquad(int32_t x0, int32_t y0, int32_t z0, int32_t x1, int32_t y1, int32_t z1,
209
                    int32_t x2, int32_t y2, int32_t z2, int32_t face)
4639 terminx 210
{
211
    UNREFERENCED_PARAMETER(x1);
212
    UNREFERENCED_PARAMETER(y1);
213
    UNREFERENCED_PARAMETER(z1);
214
    UNREFERENCED_PARAMETER(face);
215
 
4834 helixhorne 216
    int32_t x = labs(x2-x0), y = labs(y2-y0), z = labs(z2-z0);
217
 
218
    if (x == 0)
219
        x = z;
220
    else if (y == 0)
221
        y = z;
222
 
4639 terminx 223
    if (x < y) { z = x; x = y; y = z; }
4834 helixhorne 224
 
4639 terminx 225
    shcnt[y*shcntp+x]++;
4834 helixhorne 226
 
4639 terminx 227
    if (x > gmaxx) gmaxx = x;
228
    if (y > gmaxy) gmaxy = y;
4834 helixhorne 229
 
230
    garea += (x+(VOXBORDWIDTH<<1)) * (y+(VOXBORDWIDTH<<1));
4639 terminx 231
    gvox->qcnt++;
232
}
233
 
4834 helixhorne 234
static void addquad(int32_t x0, int32_t y0, int32_t z0, int32_t x1, int32_t y1, int32_t z1,
235
                    int32_t x2, int32_t y2, int32_t z2, int32_t face)
4639 terminx 236
{
4834 helixhorne 237
    int32_t i;
238
    int32_t x = labs(x2-x0), y = labs(y2-y0), z = labs(z2-z0);
4639 terminx 239
 
4834 helixhorne 240
    if (x == 0) { x = y; y = z; i = 0; }
241
    else if (y == 0) { y = z; i = 1; }
4639 terminx 242
    else i = 2;
4834 helixhorne 243
 
4639 terminx 244
    if (x < y) { z = x; x = y; y = z; i += 3; }
4834 helixhorne 245
 
4639 terminx 246
    z = shcnt[y*shcntp+x]++;
4834 helixhorne 247
    int32_t *lptr = &gvox->mytex[(shp[z].y+VOXBORDWIDTH)*gvox->mytexx +
248
                                 (shp[z].x+VOXBORDWIDTH)];
249
    int32_t nx = 0, ny = 0, nz = 0;
250
 
4639 terminx 251
    switch (face)
252
    {
253
    case 0:
254
        ny = y1; x2 = x0; x0 = x1; x1 = x2; break;
255
    case 1:
256
        ny = y0; y0++; y1++; y2++; break;
257
    case 2:
258
        nz = z1; y0 = y2; y2 = y1; y1 = y0; z0++; z1++; z2++; break;
259
    case 3:
260
        nz = z0; break;
261
    case 4:
262
        nx = x1; y2 = y0; y0 = y1; y1 = y2; x0++; x1++; x2++; break;
263
    case 5:
264
        nx = x0; break;
265
    }
4834 helixhorne 266
 
267
    for (int32_t yy=0; yy<y; yy++, lptr+=gvox->mytexx)
268
        for (int32_t xx=0; xx<x; xx++)
4639 terminx 269
        {
4834 helixhorne 270
            switch (face)
271
            {
272
            case 0:
273
                if (i < 3) { nx = x1+x-1-xx; nz = z1+yy; } //back
274
                else { nx = x1+y-1-yy; nz = z1+xx; }
275
                break;
276
            case 1:
277
                if (i < 3) { nx = x0+xx;     nz = z0+yy; } //front
278
                else { nx = x0+yy;     nz = z0+xx; }
279
                break;
280
            case 2:
281
                if (i < 3) { nx = x1-x+xx;   ny = y1-1-yy; } //bot
282
                else { nx = x1-1-yy;   ny = y1-1-xx; }
283
                break;
284
            case 3:
285
                if (i < 3) { nx = x0+xx;     ny = y0+yy; } //top
286
                else { nx = x0+yy;     ny = y0+xx; }
287
                break;
288
            case 4:
289
                if (i < 3) { ny = y1+x-1-xx; nz = z1+yy; } //right
290
                else { ny = y1+y-1-yy; nz = z1+xx; }
291
                break;
292
            case 5:
293
                if (i < 3) { ny = y0+xx;     nz = z0+yy; } //left
294
                else { ny = y0+yy;     nz = z0+xx; }
295
                break;
296
            }
297
 
298
            lptr[xx] = getvox(nx, ny, nz);
4639 terminx 299
        }
300
 
301
    //Extend borders horizontally
4834 helixhorne 302
    for (int32_t yy=VOXBORDWIDTH; yy<y+VOXBORDWIDTH; yy++)
303
        for (int32_t xx=0; xx<VOXBORDWIDTH; xx++)
4639 terminx 304
        {
4834 helixhorne 305
            lptr = &gvox->mytex[(shp[z].y+yy)*gvox->mytexx + shp[z].x];
306
            lptr[xx] = lptr[VOXBORDWIDTH];
307
            lptr[xx+x+VOXBORDWIDTH] = lptr[x-1+VOXBORDWIDTH];
4639 terminx 308
        }
4834 helixhorne 309
 
4639 terminx 310
    //Extend borders vertically
4834 helixhorne 311
    for (int32_t yy=0; yy<VOXBORDWIDTH; yy++)
4639 terminx 312
    {
4834 helixhorne 313
        Bmemcpy(&gvox->mytex[(shp[z].y+yy)*gvox->mytexx + shp[z].x],
314
                &gvox->mytex[(shp[z].y+VOXBORDWIDTH)*gvox->mytexx + shp[z].x],
315
                (x+(VOXBORDWIDTH<<1))<<2);
316
        Bmemcpy(&gvox->mytex[(shp[z].y+y+yy+VOXBORDWIDTH)*gvox->mytexx + shp[z].x],
317
                &gvox->mytex[(shp[z].y+y-1+VOXBORDWIDTH)*gvox->mytexx + shp[z].x],
318
                (x+(VOXBORDWIDTH<<1))<<2);
4639 terminx 319
    }
320
 
4834 helixhorne 321
    voxrect_t *const qptr = &gvox->quad[gvox->qcnt];
322
 
4639 terminx 323
    qptr->v[0].x = x0; qptr->v[0].y = y0; qptr->v[0].z = z0;
324
    qptr->v[1].x = x1; qptr->v[1].y = y1; qptr->v[1].z = z1;
325
    qptr->v[2].x = x2; qptr->v[2].y = y2; qptr->v[2].z = z2;
326
 
4834 helixhorne 327
    for (int32_t j=0; j<3; j++)
328
    {
329
        qptr->v[j].u = shp[z].x+VOXBORDWIDTH;
330
        qptr->v[j].v = shp[z].y+VOXBORDWIDTH;
331
    }
332
 
333
    if (i < 3)
334
        qptr->v[1].u += x;
335
    else
336
        qptr->v[1].v += y;
337
 
338
    qptr->v[2].u += x;
339
    qptr->v[2].v += y;
340
 
4639 terminx 341
    qptr->v[3].u = qptr->v[0].u - qptr->v[1].u + qptr->v[2].u;
342
    qptr->v[3].v = qptr->v[0].v - qptr->v[1].v + qptr->v[2].v;
343
    qptr->v[3].x = qptr->v[0].x - qptr->v[1].x + qptr->v[2].x;
344
    qptr->v[3].y = qptr->v[0].y - qptr->v[1].y + qptr->v[2].y;
345
    qptr->v[3].z = qptr->v[0].z - qptr->v[1].z + qptr->v[2].z;
4834 helixhorne 346
 
347
    if (gvox->qfacind[face] < 0)
348
        gvox->qfacind[face] = gvox->qcnt;
349
 
4639 terminx 350
    gvox->qcnt++;
351
}
352
 
353
static inline int32_t isolid(int32_t x, int32_t y, int32_t z)
354
{
4834 helixhorne 355
    if ((uint32_t)x >= (uint32_t)voxsiz.x) return 0;
356
    if ((uint32_t)y >= (uint32_t)voxsiz.y) return 0;
357
    if ((uint32_t)z >= (uint32_t)voxsiz.z) return 0;
358
 
359
    z += x*yzsiz + y*voxsiz.z;
360
 
361
    return vbit[z>>5] & (1<<SHIFTMOD32(z));
4639 terminx 362
}
363
 
4834 helixhorne 364
FORCE_INLINE int isair(int32_t i)
365
{
366
    return !(vbit[i>>5] & (1<<SHIFTMOD32(i)));
367
}
368
 
4639 terminx 369
static voxmodel_t *vox2poly()
370
{
4834 helixhorne 371
    int32_t i, j;
4639 terminx 372
 
4834 helixhorne 373
    gvox = (voxmodel_t *)Xmalloc(sizeof(voxmodel_t));
4639 terminx 374
    memset(gvox, 0, sizeof(voxmodel_t));
375
 
4834 helixhorne 376
    {
377
        //x is largest dimension, y is 2nd largest dimension
378
        int32_t x = voxsiz.x, y = voxsiz.y, z = voxsiz.z;
379
 
380
        if (x < y && x < z)
381
            x = z;
382
        else if (y < z)
383
            y = z;
384
 
385
        if (x < y)
386
        {
387
            z = x;
388
            x = y;
389
            y = z;
390
        }
391
 
392
        shcntp = x;
393
        i = x*y*sizeof(int32_t);
394
    }
395
 
396
    shcntmal = (int32_t *)Xmalloc(i);
397
    memset(shcntmal, 0, i);
398
    shcnt = &shcntmal[-shcntp-1];
399
 
4639 terminx 400
    gmaxx = gmaxy = garea = 0;
401
 
4834 helixhorne 402
    if (pow2m1[32] != -1)
403
    {
404
        for (i=0; i<32; i++)
405
            pow2m1[i] = (1u<<i)-1;
406
        pow2m1[32] = -1;
407
    }
4639 terminx 408
 
4834 helixhorne 409
    for (i=0; i<7; i++)
410
        gvox->qfacind[i] = -1;
4639 terminx 411
 
4834 helixhorne 412
    i = (max(voxsiz.y, voxsiz.z)+1)<<2;
413
    int32_t *const bx0 = (int32_t *)Xmalloc(i<<1);
414
    int32_t *const by0 = (int32_t *)(((intptr_t)bx0)+i);
415
 
416
    int32_t ov, oz=0;
417
 
418
    for (int32_t cnt=0; cnt<2; cnt++)
4639 terminx 419
    {
4834 helixhorne 420
        void (*daquad)(int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t) =
421
            cnt == 0 ? cntquad : addquad;
422
 
4639 terminx 423
        gvox->qcnt = 0;
424
 
4834 helixhorne 425
        memset(by0, -1, (max(voxsiz.y, voxsiz.z)+1)<<2);
426
        int32_t v = 0;
4639 terminx 427
 
428
        for (i=-1; i<=1; i+=2)
4834 helixhorne 429
            for (int32_t y=0; y<voxsiz.y; y++)
430
                for (int32_t x=0; x<=voxsiz.x; x++)
431
                    for (int32_t z=0; z<=voxsiz.z; z++)
4639 terminx 432
                    {
4834 helixhorne 433
                        ov = v; v = (isolid(x, y, z) && (!isolid(x, y+i, z)));
434
                        if ((by0[z] >= 0) && ((by0[z] != oz) || (v >= ov)))
435
                        {
436
                            daquad(bx0[z], y, by0[z], x, y, by0[z], x, y, z, i>=0);
437
                            by0[z] = -1;
438
                        }
439
 
440
                        if (v > ov) oz = z;
441
                        else if ((v < ov) && (by0[z] != oz)) { bx0[z] = x; by0[z] = oz; }
4639 terminx 442
                    }
443
 
444
        for (i=-1; i<=1; i+=2)
4834 helixhorne 445
            for (int32_t z=0; z<voxsiz.z; z++)
446
                for (int32_t x=0; x<=voxsiz.x; x++)
447
                    for (int32_t y=0; y<=voxsiz.y; y++)
4639 terminx 448
                    {
4834 helixhorne 449
                        ov = v; v = (isolid(x, y, z) && (!isolid(x, y, z-i)));
450
                        if ((by0[y] >= 0) && ((by0[y] != oz) || (v >= ov)))
451
                        {
452
                            daquad(bx0[y], by0[y], z, x, by0[y], z, x, y, z, (i>=0)+2);
453
                            by0[y] = -1;
454
                        }
455
 
456
                        if (v > ov) oz = y;
457
                        else if ((v < ov) && (by0[y] != oz)) { bx0[y] = x; by0[y] = oz; }
4639 terminx 458
                    }
459
 
460
        for (i=-1; i<=1; i+=2)
4834 helixhorne 461
            for (int32_t x=0; x<voxsiz.x; x++)
462
                for (int32_t y=0; y<=voxsiz.y; y++)
463
                    for (int32_t z=0; z<=voxsiz.z; z++)
4639 terminx 464
                    {
4834 helixhorne 465
                        ov = v; v = (isolid(x, y, z) && (!isolid(x-i, y, z)));
466
                        if ((by0[z] >= 0) && ((by0[z] != oz) || (v >= ov)))
467
                        {
468
                            daquad(x, bx0[z], by0[z], x, y, by0[z], x, y, z, (i>=0)+4);
469
                            by0[z] = -1;
470
                        }
471
 
472
                        if (v > ov) oz = z;
473
                        else if ((v < ov) && (by0[z] != oz)) { bx0[z] = y; by0[z] = oz; }
4639 terminx 474
                    }
475
 
476
        if (!cnt)
477
        {
4834 helixhorne 478
            shp = (spoint2d *)Xmalloc(gvox->qcnt*sizeof(spoint2d));
4639 terminx 479
 
4834 helixhorne 480
            int32_t sc = 0;
481
 
482
            for (int32_t y=gmaxy; y; y--)
483
                for (int32_t x=gmaxx; x>=y; x--)
4639 terminx 484
                {
4834 helixhorne 485
                    i = shcnt[y*shcntp+x]; shcnt[y*shcntp+x] = sc; //shcnt changes from counter to head index
486
 
487
                    for (; i>0; i--)
488
                    {
489
                        shp[sc].x = x;
490
                        shp[sc].y = y;
491
                        sc++;
492
                    }
4639 terminx 493
                }
494
 
4834 helixhorne 495
            for (gvox->mytexx=32; gvox->mytexx<(gmaxx+(VOXBORDWIDTH<<1)); gvox->mytexx<<=1)
496
                /* do nothing */;
497
 
498
            for (gvox->mytexy=32; gvox->mytexy<(gmaxy+(VOXBORDWIDTH<<1)); gvox->mytexy<<=1)
499
                /* do_nothing */;
500
 
4639 terminx 501
            while (gvox->mytexx*gvox->mytexy*8 < garea*9) //This should be sufficient to fit most skins...
502
            {
4834 helixhorne 503
skindidntfit:
504
                if (gvox->mytexx <= gvox->mytexy)
505
                    gvox->mytexx <<= 1;
506
                else
507
                    gvox->mytexy <<= 1;
4639 terminx 508
            }
509
 
4834 helixhorne 510
            mytexo5 = gvox->mytexx>>5;
511
 
512
            i = ((gvox->mytexx*gvox->mytexy+31)>>5)<<2;
513
            zbit = (int32_t *)Xmalloc(i);
4639 terminx 514
            memset(zbit, 0, i);
515
 
516
            v = gvox->mytexx*gvox->mytexy;
4834 helixhorne 517
            for (int32_t z=0; z<sc; z++)
4639 terminx 518
            {
4834 helixhorne 519
                const int32_t dx = shp[z].x + (VOXBORDWIDTH<<1);
520
                const int32_t dy = shp[z].y + (VOXBORDWIDTH<<1);
521
                i = v;
522
 
523
                int32_t x0, y0;
524
 
4639 terminx 525
                do
526
                {
527
#if (VOXUSECHAR != 0)
4834 helixhorne 528
                    x0 = ((rand()&32767)*(min(gvox->mytexx, 255)-dx))>>15;
529
                    y0 = ((rand()&32767)*(min(gvox->mytexy, 255)-dy))>>15;
4639 terminx 530
#else
4834 helixhorne 531
                    x0 = ((rand()&32767)*(gvox->mytexx+1-dx))>>15;
532
                    y0 = ((rand()&32767)*(gvox->mytexy+1-dy))>>15;
4639 terminx 533
#endif
534
                    i--;
535
                    if (i < 0) //Time-out! Very slow if this happens... but at least it still works :P
536
                    {
537
                        Bfree(zbit);
538
 
539
                        //Re-generate shp[].x/y (box sizes) from shcnt (now head indices) for next pass :/
540
                        j = 0;
4834 helixhorne 541
 
542
                        for (int32_t y=gmaxy; y; y--)
543
                            for (int32_t x=gmaxx; x>=y; x--)
4639 terminx 544
                            {
4834 helixhorne 545
                                i = shcnt[y*shcntp+x];
546
 
547
                                for (; j<i; j++)
548
                                {
549
                                    shp[j].x = x0;
550
                                    shp[j].y = y0;
551
                                }
552
 
553
                                x0 = x;
554
                                y0 = y;
4639 terminx 555
                            }
556
 
4834 helixhorne 557
                        for (; j<sc; j++)
558
                        {
559
                            shp[j].x = x0;
560
                            shp[j].y = y0;
561
                        }
562
 
4639 terminx 563
                        goto skindidntfit;
564
                    }
565
                } while (!isrectfree(x0, y0, dx, dy));
4834 helixhorne 566
 
567
                while (y0 && isrectfree(x0, y0-1, dx, 1))
568
                    y0--;
569
                while (x0 && isrectfree(x0-1, y0, 1, dy))
570
                    x0--;
571
 
4639 terminx 572
                setrect(x0, y0, dx, dy);
573
                shp[z].x = x0; shp[z].y = y0; //Overwrite size with top-left location
574
            }
575
 
4834 helixhorne 576
            gvox->quad = (voxrect_t *)Xmalloc(gvox->qcnt*sizeof(voxrect_t));
577
            gvox->mytex = (int32_t *)Xmalloc(gvox->mytexx*gvox->mytexy*sizeof(int32_t));
4639 terminx 578
        }
579
    }
4834 helixhorne 580
 
4639 terminx 581
    Bfree(shp); Bfree(zbit); Bfree(bx0);
4834 helixhorne 582
 
4639 terminx 583
    return(gvox);
584
}
585
 
4834 helixhorne 586
static void alloc_vcolhashead(void)
587
{
588
    vcolhashead = (int32_t *)Xmalloc((vcolhashsizm1+1)*sizeof(int32_t));
589
    memset(vcolhashead, -1, (vcolhashsizm1+1)*sizeof(int32_t));
590
}
591
 
592
static void alloc_vbit(void)
593
{
594
    yzsiz = voxsiz.y*voxsiz.z;
595
    int32_t i = ((voxsiz.x*yzsiz+31)>>3)+1;
596
 
597
    vbit = (int32_t *)Xmalloc(i);
598
    memset(vbit, 0, i);
599
}
600
 
601
static void read_pal(int32_t fil, int32_t pal[256])
602
{
603
    klseek(fil, -768, SEEK_END);
604
 
605
    for (int32_t i=0; i<256; i++)
606
    {
607
        char c[3];
608
        kread(fil, c, 3);
609
//#if B_BIG_ENDIAN != 0
610
        pal[i] = B_LITTLE32((c[0]<<18) + (c[1]<<10) + (c[2]<<2) + (i<<24));
611
//#endif
612
    }
613
}
614
 
4639 terminx 615
static int32_t loadvox(const char *filnam)
616
{
4834 helixhorne 617
    const int32_t fil = kopen4load(filnam, 0);
618
    if (fil < 0)
619
        return -1;
4639 terminx 620
 
621
    kread(fil, &voxsiz, sizeof(vec3_t));
622
#if B_BIG_ENDIAN != 0
623
    voxsiz.x = B_LITTLE32(voxsiz.x);
624
    voxsiz.y = B_LITTLE32(voxsiz.y);
625
    voxsiz.z = B_LITTLE32(voxsiz.z);
626
#endif
4834 helixhorne 627
    voxpiv.x = (float)voxsiz.x * .5f;
628
    voxpiv.y = (float)voxsiz.y * .5f;
629
    voxpiv.z = (float)voxsiz.z * .5f;
4639 terminx 630
 
4834 helixhorne 631
    int32_t pal[256];
632
    read_pal(fil, pal);
4639 terminx 633
    pal[255] = -1;
634
 
635
    vcolhashsizm1 = 8192-1;
4834 helixhorne 636
    alloc_vcolhashead();
637
    alloc_vbit();
4639 terminx 638
 
4834 helixhorne 639
    char *const tbuf = (char *)Xmalloc(voxsiz.z*sizeof(uint8_t));
4639 terminx 640
 
641
    klseek(fil, 12, SEEK_SET);
4834 helixhorne 642
    for (int32_t x=0; x<voxsiz.x; x++)
643
        for (int32_t y=0, j=x*yzsiz; y<voxsiz.y; y++, j+=voxsiz.z)
4639 terminx 644
        {
4834 helixhorne 645
            kread(fil, tbuf, voxsiz.z);
646
 
647
            for (int32_t z=voxsiz.z-1; z>=0; z--)
648
                if (tbuf[z] != 255)
649
                {
650
                    const int32_t i = j+z;
651
                    vbit[i>>5] |= (1<<SHIFTMOD32(i));
652
                }
4639 terminx 653
        }
654
 
655
    klseek(fil, 12, SEEK_SET);
4834 helixhorne 656
    for (int32_t x=0; x<voxsiz.x; x++)
657
        for (int32_t y=0, j=x*yzsiz; y<voxsiz.y; y++, j+=voxsiz.z)
4639 terminx 658
        {
4834 helixhorne 659
            kread(fil, tbuf, voxsiz.z);
660
 
661
            for (int32_t z=0; z<voxsiz.z; z++)
4639 terminx 662
            {
4834 helixhorne 663
                if (tbuf[z] == 255)
664
                    continue;
665
 
666
                if (!x || !y || !z || x == voxsiz.x-1 || y == voxsiz.y-1 || z == voxsiz.z-1)
667
                {
668
                    putvox(x, y, z, pal[tbuf[z]]);
669
                    continue;
670
                }
671
 
672
                const int32_t k = j+z;
673
 
674
                if (isair(k-yzsiz) || isair(k+yzsiz) ||
675
                    isair(k-voxsiz.z) || isair(k+voxsiz.z) ||
676
                    isair(k-1) || isair(k+1))
677
                {
678
                    putvox(x, y, z, pal[tbuf[z]]);
679
                    continue;
680
                }
4639 terminx 681
            }
682
        }
683
 
4834 helixhorne 684
    Bfree(tbuf);
685
    kclose(fil);
686
 
687
    return 0;
4639 terminx 688
}
689
 
690
static int32_t loadkvx(const char *filnam)
691
{
4834 helixhorne 692
    int32_t i, mip1leng;
4639 terminx 693
 
4834 helixhorne 694
    const int32_t fil = kopen4load(filnam, 0);
695
    if (fil < 0)
696
        return -1;
697
 
4639 terminx 698
    kread(fil, &mip1leng, 4); mip1leng = B_LITTLE32(mip1leng);
699
    kread(fil, &voxsiz, sizeof(vec3_t));
700
#if B_BIG_ENDIAN != 0
701
    voxsiz.x = B_LITTLE32(voxsiz.x);
702
    voxsiz.y = B_LITTLE32(voxsiz.y);
703
    voxsiz.z = B_LITTLE32(voxsiz.z);
704
#endif
4834 helixhorne 705
    kread(fil, &i, 4); voxpiv.x = (float)B_LITTLE32(i)*(1.f/256.f);
706
    kread(fil, &i, 4); voxpiv.y = (float)B_LITTLE32(i)*(1.f/256.f);
707
    kread(fil, &i, 4); voxpiv.z = (float)B_LITTLE32(i)*(1.f/256.f);
4639 terminx 708
    klseek(fil, (voxsiz.x+1)<<2, SEEK_CUR);
709
 
4834 helixhorne 710
    const int32_t ysizp1 = voxsiz.y+1;
4639 terminx 711
    i = voxsiz.x*ysizp1*sizeof(int16_t);
712
 
4834 helixhorne 713
    uint16_t *xyoffs = (uint16_t *)Xmalloc(i);
714
    kread(fil, xyoffs, i);
4639 terminx 715
 
4834 helixhorne 716
    for (i=i/sizeof(int16_t)-1; i>=0; i--)
717
        xyoffs[i] = B_LITTLE16(xyoffs[i]);
4639 terminx 718
 
4834 helixhorne 719
    int32_t pal[256];
720
    read_pal(fil, pal);
721
 
722
    alloc_vbit();
723
 
4639 terminx 724
    for (vcolhashsizm1=4096; vcolhashsizm1<(mip1leng>>1); vcolhashsizm1<<=1)
725
    {
726
        /* do nothing */
727
    }
728
    vcolhashsizm1--; //approx to numvoxs!
4834 helixhorne 729
    alloc_vcolhashead();
4639 terminx 730
 
731
    klseek(fil, 28+((voxsiz.x+1)<<2)+((ysizp1*voxsiz.x)<<1), SEEK_SET);
732
 
733
    i = kfilelength(fil)-ktell(fil);
4834 helixhorne 734
    char *const tbuf = (char *)Xmalloc(i);
4639 terminx 735
 
4834 helixhorne 736
    kread(fil, tbuf, i);
737
    kclose(fil);
738
 
739
    char *cptr = tbuf;
740
 
741
    for (int32_t x=0; x<voxsiz.x; x++) //Set surface voxels to 1 else 0
742
        for (int32_t y=0, j=x*yzsiz; y<voxsiz.y; y++, j+=voxsiz.z)
4639 terminx 743
        {
4834 helixhorne 744
            i = xyoffs[x*ysizp1+y+1] - xyoffs[x*ysizp1+y];
745
            if (!i)
746
                continue;
747
 
748
            int32_t z1 = 0;
749
 
750
            while (i)
751
            {
752
                const int32_t z0 = cptr[0];
753
                const int32_t k = cptr[1];
754
                cptr += 3;
755
 
756
                if (!(cptr[-1]&16))
757
                    setzrange1(vbit, j+z1, j+z0);
758
 
759
                i -= k+3;
760
                z1 = z0+k;
761
 
762
                setzrange1(vbit, j+z0, j+z1);  // PK: oob in AMC TC dev if vbit alloc'd w/o +1
763
 
764
                for (int32_t z=z0; z<z1; z++)
765
                    putvox(x, y, z, pal[*cptr++]);
766
            }
4639 terminx 767
        }
768
 
4834 helixhorne 769
    Bfree(tbuf);
770
    Bfree(xyoffs);
771
 
772
    return 0;
4639 terminx 773
}
774
 
775
static int32_t loadkv6(const char *filnam)
776
{
4834 helixhorne 777
    int32_t i;
4639 terminx 778
 
4834 helixhorne 779
    const int32_t fil = kopen4load(filnam, 0);
780
    if (fil < 0)
781
        return -1;
782
 
783
    kread(fil, &i, 4);
784
    if (B_LITTLE32(i) != 0x6c78764b)
785
    {
786
        kclose(fil);
787
        return(-1);
788
    } //Kvxl
789
 
4639 terminx 790
    kread(fil, &voxsiz, sizeof(vec3_t));
791
#if B_BIG_ENDIAN != 0
792
    voxsiz.x = B_LITTLE32(voxsiz.x);
793
    voxsiz.y = B_LITTLE32(voxsiz.y);
794
    voxsiz.z = B_LITTLE32(voxsiz.z);
795
#endif
4834 helixhorne 796
    kread(fil, &i, 4);       voxpiv.x = (float)B_LITTLE32(i);
797
    kread(fil, &i, 4);       voxpiv.y = (float)B_LITTLE32(i);
798
    kread(fil, &i, 4);       voxpiv.z = (float)B_LITTLE32(i);
799
 
800
    int32_t numvoxs;
4639 terminx 801
    kread(fil, &numvoxs, 4); numvoxs = B_LITTLE32(numvoxs);
802
 
4834 helixhorne 803
    uint16_t *const ylen = (uint16_t *)Xmalloc(voxsiz.x*voxsiz.y*sizeof(int16_t));
4639 terminx 804
 
805
    klseek(fil, 32+(numvoxs<<3)+(voxsiz.x<<2), SEEK_SET);
4834 helixhorne 806
    kread(fil, ylen, voxsiz.x*voxsiz.y*sizeof(int16_t));
807
    for (i=voxsiz.x*voxsiz.y-1; i>=0; i--)
808
        ylen[i] = B_LITTLE16(ylen[i]);
809
 
4639 terminx 810
    klseek(fil, 32, SEEK_SET);
811
 
4834 helixhorne 812
    alloc_vbit();
4639 terminx 813
 
814
    for (vcolhashsizm1=4096; vcolhashsizm1<numvoxs; vcolhashsizm1<<=1)
815
    {
816
        /* do nothing */
817
    }
818
    vcolhashsizm1--;
4834 helixhorne 819
    alloc_vcolhashead();
4639 terminx 820
 
4834 helixhorne 821
    for (int32_t x=0; x<voxsiz.x; x++)
822
        for (int32_t y=0, j=x*yzsiz; y<voxsiz.y; y++, j+=voxsiz.z)
4639 terminx 823
        {
4834 helixhorne 824
            int32_t z1 = voxsiz.z;
825
 
826
            for (i=ylen[x*voxsiz.y+y]; i>0; i--)
827
            {
828
                char c[8];
829
                kread(fil, c, 8); //b,g,r,a,z_lo,z_hi,vis,dir
830
 
831
                const int32_t z0 = B_LITTLE16(*(uint16_t *)&c[4]);
832
 
833
                if (!(c[6]&16))
834
                    setzrange1(vbit, j+z1, j+z0);
835
 
836
                vbit[(j+z0)>>5] |= (1<<SHIFTMOD32(j+z0));
837
 
838
                putvox(x, y, z0, B_LITTLE32(*(int32_t *)&c[0])&0xffffff);
839
                z1 = z0+1;
840
            }
4639 terminx 841
        }
4834 helixhorne 842
 
843
    Bfree(ylen);
844
    kclose(fil);
845
 
846
    return 0;
4639 terminx 847
}
848
 
849
void voxfree(voxmodel_t *m)
850
{
4834 helixhorne 851
    if (!m)
852
        return;
853
 
4639 terminx 854
    DO_FREE_AND_NULL(m->mytex);
855
    DO_FREE_AND_NULL(m->quad);
856
    DO_FREE_AND_NULL(m->texid);
4834 helixhorne 857
 
4639 terminx 858
    Bfree(m);
859
}
860
 
861
voxmodel_t *voxload(const char *filnam)
862
{
4834 helixhorne 863
    int32_t is8bit, ret;
4639 terminx 864
 
4834 helixhorne 865
    const int32_t i = Bstrlen(filnam)-4;
866
    if (i < 0)
867
        return NULL;
868
 
4639 terminx 869
    if (!Bstrcasecmp(&filnam[i], ".vox")) { ret = loadvox(filnam); is8bit = 1; }
870
    else if (!Bstrcasecmp(&filnam[i], ".kvx")) { ret = loadkvx(filnam); is8bit = 1; }
871
    else if (!Bstrcasecmp(&filnam[i], ".kv6")) { ret = loadkv6(filnam); is8bit = 0; }
872
    //else if (!Bstrcasecmp(&filnam[i],".vxl")) { ret = loadvxl(filnam); is8bit = 0; }
873
    else return NULL;
4834 helixhorne 874
 
875
    voxmodel_t *const vm = (ret >= 0) ? vox2poly() : NULL;
876
 
4639 terminx 877
    if (vm)
878
    {
879
        vm->mdnum = 1; //VOXel model id
880
        vm->scale = vm->bscale = 1.f;
881
        vm->siz.x = voxsiz.x; vm->siz.y = voxsiz.y; vm->siz.z = voxsiz.z;
882
        vm->piv.x = voxpiv.x; vm->piv.y = voxpiv.y; vm->piv.z = voxpiv.z;
883
        vm->is8bit = is8bit;
884
 
4834 helixhorne 885
        vm->texid = (uint32_t *)Xcalloc(MAXPALOOKUPS, sizeof(uint32_t));
4639 terminx 886
    }
4834 helixhorne 887
 
4639 terminx 888
    DO_FREE_AND_NULL(shcntmal);
889
    DO_FREE_AND_NULL(vbit);
890
    DO_FREE_AND_NULL(vcol);
891
    vnum = vmax = 0;
892
    DO_FREE_AND_NULL(vcolhashead);
893
 
894
    return vm;
895
}
896
 
897
//Draw voxel model as perfect cubes
4898 terminx 898
int32_t polymost_voxdraw(voxmodel_t *m, const tspritetype *tspr)
4639 terminx 899
{
4834 helixhorne 900
    // float clut[6] = {1.02,1.02,0.94,1.06,0.98,0.98};
901
    float f, g, k0;
4639 terminx 902
 
4834 helixhorne 903
    if ((intptr_t)m == (intptr_t)(-1)) // hackhackhack
4639 terminx 904
        return 0;
905
 
4834 helixhorne 906
    if ((tspr->cstat&48)==32)
907
        return 0;
908
 
4639 terminx 909
    //updateanimation((md2model *)m,tspr);
910
 
4834 helixhorne 911
    vec3f_t m0 = { m->scale, m->scale, m->scale };
912
    vec3f_t a0 = { 0, 0, ((globalorientation&8) ? -m->zadd : m->zadd)*m->scale };
4639 terminx 913
 
914
    //if (globalorientation&8) //y-flipping
915
    //{
916
    //   m0.z = -m0.z; a0.z = -a0.z;
917
    //      //Add height of 1st frame (use same frame to prevent animation bounce)
918
    //   a0.z += m->zsiz*m->scale;
919
    //}
920
    //if (globalorientation&4) { m0.y = -m0.y; a0.y = -a0.y; } //x-flipping
921
 
4800 helixhorne 922
    k0 = m->bscale / 64.f;
4639 terminx 923
    f = (float) tspr->xrepeat * (256.f/320.f) * k0;
924
    if ((sprite[tspr->owner].cstat&48)==16)
925
        f *= 1.25f;
926
 
927
    m0.x *= f; a0.x *= f; f = -f;
928
    m0.y *= f; a0.y *= f;
929
    f = (float) tspr->yrepeat * k0;
930
    m0.z *= f; a0.z *= f;
931
 
932
    k0 = (float) tspr->z;
933
    if (globalorientation&128) k0 += (float) ((tilesiz[tspr->picnum].y*tspr->yrepeat)<<1);
934
 
4834 helixhorne 935
    f = (65536.f*512.f) / ((float)xdimen*viewingrange);
936
    g = 32.f / ((float)xdimen*gxyaspect);
4639 terminx 937
 
4834 helixhorne 938
    m0.y *= f; a0.y = (((float)(tspr->x-globalposx)) * (1.f/1024.f) + a0.y) * f;
939
    m0.x *=-f; a0.x = (((float)(tspr->y-globalposy)) * -(1.f/1024.f) + a0.x) * -f;
940
    m0.z *= g; a0.z = (((float)(k0     -globalposz)) * -(1.f/16384.f) + a0.z) * g;
941
 
942
    float mat[16];
4639 terminx 943
    md3_vox_calcmat_common(tspr, &a0, f, mat);
944
 
945
    //Mirrors
4834 helixhorne 946
    if (grhalfxdown10x < 0)
947
    {
948
        mat[0] = -mat[0];
949
        mat[4] = -mat[4];
950
        mat[8] = -mat[8];
951
        mat[12] = -mat[12];
952
    }
4639 terminx 953
 
954
    if (tspr->cstat&CSTAT_SPRITE_MDHACK)
955
    {
956
        bglDepthFunc(GL_LESS); //NEVER,LESS,(,L)EQUAL,GREATER,(NOT,G)EQUAL,ALWAYS
4997 terminx 957
//        bglDepthRange(0.0, 0.9999);
4639 terminx 958
    }
4834 helixhorne 959
 
4997 terminx 960
//    bglPushAttrib(GL_POLYGON_BIT);
961
 
4834 helixhorne 962
    if ((grhalfxdown10x >= 0) /*^ ((globalorientation&8) != 0) ^ ((globalorientation&4) != 0)*/)
963
        bglFrontFace(GL_CW);
964
    else
965
        bglFrontFace(GL_CCW);
966
 
4639 terminx 967
    bglEnable(GL_CULL_FACE);
968
    bglCullFace(GL_BACK);
969
 
970
    bglEnable(GL_TEXTURE_2D);
971
 
4834 helixhorne 972
    float pc[4];
973
 
974
    pc[0] = pc[1] = pc[2] =
975
        (float)(numshades-min(max((globalshade * shadescale)+m->shadeoff, 0), numshades)) / (float)numshades;
4639 terminx 976
    hictinting_apply(pc, globalpal);
977
 
4834 helixhorne 978
    if (tspr->cstat&2)
979
        pc[3] = !(tspr->cstat&512) ? 0.66f : 0.33f;
980
    else
981
        pc[3] = 1.0f;
982
 
4639 terminx 983
    pc[3] *= 1.0f - spriteext[tspr->owner].alpha;
4834 helixhorne 984
 
985
    if ((tspr->cstat&2) || spriteext[tspr->owner].alpha > 0.f || pc[3] < 1.0f)
986
        bglEnable(GL_BLEND); //else bglDisable(GL_BLEND);
4639 terminx 987
    //------------
988
 
989
    //transform to Build coords
4834 helixhorne 990
    float omat[16];
4639 terminx 991
    Bmemcpy(omat, mat, sizeof(omat));
4834 helixhorne 992
 
4639 terminx 993
    f = 1.f/64.f;
994
    g = m0.x*f; mat[0] *= g; mat[1] *= g; mat[2] *= g;
995
    g = m0.y*f; mat[4] = omat[8]*g; mat[5] = omat[9]*g; mat[6] = omat[10]*g;
996
    g =-m0.z*f; mat[8] = omat[4]*g; mat[9] = omat[5]*g; mat[10] = omat[6]*g;
4834 helixhorne 997
    //
4639 terminx 998
    mat[12] -= (m->piv.x*mat[0] + m->piv.y*mat[4] + (m->piv.z+m->siz.z*.5f)*mat[8]);
999
    mat[13] -= (m->piv.x*mat[1] + m->piv.y*mat[5] + (m->piv.z+m->siz.z*.5f)*mat[9]);
1000
    mat[14] -= (m->piv.x*mat[2] + m->piv.y*mat[6] + (m->piv.z+m->siz.z*.5f)*mat[10]);
4834 helixhorne 1001
    //
4639 terminx 1002
    bglMatrixMode(GL_MODELVIEW); //Let OpenGL (and perhaps hardware :) handle the matrix rotation
1003
    mat[3] = mat[7] = mat[11] = 0.f; mat[15] = 1.f;
1004
 
1005
    bglLoadMatrixf(mat);
1006
 
4834 helixhorne 1007
    const float ru = 1.f/((float)m->mytexx);
1008
    const float rv = 1.f/((float)m->mytexy);
4639 terminx 1009
#if (VOXBORDWIDTH == 0)
1010
    uhack[0] = ru*.125; uhack[1] = -uhack[0];
1011
    vhack[0] = rv*.125; vhack[1] = -vhack[0];
1012
#endif
4834 helixhorne 1013
    const float phack[2] = { 0, 1.f/256.f };
4639 terminx 1014
 
4834 helixhorne 1015
    if (!m->texid[globalpal])
1016
        m->texid[globalpal] = gloadtex(m->mytex, m->mytexx, m->mytexy, m->is8bit, globalpal);
1017
    else
1018
        bglBindTexture(GL_TEXTURE_2D, m->texid[globalpal]);
1019
 
1020
    bglBegin(GL_QUADS);  // {{{
1021
 
1022
    for (int32_t i=0, fi=0; i<m->qcnt; i++)
4639 terminx 1023
    {
4834 helixhorne 1024
        if (i == m->qfacind[fi])
1025
        {
1026
            f = 1 /*clut[fi++]*/;
1027
            bglColor4f(pc[0]*f, pc[1]*f, pc[2]*f, pc[3]*f);
1028
        }
4639 terminx 1029
 
4834 helixhorne 1030
        const vert_t *const vptr = &m->quad[i].v[0];
4639 terminx 1031
 
4834 helixhorne 1032
        const int32_t xx = vptr[0].x + vptr[2].x;
1033
        const int32_t yy = vptr[0].y + vptr[2].y;
1034
        const int32_t zz = vptr[0].z + vptr[2].z;
1035
 
1036
        for (int32_t j=0; j<4; j++)
4639 terminx 1037
        {
1038
            vec3f_t fp;
1039
#if (VOXBORDWIDTH == 0)
4834 helixhorne 1040
            bglTexCoord2f(((float)vptr[j].u)*ru + uhack[vptr[j].u!=vptr[0].u],
1041
                          ((float)vptr[j].v)*rv + vhack[vptr[j].v!=vptr[0].v]);
4639 terminx 1042
#else
4834 helixhorne 1043
            bglTexCoord2f(((float)vptr[j].u)*ru, ((float)vptr[j].v)*rv);
4639 terminx 1044
#endif
4834 helixhorne 1045
            fp.x = ((float)vptr[j].x) - phack[xx>vptr[j].x*2] + phack[xx<vptr[j].x*2];
1046
            fp.y = ((float)vptr[j].y) - phack[yy>vptr[j].y*2] + phack[yy<vptr[j].y*2];
1047
            fp.z = ((float)vptr[j].z) - phack[zz>vptr[j].z*2] + phack[zz<vptr[j].z*2];
1048
 
1049
            bglVertex3fv((float *)&fp);
4639 terminx 1050
        }
1051
    }
1052
 
4834 helixhorne 1053
    bglEnd();  // }}}
1054
 
4639 terminx 1055
    //------------
1056
    bglDisable(GL_CULL_FACE);
4997 terminx 1057
//    bglPopAttrib();
4639 terminx 1058
    if (tspr->cstat&CSTAT_SPRITE_MDHACK)
1059
    {
1060
        bglDepthFunc(GL_LESS); //NEVER,LESS,(,L)EQUAL,GREATER,(NOT,G)EQUAL,ALWAYS
4997 terminx 1061
//        bglDepthRange(0.0, 0.99999);
4639 terminx 1062
    }
1063
    bglLoadIdentity();
4834 helixhorne 1064
 
4639 terminx 1065
    return 1;
1066
}
1067
#endif
1068
 
1069
//---------------------------------------- VOX LIBRARY ENDS ----------------------------------------