2014-09-30 04:18:43 +00:00
//--------------------------------------- VOX LIBRARY BEGINS ---------------------------------------
# ifdef USE_OPENGL
# include "compat.h"
# include "build.h"
# include "pragmas.h"
# include "baselayer.h"
# include "engine_priv.h"
# include "polymost.h"
# include "mdsprite.h"
2020-01-18 21:41:08 +00:00
# include "v_video.h"
# include "flatvertices.h"
2019-12-17 22:25:07 +00:00
2016-06-21 00:33:06 +00:00
# include "palette.h"
2019-09-16 19:08:42 +00:00
# include "../../glbackend/glbackend.h"
2014-09-30 04:18:43 +00:00
2014-12-26 17:29:48 +00:00
2014-09-30 04:18:43 +00:00
//For loading/conversion only
static vec3_t voxsiz ;
static int32_t yzsiz , * vbit = 0 ; //vbit: 1 bit per voxel: 0=air,1=solid
static vec3f_t voxpiv ;
2014-12-26 17:29:48 +00:00
2014-09-30 04:18:43 +00:00
static int32_t * vcolhashead = 0 , vcolhashsizm1 ;
typedef struct { int32_t p , c , n ; } voxcol_t ;
static voxcol_t * vcol = 0 ; int32_t vnum = 0 , vmax = 0 ;
2014-12-26 17:29:48 +00:00
2014-09-30 04:18:43 +00:00
typedef struct { int16_t x , y ; } spoint2d ;
static spoint2d * shp ;
static int32_t * shcntmal , * shcnt = 0 , shcntp ;
2014-12-26 17:29:48 +00:00
2014-09-30 04:18:43 +00:00
static int32_t mytexo5 , * zbit , gmaxx , gmaxy , garea , pow2m1 [ 33 ] ;
static voxmodel_t * gvox ;
2014-12-26 17:29:48 +00:00
2014-09-30 04:18:43 +00:00
//pitch must equal xsiz*4
2020-05-28 23:03:01 +00:00
static OpenGLRenderer : : FHardwareTexture * gloadtex ( const int32_t * picbuf , int32_t xsiz , int32_t ysiz , int32_t is8bit , const PalEntry * paldata )
2014-09-30 04:18:43 +00:00
{
// Correct for GL's RGB order; also apply gamma here:
2014-12-26 17:29:48 +00:00
const coltype * const pic = ( const coltype * ) picbuf ;
coltype * pic2 = ( coltype * ) Xmalloc ( xsiz * ysiz * sizeof ( coltype ) ) ;
2014-09-30 04:18:43 +00:00
if ( ! is8bit )
{
2016-08-27 01:41:21 +00:00
for ( bssize_t i = xsiz * ysiz - 1 ; i > = 0 ; i - - )
2014-09-30 04:18:43 +00:00
{
2019-10-19 08:21:07 +00:00
pic2 [ i ] . r = pic [ i ] . b ;
2019-10-05 19:59:03 +00:00
pic2 [ i ] . g = pic [ i ] . g ;
2019-10-19 08:21:07 +00:00
pic2 [ i ] . b = pic [ i ] . r ;
2014-09-30 04:18:43 +00:00
pic2 [ i ] . a = 255 ;
}
}
else
{
2016-08-27 01:41:21 +00:00
for ( bssize_t i = xsiz * ysiz - 1 ; i > = 0 ; i - - )
2014-09-30 04:18:43 +00:00
{
2020-02-09 19:14:26 +00:00
const int32_t ii = pic [ i ] . a ;
2014-09-30 04:18:43 +00:00
2020-02-09 19:14:26 +00:00
pic2 [ i ] . r = paldata [ ii ] . b ;
pic2 [ i ] . g = paldata [ ii ] . g ;
pic2 [ i ] . b = paldata [ ii ] . r ;
2014-09-30 04:18:43 +00:00
pic2 [ i ] . a = 255 ;
}
}
2020-05-28 23:03:01 +00:00
auto tex = GLInterface . NewTexture ( 4 ) ;
tex - > CreateTexture ( ( uint8_t * ) pic2 , xsiz , ysiz , 15 , true , " Voxel " ) ; // Mipmap should be false for this but currently this causes render errors because the proper sampler cannot be selected.
2019-06-25 11:29:08 +00:00
Xfree ( pic2 ) ;
2014-09-30 04:18:43 +00:00
2019-09-18 18:44:21 +00:00
return tex ;
2014-09-30 04:18:43 +00:00
}
static int32_t getvox ( int32_t x , int32_t y , int32_t z )
{
z + = x * yzsiz + y * voxsiz . z ;
2014-12-26 17:29:48 +00:00
2019-08-12 03:15:10 +00:00
for ( x = vcolhashead [ ( z * 214013LL ) & vcolhashsizm1 ] ; x > = 0 ; x = vcol [ x ] . n )
2014-12-26 17:29:48 +00:00
if ( vcol [ x ] . p = = z )
return vcol [ x ] . c ;
return 0x808080 ;
2014-09-30 04:18:43 +00:00
}
static void putvox ( int32_t x , int32_t y , int32_t z , int32_t col )
{
2014-12-26 17:29:48 +00:00
if ( vnum > = vmax )
{
vmax = max ( vmax < < 1 , 4096 ) ;
vcol = ( voxcol_t * ) Xrealloc ( vcol , vmax * sizeof ( voxcol_t ) ) ;
}
2014-09-30 04:18:43 +00:00
z + = x * yzsiz + y * voxsiz . z ;
2014-12-26 17:29:48 +00:00
2019-08-12 03:15:10 +00:00
vcol [ vnum ] . p = z ; z = ( z * 214013LL ) & vcolhashsizm1 ;
2014-09-30 04:18:43 +00:00
vcol [ vnum ] . c = col ;
vcol [ vnum ] . n = vcolhashead [ z ] ; vcolhashead [ z ] = vnum + + ;
}
//Set all bits in vbit from (x,y,z0) to (x,y,z1-1) to 0's
#if 0
static void setzrange0 ( int32_t * lptr , int32_t z0 , int32_t z1 )
{
2016-08-28 21:26:48 +00:00
if ( ! ( ( z0 ^ z1 ) & ~ 31 ) ) { lptr [ z0 > > 5 ] & = ( ( ~ - ( 1 < < SHIFTMOD32 ( z0 ) ) ) | - ( 1 < < SHIFTMOD32 ( z1 ) ) ) ; return ; }
2014-12-26 17:29:48 +00:00
int32_t z = ( z0 > > 5 ) , ze = ( z1 > > 5 ) ;
2016-08-28 21:26:48 +00:00
lptr [ z ] & = ~ - ( 1 < < SHIFTMOD32 ( z0 ) ) ;
for ( z + + ; z < ze ; z + + ) lptr [ z ] = 0 ;
lptr [ z ] & = - ( 1 < < SHIFTMOD32 ( z1 ) ) ;
2014-09-30 04:18:43 +00:00
}
# endif
//Set all bits in vbit from (x,y,z0) to (x,y,z1-1) to 1's
static void setzrange1 ( int32_t * lptr , int32_t z0 , int32_t z1 )
{
2016-08-28 21:26:48 +00:00
if ( ! ( ( z0 ^ z1 ) & ~ 31 ) ) { lptr [ z0 > > 5 ] | = ( ( ~ - ( 1 < < SHIFTMOD32 ( z1 ) ) ) & - ( 1 < < SHIFTMOD32 ( z0 ) ) ) ; return ; }
2014-12-26 17:29:48 +00:00
int32_t z = ( z0 > > 5 ) , ze = ( z1 > > 5 ) ;
2016-08-28 21:26:48 +00:00
lptr [ z ] | = - ( 1 < < SHIFTMOD32 ( z0 ) ) ;
for ( z + + ; z < ze ; z + + ) lptr [ z ] = - 1 ;
lptr [ z ] | = ~ - ( 1 < < SHIFTMOD32 ( z1 ) ) ;
2014-09-30 04:18:43 +00:00
}
static int32_t isrectfree ( int32_t x0 , int32_t y0 , int32_t dx , int32_t dy )
{
#if 0
int32_t i , j , x ;
i = y0 * gvox - > mytexx + x0 ;
for ( dy = 0 ; dy ; dy - - , i + = gvox - > mytexx )
2016-06-21 00:34:41 +00:00
for ( x = 0 ; x < dx ; x + + ) { j = i + x ; if ( zbit [ j > > 5 ] & ( 1 < < SHIFTMOD32 ( j ) ) ) return 0 ; }
2014-09-30 04:18:43 +00:00
# else
2014-12-26 17:29:48 +00:00
int32_t i = y0 * mytexo5 + ( x0 > > 5 ) ;
dx + = x0 - 1 ;
const int32_t c = ( dx > > 5 ) - ( x0 > > 5 ) ;
int32_t m = ~ pow2m1 [ x0 & 31 ] ;
const int32_t m1 = pow2m1 [ ( dx & 31 ) + 1 ] ;
2014-09-30 04:18:43 +00:00
2014-12-26 17:29:48 +00:00
if ( ! c )
{
for ( m & = m1 ; dy ; dy - - , i + = mytexo5 )
if ( zbit [ i ] & m )
return 0 ;
}
2014-09-30 04:18:43 +00:00
else
{
2014-12-26 17:29:48 +00:00
for ( ; dy ; dy - - , i + = mytexo5 )
2014-09-30 04:18:43 +00:00
{
2014-12-26 17:29:48 +00:00
if ( zbit [ i ] & m )
return 0 ;
int32_t x ;
for ( x = 1 ; x < c ; x + + )
if ( zbit [ i + x ] )
return 0 ;
if ( zbit [ i + x ] & m1 )
return 0 ;
2014-09-30 04:18:43 +00:00
}
}
# endif
2016-06-21 00:34:41 +00:00
return 1 ;
2014-09-30 04:18:43 +00:00
}
static void setrect ( int32_t x0 , int32_t y0 , int32_t dx , int32_t dy )
{
#if 0
int32_t i , j , y ;
i = y0 * gvox - > mytexx + x0 ;
for ( y = 0 ; y < dy ; y + + , i + = gvox - > mytexx )
for ( x = 0 ; x < dx ; x + + ) { j = i + x ; zbit [ j > > 5 ] | = ( 1 < < SHIFTMOD32 ( j ) ) ; }
# else
2014-12-26 17:29:48 +00:00
int32_t i = y0 * mytexo5 + ( x0 > > 5 ) ;
dx + = x0 - 1 ;
const int32_t c = ( dx > > 5 ) - ( x0 > > 5 ) ;
int32_t m = ~ pow2m1 [ x0 & 31 ] ;
const int32_t m1 = pow2m1 [ ( dx & 31 ) + 1 ] ;
2014-09-30 04:18:43 +00:00
2014-12-26 17:29:48 +00:00
if ( ! c )
{
for ( m & = m1 ; dy ; dy - - , i + = mytexo5 )
zbit [ i ] | = m ;
}
2014-09-30 04:18:43 +00:00
else
{
2014-12-26 17:29:48 +00:00
for ( ; dy ; dy - - , i + = mytexo5 )
2014-09-30 04:18:43 +00:00
{
zbit [ i ] | = m ;
2014-12-26 17:29:48 +00:00
int32_t x ;
for ( x = 1 ; x < c ; x + + )
zbit [ i + x ] = - 1 ;
2014-09-30 04:18:43 +00:00
zbit [ i + x ] | = m1 ;
}
}
# endif
}
2014-12-26 17:29:48 +00:00
static void cntquad ( int32_t x0 , int32_t y0 , int32_t z0 , int32_t x1 , int32_t y1 , int32_t z1 ,
int32_t x2 , int32_t y2 , int32_t z2 , int32_t face )
2014-09-30 04:18:43 +00:00
{
UNREFERENCED_PARAMETER ( x1 ) ;
UNREFERENCED_PARAMETER ( y1 ) ;
UNREFERENCED_PARAMETER ( z1 ) ;
UNREFERENCED_PARAMETER ( face ) ;
2014-12-26 17:29:48 +00:00
int32_t x = labs ( x2 - x0 ) , y = labs ( y2 - y0 ) , z = labs ( z2 - z0 ) ;
if ( x = = 0 )
x = z ;
else if ( y = = 0 )
y = z ;
2014-09-30 04:18:43 +00:00
if ( x < y ) { z = x ; x = y ; y = z ; }
2014-12-26 17:29:48 +00:00
2014-09-30 04:18:43 +00:00
shcnt [ y * shcntp + x ] + + ;
2014-12-26 17:29:48 +00:00
2014-09-30 04:18:43 +00:00
if ( x > gmaxx ) gmaxx = x ;
if ( y > gmaxy ) gmaxy = y ;
2014-12-26 17:29:48 +00:00
garea + = ( x + ( VOXBORDWIDTH < < 1 ) ) * ( y + ( VOXBORDWIDTH < < 1 ) ) ;
2014-09-30 04:18:43 +00:00
gvox - > qcnt + + ;
}
2014-12-26 17:29:48 +00:00
static void addquad ( int32_t x0 , int32_t y0 , int32_t z0 , int32_t x1 , int32_t y1 , int32_t z1 ,
int32_t x2 , int32_t y2 , int32_t z2 , int32_t face )
2014-09-30 04:18:43 +00:00
{
2014-12-26 17:29:48 +00:00
int32_t i ;
int32_t x = labs ( x2 - x0 ) , y = labs ( y2 - y0 ) , z = labs ( z2 - z0 ) ;
2014-09-30 04:18:43 +00:00
2014-12-26 17:29:48 +00:00
if ( x = = 0 ) { x = y ; y = z ; i = 0 ; }
else if ( y = = 0 ) { y = z ; i = 1 ; }
2014-09-30 04:18:43 +00:00
else i = 2 ;
2014-12-26 17:29:48 +00:00
2014-09-30 04:18:43 +00:00
if ( x < y ) { z = x ; x = y ; y = z ; i + = 3 ; }
2014-12-26 17:29:48 +00:00
2014-09-30 04:18:43 +00:00
z = shcnt [ y * shcntp + x ] + + ;
2014-12-26 17:29:48 +00:00
int32_t * lptr = & gvox - > mytex [ ( shp [ z ] . y + VOXBORDWIDTH ) * gvox - > mytexx +
( shp [ z ] . x + VOXBORDWIDTH ) ] ;
int32_t nx = 0 , ny = 0 , nz = 0 ;
2014-09-30 04:18:43 +00:00
switch ( face )
{
case 0 :
ny = y1 ; x2 = x0 ; x0 = x1 ; x1 = x2 ; break ;
case 1 :
ny = y0 ; y0 + + ; y1 + + ; y2 + + ; break ;
case 2 :
nz = z1 ; y0 = y2 ; y2 = y1 ; y1 = y0 ; z0 + + ; z1 + + ; z2 + + ; break ;
case 3 :
nz = z0 ; break ;
case 4 :
nx = x1 ; y2 = y0 ; y0 = y1 ; y1 = y2 ; x0 + + ; x1 + + ; x2 + + ; break ;
case 5 :
nx = x0 ; break ;
}
2014-12-26 17:29:48 +00:00
2016-08-27 01:41:21 +00:00
for ( bssize_t yy = 0 ; yy < y ; yy + + , lptr + = gvox - > mytexx )
for ( bssize_t xx = 0 ; xx < x ; xx + + )
2014-09-30 04:18:43 +00:00
{
2014-12-26 17:29:48 +00:00
switch ( face )
{
case 0 :
if ( i < 3 ) { nx = x1 + x - 1 - xx ; nz = z1 + yy ; } //back
else { nx = x1 + y - 1 - yy ; nz = z1 + xx ; }
break ;
case 1 :
if ( i < 3 ) { nx = x0 + xx ; nz = z0 + yy ; } //front
else { nx = x0 + yy ; nz = z0 + xx ; }
break ;
case 2 :
if ( i < 3 ) { nx = x1 - x + xx ; ny = y1 - 1 - yy ; } //bot
else { nx = x1 - 1 - yy ; ny = y1 - 1 - xx ; }
break ;
case 3 :
if ( i < 3 ) { nx = x0 + xx ; ny = y0 + yy ; } //top
else { nx = x0 + yy ; ny = y0 + xx ; }
break ;
case 4 :
if ( i < 3 ) { ny = y1 + x - 1 - xx ; nz = z1 + yy ; } //right
else { ny = y1 + y - 1 - yy ; nz = z1 + xx ; }
break ;
case 5 :
if ( i < 3 ) { ny = y0 + xx ; nz = z0 + yy ; } //left
else { ny = y0 + yy ; nz = z0 + xx ; }
break ;
}
lptr [ xx ] = getvox ( nx , ny , nz ) ;
2014-09-30 04:18:43 +00:00
}
//Extend borders horizontally
2016-08-27 01:41:21 +00:00
for ( bssize_t yy = VOXBORDWIDTH ; yy < y + VOXBORDWIDTH ; yy + + )
for ( bssize_t xx = 0 ; xx < VOXBORDWIDTH ; xx + + )
2014-09-30 04:18:43 +00:00
{
2014-12-26 17:29:48 +00:00
lptr = & gvox - > mytex [ ( shp [ z ] . y + yy ) * gvox - > mytexx + shp [ z ] . x ] ;
lptr [ xx ] = lptr [ VOXBORDWIDTH ] ;
lptr [ xx + x + VOXBORDWIDTH ] = lptr [ x - 1 + VOXBORDWIDTH ] ;
2014-09-30 04:18:43 +00:00
}
2014-12-26 17:29:48 +00:00
2014-09-30 04:18:43 +00:00
//Extend borders vertically
2016-08-27 01:41:21 +00:00
for ( bssize_t yy = 0 ; yy < VOXBORDWIDTH ; yy + + )
2014-09-30 04:18:43 +00:00
{
2014-12-26 17:29:48 +00:00
Bmemcpy ( & gvox - > mytex [ ( shp [ z ] . y + yy ) * gvox - > mytexx + shp [ z ] . x ] ,
& gvox - > mytex [ ( shp [ z ] . y + VOXBORDWIDTH ) * gvox - > mytexx + shp [ z ] . x ] ,
( x + ( VOXBORDWIDTH < < 1 ) ) < < 2 ) ;
Bmemcpy ( & gvox - > mytex [ ( shp [ z ] . y + y + yy + VOXBORDWIDTH ) * gvox - > mytexx + shp [ z ] . x ] ,
& gvox - > mytex [ ( shp [ z ] . y + y - 1 + VOXBORDWIDTH ) * gvox - > mytexx + shp [ z ] . x ] ,
( x + ( VOXBORDWIDTH < < 1 ) ) < < 2 ) ;
2014-09-30 04:18:43 +00:00
}
2014-12-26 17:29:48 +00:00
voxrect_t * const qptr = & gvox - > quad [ gvox - > qcnt ] ;
2014-09-30 04:18:43 +00:00
qptr - > v [ 0 ] . x = x0 ; qptr - > v [ 0 ] . y = y0 ; qptr - > v [ 0 ] . z = z0 ;
qptr - > v [ 1 ] . x = x1 ; qptr - > v [ 1 ] . y = y1 ; qptr - > v [ 1 ] . z = z1 ;
qptr - > v [ 2 ] . x = x2 ; qptr - > v [ 2 ] . y = y2 ; qptr - > v [ 2 ] . z = z2 ;
2014-12-26 17:29:48 +00:00
2016-08-27 01:41:21 +00:00
for ( bssize_t j = 0 ; j < 3 ; j + + )
2014-12-26 17:29:48 +00:00
{
qptr - > v [ j ] . u = shp [ z ] . x + VOXBORDWIDTH ;
qptr - > v [ j ] . v = shp [ z ] . y + VOXBORDWIDTH ;
}
if ( i < 3 )
qptr - > v [ 1 ] . u + = x ;
else
qptr - > v [ 1 ] . v + = y ;
qptr - > v [ 2 ] . u + = x ;
qptr - > v [ 2 ] . v + = y ;
2014-09-30 04:18:43 +00:00
qptr - > v [ 3 ] . u = qptr - > v [ 0 ] . u - qptr - > v [ 1 ] . u + qptr - > v [ 2 ] . u ;
qptr - > v [ 3 ] . v = qptr - > v [ 0 ] . v - qptr - > v [ 1 ] . v + qptr - > v [ 2 ] . v ;
qptr - > v [ 3 ] . x = qptr - > v [ 0 ] . x - qptr - > v [ 1 ] . x + qptr - > v [ 2 ] . x ;
qptr - > v [ 3 ] . y = qptr - > v [ 0 ] . y - qptr - > v [ 1 ] . y + qptr - > v [ 2 ] . y ;
qptr - > v [ 3 ] . z = qptr - > v [ 0 ] . z - qptr - > v [ 1 ] . z + qptr - > v [ 2 ] . z ;
2014-12-26 17:29:48 +00:00
if ( gvox - > qfacind [ face ] < 0 )
gvox - > qfacind [ face ] = gvox - > qcnt ;
gvox - > qcnt + + ;
2014-09-30 04:18:43 +00:00
}
static inline int32_t isolid ( int32_t x , int32_t y , int32_t z )
{
2014-12-26 17:29:48 +00:00
if ( ( uint32_t ) x > = ( uint32_t ) voxsiz . x ) return 0 ;
if ( ( uint32_t ) y > = ( uint32_t ) voxsiz . y ) return 0 ;
if ( ( uint32_t ) z > = ( uint32_t ) voxsiz . z ) return 0 ;
z + = x * yzsiz + y * voxsiz . z ;
return vbit [ z > > 5 ] & ( 1 < < SHIFTMOD32 ( z ) ) ;
}
2017-02-25 08:15:53 +00:00
static FORCE_INLINE int isair ( int32_t i )
2014-12-26 17:29:48 +00:00
{
return ! ( vbit [ i > > 5 ] & ( 1 < < SHIFTMOD32 ( i ) ) ) ;
2014-09-30 04:18:43 +00:00
}
static voxmodel_t * vox2poly ( )
{
2014-12-26 17:29:48 +00:00
int32_t i , j ;
2014-09-30 04:18:43 +00:00
2014-12-26 17:29:48 +00:00
gvox = ( voxmodel_t * ) Xmalloc ( sizeof ( voxmodel_t ) ) ;
2014-09-30 04:18:43 +00:00
memset ( gvox , 0 , sizeof ( voxmodel_t ) ) ;
2014-12-26 17:29:48 +00:00
{
//x is largest dimension, y is 2nd largest dimension
int32_t x = voxsiz . x , y = voxsiz . y , z = voxsiz . z ;
if ( x < y & & x < z )
x = z ;
else if ( y < z )
y = z ;
if ( x < y )
{
z = x ;
x = y ;
y = z ;
}
shcntp = x ;
i = x * y * sizeof ( int32_t ) ;
}
shcntmal = ( int32_t * ) Xmalloc ( i ) ;
memset ( shcntmal , 0 , i ) ;
shcnt = & shcntmal [ - shcntp - 1 ] ;
2014-09-30 04:18:43 +00:00
gmaxx = gmaxy = garea = 0 ;
2014-12-26 17:29:48 +00:00
if ( pow2m1 [ 32 ] ! = - 1 )
{
for ( i = 0 ; i < 32 ; i + + )
pow2m1 [ i ] = ( 1u < < i ) - 1 ;
pow2m1 [ 32 ] = - 1 ;
}
2014-09-30 04:18:43 +00:00
2014-12-26 17:29:48 +00:00
for ( i = 0 ; i < 7 ; i + + )
gvox - > qfacind [ i ] = - 1 ;
2014-09-30 04:18:43 +00:00
2014-12-26 17:29:48 +00:00
i = ( max ( voxsiz . y , voxsiz . z ) + 1 ) < < 2 ;
int32_t * const bx0 = ( int32_t * ) Xmalloc ( i < < 1 ) ;
int32_t * const by0 = ( int32_t * ) ( ( ( intptr_t ) bx0 ) + i ) ;
int32_t ov , oz = 0 ;
2016-08-27 01:41:21 +00:00
for ( bssize_t cnt = 0 ; cnt < 2 ; cnt + + )
2014-09-30 04:18:43 +00:00
{
2014-12-26 17:29:48 +00:00
void ( * daquad ) ( int32_t , int32_t , int32_t , int32_t , int32_t , int32_t , int32_t , int32_t , int32_t , int32_t ) =
cnt = = 0 ? cntquad : addquad ;
2014-09-30 04:18:43 +00:00
gvox - > qcnt = 0 ;
2014-12-26 17:29:48 +00:00
memset ( by0 , - 1 , ( max ( voxsiz . y , voxsiz . z ) + 1 ) < < 2 ) ;
int32_t v = 0 ;
2014-09-30 04:18:43 +00:00
for ( i = - 1 ; i < = 1 ; i + = 2 )
2016-08-27 01:41:21 +00:00
for ( bssize_t y = 0 ; y < voxsiz . y ; y + + )
for ( bssize_t x = 0 ; x < = voxsiz . x ; x + + )
for ( bssize_t z = 0 ; z < = voxsiz . z ; z + + )
2014-09-30 04:18:43 +00:00
{
2014-12-26 17:29:48 +00:00
ov = v ; v = ( isolid ( x , y , z ) & & ( ! isolid ( x , y + i , z ) ) ) ;
if ( ( by0 [ z ] > = 0 ) & & ( ( by0 [ z ] ! = oz ) | | ( v > = ov ) ) )
{
daquad ( bx0 [ z ] , y , by0 [ z ] , x , y , by0 [ z ] , x , y , z , i > = 0 ) ;
by0 [ z ] = - 1 ;
}
if ( v > ov ) oz = z ;
else if ( ( v < ov ) & & ( by0 [ z ] ! = oz ) ) { bx0 [ z ] = x ; by0 [ z ] = oz ; }
2014-09-30 04:18:43 +00:00
}
for ( i = - 1 ; i < = 1 ; i + = 2 )
2016-08-27 01:41:21 +00:00
for ( bssize_t z = 0 ; z < voxsiz . z ; z + + )
for ( bssize_t x = 0 ; x < = voxsiz . x ; x + + )
for ( bssize_t y = 0 ; y < = voxsiz . y ; y + + )
2014-09-30 04:18:43 +00:00
{
2014-12-26 17:29:48 +00:00
ov = v ; v = ( isolid ( x , y , z ) & & ( ! isolid ( x , y , z - i ) ) ) ;
if ( ( by0 [ y ] > = 0 ) & & ( ( by0 [ y ] ! = oz ) | | ( v > = ov ) ) )
{
daquad ( bx0 [ y ] , by0 [ y ] , z , x , by0 [ y ] , z , x , y , z , ( i > = 0 ) + 2 ) ;
by0 [ y ] = - 1 ;
}
if ( v > ov ) oz = y ;
else if ( ( v < ov ) & & ( by0 [ y ] ! = oz ) ) { bx0 [ y ] = x ; by0 [ y ] = oz ; }
2014-09-30 04:18:43 +00:00
}
for ( i = - 1 ; i < = 1 ; i + = 2 )
2016-08-27 01:41:21 +00:00
for ( bssize_t x = 0 ; x < voxsiz . x ; x + + )
for ( bssize_t y = 0 ; y < = voxsiz . y ; y + + )
for ( bssize_t z = 0 ; z < = voxsiz . z ; z + + )
2014-09-30 04:18:43 +00:00
{
2014-12-26 17:29:48 +00:00
ov = v ; v = ( isolid ( x , y , z ) & & ( ! isolid ( x - i , y , z ) ) ) ;
if ( ( by0 [ z ] > = 0 ) & & ( ( by0 [ z ] ! = oz ) | | ( v > = ov ) ) )
{
daquad ( x , bx0 [ z ] , by0 [ z ] , x , y , by0 [ z ] , x , y , z , ( i > = 0 ) + 4 ) ;
by0 [ z ] = - 1 ;
}
if ( v > ov ) oz = z ;
else if ( ( v < ov ) & & ( by0 [ z ] ! = oz ) ) { bx0 [ z ] = y ; by0 [ z ] = oz ; }
2014-09-30 04:18:43 +00:00
}
if ( ! cnt )
{
2014-12-26 17:29:48 +00:00
shp = ( spoint2d * ) Xmalloc ( gvox - > qcnt * sizeof ( spoint2d ) ) ;
2014-09-30 04:18:43 +00:00
2014-12-26 17:29:48 +00:00
int32_t sc = 0 ;
2016-08-27 01:41:21 +00:00
for ( bssize_t y = gmaxy ; y ; y - - )
for ( bssize_t x = gmaxx ; x > = y ; x - - )
2014-09-30 04:18:43 +00:00
{
2014-12-26 17:29:48 +00:00
i = shcnt [ y * shcntp + x ] ; shcnt [ y * shcntp + x ] = sc ; //shcnt changes from counter to head index
for ( ; i > 0 ; i - - )
{
shp [ sc ] . x = x ;
shp [ sc ] . y = y ;
sc + + ;
}
2014-09-30 04:18:43 +00:00
}
2014-12-26 17:29:48 +00:00
for ( gvox - > mytexx = 32 ; gvox - > mytexx < ( gmaxx + ( VOXBORDWIDTH < < 1 ) ) ; gvox - > mytexx < < = 1 )
/* do nothing */ ;
for ( gvox - > mytexy = 32 ; gvox - > mytexy < ( gmaxy + ( VOXBORDWIDTH < < 1 ) ) ; gvox - > mytexy < < = 1 )
/* do_nothing */ ;
2014-09-30 04:18:43 +00:00
while ( gvox - > mytexx * gvox - > mytexy * 8 < garea * 9 ) //This should be sufficient to fit most skins...
{
2014-12-26 17:29:48 +00:00
skindidntfit :
if ( gvox - > mytexx < = gvox - > mytexy )
gvox - > mytexx < < = 1 ;
else
gvox - > mytexy < < = 1 ;
2014-09-30 04:18:43 +00:00
}
2014-12-26 17:29:48 +00:00
mytexo5 = gvox - > mytexx > > 5 ;
i = ( ( gvox - > mytexx * gvox - > mytexy + 31 ) > > 5 ) < < 2 ;
zbit = ( int32_t * ) Xmalloc ( i ) ;
2014-09-30 04:18:43 +00:00
memset ( zbit , 0 , i ) ;
v = gvox - > mytexx * gvox - > mytexy ;
2016-08-27 01:41:21 +00:00
for ( bssize_t z = 0 ; z < sc ; z + + )
2014-09-30 04:18:43 +00:00
{
2014-12-26 17:29:48 +00:00
const int32_t dx = shp [ z ] . x + ( VOXBORDWIDTH < < 1 ) ;
const int32_t dy = shp [ z ] . y + ( VOXBORDWIDTH < < 1 ) ;
i = v ;
int32_t x0 , y0 ;
2014-09-30 04:18:43 +00:00
do
{
# if (VOXUSECHAR != 0)
2014-12-26 17:29:48 +00:00
x0 = ( ( rand ( ) & 32767 ) * ( min ( gvox - > mytexx , 255 ) - dx ) ) > > 15 ;
y0 = ( ( rand ( ) & 32767 ) * ( min ( gvox - > mytexy , 255 ) - dy ) ) > > 15 ;
2014-09-30 04:18:43 +00:00
# else
2014-12-26 17:29:48 +00:00
x0 = ( ( rand ( ) & 32767 ) * ( gvox - > mytexx + 1 - dx ) ) > > 15 ;
y0 = ( ( rand ( ) & 32767 ) * ( gvox - > mytexy + 1 - dy ) ) > > 15 ;
2014-09-30 04:18:43 +00:00
# endif
i - - ;
if ( i < 0 ) //Time-out! Very slow if this happens... but at least it still works :P
{
2019-06-25 11:29:08 +00:00
Xfree ( zbit ) ;
2014-09-30 04:18:43 +00:00
//Re-generate shp[].x/y (box sizes) from shcnt (now head indices) for next pass :/
j = 0 ;
2014-12-26 17:29:48 +00:00
2016-08-27 01:41:21 +00:00
for ( bssize_t y = gmaxy ; y ; y - - )
for ( bssize_t x = gmaxx ; x > = y ; x - - )
2014-09-30 04:18:43 +00:00
{
2014-12-26 17:29:48 +00:00
i = shcnt [ y * shcntp + x ] ;
for ( ; j < i ; j + + )
{
shp [ j ] . x = x0 ;
shp [ j ] . y = y0 ;
}
x0 = x ;
y0 = y ;
2014-09-30 04:18:43 +00:00
}
2014-12-26 17:29:48 +00:00
for ( ; j < sc ; j + + )
{
shp [ j ] . x = x0 ;
shp [ j ] . y = y0 ;
}
2014-09-30 04:18:43 +00:00
goto skindidntfit ;
}
} while ( ! isrectfree ( x0 , y0 , dx , dy ) ) ;
2014-12-26 17:29:48 +00:00
while ( y0 & & isrectfree ( x0 , y0 - 1 , dx , 1 ) )
y0 - - ;
while ( x0 & & isrectfree ( x0 - 1 , y0 , 1 , dy ) )
x0 - - ;
2014-09-30 04:18:43 +00:00
setrect ( x0 , y0 , dx , dy ) ;
shp [ z ] . x = x0 ; shp [ z ] . y = y0 ; //Overwrite size with top-left location
}
2014-12-26 17:29:48 +00:00
gvox - > quad = ( voxrect_t * ) Xmalloc ( gvox - > qcnt * sizeof ( voxrect_t ) ) ;
gvox - > mytex = ( int32_t * ) Xmalloc ( gvox - > mytexx * gvox - > mytexy * sizeof ( int32_t ) ) ;
2014-09-30 04:18:43 +00:00
}
}
2014-12-26 17:29:48 +00:00
2019-06-25 11:29:08 +00:00
Xfree ( shp ) ; Xfree ( zbit ) ; Xfree ( bx0 ) ;
2014-12-26 17:29:48 +00:00
2016-06-21 00:34:41 +00:00
return gvox ;
2014-09-30 04:18:43 +00:00
}
2014-12-26 17:29:48 +00:00
static void alloc_vcolhashead ( void )
{
vcolhashead = ( int32_t * ) Xmalloc ( ( vcolhashsizm1 + 1 ) * sizeof ( int32_t ) ) ;
memset ( vcolhashead , - 1 , ( vcolhashsizm1 + 1 ) * sizeof ( int32_t ) ) ;
}
static void alloc_vbit ( void )
{
yzsiz = voxsiz . y * voxsiz . z ;
int32_t i = ( ( voxsiz . x * yzsiz + 31 ) > > 3 ) + 1 ;
vbit = ( int32_t * ) Xmalloc ( i ) ;
memset ( vbit , 0 , i ) ;
}
2019-10-20 22:13:17 +00:00
static void read_pal ( FileReader & fil , int32_t pal [ 256 ] )
2014-12-26 17:29:48 +00:00
{
2019-10-20 22:13:17 +00:00
fil . Seek ( - 768 , FileReader : : SeekEnd ) ;
2014-12-26 17:29:48 +00:00
2016-08-27 01:41:21 +00:00
for ( bssize_t i = 0 ; i < 256 ; i + + )
2014-12-26 17:29:48 +00:00
{
char c [ 3 ] ;
2019-10-20 22:13:17 +00:00
fil . Read ( c , 3 ) ;
2014-12-26 17:29:48 +00:00
//#if B_BIG_ENDIAN != 0
pal [ i ] = B_LITTLE32 ( ( c [ 0 ] < < 18 ) + ( c [ 1 ] < < 10 ) + ( c [ 2 ] < < 2 ) + ( i < < 24 ) ) ;
//#endif
}
}
2014-09-30 04:18:43 +00:00
static int32_t loadvox ( const char * filnam )
{
2020-04-11 21:54:33 +00:00
auto fil = fileSystem . OpenFileReader ( filnam ) ;
2019-10-20 22:13:17 +00:00
if ( ! fil . isOpen ( ) )
return - 1 ;
2014-09-30 04:18:43 +00:00
2019-10-20 22:13:17 +00:00
fil . Read ( & voxsiz , sizeof ( vec3_t ) ) ;
2014-09-30 04:18:43 +00:00
# if B_BIG_ENDIAN != 0
voxsiz . x = B_LITTLE32 ( voxsiz . x ) ;
voxsiz . y = B_LITTLE32 ( voxsiz . y ) ;
voxsiz . z = B_LITTLE32 ( voxsiz . z ) ;
# endif
2014-12-26 17:29:48 +00:00
voxpiv . x = ( float ) voxsiz . x * .5f ;
voxpiv . y = ( float ) voxsiz . y * .5f ;
voxpiv . z = ( float ) voxsiz . z * .5f ;
2014-09-30 04:18:43 +00:00
2014-12-26 17:29:48 +00:00
int32_t pal [ 256 ] ;
read_pal ( fil , pal ) ;
2014-09-30 04:18:43 +00:00
pal [ 255 ] = - 1 ;
vcolhashsizm1 = 8192 - 1 ;
2014-12-26 17:29:48 +00:00
alloc_vcolhashead ( ) ;
alloc_vbit ( ) ;
2014-09-30 04:18:43 +00:00
2014-12-26 17:29:48 +00:00
char * const tbuf = ( char * ) Xmalloc ( voxsiz . z * sizeof ( uint8_t ) ) ;
2014-09-30 04:18:43 +00:00
2019-10-20 22:13:17 +00:00
fil . Seek ( 12 , FileReader : : SeekSet ) ;
2016-08-27 01:41:21 +00:00
for ( bssize_t x = 0 ; x < voxsiz . x ; x + + )
for ( bssize_t y = 0 , j = x * yzsiz ; y < voxsiz . y ; y + + , j + = voxsiz . z )
2014-09-30 04:18:43 +00:00
{
2019-10-20 22:13:17 +00:00
fil . Read ( tbuf , voxsiz . z ) ;
2014-12-26 17:29:48 +00:00
2016-08-27 01:41:21 +00:00
for ( bssize_t z = voxsiz . z - 1 ; z > = 0 ; z - - )
2020-05-28 06:31:08 +00:00
if ( tbuf [ z ] ! = 255 )
2014-12-26 17:29:48 +00:00
{
const int32_t i = j + z ;
vbit [ i > > 5 ] | = ( 1 < < SHIFTMOD32 ( i ) ) ;
}
2014-09-30 04:18:43 +00:00
}
2019-10-20 22:13:17 +00:00
fil . Seek ( 12 , FileReader : : SeekSet ) ;
2016-08-27 01:41:21 +00:00
for ( bssize_t x = 0 ; x < voxsiz . x ; x + + )
for ( bssize_t y = 0 , j = x * yzsiz ; y < voxsiz . y ; y + + , j + = voxsiz . z )
2014-09-30 04:18:43 +00:00
{
2019-10-20 22:13:17 +00:00
fil . Read ( tbuf , voxsiz . z ) ;
2014-12-26 17:29:48 +00:00
2016-08-27 01:41:21 +00:00
for ( bssize_t z = 0 ; z < voxsiz . z ; z + + )
2014-09-30 04:18:43 +00:00
{
2020-04-11 22:18:12 +00:00
if ( tbuf [ z ] = = TRANSPARENT_INDEX )
2014-12-26 17:29:48 +00:00
continue ;
if ( ! x | | ! y | | ! z | | x = = voxsiz . x - 1 | | y = = voxsiz . y - 1 | | z = = voxsiz . z - 1 )
{
putvox ( x , y , z , pal [ tbuf [ z ] ] ) ;
continue ;
}
const int32_t k = j + z ;
if ( isair ( k - yzsiz ) | | isair ( k + yzsiz ) | |
isair ( k - voxsiz . z ) | | isair ( k + voxsiz . z ) | |
isair ( k - 1 ) | | isair ( k + 1 ) )
{
putvox ( x , y , z , pal [ tbuf [ z ] ] ) ;
continue ;
}
2014-09-30 04:18:43 +00:00
}
}
2019-06-25 11:29:08 +00:00
Xfree ( tbuf ) ;
2014-12-26 17:29:48 +00:00
return 0 ;
2014-09-30 04:18:43 +00:00
}
static int32_t loadkvx ( const char * filnam )
{
2014-12-26 17:29:48 +00:00
int32_t i , mip1leng ;
2020-04-11 21:54:33 +00:00
auto fil = fileSystem . OpenFileReader ( filnam ) ;
2019-10-20 22:13:17 +00:00
if ( ! fil . isOpen ( ) )
return - 1 ;
2014-09-30 04:18:43 +00:00
2019-10-20 22:13:17 +00:00
fil . Read ( & mip1leng , 4 ) ; mip1leng = B_LITTLE32 ( mip1leng ) ;
fil . Read ( & voxsiz , sizeof ( vec3_t ) ) ;
2014-09-30 04:18:43 +00:00
# if B_BIG_ENDIAN != 0
voxsiz . x = B_LITTLE32 ( voxsiz . x ) ;
voxsiz . y = B_LITTLE32 ( voxsiz . y ) ;
voxsiz . z = B_LITTLE32 ( voxsiz . z ) ;
# endif
2019-10-20 22:13:17 +00:00
fil . Read ( & i , 4 ) ; voxpiv . x = ( float ) B_LITTLE32 ( i ) * ( 1.f / 256.f ) ;
fil . Read ( & i , 4 ) ; voxpiv . y = ( float ) B_LITTLE32 ( i ) * ( 1.f / 256.f ) ;
fil . Read ( & i , 4 ) ; voxpiv . z = ( float ) B_LITTLE32 ( i ) * ( 1.f / 256.f ) ;
fil . Seek ( ( voxsiz . x + 1 ) < < 2 , FileReader : : SeekCur ) ;
2014-09-30 04:18:43 +00:00
2014-12-26 17:29:48 +00:00
const int32_t ysizp1 = voxsiz . y + 1 ;
2014-09-30 04:18:43 +00:00
i = voxsiz . x * ysizp1 * sizeof ( int16_t ) ;
2014-12-26 17:29:48 +00:00
uint16_t * xyoffs = ( uint16_t * ) Xmalloc ( i ) ;
2019-10-20 22:13:17 +00:00
fil . Read ( xyoffs , i ) ;
2014-09-30 04:18:43 +00:00
2014-12-26 17:29:48 +00:00
for ( i = i / sizeof ( int16_t ) - 1 ; i > = 0 ; i - - )
xyoffs [ i ] = B_LITTLE16 ( xyoffs [ i ] ) ;
int32_t pal [ 256 ] ;
read_pal ( fil , pal ) ;
alloc_vbit ( ) ;
2014-09-30 04:18:43 +00:00
for ( vcolhashsizm1 = 4096 ; vcolhashsizm1 < ( mip1leng > > 1 ) ; vcolhashsizm1 < < = 1 )
{
/* do nothing */
}
vcolhashsizm1 - - ; //approx to numvoxs!
2014-12-26 17:29:48 +00:00
alloc_vcolhashead ( ) ;
2014-09-30 04:18:43 +00:00
2019-10-20 22:13:17 +00:00
fil . Seek ( 28 + ( ( voxsiz . x + 1 ) < < 2 ) + ( ( ysizp1 * voxsiz . x ) < < 1 ) , FileReader : : SeekSet ) ;
2014-09-30 04:18:43 +00:00
2019-10-20 22:13:17 +00:00
i = fil . GetLength ( ) - fil . Tell ( ) ;
2014-12-26 17:29:48 +00:00
char * const tbuf = ( char * ) Xmalloc ( i ) ;
2014-09-30 04:18:43 +00:00
2019-10-20 22:13:17 +00:00
fil . Read ( tbuf , i ) ;
2014-12-26 17:29:48 +00:00
char * cptr = tbuf ;
2016-08-27 01:41:21 +00:00
for ( bssize_t x = 0 ; x < voxsiz . x ; x + + ) //Set surface voxels to 1 else 0
for ( bssize_t y = 0 , j = x * yzsiz ; y < voxsiz . y ; y + + , j + = voxsiz . z )
2014-09-30 04:18:43 +00:00
{
2014-12-26 17:29:48 +00:00
i = xyoffs [ x * ysizp1 + y + 1 ] - xyoffs [ x * ysizp1 + y ] ;
if ( ! i )
continue ;
int32_t z1 = 0 ;
while ( i )
{
const int32_t z0 = cptr [ 0 ] ;
const int32_t k = cptr [ 1 ] ;
cptr + = 3 ;
if ( ! ( cptr [ - 1 ] & 16 ) )
setzrange1 ( vbit , j + z1 , j + z0 ) ;
i - = k + 3 ;
z1 = z0 + k ;
setzrange1 ( vbit , j + z0 , j + z1 ) ; // PK: oob in AMC TC dev if vbit alloc'd w/o +1
2016-08-27 01:41:21 +00:00
for ( bssize_t z = z0 ; z < z1 ; z + + )
2014-12-26 17:29:48 +00:00
putvox ( x , y , z , pal [ * cptr + + ] ) ;
}
2014-09-30 04:18:43 +00:00
}
2019-06-25 11:29:08 +00:00
Xfree ( tbuf ) ;
Xfree ( xyoffs ) ;
2014-12-26 17:29:48 +00:00
return 0 ;
2014-09-30 04:18:43 +00:00
}
static int32_t loadkv6 ( const char * filnam )
{
2014-12-26 17:29:48 +00:00
int32_t i ;
2020-04-11 21:54:33 +00:00
auto fil = fileSystem . OpenFileReader ( filnam ) ;
2019-10-20 22:13:17 +00:00
if ( ! fil . isOpen ( ) )
2014-12-26 17:29:48 +00:00
return - 1 ;
2019-10-20 22:13:17 +00:00
fil . Read ( & i , 4 ) ;
2014-12-26 17:29:48 +00:00
if ( B_LITTLE32 ( i ) ! = 0x6c78764b )
{
2016-06-21 00:34:41 +00:00
return - 1 ;
2014-12-26 17:29:48 +00:00
} //Kvxl
2014-09-30 04:18:43 +00:00
2019-10-20 22:13:17 +00:00
fil . Read ( & voxsiz , sizeof ( vec3_t ) ) ;
2014-09-30 04:18:43 +00:00
# if B_BIG_ENDIAN != 0
voxsiz . x = B_LITTLE32 ( voxsiz . x ) ;
voxsiz . y = B_LITTLE32 ( voxsiz . y ) ;
voxsiz . z = B_LITTLE32 ( voxsiz . z ) ;
# endif
2019-10-20 22:13:17 +00:00
fil . Read ( & i , 4 ) ; voxpiv . x = ( float ) B_LITTLE32 ( i ) ;
fil . Read ( & i , 4 ) ; voxpiv . y = ( float ) B_LITTLE32 ( i ) ;
fil . Read ( & i , 4 ) ; voxpiv . z = ( float ) B_LITTLE32 ( i ) ;
2014-12-26 17:29:48 +00:00
int32_t numvoxs ;
2019-10-20 22:13:17 +00:00
fil . Read ( & numvoxs , 4 ) ; numvoxs = B_LITTLE32 ( numvoxs ) ;
2014-09-30 04:18:43 +00:00
2014-12-26 17:29:48 +00:00
uint16_t * const ylen = ( uint16_t * ) Xmalloc ( voxsiz . x * voxsiz . y * sizeof ( int16_t ) ) ;
2014-09-30 04:18:43 +00:00
2019-10-20 22:13:17 +00:00
fil . Seek ( 32 + ( numvoxs < < 3 ) + ( voxsiz . x < < 2 ) , FileReader : : SeekSet ) ;
fil . Read ( ylen , voxsiz . x * voxsiz . y * sizeof ( int16_t ) ) ;
2014-12-26 17:29:48 +00:00
for ( i = voxsiz . x * voxsiz . y - 1 ; i > = 0 ; i - - )
ylen [ i ] = B_LITTLE16 ( ylen [ i ] ) ;
2019-10-20 22:13:17 +00:00
fil . Seek ( 32 , FileReader : : SeekSet ) ;
2014-09-30 04:18:43 +00:00
2014-12-26 17:29:48 +00:00
alloc_vbit ( ) ;
2014-09-30 04:18:43 +00:00
for ( vcolhashsizm1 = 4096 ; vcolhashsizm1 < numvoxs ; vcolhashsizm1 < < = 1 )
{
/* do nothing */
}
vcolhashsizm1 - - ;
2014-12-26 17:29:48 +00:00
alloc_vcolhashead ( ) ;
2014-09-30 04:18:43 +00:00
2016-08-27 01:41:21 +00:00
for ( bssize_t x = 0 ; x < voxsiz . x ; x + + )
for ( bssize_t y = 0 , j = x * yzsiz ; y < voxsiz . y ; y + + , j + = voxsiz . z )
2014-09-30 04:18:43 +00:00
{
2014-12-26 17:29:48 +00:00
int32_t z1 = voxsiz . z ;
for ( i = ylen [ x * voxsiz . y + y ] ; i > 0 ; i - - )
{
char c [ 8 ] ;
2019-10-20 22:13:17 +00:00
fil . Read ( c , 8 ) ; //b,g,r,a,z_lo,z_hi,vis,dir
2014-12-26 17:29:48 +00:00
2015-05-03 07:03:48 +00:00
const int32_t z0 = B_LITTLE16 ( B_UNBUF16 ( & c [ 4 ] ) ) ;
2014-12-26 17:29:48 +00:00
if ( ! ( c [ 6 ] & 16 ) )
setzrange1 ( vbit , j + z1 , j + z0 ) ;
vbit [ ( j + z0 ) > > 5 ] | = ( 1 < < SHIFTMOD32 ( j + z0 ) ) ;
2015-05-03 07:03:48 +00:00
putvox ( x , y , z0 , B_LITTLE32 ( B_UNBUF32 ( & c [ 0 ] ) ) & 0xffffff ) ;
2014-12-26 17:29:48 +00:00
z1 = z0 + 1 ;
}
2014-09-30 04:18:43 +00:00
}
2014-12-26 17:29:48 +00:00
2019-06-25 11:29:08 +00:00
Xfree ( ylen ) ;
2014-12-26 17:29:48 +00:00
return 0 ;
2014-09-30 04:18:43 +00:00
}
void voxfree ( voxmodel_t * m )
{
2014-12-26 17:29:48 +00:00
if ( ! m )
return ;
2014-09-30 04:18:43 +00:00
DO_FREE_AND_NULL ( m - > mytex ) ;
DO_FREE_AND_NULL ( m - > quad ) ;
2020-02-09 19:14:26 +00:00
if ( m - > texIds )
2019-12-25 07:57:58 +00:00
{
2020-05-28 23:03:01 +00:00
TMap < int , OpenGLRenderer : : FHardwareTexture * > : : Iterator it ( * m - > texIds ) ;
TMap < int , OpenGLRenderer : : FHardwareTexture * > : : Pair * pair ;
2020-02-09 19:14:26 +00:00
while ( it . NextPair ( pair ) )
{
if ( pair - > Value ) delete pair - > Value ;
}
delete m - > texIds ;
2019-12-25 07:57:58 +00:00
}
2014-12-26 17:29:48 +00:00
2019-06-25 11:29:08 +00:00
Xfree ( m ) ;
2014-09-30 04:18:43 +00:00
}
voxmodel_t * voxload ( const char * filnam )
{
2014-12-26 17:29:48 +00:00
int32_t is8bit , ret ;
const int32_t i = Bstrlen ( filnam ) - 4 ;
if ( i < 0 )
return NULL ;
2014-09-30 04:18:43 +00:00
if ( ! Bstrcasecmp ( & filnam [ i ] , " .vox " ) ) { ret = loadvox ( filnam ) ; is8bit = 1 ; }
else if ( ! Bstrcasecmp ( & filnam [ i ] , " .kvx " ) ) { ret = loadkvx ( filnam ) ; is8bit = 1 ; }
else if ( ! Bstrcasecmp ( & filnam [ i ] , " .kv6 " ) ) { ret = loadkv6 ( filnam ) ; is8bit = 0 ; }
//else if (!Bstrcasecmp(&filnam[i],".vxl")) { ret = loadvxl(filnam); is8bit = 0; }
else return NULL ;
2014-12-26 17:29:48 +00:00
voxmodel_t * const vm = ( ret > = 0 ) ? vox2poly ( ) : NULL ;
2014-09-30 04:18:43 +00:00
if ( vm )
{
vm - > mdnum = 1 ; //VOXel model id
vm - > scale = vm - > bscale = 1.f ;
vm - > siz . x = voxsiz . x ; vm - > siz . y = voxsiz . y ; vm - > siz . z = voxsiz . z ;
vm - > piv . x = voxpiv . x ; vm - > piv . y = voxpiv . y ; vm - > piv . z = voxpiv . z ;
vm - > is8bit = is8bit ;
2019-10-18 17:06:57 +00:00
vm - > texture = nullptr ;
2014-09-30 04:18:43 +00:00
}
2014-12-26 17:29:48 +00:00
2014-09-30 04:18:43 +00:00
DO_FREE_AND_NULL ( shcntmal ) ;
DO_FREE_AND_NULL ( vbit ) ;
DO_FREE_AND_NULL ( vcol ) ;
vnum = vmax = 0 ;
DO_FREE_AND_NULL ( vcolhashead ) ;
return vm ;
}
2019-09-19 20:02:45 +00:00
voxmodel_t * loadkvxfrombuf ( const char * kvxbuffer , int32_t length )
{
int32_t i , mip1leng ;
if ( ! kvxbuffer )
return NULL ;
char * buffer = ( char * ) Xmalloc ( length ) ;
if ( ! buffer )
return NULL ;
Bmemcpy ( buffer , kvxbuffer , length ) ;
int32_t * longptr = ( int32_t * ) buffer ;
mip1leng = * longptr + + ; mip1leng = B_LITTLE32 ( mip1leng ) ;
if ( mip1leng > length - 4 )
{
// Invalid KVX file
2019-12-26 13:43:44 +00:00
Xfree ( buffer ) ;
2019-09-19 20:02:45 +00:00
return NULL ;
}
memcpy ( & voxsiz , longptr , sizeof ( vec3_t ) ) ;
longptr + = 3 ;
# if B_BIG_ENDIAN != 0
voxsiz . x = B_LITTLE32 ( voxsiz . x ) ;
voxsiz . y = B_LITTLE32 ( voxsiz . y ) ;
voxsiz . z = B_LITTLE32 ( voxsiz . z ) ;
# endif
i = * longptr + + ; voxpiv . x = ( float ) B_LITTLE32 ( i ) * ( 1.f / 256.f ) ;
i = * longptr + + ; voxpiv . y = ( float ) B_LITTLE32 ( i ) * ( 1.f / 256.f ) ;
i = * longptr + + ; voxpiv . z = ( float ) B_LITTLE32 ( i ) * ( 1.f / 256.f ) ;
longptr + = voxsiz . x + 1 ;
const int32_t ysizp1 = voxsiz . y + 1 ;
i = voxsiz . x * ysizp1 * sizeof ( int16_t ) ;
uint16_t * xyoffs = ( uint16_t * ) longptr ;
for ( i = i / sizeof ( int16_t ) - 1 ; i > = 0 ; i - - )
xyoffs [ i ] = B_LITTLE16 ( xyoffs [ i ] ) ;
const char * paloff = buffer + length - 768 ;
int32_t pal [ 256 ] ;
for ( bssize_t i = 0 ; i < 256 ; i + + )
{
const char * c = & paloff [ i * 3 ] ;
//#if B_BIG_ENDIAN != 0
pal [ i ] = B_LITTLE32 ( ( c [ 0 ] < < 18 ) + ( c [ 1 ] < < 10 ) + ( c [ 2 ] < < 2 ) + ( i < < 24 ) ) ;
//#endif
}
alloc_vbit ( ) ;
for ( vcolhashsizm1 = 4096 ; vcolhashsizm1 < ( mip1leng > > 1 ) ; vcolhashsizm1 < < = 1 )
{
/* do nothing */
}
vcolhashsizm1 - - ; //approx to numvoxs!
alloc_vcolhashead ( ) ;
const char * cptr = buffer + 28 + ( ( voxsiz . x + 1 ) < < 2 ) + ( ( ysizp1 * voxsiz . x ) < < 1 ) ;
for ( bssize_t x = 0 ; x < voxsiz . x ; x + + ) //Set surface voxels to 1 else 0
for ( bssize_t y = 0 , j = x * yzsiz ; y < voxsiz . y ; y + + , j + = voxsiz . z )
{
i = xyoffs [ x * ysizp1 + y + 1 ] - xyoffs [ x * ysizp1 + y ] ;
if ( ! i )
continue ;
int32_t z1 = 0 ;
while ( i )
{
const int32_t z0 = cptr [ 0 ] ;
const int32_t k = cptr [ 1 ] ;
cptr + = 3 ;
if ( ! ( cptr [ - 1 ] & 16 ) )
setzrange1 ( vbit , j + z1 , j + z0 ) ;
i - = k + 3 ;
z1 = z0 + k ;
setzrange1 ( vbit , j + z0 , j + z1 ) ; // PK: oob in AMC TC dev if vbit alloc'd w/o +1
for ( bssize_t z = z0 ; z < z1 ; z + + )
putvox ( x , y , z , pal [ * cptr + + ] ) ;
}
}
voxmodel_t * const vm = vox2poly ( ) ;
if ( vm )
{
vm - > mdnum = 1 ; //VOXel model id
vm - > scale = vm - > bscale = 1.f ;
vm - > siz . x = voxsiz . x ; vm - > siz . y = voxsiz . y ; vm - > siz . z = voxsiz . z ;
vm - > piv . x = voxpiv . x ; vm - > piv . y = voxpiv . y ; vm - > piv . z = voxpiv . z ;
vm - > is8bit = 1 ;
}
DO_FREE_AND_NULL ( shcntmal ) ;
DO_FREE_AND_NULL ( vbit ) ;
DO_FREE_AND_NULL ( vcol ) ;
vnum = vmax = 0 ;
DO_FREE_AND_NULL ( vcolhashead ) ;
2019-12-26 13:43:44 +00:00
Xfree ( buffer ) ;
2019-09-19 20:02:45 +00:00
return vm ;
}
2019-09-16 19:08:42 +00:00
2014-09-30 04:18:43 +00:00
//Draw voxel model as perfect cubes
2019-09-16 19:08:42 +00:00
// Note: This is a hopeless mess that totally forfeits any chance of using a vertex buffer with its messy coordinate adjustments. :(
2019-04-18 17:25:24 +00:00
int32_t polymost_voxdraw ( voxmodel_t * m , tspriteptr_t const tspr )
2014-09-30 04:18:43 +00:00
{
2014-12-26 17:29:48 +00:00
// float clut[6] = {1.02,1.02,0.94,1.06,0.98,0.98};
2019-07-13 03:20:17 +00:00
float f , g , k0 , zoff ;
2014-09-30 04:18:43 +00:00
2014-12-26 17:29:48 +00:00
if ( ( intptr_t ) m = = ( intptr_t ) ( - 1 ) ) // hackhackhack
return 0 ;
if ( ( tspr - > cstat & 48 ) = = 32 )
2014-09-30 04:18:43 +00:00
return 0 ;
2019-05-25 14:59:09 +00:00
polymost_outputGLDebugMessage ( 3 , " polymost_voxdraw(m:%p, tspr:%p) " , m , tspr ) ;
2014-09-30 04:18:43 +00:00
//updateanimation((md2model *)m,tspr);
2014-12-26 17:29:48 +00:00
vec3f_t m0 = { m - > scale , m - > scale , m - > scale } ;
2019-06-25 11:30:27 +00:00
vec3f_t a0 = { 0 , 0 , m - > zadd * m - > scale } ;
2014-09-30 04:18:43 +00:00
2014-12-06 21:05:36 +00:00
k0 = m - > bscale / 64.f ;
2014-09-30 04:18:43 +00:00
f = ( float ) tspr - > xrepeat * ( 256.f / 320.f ) * k0 ;
if ( ( sprite [ tspr - > owner ] . cstat & 48 ) = = 16 )
2019-06-25 11:30:27 +00:00
{
2014-09-30 04:18:43 +00:00
f * = 1.25f ;
2019-09-30 06:35:33 +00:00
a0 . y - = tspr - > xoffset * sintable [ ( spriteext [ tspr - > owner ] . angoff + 512 ) & 2047 ] * ( 1.f / ( 64.f * 16384.f ) ) ;
a0 . x + = tspr - > xoffset * sintable [ ( spriteext [ tspr - > owner ] . angoff ) & 2047 ] * ( 1.f / ( 64.f * 16384.f ) ) ;
2019-06-25 11:30:27 +00:00
}
if ( globalorientation & 8 ) { m0 . z = - m0 . z ; a0 . z = - a0 . z ; } //y-flipping
if ( globalorientation & 4 ) { m0 . x = - m0 . x ; a0 . x = - a0 . x ; a0 . y = - a0 . y ; } //x-flipping
2014-09-30 04:18:43 +00:00
m0 . x * = f ; a0 . x * = f ; f = - f ;
m0 . y * = f ; a0 . y * = f ;
f = ( float ) tspr - > yrepeat * k0 ;
m0 . z * = f ; a0 . z * = f ;
2019-12-31 19:35:28 +00:00
k0 = ( float ) ( tspr - > z + spriteext [ tspr - > owner ] . position_offset . z ) ;
2019-07-09 05:42:15 +00:00
f = ( ( globalorientation & 8 ) & & ( sprite [ tspr - > owner ] . cstat & 48 ) ! = 0 ) ? - 4.f : 4.f ;
2019-06-25 11:30:27 +00:00
k0 - = ( tspr - > yoffset * tspr - > yrepeat ) * f * m - > bscale ;
2019-07-13 03:20:17 +00:00
zoff = m - > siz . z * .5f ;
if ( ! ( tspr - > cstat & 128 ) )
zoff + = m - > piv . z ;
else if ( ( tspr - > cstat & 48 ) ! = 48 )
{
zoff + = m - > piv . z ;
zoff - = m - > siz . z * .5f ;
}
2020-03-12 00:58:45 +00:00
if ( globalorientation & 8 ) zoff = m - > siz . z - zoff ;
2014-09-30 04:18:43 +00:00
2014-12-26 17:29:48 +00:00
f = ( 65536.f * 512.f ) / ( ( float ) xdimen * viewingrange ) ;
g = 32.f / ( ( float ) xdimen * gxyaspect ) ;
2019-12-26 06:28:03 +00:00
int const shadowHack = ! ! ( tspr - > clipdist & TSPR_FLAGS_MDHACK ) ;
2019-07-06 19:04:54 +00:00
2019-12-31 19:35:28 +00:00
m0 . y * = f ; a0 . y = ( ( ( float ) ( tspr - > x + spriteext [ tspr - > owner ] . position_offset . x - globalposx ) ) * ( 1.f / 1024.f ) + a0 . y ) * f ;
m0 . x * = - f ; a0 . x = ( ( ( float ) ( tspr - > y + spriteext [ tspr - > owner ] . position_offset . y - globalposy ) ) * - ( 1.f / 1024.f ) + a0 . x ) * - f ;
2019-07-06 19:04:54 +00:00
m0 . z * = g ; a0 . z = ( ( ( float ) ( k0 - globalposz - shadowHack ) ) * - ( 1.f / 16384.f ) + a0 . z ) * g ;
2014-09-30 04:18:43 +00:00
2014-12-26 17:29:48 +00:00
float mat [ 16 ] ;
2019-09-30 06:35:33 +00:00
md3_vox_calcmat_common ( tspr , & a0 , f , mat ) ;
2014-09-30 04:18:43 +00:00
//Mirrors
2014-12-26 17:29:48 +00:00
if ( grhalfxdown10x < 0 )
{
mat [ 0 ] = - mat [ 0 ] ;
mat [ 4 ] = - mat [ 4 ] ;
mat [ 8 ] = - mat [ 8 ] ;
mat [ 12 ] = - mat [ 12 ] ;
}
2014-09-30 04:18:43 +00:00
2019-07-06 19:04:54 +00:00
if ( shadowHack )
2014-09-30 04:18:43 +00:00
{
2019-10-04 16:44:16 +00:00
GLInterface . SetDepthFunc ( Depth_LessEqual ) ;
}
2014-12-26 17:29:48 +00:00
2015-02-11 05:22:48 +00:00
2019-10-04 19:13:04 +00:00
int winding = ( ( grhalfxdown10x > = 0 ) ^ ( ( globalorientation & 8 ) ! = 0 ) ^ ( ( globalorientation & 4 ) ! = 0 ) ) ? Winding_CW : Winding_CCW ;
GLInterface . SetCull ( Cull_Back , winding ) ;
2014-09-30 04:18:43 +00:00
2014-12-26 17:29:48 +00:00
float pc [ 4 ] ;
2020-01-22 20:34:18 +00:00
pc [ 0 ] = pc [ 1 ] = pc [ 2 ] = 1.f ;
2019-10-17 18:29:58 +00:00
2020-05-29 18:15:42 +00:00
auto & h = lookups . tables [ globalpal ] ;
if ( h . tintFlags & ( TINTF_USEONART | TINTF_ALWAYSUSEART ) )
GLInterface . SetTinting ( h . tintFlags , h . tintColor , h . tintColor ) ;
2020-01-11 21:39:53 +00:00
else
GLInterface . SetTinting ( - 1 , 0xffffff , 0xffffff ) ;
2019-07-06 19:04:54 +00:00
if ( ! shadowHack )
{
pc [ 3 ] = ( tspr - > cstat & 2 ) ? glblend [ tspr - > blend ] . def [ ! ! ( tspr - > cstat & 512 ) ] . alpha : 1.0f ;
pc [ 3 ] * = 1.0f - spriteext [ tspr - > owner ] . alpha ;
2014-12-26 17:29:48 +00:00
2020-05-23 12:40:54 +00:00
SetRenderStyleFromBlend ( ! ! ( tspr - > cstat & 2 ) , tspr - > blend , ! ! ( tspr - > cstat & 512 ) ) ;
2016-10-09 07:55:23 +00:00
2019-07-06 19:04:54 +00:00
if ( ! ( tspr - > cstat & 2 ) | | spriteext [ tspr - > owner ] . alpha > 0.f | | pc [ 3 ] < 1.0f )
2019-10-04 16:12:03 +00:00
GLInterface . EnableBlend ( true ) ; // else GLInterface.EnableBlend(false);
2019-07-06 19:04:54 +00:00
}
else pc [ 3 ] = 1.f ;
2019-12-19 16:51:33 +00:00
GLInterface . SetShade ( std : : max ( 0 , globalshade ) , numshades ) ;
2014-09-30 04:18:43 +00:00
//------------
//transform to Build coords
2014-12-26 17:29:48 +00:00
float omat [ 16 ] ;
2014-09-30 04:18:43 +00:00
Bmemcpy ( omat , mat , sizeof ( omat ) ) ;
2014-12-26 17:29:48 +00:00
2014-09-30 04:18:43 +00:00
f = 1.f / 64.f ;
g = m0 . x * f ; mat [ 0 ] * = g ; mat [ 1 ] * = g ; mat [ 2 ] * = g ;
g = m0 . y * f ; mat [ 4 ] = omat [ 8 ] * g ; mat [ 5 ] = omat [ 9 ] * g ; mat [ 6 ] = omat [ 10 ] * g ;
g = - m0 . z * f ; mat [ 8 ] = omat [ 4 ] * g ; mat [ 9 ] = omat [ 5 ] * g ; mat [ 10 ] = omat [ 6 ] * g ;
2014-12-26 17:29:48 +00:00
//
2019-07-13 03:20:17 +00:00
mat [ 12 ] - = ( m - > piv . x * mat [ 0 ] + m - > piv . y * mat [ 4 ] + zoff * mat [ 8 ] ) ;
mat [ 13 ] - = ( m - > piv . x * mat [ 1 ] + m - > piv . y * mat [ 5 ] + zoff * mat [ 9 ] ) ;
mat [ 14 ] - = ( m - > piv . x * mat [ 2 ] + m - > piv . y * mat [ 6 ] + zoff * mat [ 10 ] ) ;
2014-12-26 17:29:48 +00:00
//
2019-10-04 16:12:03 +00:00
//Let OpenGL (and perhaps hardware :) handle the matrix rotation
2014-09-30 04:18:43 +00:00
mat [ 3 ] = mat [ 7 ] = mat [ 11 ] = 0.f ; mat [ 15 ] = 1.f ;
2020-01-19 15:06:31 +00:00
int matrixindex = GLInterface . SetMatrix ( Matrix_Model , mat ) ;
2014-09-30 04:18:43 +00:00
2014-12-26 17:29:48 +00:00
const float ru = 1.f / ( ( float ) m - > mytexx ) ;
const float rv = 1.f / ( ( float ) m - > mytexy ) ;
2014-09-30 04:18:43 +00:00
# if (VOXBORDWIDTH == 0)
uhack [ 0 ] = ru * .125 ; uhack [ 1 ] = - uhack [ 0 ] ;
vhack [ 0 ] = rv * .125 ; vhack [ 1 ] = - vhack [ 0 ] ;
# endif
2014-12-26 17:29:48 +00:00
const float phack [ 2 ] = { 0 , 1.f / 256.f } ;
2019-10-05 10:28:08 +00:00
int prevClamp = GLInterface . GetClamp ( ) ;
GLInterface . SetClamp ( 0 ) ;
2019-10-18 20:25:47 +00:00
# if 1
2020-05-24 22:31:05 +00:00
int palId = TRANSLATION ( Translation_Remap + curbasepal , globalpal ) ;
auto palette = GPalette . TranslationToTable ( palId ) ;
2020-05-28 23:03:01 +00:00
if ( ! m - > texIds ) m - > texIds = new TMap < int , OpenGLRenderer : : FHardwareTexture * > ;
2020-02-09 19:14:26 +00:00
auto pTex = m - > texIds - > CheckKey ( palId ) ;
2020-05-28 23:03:01 +00:00
OpenGLRenderer : : FHardwareTexture * htex ;
2020-02-09 19:14:26 +00:00
if ( ! pTex )
{
2020-05-24 22:31:05 +00:00
htex = gloadtex ( m - > mytex , m - > mytexx , m - > mytexy , m - > is8bit , palette - > Palette ) ;
2020-02-09 19:14:26 +00:00
m - > texIds - > Insert ( palId , htex ) ;
}
else
{
htex = * pTex ;
}
2019-09-18 18:44:21 +00:00
2020-02-10 21:05:53 +00:00
GLInterface . SetPalswap ( globalpal ) ;
2020-02-09 19:14:26 +00:00
GLInterface . BindTexture ( 0 , htex , - 1 ) ;
2019-11-11 22:54:09 +00:00
GLInterface . UseBrightmaps ( false ) ;
GLInterface . UseGlowMapping ( false ) ;
GLInterface . UseDetailMapping ( false ) ;
2019-10-18 17:06:57 +00:00
# endif
2014-12-26 17:29:48 +00:00
2020-01-18 21:41:08 +00:00
auto data = screen - > mVertexData - > AllocVertices ( m - > qcnt * 6 ) ;
auto vt = data . first ;
2014-09-30 04:18:43 +00:00
2020-01-18 21:41:08 +00:00
int qstart = data . second ;
2019-09-16 19:08:42 +00:00
int qdone = 0 ;
2016-08-27 01:41:21 +00:00
for ( bssize_t i = 0 , fi = 0 ; i < m - > qcnt ; i + + )
2014-09-30 04:18:43 +00:00
{
2014-12-26 17:29:48 +00:00
if ( i = = m - > qfacind [ fi ] )
{
f = 1 /*clut[fi++]*/ ;
2019-09-16 19:08:42 +00:00
if ( qdone > 0 )
{
2020-01-18 21:41:08 +00:00
GLInterface . Draw ( DT_TRIANGLES , qstart , qdone * 6 ) ;
2020-01-03 17:09:05 +00:00
qstart + = qdone * 6 ;
2019-09-16 19:08:42 +00:00
qdone = 0 ;
}
2019-10-04 16:25:18 +00:00
GLInterface . SetColor ( pc [ 0 ] * f , pc [ 1 ] * f , pc [ 2 ] * f , pc [ 3 ] * f ) ;
2014-12-26 17:29:48 +00:00
}
const vert_t * const vptr = & m - > quad [ i ] . v [ 0 ] ;
2014-09-30 04:18:43 +00:00
2014-12-26 17:29:48 +00:00
const int32_t xx = vptr [ 0 ] . x + vptr [ 2 ] . x ;
const int32_t yy = vptr [ 0 ] . y + vptr [ 2 ] . y ;
const int32_t zz = vptr [ 0 ] . z + vptr [ 2 ] . z ;
2014-09-30 04:18:43 +00:00
2020-01-03 17:09:05 +00:00
for ( bssize_t jj = 0 ; jj < 6 ; jj + + , vt + + )
2014-09-30 04:18:43 +00:00
{
2020-01-03 17:09:05 +00:00
static uint8_t trix [ ] = { 0 , 1 , 2 , 0 , 2 , 3 } ;
int j = trix [ jj ] ;
2014-09-30 04:18:43 +00:00
# if (VOXBORDWIDTH == 0)
2019-09-16 19:08:42 +00:00
vt - > SetTexCoord ( ( ( float ) vptr [ j ] . u ) * ru + uhack [ vptr [ j ] . u ! = vptr [ 0 ] . u ] ,
2014-12-26 17:29:48 +00:00
( ( float ) vptr [ j ] . v ) * rv + vhack [ vptr [ j ] . v ! = vptr [ 0 ] . v ] ) ;
2014-09-30 04:18:43 +00:00
# else
2019-09-16 19:08:42 +00:00
vt - > SetTexCoord ( ( ( float ) vptr [ j ] . u ) * ru , ( ( float ) vptr [ j ] . v ) * rv ) ;
2014-09-30 04:18:43 +00:00
# endif
2020-01-19 12:50:31 +00:00
vt - > SetVertex (
( ( float ) vptr [ j ] . x ) - phack [ xx > vptr [ j ] . x * 2 ] + phack [ xx < vptr [ j ] . x * 2 ] ,
( ( float ) vptr [ j ] . y ) - phack [ yy > vptr [ j ] . y * 2 ] + phack [ yy < vptr [ j ] . y * 2 ] ,
( ( float ) vptr [ j ] . z ) - phack [ zz > vptr [ j ] . z * 2 ] + phack [ zz < vptr [ j ] . z * 2 ] ) ;
2014-09-30 04:18:43 +00:00
}
2019-09-16 20:14:44 +00:00
qdone + + ;
2014-09-30 04:18:43 +00:00
}
2014-12-26 17:29:48 +00:00
2020-01-18 21:41:08 +00:00
GLInterface . Draw ( DT_TRIANGLES , qstart , qdone * 6 ) ;
2019-10-05 10:28:08 +00:00
GLInterface . SetClamp ( prevClamp ) ;
2014-09-30 04:18:43 +00:00
//------------
2019-10-04 16:12:03 +00:00
GLInterface . SetCull ( Cull_None ) ;
2019-07-06 19:04:54 +00:00
if ( shadowHack )
2014-09-30 04:18:43 +00:00
{
2019-10-04 16:44:16 +00:00
GLInterface . SetDepthFunc ( Depth_Less ) ;
}
2019-10-04 16:12:03 +00:00
VSMatrix identity ( 0 ) ;
2020-01-19 15:06:31 +00:00
GLInterface . RestoreMatrix ( Matrix_Model , matrixindex ) ;
2019-10-19 16:14:13 +00:00
GLInterface . SetFadeDisable ( false ) ;
2020-01-18 15:13:39 +00:00
GLInterface . SetTinting ( - 1 , 0xffffff , 0xffffff ) ;
return 1 ;
2014-09-30 04:18:43 +00:00
}
# endif
//---------------------------------------- VOX LIBRARY ENDS ----------------------------------------