From 4263626f97d88db13b39bc302bcd24021937d44c Mon Sep 17 00:00:00 2001 From: terminx Date: Tue, 30 Sep 2014 04:18:43 +0000 Subject: [PATCH] Misc additional optimizations, mostly to polymost/mdsprite. Also separate voxmodel into its own source file and object. This commit is pretty large because I was hitting the limit of what could realistically be carved up into smaller patches. DONT_BUILD. git-svn-id: https://svn.eduke32.com/eduke32@4639 1a8010ca-5511-0410-912e-c29ae57300e0 --- polymer/eduke32/Makefile | 2 +- polymer/eduke32/Makefile.msvc | 13 +- polymer/eduke32/build/Makefile.deps | 1 + polymer/eduke32/build/include/build.h | 4 +- polymer/eduke32/build/include/cache1d.h | 2 + polymer/eduke32/build/include/mdsprite.h | 70 +- polymer/eduke32/build/src/engine.c | 46 +- polymer/eduke32/build/src/mdsprite.c | 1549 +++++----------------- polymer/eduke32/build/src/polymost.c | 300 ++--- polymer/eduke32/build/src/texcache.c | 12 +- polymer/eduke32/build/src/voxmodel.c | 811 +++++++++++ 11 files changed, 1377 insertions(+), 1433 deletions(-) create mode 100644 polymer/eduke32/build/src/voxmodel.c diff --git a/polymer/eduke32/Makefile b/polymer/eduke32/Makefile index 899b942f2..b7fb2b761 100644 --- a/polymer/eduke32/Makefile +++ b/polymer/eduke32/Makefile @@ -46,7 +46,7 @@ else endif endif ifeq (1,$(USE_OPENGL)) - ENGINE_OBJS+= mdsprite glbuild + ENGINE_OBJS+= glbuild voxmodel mdsprite ifeq (1,$(POLYMER)) ENGINE_OBJS+= polymer endif diff --git a/polymer/eduke32/Makefile.msvc b/polymer/eduke32/Makefile.msvc index 2d16b8213..65ef44983 100644 --- a/polymer/eduke32/Makefile.msvc +++ b/polymer/eduke32/Makefile.msvc @@ -131,22 +131,23 @@ ENGINE_OBJS= \ $(ENGINE_OBJ)\crc32.$o \ $(ENGINE_OBJ)\defs.$o \ $(ENGINE_OBJ)\engine.$o \ + $(ENGINE_OBJ)\glbuild.$o \ + $(ENGINE_OBJ)\texcache.$o \ + $(ENGINE_OBJ)\kplib.$o \ + $(ENGINE_OBJ)\hightile.$o \ $(ENGINE_OBJ)\polymost.$o \ - $(ENGINE_OBJ)\texcache.$o \ + $(ENGINE_OBJ)\polymer.$o \ + $(ENGINE_OBJ)\mdsprite.$o \ + $(ENGINE_OBJ)\voxmodel.$o \ $(ENGINE_OBJ)\dxtfilter.$o \ - $(ENGINE_OBJ)\hightile.$o \ - $(ENGINE_OBJ)\mdsprite.$o \ $(ENGINE_OBJ)\textfont.$o \ $(ENGINE_OBJ)\smalltextfont.$o \ - $(ENGINE_OBJ)\glbuild.$o \ - $(ENGINE_OBJ)\kplib.$o \ $(ENGINE_OBJ)\lz4.$o \ $(ENGINE_OBJ)\lzwnew.$o \ $(ENGINE_OBJ)\mmulti_null.$o \ $(ENGINE_OBJ)\osd.$o \ $(ENGINE_OBJ)\pragmas.$o \ $(ENGINE_OBJ)\scriptfile.$o \ - $(ENGINE_OBJ)\polymer.$o \ $(ENGINE_OBJ)\mutex.$o \ $(ENGINE_OBJ)\winbits.$o \ $(ENGINE_OBJ)\xxhash.$o diff --git a/polymer/eduke32/build/Makefile.deps b/polymer/eduke32/build/Makefile.deps index 7bddb05a6..b63587e3b 100644 --- a/polymer/eduke32/build/Makefile.deps +++ b/polymer/eduke32/build/Makefile.deps @@ -14,6 +14,7 @@ $(ENGINE_OBJ)/polymost.$o: $(ENGINE_SRC)/polymost.c $(ENGINE_INC)/lz4.h $(ENGINE $(ENGINE_OBJ)/texcache.$o: $(ENGINE_SRC)/texcache.c $(ENGINE_INC)/texcache.h $(ENGINE_INC)/polymost.h $(ENGINE_INC)/dxtfilter.h $(ENGINE_OBJ)/dxtfilter.$o: $(ENGINE_SRC)/dxtfilter.c $(ENGINE_INC)/dxtfilter.h $(ENGINE_INC)/texcache.h $(ENGINE_OBJ)/hightile.$o: $(ENGINE_SRC)/hightile.c $(ENGINE_INC)/kplib.h $(ENGINE_INC)/hightile.h +$(ENGINE_OBJ)/voxmodel.$o: $(ENGINE_SRC)/voxmodel.c $(ENGINE_SRC)/engine_priv.h $(ENGINE_INC)/polymost.h $(ENGINE_INC)/hightile.h $(ENGINE_INC)/mdsprite.h $(ENGINE_INC)/texcache.h $(ENGINE_OBJ)/mdsprite.$o: $(ENGINE_SRC)/mdsprite.c $(ENGINE_SRC)/engine_priv.h $(ENGINE_INC)/polymost.h $(ENGINE_INC)/hightile.h $(ENGINE_INC)/mdsprite.h $(ENGINE_INC)/texcache.h $(ENGINE_OBJ)/textfont.$o: $(ENGINE_SRC)/textfont.c $(ENGINE_OBJ)/smalltextfont.$o: $(ENGINE_SRC)/smalltextfont.c diff --git a/polymer/eduke32/build/include/build.h b/polymer/eduke32/build/include/build.h index 5b0c75b7c..59882a7ba 100644 --- a/polymer/eduke32/build/include/build.h +++ b/polymer/eduke32/build/include/build.h @@ -287,11 +287,11 @@ typedef struct { typedef struct { float x, y; -} fvec2_t; +} vec2f_t; typedef struct { float x, y, z; -} fvec3_t; +} vec3f_t; // Links to various ABIs specifying (or documenting non-normatively) the // alignment requirements of aggregates: diff --git a/polymer/eduke32/build/include/cache1d.h b/polymer/eduke32/build/include/cache1d.h index 0cd489960..71f769c1e 100644 --- a/polymer/eduke32/build/include/cache1d.h +++ b/polymer/eduke32/build/include/cache1d.h @@ -15,6 +15,8 @@ extern "C" { #ifdef WITHKPLIB int32_t cache1d_file_fromzip(int32_t fil); +extern char *kpzbuf; +extern int32_t kpzbufsiz; #endif void initcache(intptr_t dacachestart, int32_t dacachesize); diff --git a/polymer/eduke32/build/include/mdsprite.h b/polymer/eduke32/build/include/mdsprite.h index fd308a7f9..84aaaa25f 100644 --- a/polymer/eduke32/build/include/mdsprite.h +++ b/polymer/eduke32/build/include/mdsprite.h @@ -6,13 +6,23 @@ #define SHIFTMOD32(a) ((a)&31) +#define SHARED_MODEL_DATA int32_t mdnum, shadeoff; \ + float scale, bscale, zadd, yoffset; \ + GLuint *texid; \ + int32_t flags; + +#define IDMODEL_SHARED_DATA int32_t numframes, cframe, nframe, fpssc, usesalpha; \ + float oldtime, curtime, interpol; \ + mdanim_t *animations; \ + mdskinmap_t *skinmap; \ + int32_t numskins, skinloaded; + +#define IDP2_MAGIC 0x32504449 +#define IDP3_MAGIC 0x33504449 + typedef struct { - int32_t mdnum; //VOX=1, MD2=2, MD3=3. NOTE: must be first in structure! - int32_t shadeoff; - float scale, bscale, zadd, yoffset; - GLuint *texid; // skins - int32_t flags; + SHARED_MODEL_DATA; } mdmodel_t; typedef struct _mdanim_t @@ -21,6 +31,7 @@ typedef struct _mdanim_t int32_t fpssc, flags; struct _mdanim_t *next; } mdanim_t; + #define MDANIM_LOOP 0 #define MDANIM_ONESHOT 1 @@ -40,7 +51,6 @@ typedef struct _mdskinmap_t // Available from http://web.archive.org/web/20030816010242/http://tfc.duke.free.fr/us/tutorials/models/md2.htm // Now at http://tfc.duke.free.fr/coding/md2.html (in French) //He probably wouldn't recognize it if he looked at it though :) -typedef struct { float x, y, z; } point3d; typedef struct { @@ -52,7 +62,7 @@ typedef struct typedef struct { uint8_t v[3], ni; } md2vert_t; //compressed vertex coords (x,y,z) typedef struct { - point3d mul, add; //scale&translation vector + vec3f_t mul, add; //scale&translation vector char name[16]; //frame name md2vert_t verts[1]; //first vertex of this frame } md2frame_t; @@ -66,18 +76,8 @@ typedef struct typedef struct { - //WARNING: This top block is a union between md2model&md3model: Make sure it matches! - int32_t mdnum; //VOX=1, MD2=2, MD3=3. NOTE: must be first in structure! - int32_t shadeoff; - float scale, bscale, zadd, yoffset; - GLuint *texid; // texture ids for base skin if no mappings defined - int32_t flags; - - int32_t numframes, cframe, nframe, fpssc, usesalpha; - float oldtime, curtime, interpol; - mdanim_t *animations; - mdskinmap_t *skinmap; - int32_t numskins, skinloaded; // set to 1+numofskin when a skin is loaded and the tex coords are modified, + SHARED_MODEL_DATA; + IDMODEL_SHARED_DATA; //MD2 specific stuff: int32_t numverts, numglcmds, framebytes, *glcmds; @@ -96,7 +96,7 @@ typedef struct { int16_t x, y, z; uint8_t nlat, nlng; } md3xyzn_t; //xyz are [10 typedef struct { - point3d min, max, cen; //bounding box&origin + vec3f_t min, max, cen; //bounding box&origin float r; //radius of bounding sphere char nam[16]; //ascz frame name } md3frame_t; @@ -104,7 +104,7 @@ typedef struct typedef struct { char nam[64]; //ascz tag name - point3d p, x, y, z; //tag object pos&orient + vec3f_t p, x, y, z; //tag object pos&orient } md3tag_t; typedef struct @@ -152,22 +152,12 @@ typedef struct typedef struct { - //WARNING: This top block is a union between md2model&md3model: Make sure it matches! - int32_t mdnum; //VOX=1, MD2=2, MD3=3. NOTE: must be first in structure! - int32_t shadeoff; - float scale, bscale, zadd, yoffset; - uint32_t *texid; // texture ids for base skin if no mappings defined - int32_t flags; - - int32_t numframes, cframe, nframe, fpssc, usesalpha; - float oldtime, curtime, interpol; - mdanim_t *animations; - mdskinmap_t *skinmap; - int32_t numskins, skinloaded; // set to 1+numofskin when a skin is loaded and the tex coords are modified, + SHARED_MODEL_DATA; + IDMODEL_SHARED_DATA; //MD3 specific md3head_t head; - point3d *muladdframes; + vec3f_t *muladdframes; uint16_t *indexes; uint16_t *vindexes; float *maxdepths; @@ -198,8 +188,8 @@ typedef struct //VOX specific stuff: voxrect_t *quad; int32_t qcnt, qfacind[7]; int32_t *mytex, mytexx, mytexy; - int32_t xsiz, ysiz, zsiz; - float xpiv, ypiv, zpiv; + vec3_t siz; + vec3f_t piv; int32_t is8bit; } voxmodel_t; @@ -210,9 +200,10 @@ int32_t mdloadskin(md2model_t *m, int32_t number, int32_t pal, int32_t surf); void mdinit(void); void freeallmodels(void); void clearskins(void); -int32_t mddraw(const spritetype *tspr); +int32_t polymost_mddraw(const spritetype *tspr); +EXTERN void md3_vox_calcmat_common(const spritetype *tspr, const vec3f_t *a0, float f, float mat[16]); -typedef struct { float xadd, yadd, zadd; int16_t angadd, flags, fov; } hudtyp; +typedef struct { vec3f_t add; int16_t angadd, flags, fov; } hudtyp; EXTERN hudtyp hudmem[2][MAXTILES]; @@ -222,10 +213,11 @@ EXTERN voxmodel_t *voxmodels[MAXVOXELS]; void voxfree(voxmodel_t *m); voxmodel_t *voxload(const char *filnam); -int32_t voxdraw(voxmodel_t *m, const spritetype *tspr); +int32_t polymost_voxdraw(voxmodel_t *m, const spritetype *tspr); int md3postload_polymer(md3model_t* m); //int32_t md_thinoutmodel(int32_t modelid, uint8_t *usedframebitmap); +EXTERN void md_freevbos(void); #endif // defined USE_OPENGL diff --git a/polymer/eduke32/build/src/engine.c b/polymer/eduke32/build/src/engine.c index b4f04b373..40410e55b 100644 --- a/polymer/eduke32/build/src/engine.c +++ b/polymer/eduke32/build/src/engine.c @@ -2767,7 +2767,7 @@ static WSHELPER_DECL void calc_vplcinc_wall(uint32_t *vplc, int32_t *vinc, inthi #ifdef HIGH_PRECISION_SPRITE static WSHELPER_DECL void calc_vplcinc_sprite(uint32_t *vplc, int32_t *vinc, int32_t x, int32_t y1v) { - inthi_t tmpvinc = swallf[x]; + inthi_t tmpvinc = Blrintf(swallf[x]); inthi_t tmpvplc = globalzd + tmpvinc*(y1v-globalhoriz+1); *vinc = tmpvinc; @@ -6897,7 +6897,7 @@ static inline int32_t addscaleclamp(int32_t a, int32_t b, int32_t s1, int32_t s2 // a + scale(b, s1, s1-s2), but without arithmetic exception when the // scale() expression overflows - double tmp = (double)a + ((double)b*s1)/(s1-s2); + int64_t tmp = (int64_t)a + ((int64_t)b*s1)/(s1-s2); if (tmp <= INT32_MIN+1) return INT32_MIN+1; @@ -7896,18 +7896,20 @@ static void dosetaspect(void) // static inline void calcbritable(void) { - int32_t i,j; - double a,b; + int32_t i, j; + float a, b; + for (i=0; i<16; i++) { - a = (double)8 / ((double)i+8); - b = (double)255 / pow((double)255,a); + a = 8.f / ((float)i+8.f); + b = 255.f / powf(255.f, a); + for (j=0; j<256; j++) // JBF 20040207: full 8bit precision - britable[i][j] = (uint8_t)(pow((double)j,a)*b); + britable[i][j] = (uint8_t) (powf((float)j, a) * b); } } -#define BANG2RAD (PI/1024.0) +#define BANG2RAD ((float)PI * (1.f/1024.f)) static int32_t loadtables(void) { @@ -8290,16 +8292,16 @@ int32_t getclosestcol_lim(int32_t r, int32_t g, int32_t b, int32_t lastokcol) if (dist < mindist && i <= lastokcol) { dist += rdist[pal1[0]+r]; - if (dist < mindist) - { - dist += bdist[pal1[2]+b]; - if (dist < mindist) { mindist = dist; retcol = i; } - } + if (dist >= mindist) + continue; + dist += bdist[pal1[2]+b]; + if (dist >= mindist) + continue; + mindist = dist; + retcol = i; } - - i = colnext[i]; } - while (i >= 0); + while ((i = colnext[i]) >= 0); } if (retcol >= 0) @@ -8609,12 +8611,12 @@ static inline void keepaway(int32_t *x, int32_t *y, int32_t w) ox = ksgn(-dy); oy = ksgn(dx); first = (klabs(dx) <= klabs(dy)); - while (1) + do { if (dx*(*y-y1) > (*x-x1)*dy) return; if (first == 0) *x += ox; else *y += oy; first ^= 1; - } + } while (1); } @@ -8797,6 +8799,7 @@ int32_t preinitengine(void) getvalidmodes(); initcrc32table(); + #ifdef HAVE_CLIPSHAPE_FEATURE clipmapinfo_init(); #endif @@ -8920,6 +8923,9 @@ void uninitengine(void) DO_FREE_AND_NULL(blockptr); #endif +#ifdef WITHKPLIB + DO_FREE_AND_NULL(kpzbuf); +#endif uninitsystem(); } @@ -17511,9 +17517,7 @@ int32_t setrendermode(int32_t renderer) #ifdef USE_OPENGL void setrollangle(int32_t rolla) { - UNREFERENCED_PARAMETER(rolla); - if (rolla == 0) gtang = 0.0; - else gtang = PI * (double)rolla / 1024.0; + gtang = (float) rolla * PI * (1.f/1024.f); } #endif diff --git a/polymer/eduke32/build/src/mdsprite.c b/polymer/eduke32/build/src/mdsprite.c index a30254160..881946d32 100644 --- a/polymer/eduke32/build/src/mdsprite.c +++ b/polymer/eduke32/build/src/mdsprite.c @@ -80,19 +80,22 @@ static int32_t nummodelsalloced = 0; static int32_t maxmodelverts = 0, allocmodelverts = 0; static int32_t maxmodeltris = 0, allocmodeltris = 0; -static point3d *vertlist = NULL; //temp array to store interpolated vertices for drawing +static vec3f_t *vertlist = NULL; //temp array to store interpolated vertices for drawing static int32_t allocvbos = 0, curvbo = 0; static GLuint *vertvbos = NULL; static GLuint *indexvbos = NULL; +static int32_t *tribuf = NULL; +static int32_t tribufverts = 0; + static mdmodel_t *mdload(const char *); static void mdfree(mdmodel_t *); int32_t globalnoeffect=0; extern int32_t timerticspersec; -void freevbos() +void md_freevbos() { int32_t i; @@ -139,15 +142,9 @@ void freeallmodels() allocmodelverts = maxmodelverts = 0; allocmodeltris = maxmodeltris = 0; } - freevbos(); - /* - if (model_data_pool) - { - neddestroypool(model_data_pool); - model_data_pool = NULL; - } - */ + md_freevbos(); + DO_FREE_AND_NULL(tribuf); } @@ -244,8 +241,6 @@ void mdinit() { memset(hudmem,0,sizeof(hudmem)); freeallmodels(); -// if (!model_data_pool) -// model_data_pool = nedcreatepool(MODEL_POOL_SIZE, 0); mdinited = 1; } @@ -352,7 +347,7 @@ int32_t md_defineanimation(int32_t modelid, const char *framestart, const char * if ((uint32_t)modelid >= (uint32_t)nextmodelid) return(-1); - memset(&ma, 0, sizeof(ma)); + Bmemset(&ma, 0, sizeof(ma)); m = (md2model_t *)models[modelid]; if (m->mdnum < 2) return 0; @@ -429,7 +424,7 @@ int32_t md_thinoutmodel(int32_t modelid, uint8_t *usedframebitmap) if (otonframe[i]>=0 && otonframe[i] != i) { if (m->muladdframes) - Bmemcpy(&m->muladdframes[2*otonframe[i]], &m->muladdframes[2*i], 2*sizeof(point3d)); + Bmemcpy(&m->muladdframes[2*otonframe[i]], &m->muladdframes[2*i], 2*sizeof(vec3f_t)); Bmemcpy(&m->head.frames[otonframe[i]], &m->head.frames[i], sizeof(md3frame_t)); } } @@ -465,7 +460,7 @@ int32_t md_thinoutmodel(int32_t modelid, uint8_t *usedframebitmap) ////// realloc & change "numframes" everywhere if (m->muladdframes) - m->muladdframes = Xrealloc(m->muladdframes, 2*sizeof(point3d)*usedframes); + m->muladdframes = Xrealloc(m->muladdframes, 2*sizeof(vec3f_t)*usedframes); m->head.frames = Xrealloc(m->head.frames, sizeof(md3frame_t)*usedframes); for (surfi=0; surfi < m->head.numsurfs; surfi++) @@ -529,9 +524,9 @@ int32_t md_definehud(int32_t modelid, int32_t tilex, float xadd, float yadd, flo if ((uint32_t)modelid >= (uint32_t)nextmodelid) return -1; if ((uint32_t)tilex >= (uint32_t)MAXTILES) return -2; - hudmem[(flags>>2)&1][tilex].xadd = xadd; - hudmem[(flags>>2)&1][tilex].yadd = yadd; - hudmem[(flags>>2)&1][tilex].zadd = zadd; + hudmem[(flags>>2)&1][tilex].add.x = xadd; + hudmem[(flags>>2)&1][tilex].add.y = yadd; + hudmem[(flags>>2)&1][tilex].add.z = zadd; hudmem[(flags>>2)&1][tilex].angadd = ((int16_t)angadd)|2048; hudmem[(flags>>2)&1][tilex].flags = (int16_t)flags; hudmem[(flags>>2)&1][tilex].fov = (int16_t)fov; @@ -604,7 +599,7 @@ static int32_t daskinloader(int32_t filh, intptr_t *fptr, int32_t *bpl, int32_t memset(pic,0,xsiz*ysiz*sizeof(coltype)); - if (kprender(picfil,picfillen,(intptr_t)pic,xsiz*sizeof(coltype),xsiz,ysiz,0,0)) + if (kprender(picfil,picfillen,(intptr_t)pic,xsiz*sizeof(coltype),xsiz,ysiz)) { Bfree(picfil); Bfree(pic); return -2; } Bfree(picfil); @@ -1111,6 +1106,7 @@ static md2model_t *md2load(int32_t fil, const char *filnam) m->mdnum = 2; m->scale = .01f; kread(fil,(char *)&head,sizeof(md2head_t)); +#if B_BIG_ENDIAN != 0 head.id = B_LITTLE32(head.id); head.vers = B_LITTLE32(head.vers); head.skinxsiz = B_LITTLE32(head.skinxsiz); head.skinysiz = B_LITTLE32(head.skinysiz); head.framebytes = B_LITTLE32(head.framebytes); head.numskins = B_LITTLE32(head.numskins); @@ -1120,8 +1116,9 @@ static md2model_t *md2load(int32_t fil, const char *filnam) head.ofsuv = B_LITTLE32(head.ofsuv); head.ofstris = B_LITTLE32(head.ofstris); head.ofsframes = B_LITTLE32(head.ofsframes); head.ofsglcmds = B_LITTLE32(head.ofsglcmds); head.ofseof = B_LITTLE32(head.ofseof); +#endif - if ((head.id != 0x32504449) || (head.vers != 8)) { Bfree(m); return(0); } //"IDP2" + if ((head.id != IDP2_MAGIC) || (head.vers != 8)) { Bfree(m); return(0); } //"IDP2" ournumskins = head.numskins ? head.numskins : 1; ournumglcmds = head.numglcmds ? head.numglcmds : 1; @@ -1218,7 +1215,7 @@ static md2model_t *md2load(int32_t fil, const char *filnam) //OSD_Printf("Beginning md3 conversion.\n"); m3 = (md3model_t *)Xcalloc(1, sizeof(md3model_t)); m3->mdnum = 3; m3->texid = 0; m3->scale = m->scale; - m3->head.id = 0x33504449; m3->head.vers = 15; + m3->head.id = IDP3_MAGIC; m3->head.vers = 15; // DO_MD2_MD3_CONV: // 1: use the conversion code to do real MD2->MD3 conversion, @@ -1241,7 +1238,7 @@ static md2model_t *md2load(int32_t fil, const char *filnam) m3->numframes = m3->head.numframes; m3->head.frames = (md3frame_t *)Xcalloc(m3->head.numframes, sizeof(md3frame_t)); - m3->muladdframes = (point3d *)Xcalloc(m->numframes * 2, sizeof(point3d)); + m3->muladdframes = (vec3f_t *)Xcalloc(m->numframes * 2, sizeof(vec3f_t)); f = (md2frame_t *)(m->frames); @@ -1263,7 +1260,7 @@ static md2model_t *md2load(int32_t fil, const char *filnam) s = m3->head.surfs; // model converting - s->id = 0x33504449; s->flags = 0; + s->id = IDP3_MAGIC; s->flags = 0; s->numframes = m->numframes; s->numshaders = 0; s->numtris = head.numtris; s->numverts = head.numtris * 3; // oh man talk about memory effectiveness :(((( @@ -1359,16 +1356,12 @@ static md2model_t *md2load(int32_t fil, const char *filnam) } //---------------------------------------- MD2 LIBRARY ENDS ---------------------------------------- -// DICHOTOMIC RECURSIVE SORTING - USED BY MD3DRAW - MAY PUT IT IN ITS OWN SOURCE FILE LATER +// DICHOTOMIC RECURSIVE SORTING - USED BY MD3DRAW int32_t partition(uint16_t *indexes, float *depths, int32_t f, int32_t l) { - int32_t up,down; - float tempf; - uint16_t tempus; + int32_t up = f, down = l; float piv = depths[f]; uint16_t piv2 = indexes[f]; - up = f; - down = l; do { while ((depths[up] <= piv) && (up < l)) @@ -1377,31 +1370,24 @@ int32_t partition(uint16_t *indexes, float *depths, int32_t f, int32_t l) down--; if (up < down) { - tempf = depths[up]; - depths[up] = depths[down]; - depths[down] = tempf; - tempus = indexes[up]; - indexes[up] = indexes[down]; - indexes[down] = tempus; + swapfloat(&depths[up], &depths[down]); + swapshort(&indexes[up], &indexes[down]); } } while (down > up); - depths[f] = depths[down]; - depths[down] = piv; - indexes[f] = indexes[down]; - indexes[down] = piv2; + depths[f] = depths[down], depths[down] = piv; + indexes[f] = indexes[down], indexes[down] = piv2; return down; } -void quicksort(uint16_t *indexes, float *depths, int32_t first, int32_t last) +static inline void quicksort(uint16_t *indexes, float *depths, int32_t first, int32_t last) { - int32_t pivIndex = 0; - if (first < last) - { - pivIndex = partition(indexes,depths,first, last); - quicksort(indexes,depths,first,(pivIndex-1)); - quicksort(indexes,depths,(pivIndex+1),last); - } + int32_t pivIndex; + if (first >= last) return; + pivIndex = partition(indexes, depths, first, last); + if (first < (pivIndex-1)) quicksort(indexes, depths, first, (pivIndex-1)); + if ((pivIndex+1) >= last) return; + quicksort(indexes, depths, (pivIndex+1), last); } // END OF QUICKSORT LIB @@ -1420,14 +1406,17 @@ static md3model_t *md3load(int32_t fil) m->muladdframes = NULL; kread(fil,&m->head,SIZEOF_MD3HEAD_T); + +#if B_BIG_ENDIAN != 0 m->head.id = B_LITTLE32(m->head.id); m->head.vers = B_LITTLE32(m->head.vers); m->head.flags = B_LITTLE32(m->head.flags); m->head.numframes = B_LITTLE32(m->head.numframes); m->head.numtags = B_LITTLE32(m->head.numtags); m->head.numsurfs = B_LITTLE32(m->head.numsurfs); m->head.numskins = B_LITTLE32(m->head.numskins); m->head.ofsframes = B_LITTLE32(m->head.ofsframes); m->head.ofstags = B_LITTLE32(m->head.ofstags); m->head.ofssurfs = B_LITTLE32(m->head.ofssurfs); m->head.eof = B_LITTLE32(m->head.eof); +#endif - if ((m->head.id != 0x33504449) && (m->head.vers != 15)) { Bfree(m); return(0); } //"IDP3" + if ((m->head.id != IDP3_MAGIC) && (m->head.vers != 15)) { Bfree(m); return(0); } //"IDP3" m->numskins = m->head.numskins; //<- dead code? m->numframes = m->head.numframes; @@ -1484,15 +1473,20 @@ static md3model_t *md3load(int32_t fil) } #endif - offs[0] = ofsurf+s->ofstris; leng[0] = s->numtris*sizeof(md3tri_t); - offs[1] = ofsurf+s->ofsshaders; leng[1] = s->numshaders*sizeof(md3shader_t); - offs[2] = ofsurf+s->ofsuv; leng[2] = s->numverts*sizeof(md3uv_t); - offs[3] = ofsurf+s->ofsxyzn; leng[3] = s->numframes*s->numverts*sizeof(md3xyzn_t); + offs[0] = ofsurf+s->ofstris; + offs[1] = ofsurf+s->ofsshaders; + offs[2] = ofsurf+s->ofsuv; + offs[3] = ofsurf+s->ofsxyzn; + + leng[0] = s->numtris*sizeof(md3tri_t); + leng[1] = s->numshaders*sizeof(md3shader_t); + leng[2] = s->numverts*sizeof(md3uv_t); + leng[3] = s->numframes*s->numverts*sizeof(md3xyzn_t); + //memoryusage += (s->numverts * s->numframes * sizeof(md3xyzn_t)); //OSD_Printf("Current model geometry memory usage : %i.\n", memoryusage); - - s->tris = (md3tri_t *)Xmalloc(leng[0]+leng[1]+leng[2]+leng[3]); + s->tris = (md3tri_t *)Xmalloc((leng[0] + leng[1]) + (leng[2] + leng[3])); s->shaders = (md3shader_t *)(((intptr_t)s->tris)+leng[0]); s->uv = (md3uv_t *)(((intptr_t)s->shaders)+leng[1]); @@ -1535,32 +1529,6 @@ static md3model_t *md3load(int32_t fil) ofsurf += s->ofsend; } -#if 0 - { - char *buf, st[BMAX_PATH+2], bst[BMAX_PATH+2]; - int32_t j, bsc; - - Bstrcpy(st,filnam); - for (i=0,j=0; st[i]; i++) if ((st[i] == '/') || (st[i] == '\\')) j = i+1; - st[j] = '*'; st[j+1] = 0; - kzfindfilestart(st); bsc = -1; - while (kzfindfile(st)) - { - if (st[0] == '\\') continue; - - for (i=0,j=0; st[i]; i++) if (st[i] == '.') j = i+1; - if ((!stricmp(&st[j],"JPG")) || (!stricmp(&st[j],"PNG")) || (!stricmp(&st[j],"GIF")) || - (!stricmp(&st[j],"PCX")) || (!stricmp(&st[j],"TGA")) || (!stricmp(&st[j],"BMP")) || - (!stricmp(&st[j],"CEL"))) - { - for (i=0; st[i]; i++) if (st[i] != filnam[i]) break; - if (i > bsc) { bsc = i; Bstrcpy(bst,st); } - } - } - if (!mdloadskin(&m->texid,&m->usesalpha,bst)) ;//bad! - } -#endif - m->indexes = (uint16_t *)Xmalloc(sizeof(uint16_t) * maxtrispersurf); m->vindexes = (uint16_t *)Xmalloc(sizeof(uint16_t) * maxtrispersurf * 3); m->maxdepths = (float *)Xmalloc(sizeof(float) * maxtrispersurf); @@ -1574,48 +1542,41 @@ static inline void invertmatrix(float *m, float *out) { float det; - det = m[0] * (m[4]*m[8] - m[5] * m[7]); - det -= m[1] * (m[3]*m[8] - m[5] * m[6]); - det += m[2] * (m[3]*m[7] - m[4] * m[6]); + det = (m[0] * (m[4]*m[8] - m[5] * m[7])) + - (m[1] * (m[3]*m[8] - m[5] * m[6])) + + (m[2] * (m[3]*m[7] - m[4] * m[6])); - if (det != 0.0f) + if (det == 0.0f) { - det = 1.0f / det; - - out[0] = det * (m[4] * m[8] - m[5] * m[7]); - out[3] = det * (m[5] * m[6] - m[3] * m[8]); - out[6] = det * (m[3] * m[7] - m[1] * m[6]); - - out[1] = det * (m[2] * m[7] - m[1] * m[8]); - out[4] = det * (m[0] * m[8] - m[2] * m[6]); - out[7] = det * (m[1] * m[6] - m[0] * m[7]); - - out[2] = det * (m[1] * m[5] - m[2] * m[4]); - out[5] = det * (m[2] * m[3] - m[0] * m[5]); - out[8] = det * (m[0] * m[4] - m[1] * m[3]); - } - else - { - out[0] = 1.0; out[1] = 0.0; out[2] = 0.0; - out[3] = 0.0; out[4] = 1.0; out[5] = 0.0; - out[6] = 0.0; out[7] = 0.0; out[8] = 1.0; + Bmemset(out, 0, sizeof(float) * 9); + out[8] = out[4] = out[0] = 1.f; + return; } + + det = 1.0f / det; + + out[0] = det * (m[4] * m[8] - m[5] * m[7]); + out[1] = det * (m[2] * m[7] - m[1] * m[8]); + out[2] = det * (m[1] * m[5] - m[2] * m[4]); + out[3] = det * (m[5] * m[6] - m[3] * m[8]); + out[4] = det * (m[0] * m[8] - m[2] * m[6]); + out[5] = det * (m[2] * m[3] - m[0] * m[5]); + out[6] = det * (m[3] * m[7] - m[1] * m[6]); + out[7] = det * (m[1] * m[6] - m[0] * m[7]); + out[8] = det * (m[0] * m[4] - m[1] * m[3]); } static inline void normalize(float *vec) { - double norm; + float norm; - norm = vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2]; + if ((norm = vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2]) == 0.f) + return; - if (norm != 0.0) - { - norm = sqrt(norm); - norm = 1.0 / norm; - vec[0] *= norm; - vec[1] *= norm; - vec[2] *= norm; - } + norm = polymost_invsqrt(norm); + vec[0] *= norm; + vec[1] *= norm; + vec[2] *= norm; } static void md3postload_common(md3model_t *m) @@ -1623,98 +1584,78 @@ static void md3postload_common(md3model_t *m) int framei, surfi, verti; md3frame_t *frame; md3xyzn_t *frameverts; - float dist, vec1[5]; // apparently we can't trust loaded models bounding box/sphere information, // so let's compute it ourselves framei = 0; - - while (framei < m->head.numframes) + do // while (++framei < m->head.numframes); { frame = &m->head.frames[framei]; - - frame->min.x = 0.0f; - frame->min.y = 0.0f; - frame->min.z = 0.0f; - - frame->max.x = 0.0f; - frame->max.y = 0.0f; - frame->max.z = 0.0f; - + Bmemset(&frame->min, 0, sizeof(vec3f_t) * 2); frame->r = 0.0f; surfi = 0; - while (surfi < m->head.numsurfs) + do // while (++surfi < m->head.numsurfs); { frameverts = &m->head.surfs[surfi].xyzn[framei * m->head.surfs[surfi].numverts]; verti = 0; - while (verti < m->head.surfs[surfi].numverts) + + if (!surfi) { - if (!verti && !surfi) - { - frame->min.x = frameverts[verti].x; - frame->min.y = frameverts[verti].y; - frame->min.z = frameverts[verti].z; - - frame->max.x = frameverts[verti].x; - frame->max.y = frameverts[verti].y; - frame->max.z = frameverts[verti].z; - } - else - { - if (frame->min.x > frameverts[verti].x) - frame->min.x = frameverts[verti].x; - if (frame->max.x < frameverts[verti].x) - frame->max.x = frameverts[verti].x; - - if (frame->min.y > frameverts[verti].y) - frame->min.y = frameverts[verti].y; - if (frame->max.y < frameverts[verti].y) - frame->max.y = frameverts[verti].y; - - if (frame->min.z > frameverts[verti].z) - frame->min.z = frameverts[verti].z; - if (frame->max.z < frameverts[verti].z) - frame->max.z = frameverts[verti].z; - } - - verti++; + frame->min.x = (float)frameverts[0].x; + frame->min.y = (float)frameverts[0].y; + frame->min.z = (float)frameverts[0].z; + frame->max = frame->min; } - surfi++; - } - frame->cen.x = (frame->min.x + frame->max.x) / 2.0f; - frame->cen.y = (frame->min.y + frame->max.y) / 2.0f; - frame->cen.z = (frame->min.z + frame->max.z) / 2.0f; + do // while(++verti < m->head.surfs[surfi].numverts); + { + vec3f_t f = { frameverts[verti].x, frameverts[verti].y, frameverts[verti].z }; + + if (!verti && !surfi) + continue; + + frame->min.x = max(frame->min.x, f.x); + frame->min.y = max(frame->min.y, f.y); + frame->min.z = max(frame->min.z, f.z); + frame->max.x = max(frame->max.x, f.x); + frame->max.y = max(frame->max.y, f.y); + frame->max.z = max(frame->max.z, f.z); + } + while(++verti < m->head.surfs[surfi].numverts); + } + while (++surfi < m->head.numsurfs); + + frame->cen.x = (frame->min.x + frame->max.x) * .5f; + frame->cen.y = (frame->min.y + frame->max.y) * .5f; + frame->cen.z = (frame->min.z + frame->max.z) * .5f; surfi = 0; - while (surfi < m->head.numsurfs) + do // while (++surfi < m->head.numsurfs); { + float vec1[4]; + frameverts = &m->head.surfs[surfi].xyzn[framei * m->head.surfs[surfi].numverts]; verti = 0; - while (verti < m->head.surfs[surfi].numverts) + do // while (++verti < m->head.surfs[surfi].numverts); { vec1[0] = frameverts[verti].x - frame->cen.x; vec1[1] = frameverts[verti].y - frame->cen.y; vec1[2] = frameverts[verti].z - frame->cen.z; - dist = vec1[0] * vec1[0] + vec1[1] * vec1[1] + vec1[2] * vec1[2]; + vec1[3] = (vec1[0] * vec1[0]) + (vec1[1] * vec1[1]) + (vec1[2] * vec1[2]); - if (dist > frame->r) - frame->r = dist; - - verti++; + frame->r = max(vec1[3], frame->r); } - surfi++; + while (++verti < m->head.surfs[surfi].numverts); } - - frame->r = sqrt(frame->r); - - framei++; + while (++surfi < m->head.numsurfs); + frame->r = Bsqrtf(frame->r); } + while (++framei < m->head.numframes); } #ifdef POLYMER @@ -1722,54 +1663,52 @@ static void md3postload_common(md3model_t *m) // keep in sync with md3postload_polymer! static int md3postload_polymer_check(md3model_t *m) { - int surfi, trii; + uint32_t surfi, trii; md3surf_t *s; surfi = 0; - while (surfi < m->head.numsurfs) + do { s = &m->head.surfs[surfi]; trii = 0; - while (trii < s->numtris) + do { // let the vertices know they're being referenced by a triangle - if (s->tris[trii].i[0] >= s->numverts || s->tris[trii].i[0] < 0 || - s->tris[trii].i[1] >= s->numverts || s->tris[trii].i[1] < 0 || - s->tris[trii].i[2] >= s->numverts || s->tris[trii].i[2] < 0) + if ((unsigned)s->tris[trii].i[0] >= (unsigned)s->numverts || + (unsigned)s->tris[trii].i[1] >= (unsigned)s->numverts || + (unsigned)s->tris[trii].i[2] >= (unsigned)s->numverts) { // corrupt model OSD_Printf("%s: Triangle index out of bounds!\n", m->head.nam); - return 0; + return 1; } - - trii++; } - - surfi++; + while (++trii < (unsigned)s->numtris); } + while (++surfi < (unsigned)m->head.numsurfs); - return 1; + return 0; } // Precalculated cos/sin arrays. -static double g_mdcos[256], g_mdsin[256]; +static float g_mdcos[256], g_mdsin[256]; +static int32_t mdtrig_init = 0; static void init_mdtrig_arrays(void) { int32_t i; - - static int inited; - if (inited) - return; - inited = 1; + static const float acc = ((2.f * PI) * (1.f/255.f)); + float ang = 0.f; for (i=0; i<256; i++) { - double ang = i * (2 * PI) / 255.0; - g_mdcos[i] = cos(ang); - g_mdsin[i] = sin(ang); + g_mdcos[i] = cosf(ang); + g_mdsin[i] = sinf(ang); + ang += acc; } + + mdtrig_init = 1; } #endif @@ -1778,19 +1717,21 @@ int md3postload_polymer(md3model_t *m) #ifdef POLYMER int framei, surfi, verti, trii, i; md3surf_t *s; - int *numtris; float vec1[5], vec2[5], mat[9], r; if (m->head.surfs[0].geometry) return -1; // already postprocessed - init_mdtrig_arrays(); + if (!mdtrig_init) + init_mdtrig_arrays(); // let's also repack the geometry to more usable formats surfi = 0; - while (surfi < m->head.numsurfs) + do // while (++surfi < m->head.numsurfs) { + handleevents(); + s = &m->head.surfs[surfi]; #ifdef DEBUG_MODEL_MEM i = (m->head.numframes * s->numverts * sizeof(float) * 15); @@ -1798,71 +1739,77 @@ int md3postload_polymer(md3model_t *m) initprintf("size %d (%d fr, %d v): md %s surf %d/%d\n", i, m->head.numframes, s->numverts, m->head.nam, surfi, m->head.numsurfs); #endif - s->geometry = (float *)Xcalloc(m->head.numframes * s->numverts * sizeof(float), 15); + s->geometry = (float *)Xcalloc(m->head.numframes * s->numverts * 15, sizeof(float)); - numtris = (int *)Xcalloc(s->numverts, sizeof(int)); + if (s->numverts > tribufverts) + { + tribuf = (int32_t *) Xrealloc(tribuf, s->numverts * sizeof(int32_t)); + Bmemset(tribuf, 0, s->numverts * sizeof(int32_t)); + tribufverts = s->numverts; + } verti = 0; - while (verti < (m->head.numframes * s->numverts)) + do // while (++verti < (m->head.numframes * s->numverts)) { // normal extraction from packed spherical coordinates // FIXME: swapping lat and lng because of npherno's compiler uint8_t lat = s->xyzn[verti].nlng; uint8_t lng = s->xyzn[verti].nlat; + uint32_t verti15 = (verti<<4)-verti; - s->geometry[(verti * 15) + 0] = s->xyzn[verti].x; - s->geometry[(verti * 15) + 1] = s->xyzn[verti].y; - s->geometry[(verti * 15) + 2] = s->xyzn[verti].z; + s->geometry[verti15 + 0] = s->xyzn[verti].x; + s->geometry[verti15 + 1] = s->xyzn[verti].y; + s->geometry[verti15 + 2] = s->xyzn[verti].z; - s->geometry[(verti * 15) + 3] = g_mdcos[lat] * g_mdsin[lng]; - s->geometry[(verti * 15) + 4] = g_mdsin[lat] * g_mdsin[lng]; - s->geometry[(verti * 15) + 5] = g_mdcos[lng]; - - verti++; + s->geometry[verti15 + 3] = g_mdcos[lat] * g_mdsin[lng]; + s->geometry[verti15 + 4] = g_mdsin[lat] * g_mdsin[lng]; + s->geometry[verti15 + 5] = g_mdcos[lng]; } + while (++verti < (m->head.numframes * s->numverts)); trii = 0; - while (trii < s->numtris) + do // while (++trii < s->numtris) { + uint32_t tris15[3]; + // let the vertices know they're being referenced by a triangle - if (s->tris[trii].i[0] >= s->numverts || s->tris[trii].i[0] < 0 || - s->tris[trii].i[1] >= s->numverts || s->tris[trii].i[1] < 0 || - s->tris[trii].i[2] >= s->numverts || s->tris[trii].i[2] < 0) + if ((unsigned) s->tris[trii].i[0] >= (unsigned) s->numverts || + (unsigned) s->tris[trii].i[1] >= (unsigned) s->numverts || + (unsigned) s->tris[trii].i[2] >= (unsigned) s->numverts) { // corrupt model - Bfree(numtris); -// OSD_Printf("Triangle index out of bounds!\n"); return 0; } - numtris[s->tris[trii].i[0]]++; - numtris[s->tris[trii].i[1]]++; - numtris[s->tris[trii].i[2]]++; + tribuf[s->tris[trii].i[0]]++; + tribuf[s->tris[trii].i[1]]++; + tribuf[s->tris[trii].i[2]]++; + + tris15[0] = (s->tris[trii].i[0]<<4)-s->tris[trii].i[0]; + tris15[1] = (s->tris[trii].i[1]<<4)-s->tris[trii].i[1]; + tris15[2] = (s->tris[trii].i[2]<<4)-s->tris[trii].i[2]; + framei = 0; - while (framei < m->head.numframes) + do // while (++framei < m->head.numframes) { - vec1[0] = s->geometry[(framei * s->numverts * 15) + (s->tris[trii].i[1] * 15) + 0] - - s->geometry[(framei * s->numverts * 15) + (s->tris[trii].i[0] * 15) + 0]; - vec1[1] = s->geometry[(framei * s->numverts * 15) + (s->tris[trii].i[1] * 15) + 1] - - s->geometry[(framei * s->numverts * 15) + (s->tris[trii].i[0] * 15) + 1]; - vec1[2] = s->geometry[(framei * s->numverts * 15) + (s->tris[trii].i[1] * 15) + 2] - - s->geometry[(framei * s->numverts * 15) + (s->tris[trii].i[0] * 15) + 2]; + const uint32_t verti15 = framei * s->numverts * 15; + + vec1[0] = s->geometry[verti15 + tris15[1]] - s->geometry[verti15 + tris15[0]]; + vec1[1] = s->geometry[verti15 + tris15[1] + 1] - s->geometry[verti15 + tris15[0] + 1]; + vec1[2] = s->geometry[verti15 + tris15[1] + 2] - s->geometry[verti15 + tris15[0] + 2]; vec1[3] = s->uv[s->tris[trii].i[1]].u - s->uv[s->tris[trii].i[0]].u; vec1[4] = s->uv[s->tris[trii].i[1]].v - s->uv[s->tris[trii].i[0]].v; - vec2[0] = s->geometry[(framei * s->numverts * 15) + (s->tris[trii].i[2] * 15) + 0] - - s->geometry[(framei * s->numverts * 15) + (s->tris[trii].i[1] * 15) + 0]; - vec2[1] = s->geometry[(framei * s->numverts * 15) + (s->tris[trii].i[2] * 15) + 1] - - s->geometry[(framei * s->numverts * 15) + (s->tris[trii].i[1] * 15) + 1]; - vec2[2] = s->geometry[(framei * s->numverts * 15) + (s->tris[trii].i[2] * 15) + 2] - - s->geometry[(framei * s->numverts * 15) + (s->tris[trii].i[1] * 15) + 2]; + vec2[0] = s->geometry[verti15 + tris15[2] ] - s->geometry[verti15 + tris15[1]]; + vec2[1] = s->geometry[verti15 + tris15[2] + 1] - s->geometry[verti15 + tris15[1] + 1]; + vec2[2] = s->geometry[verti15 + tris15[2] + 2] - s->geometry[verti15 + tris15[1] + 2]; vec2[3] = s->uv[s->tris[trii].i[2]].u - s->uv[s->tris[trii].i[1]].u; vec2[4] = s->uv[s->tris[trii].i[2]].v - s->uv[s->tris[trii].i[1]].v; r = (vec1[3] * vec2[4] - vec2[3] * vec1[4]); if (r != 0.0f) { - r = 1.0 / r; + r = 1.f/r; // tangent mat[0] = (vec2[4] * vec1[0] - vec1[4] * vec2[0]) * r; @@ -1878,42 +1825,39 @@ int md3postload_polymer(md3model_t *m) normalize(&mat[3]); } - else - { - mat[0] = mat[1] = mat[2] = 0.0f; - mat[3] = mat[4] = mat[5] = 0.0f; - } + else Bmemset(mat, 0, sizeof(float) * 6); // T and B are shared for the three vertices in that triangle i = 0; - while (i < 6) + do { - s->geometry[(framei * s->numverts * 15) + (s->tris[trii].i[0] * 15) + 6 + i] += mat[i]; - s->geometry[(framei * s->numverts * 15) + (s->tris[trii].i[1] * 15) + 6 + i] += mat[i]; - s->geometry[(framei * s->numverts * 15) + (s->tris[trii].i[2] * 15) + 6 + i] += mat[i]; - i++; + const uint32_t offs = (framei * s->numverts * 15) + i + 6; + + s->geometry[offs + tris15[0]] += mat[i]; + s->geometry[offs + tris15[1]] += mat[i]; + s->geometry[offs + tris15[2]] += mat[i]; } - - framei++; + while (++i < 6); } - - trii++; + while (++framei < m->head.numframes); } + while (++trii < s->numtris); // now that we accumulated the TBNs, average and invert them for each vertex - verti = 0; - while (verti < (m->head.numframes * s->numverts)) + verti = (m->head.numframes * s->numverts)-1; + + do // while (verti-- > 0) { - int32_t curnumtris = numtris[verti % s->numverts]; + const int32_t curnumtris = tribuf[verti % s->numverts]; + const uint32_t verti15 = (verti<<4) - verti; if (curnumtris > 0) { + const float rfcurnumtris = 1.f/(float)curnumtris; i = 6; - while (i < 12) - { - s->geometry[(verti * 15) + i] /= curnumtris; - i++; - } + do { + s->geometry[verti15 + i] *= rfcurnumtris; + } while (++i < 12); } #ifdef DEBUG_MODEL_MEM else if (verti == verti%s->numverts) @@ -1922,20 +1866,13 @@ int md3postload_polymer(md3model_t *m) } #endif // copy N over - s->geometry[(verti * 15) + 12] = s->geometry[(verti * 15) + 3]; - s->geometry[(verti * 15) + 13] = s->geometry[(verti * 15) + 4]; - s->geometry[(verti * 15) + 14] = s->geometry[(verti * 15) + 5]; - - invertmatrix(&s->geometry[(verti * 15) + 6], mat); - memcpy(&s->geometry[(verti * 15) + 6], mat, sizeof(float) * 9); - - verti++; + Bmemcpy(&s->geometry[verti15 + 12], &s->geometry[verti15 + 3], sizeof(float) * 3); + invertmatrix(&s->geometry[verti15 + 6], mat); + Bmemcpy(&s->geometry[verti15 + 6], mat, sizeof(float) * 9); } - - Bfree(numtris); - - surfi++; + while (verti-- > 0); } + while (++surfi < m->head.numsurfs); #else UNREFERENCED_PARAMETER(m); @@ -1945,17 +1882,17 @@ int md3postload_polymer(md3model_t *m) } -static void md3_vox_calcmat_common(const spritetype *tspr, const point3d *a0, float f, float mat[16]) +void md3_vox_calcmat_common(const spritetype *tspr, const vec3f_t *a0, float f, float mat[16]) { float g; float k0, k1, k2, k3, k4, k5, k6, k7; - k0 = ((float)(tspr->x-globalposx))*f/1024.0; - k1 = ((float)(tspr->y-globalposy))*f/1024.0; + k0 = ((float)(tspr->x-globalposx))*f*(1.f/1024.f); + k1 = ((float)(tspr->y-globalposy))*f*(1.f/1024.f); f = gcosang2*gshang; g = gsinang2*gshang; - k4 = (float)sintable[(tspr->ang+spriteext[tspr->owner].angoff+1024)&2047] / 16384.0; - k5 = (float)sintable[(tspr->ang+spriteext[tspr->owner].angoff+ 512)&2047] / 16384.0; + k4 = (float)sintable[(tspr->ang+spriteext[tspr->owner].angoff+1024)&2047] * (1.f/16384.f); + k5 = (float)sintable[(tspr->ang+spriteext[tspr->owner].angoff+ 512)&2047] * (1.f/16384.f); k2 = k0*(1-k4)+k1*k5; k3 = k1*(1-k4)-k0*k5; k6 = f*gstang - gsinang*gctang; k7 = g*gstang + gcosang*gctang; @@ -1965,57 +1902,63 @@ static void md3_vox_calcmat_common(const spritetype *tspr, const point3d *a0, fl k6 = gcosang2*gchang; k7 = gsinang2*gchang; mat[2] = k4*k6 + k5*k7; mat[6] =-gshang; mat[10] = k4*k7 - k5*k6; mat[14] = k2*k6 + k3*k7; - mat[12] += a0->y*mat[0] + a0->z*mat[4] + a0->x*mat[ 8]; - mat[13] += a0->y*mat[1] + a0->z*mat[5] + a0->x*mat[ 9]; - mat[14] += a0->y*mat[2] + a0->z*mat[6] + a0->x*mat[10]; + mat[12] = (mat[12] + a0->y*mat[0]) + (a0->z*mat[4] + a0->x*mat[ 8]); + mat[13] = (mat[13] + a0->y*mat[1]) + (a0->z*mat[5] + a0->x*mat[ 9]); + mat[14] = (mat[14] + a0->y*mat[2]) + (a0->z*mat[6] + a0->x*mat[10]); } static inline void md3draw_handle_triangles(const md3surf_t *s, uint16_t *indexhandle, int32_t texunits, const md3model_t *M) { - int32_t i, j; + int32_t i; if (r_vertexarrays) { int32_t k = 0; + uint16_t tri; + for (i=s->numtris-1; i>=0; i--) { - uint16_t tri = M ? M->indexes[i] : i; + tri = M ? M->indexes[i] : i; - for (j=0; j<3; j++) - indexhandle[k++] = s->tris[tri].i[j]; + indexhandle[k] = s->tris[tri].i[0]; + indexhandle[k+1] = s->tris[tri].i[1]; + indexhandle[k+2] = s->tris[tri].i[2]; + + k += 3; } + + return; } - else + + bglBegin(GL_TRIANGLES); + for (i=s->numtris-1; i>=0; i--) { - bglBegin(GL_TRIANGLES); - for (i=s->numtris-1; i>=0; i--) + uint16_t tri = M ? M->indexes[i] : i; + int32_t j; + + for (j=0; j<3; j++) { - uint16_t tri = M ? M->indexes[i] : i; + int32_t k = s->tris[tri].i[j]; - for (j=0; j<3; j++) + if (texunits > GL_TEXTURE0_ARB) { - int32_t k = s->tris[tri].i[j]; - - if (texunits > GL_TEXTURE0_ARB) - { - int32_t l = GL_TEXTURE0_ARB; - while (l <= texunits) - bglMultiTexCoord2fARB(l++, s->uv[k].u,s->uv[k].v); - } - else - bglTexCoord2f(s->uv[k].u,s->uv[k].v); - - bglVertex3fv((float *)&vertlist[k]); + int32_t l = GL_TEXTURE0_ARB; + while (l <= texunits) + bglMultiTexCoord2fARB(l++, s->uv[k].u, s->uv[k].v); } + else + bglTexCoord2f(s->uv[k].u, s->uv[k].v); + + bglVertex3fv((float *) &vertlist[k]); } - bglEnd(); } + bglEnd(); } -static int32_t md3draw(md3model_t *m, const spritetype *tspr) +static int32_t polymost_md3draw(md3model_t *m, const spritetype *tspr) { - point3d m0, m1, a0; + vec3f_t m0, m1, a0; md3xyzn_t *v0, *v1; int32_t i, surfi; float f, g, k0, k1, k2=0, k3=0, mat[16]; // inits: compiler-happy @@ -2048,34 +1991,27 @@ static int32_t md3draw(md3model_t *m, const spritetype *tspr) OSD_Printf("%s: mdframe oob: c:%d n:%d total:%d interpol:%.02f\n", m->head.nam, m->cframe, m->nframe, m->numframes, m->interpol); #endif - if (m->interpol < 0) - m->interpol = 0; - if (m->interpol > 1) - m->interpol = 1; - if (m->cframe < 0) - m->cframe = 0; - if (m->cframe >= m->numframes) - m->cframe = m->numframes - 1; - if (m->nframe < 0) - m->nframe = 0; - if (m->nframe >= m->numframes) - m->nframe = m->numframes - 1; + + m->interpol = fclamp(m->interpol, 0.f, 1.f); + m->cframe = clamp(m->cframe, 0, m->numframes-1); + m->nframe = clamp(m->nframe, 0, m->numframes-1); } if (MFLAGS_NOCONV(m)) { // md2 - m0.x = m->scale * g; m1.x = m->scale *f; - m0.y = m->scale * g; m1.y = m->scale *f; - m0.z = m->scale * g; m1.z = m->scale *f; + g *= m->scale; + f *= m->scale; } else { - m0.x = (1.0/64.0) * m->scale * g; m1.x = (1.0/64.0) * m->scale *f; - m0.y = (1.0/64.0) * m->scale * g; m1.y = (1.0/64.0) * m->scale *f; - m0.z = (1.0/64.0) * m->scale * g; m1.z = (1.0/64.0) * m->scale *f; + g = m->scale * g * (1.f/64.f); + f = m->scale * f * (1.f/64.f); } + m0.x = g; m0.y = g; m0.z = g; + m1.x = f; m1.y = f; m1.z = f; + a0.x = a0.y = 0; a0.z = m->zadd*m->scale; // Parkar: Moved up to be able to use k0 for the y-flipping code @@ -2094,10 +2030,11 @@ static int32_t md3draw(md3model_t *m, const spritetype *tspr) // yoffset differs from zadd in that it does not follow cstat&8 y-flipping a0.z += m->yoffset*m->scale; - f = ((float)tspr->xrepeat)/64*m->bscale; - m0.x *= f; m1.x *= f; a0.x *= f; f = -f; // 20040610: backwards models aren't cool - m0.y *= f; m1.y *= f; a0.y *= f; - f = ((float)tspr->yrepeat)/64*m->bscale; + f = ((float)tspr->xrepeat) * (1.f/64.f) * m->bscale; + m0.x *= f; m0.y *= -f; + m1.x *= f; m1.y *= -f; + a0.x *= f; a0.y *= -f; + f = ((float)tspr->yrepeat) * (1.f/64.f) * m->bscale; m0.z *= f; m1.z *= f; a0.z *= f; // floor aligned @@ -2112,20 +2049,20 @@ static int32_t md3draw(md3model_t *m, const spritetype *tspr) // Note: These SCREEN_FACTORS will be neutralized in axes offset // calculations below again, but are needed for the base offsets. - f = (65536.0*512.0)/((float)xdimen*viewingrange); - g = 32.0/((float)xdimen*gxyaspect); - m0.y *= f; m1.y *= f; a0.y = (((float)(tspr->x-globalposx))/ 1024.0 + a0.y)*f; - m0.x *=-f; m1.x *=-f; a0.x = (((float)(k1 -globalposy))/ -1024.0 + a0.x)*-f; - m0.z *= g; m1.z *= g; a0.z = (((float)(k0 -globalposz))/-16384.0 + a0.z)*g; + f = (65536.f*512.f)/((float)xdimen*viewingrange); + g = 32.f/((float)xdimen*gxyaspect); + m0.y *= f; m1.y *= f; a0.y = (((float)(tspr->x-globalposx))* (1.f/1024.f) + a0.y)*f; + m0.x *=-f; m1.x *=-f; a0.x = (((float)(k1 -globalposy))* -(1.f/1024.f) + a0.x)*-f; + m0.z *= g; m1.z *= g; a0.z = (((float)(k0 -globalposz))* -(1.f/16384.f) + a0.z)*g; md3_vox_calcmat_common(tspr, &a0, f, mat); // floor aligned if ((globalorientation&48)==32) { - f = mat[4]; mat[4] = mat[8]*16.0; mat[8] = -f*(1.0/16.0); - f = mat[5]; mat[5] = mat[9]*16.0; mat[9] = -f*(1.0/16.0); - f = mat[6]; mat[6] = mat[10]*16.0; mat[10] = -f*(1.0/16.0); + f = mat[4]; mat[4] = mat[8]*16.f; mat[8] = -f*(1.f/16.f); + f = mat[5]; mat[5] = mat[9]*16.f; mat[9] = -f*(1.f/16.f); + f = mat[6]; mat[6] = mat[10]*16.f; mat[10] = -f*(1.f/16.f); } //Mirrors @@ -2188,29 +2125,29 @@ static int32_t md3draw(md3model_t *m, const spritetype *tspr) // PLAG: Cleaner model rotation code if (sext->pitch || sext->roll || MFLAGS_NOCONV(m)) { + float f = 1.f/((float)(xdimen*viewingrange)*(m0.x+m1.x)*(2560.f*(1.f/(65536.f*1280.f)))); + Bmemset(&a0, 0, sizeof(a0)); + if (sext->xoff) - a0.x = (float)(sext->xoff / (2560 * (m0.x+m1.x) * ((float)xdimen*viewingrange)/(65536.0*1280.0))); - else - a0.x = 0; + a0.x = (float) sext->xoff * f; + if (sext->yoff) // Compare with SCREEN_FACTORS above - a0.y = (float)(sext->yoff / (2560 * (m0.x+m1.x) * ((float)xdimen*viewingrange)/(65536.0*1280.0))); - else - a0.y = 0; + a0.y = (float) sext->yoff * f; + if ((sext->zoff) && !(tspr->cstat&CSTAT_SPRITE_MDHACK)) // Compare with SCREEN_FACTORS above - a0.z = (float)(sext->zoff / (655360 * (m0.z+m1.z) * (gxyaspect*xdimen/1280.0))); - else - a0.z = 0; - k0 = (float)sintable[(sext->pitch+512)&2047] / 16384.0; - k1 = (float)sintable[sext->pitch&2047] / 16384.0; - k2 = (float)sintable[(sext->roll+512)&2047] / 16384.0; - k3 = (float)sintable[sext->roll&2047] / 16384.0; + a0.z = (float)sext->zoff / (655360.f * (m0.z+m1.z) * (gxyaspect*xdimen*(1.f/1280.f))); + + k0 = (float)sintable[(sext->pitch+512)&2047] * (1.f/16384.f); + k1 = (float)sintable[sext->pitch&2047] * (1.f/16384.f); + k2 = (float)sintable[(sext->roll+512)&2047] * (1.f/16384.f); + k3 = (float)sintable[sext->roll&2047] * (1.f/16384.f); } for (surfi=0; surfihead.numsurfs; surfi++) { //PLAG : sorting stuff void *vbotemp; - point3d *vertexhandle = NULL; + vec3f_t *vertexhandle = NULL; uint16_t *indexhandle; const md3surf_t *const s = &m->head.surfs[surfi]; @@ -2225,26 +2162,50 @@ static int32_t md3draw(md3model_t *m, const spritetype *tspr) bglBindBufferARB(GL_ARRAY_BUFFER_ARB, vertvbos[curvbo]); vbotemp = bglMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); - vertexhandle = (point3d *)vbotemp; + vertexhandle = (vec3f_t *)vbotemp; } for (i=s->numverts-1; i>=0; i--) { - point3d fp; + vec3f_t fp; if (sext->pitch || sext->roll || MFLAGS_NOCONV(m)) { - point3d fp1, fp2; + vec3f_t fp1, fp2; + + if (MFLAGS_NOCONV(m)) + { + const int32_t mcf = m->cframe<<1; + const int32_t mnf = m->nframe<<1; + + fp.z = (v0[i].x * m->muladdframes[mcf].x) + (m->muladdframes[mcf+1].x + a0.x); + fp.x = (v0[i].y * m->muladdframes[mcf].y) + (m->muladdframes[mcf+1].y + a0.y); + fp.y = (v0[i].z * m->muladdframes[mcf].z) + (m->muladdframes[mcf+1].z + a0.z); + + fp1.x = fp.x*k2 + fp.y*k3; + fp1.y = fp.x*k0*(-k3) + fp.y*k0*k2 + fp.z*(-k1); + fp1.z = fp.x*k1*(-k3) + fp.y*k1*k2 + fp.z*k0; + + fp.z = (v1[i].x * m->muladdframes[mnf].x) + (m->muladdframes[mnf+1].x + a0.x); + fp.x = (v1[i].y * m->muladdframes[mnf].y) + (m->muladdframes[mnf+1].y + a0.y); + fp.y = (v1[i].z * m->muladdframes[mnf].z) + (m->muladdframes[mnf+1].z + a0.z); + + } + else + { + fp.z = v0[i].x + a0.x; + fp.x = v0[i].y + a0.y; + fp.y = v0[i].z + a0.z; + + fp1.x = fp.x*k2 + fp.y*k3; + fp1.y = fp.x*k0*(-k3) + fp.y*k0*k2 + fp.z*(-k1); + fp1.z = fp.x*k1*(-k3) + fp.y*k1*k2 + fp.z*k0; + + fp.z = v1[i].x + a0.x; + fp.x = v1[i].y + a0.y; + fp.y = v1[i].z + a0.z; + } - fp.z = ((MFLAGS_NOCONV(m)) ? (v0[i].x * m->muladdframes[m->cframe*2].x) + m->muladdframes[m->cframe*2+1].x : v0[i].x) + a0.x; - fp.x = ((MFLAGS_NOCONV(m)) ? (v0[i].y * m->muladdframes[m->cframe*2].y) + m->muladdframes[m->cframe*2+1].y : v0[i].y) + a0.y; - fp.y = ((MFLAGS_NOCONV(m)) ? (v0[i].z * m->muladdframes[m->cframe*2].z) + m->muladdframes[m->cframe*2+1].z : v0[i].z) + a0.z; - fp1.x = fp.x*k2 + fp.y*k3; - fp1.y = fp.x*k0*(-k3) + fp.y*k0*k2 + fp.z*(-k1); - fp1.z = fp.x*k1*(-k3) + fp.y*k1*k2 + fp.z*k0; - fp.z = ((MFLAGS_NOCONV(m)) ? (v1[i].x * m->muladdframes[m->nframe*2].x) + m->muladdframes[m->nframe*2+1].x : v1[i].x) + a0.x; - fp.x = ((MFLAGS_NOCONV(m)) ? (v1[i].y * m->muladdframes[m->nframe*2].y) + m->muladdframes[m->nframe*2+1].y : v1[i].y) + a0.y; - fp.y = ((MFLAGS_NOCONV(m)) ? (v1[i].z * m->muladdframes[m->nframe*2].z) + m->muladdframes[m->nframe*2+1].z : v1[i].z) + a0.z; fp2.x = fp.x*k2 + fp.y*k3; fp2.y = fp.x*k0*(-k3) + fp.y*k0*k2 + fp.z*(-k1); fp2.z = fp.x*k1*(-k3) + fp.y*k1*k2 + fp.z*k0; @@ -2260,14 +2221,9 @@ static int32_t md3draw(md3model_t *m, const spritetype *tspr) } if (r_vertexarrays && r_vbos) - { - vertexhandle[i].x = fp.x; - vertexhandle[i].y = fp.y; - vertexhandle[i].z = fp.z; - } - vertlist[i].x = fp.x; - vertlist[i].y = fp.y; - vertlist[i].z = fp.z; + vertexhandle[i] = fp; + + vertlist[i] = fp; } if (r_vertexarrays && r_vbos) @@ -2328,7 +2284,7 @@ static int32_t md3draw(md3model_t *m, const spritetype *tspr) { for (i=s->numtris-1; i>=0; i--) { - point3d fp, fp1, fp2; + vec3f_t fp, fp1, fp2; // Matrix multiplication - ugly but clear fp.x = (vertlist[s->tris[i].i[0]].x * mat[0]) + (vertlist[s->tris[i].i[0]].y * mat[4]) + (vertlist[s->tris[i].i[0]].z * mat[8]) + mat[12]; @@ -2503,818 +2459,6 @@ static void md3free(md3model_t *m) } //---------------------------------------- MD3 LIBRARY ENDS ---------------------------------------- -//--------------------------------------- VOX LIBRARY BEGINS --------------------------------------- - -//For loading/conversion only -static int32_t xsiz, ysiz, zsiz, yzsiz, *vbit = 0; //vbit: 1 bit per voxel: 0=air,1=solid -static float xpiv, ypiv, zpiv; //Might want to use more complex/unique names! -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; -typedef struct { int16_t x, y; } spoint2d; -static spoint2d *shp; -static int32_t *shcntmal, *shcnt = 0, shcntp; -static int32_t mytexo5, *zbit, gmaxx, gmaxy, garea, pow2m1[33]; -static voxmodel_t *gvox; - -//pitch must equal xsiz*4 -uint32_t gloadtex(int32_t *picbuf, int32_t xsiz, int32_t ysiz, int32_t is8bit, int32_t dapal) -{ - uint32_t rtexid; - int32_t i; - - const char *const cptr = &britable[gammabrightness ? 0 : curbrightness][0]; - - // Correct for GL's RGB order; also apply gamma here: - const coltype *const pic = (const coltype *)picbuf; - coltype *pic2 = (coltype *)Xmalloc(xsiz*ysiz*sizeof(coltype)); - - if (!is8bit) - { - for (i=xsiz*ysiz-1; i>=0; i--) - { - pic2[i].b = cptr[pic[i].r]; - pic2[i].g = cptr[pic[i].g]; - pic2[i].r = cptr[pic[i].b]; - pic2[i].a = 255; - } - } - else - { - if (palookup[dapal] == NULL) - dapal = 0; - - for (i=xsiz*ysiz-1; i>=0; i--) - { - const int32_t ii = palookup[dapal][pic[i].a] * 3; - - pic2[i].b = cptr[palette[ii+2]*4]; - pic2[i].g = cptr[palette[ii+1]*4]; - pic2[i].r = cptr[palette[ii+0]*4]; - pic2[i].a = 255; - } - } - - bglGenTextures(1,(GLuint *)&rtexid); - bglBindTexture(GL_TEXTURE_2D,rtexid); - bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); - bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); - bglTexImage2D(GL_TEXTURE_2D,0,4,xsiz,ysiz,0,GL_RGBA,GL_UNSIGNED_BYTE,(char *)pic2); - - Bfree(pic2); - - return rtexid; -} - -static int32_t getvox(int32_t x, int32_t y, int32_t z) -{ - z += x*yzsiz + y*zsiz; - for (x=vcolhashead[(z*214013)&vcolhashsizm1]; x>=0; x=vcol[x].n) - if (vcol[x].p == z) return(vcol[x].c); - return(0x808080); -} - -static void putvox(int32_t x, int32_t y, int32_t z, int32_t col) -{ - if (vnum >= vmax) { vmax = max(vmax<<1,4096); vcol = (voxcol_t *)Xrealloc(vcol,vmax*sizeof(voxcol_t)); } - - z += x*yzsiz + y*zsiz; - vcol[vnum].p = z; z = ((z*214013)&vcolhashsizm1); - 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) -{ - int32_t z, ze; - if (!((z0^z1)&~31)) { lptr[z0>>5] &= ((~(-1<>5); ze = (z1>>5); - lptr[z] &=~(-1<>5] |= ((~(-1<>5); ze = (z1>>5); - lptr[z] |= (-1<mytexx + x0; - for (dy=0; dy; dy--,i+=gvox->mytexx) - for (x=0; x>5]&(1<>5); dx += x0-1; c = (dx>>5) - (x0>>5); - m = ~pow2m1[x0&31]; m1 = pow2m1[(dx&31)+1]; - if (!c) { for (m&=m1; dy; dy--,i+=mytexo5) if (zbit[i]&m) return(0); } - else - { - for (; dy; dy--,i+=mytexo5) - { - if (zbit[i]&m) return(0); - for (x=1; xmytexx + x0; - for (y=0; ymytexx) - for (x=0; x>5] |= (1<>5); dx += x0-1; c = (dx>>5) - (x0>>5); - m = ~pow2m1[x0&31]; m1 = pow2m1[(dx&31)+1]; - if (!c) { for (m&=m1; dy; dy--,i+=mytexo5) zbit[i] |= m; } - else - { - for (; dy; dy--,i+=mytexo5) - { - zbit[i] |= m; - for (x=1; x gmaxx) gmaxx = x; - if (y > gmaxy) gmaxy = y; - garea += (x+(VOXBORDWIDTH<<1))*(y+(VOXBORDWIDTH<<1)); - gvox->qcnt++; -} - -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) -{ - int32_t i, j, x, y, z, xx, yy, nx = 0, ny = 0, nz = 0, *lptr; - voxrect_t *qptr; - - x = labs(x2-x0); y = labs(y2-y0); z = labs(z2-z0); - if (!x) { x = y; y = z; i = 0; } - else if (!y) { y = z; i = 1; } - else i = 2; - if (x < y) { z = x; x = y; y = z; i += 3; } - z = shcnt[y*shcntp+x]++; - lptr = &gvox->mytex[(shp[z].y+VOXBORDWIDTH)*gvox->mytexx+(shp[z].x+VOXBORDWIDTH)]; - 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; - } - for (yy=0; yymytexx) - for (xx=0; xxmytex[(shp[z].y+yy)*gvox->mytexx+shp[z].x]; - lptr[xx] = lptr[VOXBORDWIDTH]; lptr[xx+x+VOXBORDWIDTH] = lptr[x-1+VOXBORDWIDTH]; - } - //Extend borders vertically - for (yy=0; yymytex[(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); - } - - qptr = &gvox->quad[gvox->qcnt]; - 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; - for (j=0; j<3; j++) { 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; - - 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; - if (gvox->qfacind[face] < 0) gvox->qfacind[face] = gvox->qcnt; - gvox->qcnt++; - -} - -static int32_t isolid(int32_t x, int32_t y, int32_t z) -{ - if ((uint32_t)x >= (uint32_t)xsiz) return(0); - if ((uint32_t)y >= (uint32_t)ysiz) return(0); - if ((uint32_t)z >= (uint32_t)zsiz) return(0); - z += x*yzsiz + y*zsiz; return(vbit[z>>5]&(1<qfacind[i] = -1; - - i = ((max(ysiz,zsiz)+1)<<2); - bx0 = (int32_t *)Xmalloc(i<<1); - by0 = (int32_t *)(((intptr_t)bx0)+i); - - for (cnt=0; cnt<2; cnt++) - { - if (!cnt) daquad = cntquad; - else daquad = addquad; - gvox->qcnt = 0; - - memset(by0,-1,(max(ysiz,zsiz)+1)<<2); v = 0; - - for (i=-1; i<=1; i+=2) - for (y=0; y= 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; } - } - - for (i=-1; i<=1; i+=2) - for (z=0; z= 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; } - } - - for (i=-1; i<=1; i+=2) - for (x=0; x= 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; } - } - - if (!cnt) - { - shp = (spoint2d *)Xmalloc(gvox->qcnt*sizeof(spoint2d)); - - sc = 0; - for (y=gmaxy; y; y--) - for (x=gmaxx; x>=y; x--) - { - 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++; } - } - - for (gvox->mytexx=32; gvox->mytexx<(gmaxx+(VOXBORDWIDTH<<1)); gvox->mytexx<<=1); - for (gvox->mytexy=32; gvox->mytexy<(gmaxy+(VOXBORDWIDTH<<1)); gvox->mytexy<<=1); - while (gvox->mytexx*gvox->mytexy*8 < garea*9) //This should be sufficient to fit most skins... - { -skindidntfit: - ; - if (gvox->mytexx <= gvox->mytexy) gvox->mytexx <<= 1; else gvox->mytexy <<= 1; - } - mytexo5 = (gvox->mytexx>>5); - - i = (((gvox->mytexx*gvox->mytexy+31)>>5)<<2); - zbit = (int32_t *)Xmalloc(i); - memset(zbit,0,i); - - v = gvox->mytexx*gvox->mytexy; - for (z=0; zmytexx,255)-dx))>>15); - y0 = (((rand()&32767)*(min(gvox->mytexy,255)-dy))>>15); -#else - x0 = (((rand()&32767)*(gvox->mytexx+1-dx))>>15); - y0 = (((rand()&32767)*(gvox->mytexy+1-dy))>>15); -#endif - i--; - if (i < 0) //Time-out! Very slow if this happens... but at least it still works :P - { - Bfree(zbit); - - //Re-generate shp[].x/y (box sizes) from shcnt (now head indices) for next pass :/ - j = 0; - for (y=gmaxy; y; y--) - for (x=gmaxx; x>=y; x--) - { - i = shcnt[y*shcntp+x]; - for (; jquad = (voxrect_t *)Xmalloc(gvox->qcnt*sizeof(voxrect_t)); - gvox->mytex = (int32_t *)Xmalloc(gvox->mytexx*gvox->mytexy*sizeof(int32_t)); - } - } - Bfree(shp); Bfree(zbit); Bfree(bx0); - return(gvox); -} - -static int32_t loadvox(const char *filnam) -{ - int32_t i, j, k, x, y, z, pal[256], fil; - char c[3], *tbuf; - - fil = kopen4load(filnam,0); if (fil < 0) return(-1); - kread(fil,&xsiz,4); xsiz = B_LITTLE32(xsiz); - kread(fil,&ysiz,4); ysiz = B_LITTLE32(ysiz); - kread(fil,&zsiz,4); zsiz = B_LITTLE32(zsiz); - xpiv = ((float)xsiz)*.5; - ypiv = ((float)ysiz)*.5; - zpiv = ((float)zsiz)*.5; - - klseek(fil,-768,SEEK_END); - for (i=0; i<256; i++) - { kread(fil,c,3); pal[i] = (((int32_t)c[0])<<18)+(((int32_t)c[1])<<10)+(((int32_t)c[2])<<2)+(i<<24); } - pal[255] = -1; - - vcolhashsizm1 = 8192-1; - vcolhashead = (int32_t *)Xmalloc((vcolhashsizm1+1)*sizeof(int32_t)); - memset(vcolhashead,-1,(vcolhashsizm1+1)*sizeof(int32_t)); - - yzsiz = ysiz*zsiz; i = ((xsiz*yzsiz+31)>>3)+1; - vbit = (int32_t *)Xmalloc(i); - memset(vbit,0,i); - - tbuf = (char *)Xmalloc(zsiz*sizeof(uint8_t)); - - klseek(fil,12,SEEK_SET); - for (x=0; x=0; z--) - { if (tbuf[z] != 255) { i = j+z; vbit[i>>5] |= (1<>5]&(1<>5]&(1<>5]&(1<>5]&(1<>5]&(1<>5]&(1<=0; i--) xyoffs[i] = B_LITTLE16(xyoffs[i]); - - klseek(fil,-768,SEEK_END); - for (i=0; i<256; i++) - { kread(fil,c,3); pal[i] = B_LITTLE32((((int32_t)c[0])<<18)+(((int32_t)c[1])<<10)+(((int32_t)c[2])<<2)+(i<<24)); } - - yzsiz = ysiz*zsiz; i = ((xsiz*yzsiz+31)>>3)+1; - vbit = (int32_t *)Xmalloc(i); - memset(vbit,0,i); - - for (vcolhashsizm1=4096; vcolhashsizm1<(mip1leng>>1); vcolhashsizm1<<=1) - { - /* do nothing */ - } - vcolhashsizm1--; //approx to numvoxs! - vcolhashead = (int32_t *)Xmalloc((vcolhashsizm1+1)*sizeof(int32_t)); - memset(vcolhashead,-1,(vcolhashsizm1+1)*sizeof(int32_t)); - - klseek(fil,28+((xsiz+1)<<2)+((ysizp1*xsiz)<<1),SEEK_SET); - - i = kfilelength(fil)-ktell(fil); - tbuf = (char *)Xmalloc(i); - kread(fil,tbuf,i); kclose(fil); - - cptr = tbuf; - for (x=0; x=0; i--) ylen[i] = B_LITTLE16(ylen[i]); - klseek(fil,32,SEEK_SET); - - yzsiz = ysiz*zsiz; i = ((xsiz*yzsiz+31)>>3)+1; - vbit = (int32_t *)Xmalloc(i); - memset(vbit,0,i); - - for (vcolhashsizm1=4096; vcolhashsizm10; i--) - { - kread(fil,c,8); //b,g,r,a,z_lo,z_hi,vis,dir - z0 = B_LITTLE16(*(uint16_t *)&c[4]); - if (!(c[6]&16)) setzrange1(vbit,j+z1,j+z0); - vbit[(j+z0)>>5] |= (1<>3); - vbit = (int32_t *)Xmalloc(i); - memset(vbit,-1,i); - - vcolhashsizm1 = 1048576-1; - vcolhashead = (int32_t *)Xmalloc((vcolhashsizm1+1)*sizeof(int32_t)); - memset(vcolhashead,-1,(vcolhashsizm1+1)*sizeof(int32_t)); - - //Allocate huge buffer and load rest of file into it... - i = kfilelength(fil)-ktell(fil); - vbuf = (char *)Xmalloc(i); - kread(fil,vbuf,i); - kclose(fil); - - v = vbuf; - for (y=0; ymytex) Bfree(m->mytex); - if (m->quad) Bfree(m->quad); - if (m->texid) Bfree(m->texid); - Bfree(m); -} - -voxmodel_t *voxload(const char *filnam) -{ - int32_t i, is8bit, ret; - voxmodel_t *vm; - - i = strlen(filnam)-4; if (i < 0) return(0); - 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(0); - if (ret >= 0) vm = vox2poly(); else vm = 0; - if (vm) - { - vm->mdnum = 1; //VOXel model id - vm->scale = vm->bscale = 1.0; - vm->xsiz = xsiz; vm->ysiz = ysiz; vm->zsiz = zsiz; - vm->xpiv = xpiv; vm->ypiv = ypiv; vm->zpiv = zpiv; - vm->is8bit = is8bit; - - vm->texid = (uint32_t *)Xcalloc(MAXPALOOKUPS,sizeof(uint32_t)); - } - if (shcntmal) { Bfree(shcntmal); shcntmal = 0; } - if (vbit) { Bfree(vbit); vbit = 0; } - if (vcol) { Bfree(vcol); vcol = 0; vnum = 0; vmax = 0; } - if (vcolhashead) { Bfree(vcolhashead); vcolhashead = 0; } - return(vm); -} - -//Draw voxel model as perfect cubes -int32_t voxdraw(voxmodel_t *m, const spritetype *tspr) -{ - point3d m0, a0; - int32_t i, j, fi, xx, yy, zz; - float ru, rv, phack[2]; //, clut[6] = {1.02,1.02,0.94,1.06,0.98,0.98}; - float f, g, k0, mat[16], omat[16], pc[4]; - vert_t *vptr; - - if ((intptr_t)m == (intptr_t)(-1)) // hackhackhack - return 0; - if ((tspr->cstat&48)==32) return 0; - - //updateanimation((md2model *)m,tspr); - - m0.x = m->scale; - m0.y = m->scale; - m0.z = m->scale; - a0.x = a0.y = 0; a0.z = ((globalorientation&8)?-m->zadd:m->zadd)*m->scale; - - //if (globalorientation&8) //y-flipping - //{ - // m0.z = -m0.z; a0.z = -a0.z; - // //Add height of 1st frame (use same frame to prevent animation bounce) - // a0.z += m->zsiz*m->scale; - //} - //if (globalorientation&4) { m0.y = -m0.y; a0.y = -a0.y; } //x-flipping - - f = ((float)tspr->xrepeat)*(256.0/320.0)/64.0*m->bscale; - if ((sprite[tspr->owner].cstat&48)==16) - f *= 1.25f; - - m0.x *= f; a0.x *= f; f = -f; - m0.y *= f; a0.y *= f; - f = ((float)tspr->yrepeat)/64.0*m->bscale; - m0.z *= f; a0.z *= f; - - k0 = (float)tspr->z; - if (globalorientation&128) k0 += (float)((tilesiz[tspr->picnum].y*tspr->yrepeat)<<1); - - f = (65536.0*512.0)/((float)xdimen*viewingrange); - g = 32.0/((float)xdimen*gxyaspect); - m0.y *= f; a0.y = (((float)(tspr->x-globalposx))/ 1024.0 + a0.y)*f; - m0.x *=-f; a0.x = (((float)(tspr->y-globalposy))/ -1024.0 + a0.x)*-f; - m0.z *= g; a0.z = (((float)(k0 -globalposz))/-16384.0 + a0.z)*g; - - md3_vox_calcmat_common(tspr, &a0, f, mat); - - //Mirrors - if (grhalfxdown10x < 0) { mat[0] = -mat[0]; mat[4] = -mat[4]; mat[8] = -mat[8]; mat[12] = -mat[12]; } - - if (tspr->cstat&CSTAT_SPRITE_MDHACK) - { - bglDepthFunc(GL_LESS); //NEVER,LESS,(,L)EQUAL,GREATER,(NOT,G)EQUAL,ALWAYS - bglDepthRange(0.0,0.9999); - } - bglPushAttrib(GL_POLYGON_BIT); - if ((grhalfxdown10x >= 0) /*^ ((globalorientation&8) != 0) ^ ((globalorientation&4) != 0)*/) bglFrontFace(GL_CW); else bglFrontFace(GL_CCW); - bglEnable(GL_CULL_FACE); - bglCullFace(GL_BACK); - - bglEnable(GL_TEXTURE_2D); - - pc[0] = pc[1] = pc[2] = ((float)(numshades-min(max((globalshade * shadescale)+m->shadeoff,0),numshades)))/((float)numshades); - hictinting_apply(pc, globalpal); - - if (tspr->cstat&2) { if (!(tspr->cstat&512)) pc[3] = 0.66f; else pc[3] = 0.33f; } - else pc[3] = 1.0f; - pc[3] *= 1.0f - spriteext[tspr->owner].alpha; - if ((tspr->cstat&2) || spriteext[tspr->owner].alpha > 0.f || pc[3] < 1.0f) bglEnable(GL_BLEND); //else bglDisable(GL_BLEND); - //------------ - - //transform to Build coords - Bmemcpy(omat,mat,sizeof(omat)); - 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; - mat[12] -= (m->xpiv*mat[0] + m->ypiv*mat[4] + (m->zpiv+m->zsiz*.5)*mat[ 8]); - mat[13] -= (m->xpiv*mat[1] + m->ypiv*mat[5] + (m->zpiv+m->zsiz*.5)*mat[ 9]); - mat[14] -= (m->xpiv*mat[2] + m->ypiv*mat[6] + (m->zpiv+m->zsiz*.5)*mat[10]); - bglMatrixMode(GL_MODELVIEW); //Let OpenGL (and perhaps hardware :) handle the matrix rotation - mat[3] = mat[7] = mat[11] = 0.f; mat[15] = 1.f; - - bglLoadMatrixf(mat); - - ru = 1.f/((float)m->mytexx); - rv = 1.f/((float)m->mytexy); -#if (VOXBORDWIDTH == 0) - uhack[0] = ru*.125; uhack[1] = -uhack[0]; - vhack[0] = rv*.125; vhack[1] = -vhack[0]; -#endif - phack[0] = 0; phack[1] = 1.f/256.f; - - if (!m->texid[globalpal]) m->texid[globalpal] = gloadtex(m->mytex,m->mytexx,m->mytexy,m->is8bit,globalpal); - else bglBindTexture(GL_TEXTURE_2D,m->texid[globalpal]); - bglBegin(GL_QUADS); - for (i=0,fi=0; iqcnt; i++) - { - if (i == m->qfacind[fi]) { f = 1 /*clut[fi++]*/; bglColor4f(pc[0]*f,pc[1]*f,pc[2]*f,pc[3]*f); } - vptr = &m->quad[i].v[0]; - - xx = vptr[0].x+vptr[2].x; - yy = vptr[0].y+vptr[2].y; - zz = vptr[0].z+vptr[2].z; - - for (j=0; j<4; j++) - { - point3d fp; -#if (VOXBORDWIDTH == 0) - bglTexCoord2f(((float)vptr[j].u)*ru+uhack[vptr[j].u!=vptr[0].u], - ((float)vptr[j].v)*rv+vhack[vptr[j].v!=vptr[0].v]); -#else - bglTexCoord2f(((float)vptr[j].u)*ru,((float)vptr[j].v)*rv); -#endif - fp.x = ((float)vptr[j].x) - phack[xx>vptr[j].x*2] + phack[xxvptr[j].y*2] + phack[yyvptr[j].z*2] + phack[zzcstat&CSTAT_SPRITE_MDHACK) - { - bglDepthFunc(GL_LESS); //NEVER,LESS,(,L)EQUAL,GREATER,(NOT,G)EQUAL,ALWAYS - bglDepthRange(0.0,0.99999); - } - bglLoadIdentity(); - return 1; -} - -//---------------------------------------- VOX LIBRARY ENDS ---------------------------------------- //--------------------------------------- MD LIBRARY BEGINS --------------------------------------- mdmodel_t *mdload(const char *filnam) @@ -3323,23 +2467,31 @@ mdmodel_t *mdload(const char *filnam) int32_t fil; int32_t i; - vm = (mdmodel_t *)voxload(filnam); if (vm) return(vm); + vm = (mdmodel_t *)voxload(filnam); + if (vm) return vm; - fil = kopen4load((char *)filnam,0); if (fil < 0) return(0); - kread(fil,&i,4); klseek(fil,0,SEEK_SET); + fil = kopen4load((char *)filnam,0); + + if (fil < 0) + return NULL; + + kread(fil,&i,4); + klseek(fil,0,SEEK_SET); switch (B_LITTLE32(i)) { - case 0x32504449: + case IDP2_MAGIC: // initprintf("Warning: model \"%s\" is version IDP2; wanted version IDP3\n",filnam); vm = (mdmodel_t *)md2load(fil,filnam); break; //IDP2 - case 0x33504449: + case IDP3_MAGIC: vm = (mdmodel_t *)md3load(fil); break; //IDP3 default: - vm = (mdmodel_t *)0; break; + vm = NULL; + break; } + kclose(fil); if (vm) @@ -3354,27 +2506,26 @@ mdmodel_t *mdload(const char *filnam) #ifdef POLYMER if (glrendmode != REND_POLYMER) - if (!md3postload_polymer_check(vm3)) + if (md3postload_polymer_check(vm3)) { mdfree(vm); - vm = (mdmodel_t *)0; + vm = NULL; } #endif } - return(vm); + return vm; } -int32_t mddraw(const spritetype *tspr) +void md_allocvbos(void) { - mdmodel_t *vm; int32_t i; - if (r_vbos && (r_vbocount > allocvbos)) - { - indexvbos = (GLuint *)Xrealloc(indexvbos, sizeof(GLuint) * r_vbocount); - vertvbos = (GLuint *)Xrealloc(vertvbos, sizeof(GLuint) * r_vbocount); + indexvbos = (GLuint *) Xrealloc(indexvbos, sizeof(GLuint) * r_vbocount); + vertvbos = (GLuint *) Xrealloc(vertvbos, sizeof(GLuint) * r_vbocount); + if (r_vbocount != allocvbos) + { bglGenBuffersARB(r_vbocount - allocvbos, &(indexvbos[allocvbos])); bglGenBuffersARB(r_vbocount - allocvbos, &(vertvbos[allocvbos])); @@ -3384,27 +2535,33 @@ int32_t mddraw(const spritetype *tspr) bglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, indexvbos[i]); bglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, maxmodeltris * 3 * sizeof(uint16_t), NULL, GL_STREAM_DRAW_ARB); bglBindBufferARB(GL_ARRAY_BUFFER_ARB, vertvbos[i]); - bglBufferDataARB(GL_ARRAY_BUFFER_ARB, maxmodelverts * sizeof(point3d), NULL, GL_STREAM_DRAW_ARB); + bglBufferDataARB(GL_ARRAY_BUFFER_ARB, maxmodelverts * sizeof(vec3f_t), NULL, GL_STREAM_DRAW_ARB); i++; } - bglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,0); + bglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); bglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); allocvbos = r_vbocount; } +} + +int32_t polymost_mddraw(const spritetype *tspr) +{ + mdmodel_t *vm; + + if (r_vbos && (r_vbocount > allocvbos)) + md_allocvbos(); if (maxmodelverts > allocmodelverts) { - point3d *vl = (point3d *)Xrealloc(vertlist,sizeof(point3d)*maxmodelverts); - - vertlist = vl; + vertlist = (vec3f_t *) Xrealloc(vertlist, sizeof(vec3f_t)*maxmodelverts); allocmodelverts = maxmodelverts; } vm = models[tile2model[Ptile2tile(tspr->picnum,(tspr->owner >= MAXSPRITES) ? tspr->pal : sprite[tspr->owner].pal)].modelid]; - if (vm->mdnum == 1) { return voxdraw((voxmodel_t *)vm,tspr); } - if (vm->mdnum == 3) { return md3draw((md3model_t *)vm,tspr); } + if (vm->mdnum == 1) { return polymost_voxdraw((voxmodel_t *)vm,tspr); } + if (vm->mdnum == 3) { return polymost_md3draw((md3model_t *)vm,tspr); } return 0; } diff --git a/polymer/eduke32/build/src/polymost.c b/polymer/eduke32/build/src/polymost.c index 92870851c..351bae6c0 100644 --- a/polymer/eduke32/build/src/polymost.c +++ b/polymer/eduke32/build/src/polymost.c @@ -83,24 +83,6 @@ Low priority: #include "kplib.h" #include "texcache.h" - -#if defined(_MSC_VER) && defined(_WIN64) -/* -#include -static inline int32_t Blrintf(float const x) { - return _mm_cvtss_si32(_mm_load_ss(&x));} */ -#define Blrintf (int32_t) -#elif defined (_MSC_VER) -static inline int32_t Blrintf(const float x) -{ - int n; - __asm fld x; - __asm fistp n; - return n; } -#else -#define Blrintf lrintf -#endif - #ifndef _WIN32 extern int32_t filelength(int h); // kplib.c #endif @@ -376,7 +358,6 @@ float glox1, gloy1, glox2, gloy2; //Use this for both initialization and uninitialization of OpenGL. static int32_t gltexcacnum = -1; -extern void freevbos(void); void polymost_glreset() { @@ -427,7 +408,7 @@ void polymost_glreset() bglDeleteTextures(1,&polymosttext); polymosttext=0; - freevbos(); + md_freevbos(); memset(texcache.list,0,sizeof(texcache.list)); glox1 = -1; @@ -710,28 +691,24 @@ static void resizeglcheck(void) } } -// NOTE: must not use DAPICNUM for indexing into tile arrays. -static void fixtransparency(const int32_t dapicnum, coltype *dapic, int32_t daxsiz, int32_t daysiz, - const int32_t daxsiz2, const int32_t daysiz2, const int32_t dameth) +static void fixtransparency(coltype *dapic, vec2_t dasiz, vec2_t dasiz2, int32_t dameth) { int32_t y, naxsiz2; - int32_t dox = daxsiz2-1, doy = daysiz2-1; + vec2_t doxy = { dasiz2.x-1, dasiz2.y-1 }; - UNREFERENCED_PARAMETER(dapicnum); + if (dameth&4) { doxy.x = min(doxy.x, dasiz.x); doxy.y = min(doxy.y, dasiz.y); } + else { dasiz = dasiz2; } //Make repeating textures duplicate top/left parts - if (dameth&4) { dox = min(dox,daxsiz); doy = min(doy,daysiz); } - else { daxsiz = daxsiz2; daysiz = daysiz2; } //Make repeating textures duplicate top/left parts - - daxsiz--; daysiz--; naxsiz2 = -daxsiz2; //Hacks for optimization inside loop + dasiz.x--; dasiz.y--; naxsiz2 = -dasiz2.x; //Hacks for optimization inside loop //Set transparent pixels to average color of neighboring opaque pixels //Doing this makes bilinear filtering look much better for masked textures (I.E. sprites) - for (y=doy; y>=0; y--) + for (y=doxy.y; y>=0; y--) { int32_t x; - coltype * wpptr = &dapic[y*daxsiz2+dox]; + coltype * wpptr = &dapic[y*dasiz2.x+doxy.x]; - for (x=dox; x>=0; x--,wpptr--) + for (x=doxy.x; x>=0; x--,wpptr--) { int32_t r=0, g=0, b=0, j=0; @@ -739,9 +716,9 @@ static void fixtransparency(const int32_t dapicnum, coltype *dapic, int32_t daxs r = g = b = j = 0; if ((x> 0) && (wpptr[ -1].a)) { r += wpptr[ -1].r; g += wpptr[ -1].g; b += wpptr[ -1].b; j++; } - if ((x 0) && (wpptr[naxsiz2].a)) { r += wpptr[naxsiz2].r; g += wpptr[naxsiz2].g; b += wpptr[naxsiz2].b; j++; } - if ((ya) wpptr->a = 255; } } - if (tsizx >= 0) fixtransparency(-1, pic,(tsizx+(1<>j,(tsizy+(1<>j,x3,y3,dameth); + + if (tsizx >= 0) + { + vec2_t tsizzle; + vec2_t mnizzle = { x3, y3 }; + + tsizzle.x = (tsizx+(1<>j; + tsizzle.y = (tsizy+(1<>j; + fixtransparency(pic, tsizzle, mnizzle, dameth); + } + if (j >= js) { if (doalloc&1) @@ -907,64 +894,63 @@ static void texture_setup(const int32_t dameth) void gloadtile_art(int32_t dapic, int32_t dapal, int32_t dashade, int32_t dameth, pthtyp *pth, int32_t doalloc) { coltype *pic; - int32_t xsiz, ysiz, npoty = 0; + int32_t npoty = 0; char hasalpha = 0, hasfullbright = 0; static int32_t fullbrightloadingpass = 0; - int32_t tsizx = tilesiz[dapic].x; - int32_t tsizy = tilesiz[dapic].y; + vec2_t siz, tsiz = tilesiz[dapic]; if (!glinfo.texnpot) { - for (xsiz=1; xsiz= tsizx || y >= tsizy)) //Clamp texture + if ((dameth & DAMETH_CLAMPED) && (x >= tsiz.x || y >= tsiz.y)) //Clamp texture { wpptr->r = wpptr->g = wpptr->b = wpptr->a = 0; continue; } - dacol = *(char *)(waloff[dapic]+x2*tsizy+y2); + dacol = *(char *)(waloff[dapic]+x2*tsiz.y+y2); if (!fullbrightloadingpass) { @@ -1007,27 +993,27 @@ void gloadtile_art(int32_t dapic, int32_t dapal, int32_t dashade, int32_t dameth if (doalloc) bglGenTextures(1,(GLuint *)&pth->glpic); //# of textures (make OpenGL allocate structure) bglBindTexture(GL_TEXTURE_2D,pth->glpic); - fixtransparency(dapic, pic,tsizx,tsizy,xsiz,ysiz,dameth); + fixtransparency(pic,tsiz,siz,dameth); - if (polymost_want_npotytex(dameth, ysiz) && - tsizx==xsiz && tsizy==ysiz) // XXX + if (polymost_want_npotytex(dameth, siz.y) && + tsiz.x==siz.x && tsiz.y==siz.y) // XXX { const int32_t nextpoty = 1<<((picsiz[dapic]>>4)+1); - const int32_t ydif = nextpoty - ysiz; + const int32_t ydif = nextpoty - siz.y; coltype *paddedpic; - Bassert(ydif > 0 && ydif < ysiz); + Bassert(ydif > 0 && ydif < siz.y); - paddedpic = (coltype*) Xrealloc(pic, xsiz*nextpoty*sizeof(coltype)); + paddedpic = (coltype*) Xrealloc(pic, siz.x*nextpoty*sizeof(coltype)); pic = paddedpic; - Bmemcpy(&pic[xsiz*ysiz], pic, xsiz*ydif*sizeof(coltype)); - ysiz = tsizy = nextpoty; + Bmemcpy(&pic[siz.x*siz.y], pic, siz.x*ydif*sizeof(coltype)); + siz.y = tsiz.y = nextpoty; npoty = PTH_NPOTWALL; } - uploadtexture(doalloc,xsiz,ysiz,hasalpha?GL_RGBA:GL_RGB,GL_RGBA,pic,tsizx,tsizy,dameth); + uploadtexture(doalloc,siz.x,siz.y,hasalpha?GL_RGBA:GL_RGB,GL_RGBA,pic,tsiz.x,tsiz.y,dameth); texture_setup(dameth); @@ -1059,7 +1045,9 @@ int32_t gloadtile_hi(int32_t dapic,int32_t dapalnum, int32_t facen, hicreplctyp int32_t dameth, pthtyp *pth, int32_t doalloc, char effect) { coltype *pic = NULL; - int32_t xsiz=0, ysiz=0, tsizx, tsizy; +// int32_t xsiz=0, ysiz=0, tsizx, tsizy; + vec2_t siz ={ 0, 0 }; + vec2_t tsiz; char *picfil = NULL, *fn, hasalpha = 255; int32_t picfillen, texfmt = GL_RGBA, intexfmt = GL_RGBA, filh; @@ -1102,8 +1090,8 @@ int32_t gloadtile_hi(int32_t dapic,int32_t dapalnum, int32_t facen, hicreplctyp if (gotcache && !texcache_loadtile(&cachead, &doalloc, pth)) { - tsizx = cachead.xdim; - tsizy = cachead.ydim; + tsiz.x = cachead.xdim; + tsiz.y = cachead.ydim; hasalpha = (cachead.flags & CACHEAD_HASALPHA) ? 0 : 255; } else @@ -1127,33 +1115,34 @@ int32_t gloadtile_hi(int32_t dapic,int32_t dapalnum, int32_t facen, hicreplctyp // tsizx/y = replacement texture's natural size // xsiz/y = 2^x size of replacement - kpgetdim(picfil,picfillen,&tsizx,&tsizy); - if (tsizx == 0 || tsizy == 0) { Bfree(picfil); return -1; } - pth->sizx = tsizx; - pth->sizy = tsizy; + kpgetdim(picfil,picfillen,&tsiz.x,&tsiz.y); + if (tsiz.x == 0 || tsiz.y == 0) { Bfree(picfil); return -1; } + + pth->siz.x = tsiz.x; + pth->siz.y = tsiz.y; if (!glinfo.texnpot) { - for (xsiz=1; xsiz tsizx) //Copy left to right + if (siz.x > tsiz.x) //Copy left to right { int32_t *lptr = (int32_t *)pic; - for (y=0; y tsizy) //Copy top to bottom - Bmemcpy(&pic[xsiz*tsizy],pic,(ysiz-tsizy)*xsiz<<2); + if (siz.y > tsiz.y) //Copy top to bottom + Bmemcpy(&pic[siz.x*tsiz.y],pic,(siz.y-tsiz.y)*siz.x<<2); } if (!glinfo.bgra) { - for (j=xsiz*ysiz-1; j>=0; j--) + for (j=siz.x*siz.y-1; j>=0; j--) { swapchar(&pic[j].r, &pic[j].b); } @@ -1251,7 +1238,7 @@ int32_t gloadtile_hi(int32_t dapic,int32_t dapalnum, int32_t facen, hicreplctyp Bfree(picfil); picfil = 0; - if (tsizx>>r_downsize <= tilesiz[dapic].x || tsizy>>r_downsize <= tilesiz[dapic].y) + if (tsiz.x>>r_downsize <= tilesiz[dapic].x || tsiz.y>>r_downsize <= tilesiz[dapic].y) hicr->flags |= (HICR_NOCOMPRESS + HICR_NOSAVE); if (glinfo.texcompr && glusetexcompr && !(hicr->flags & HICR_NOSAVE)) @@ -1262,48 +1249,45 @@ int32_t gloadtile_hi(int32_t dapic,int32_t dapalnum, int32_t facen, hicreplctyp bglGenTextures(1, &pth->glpic); //# of textures (make OpenGL allocate structure) bglBindTexture(GL_TEXTURE_2D,pth->glpic); - fixtransparency(-1, pic,tsizx,tsizy,xsiz,ysiz,dameth); - uploadtexture(doalloc,xsiz,ysiz,intexfmt,texfmt,pic,-1,tsizy, + fixtransparency(pic,tsiz,siz,dameth); + uploadtexture(doalloc,siz.x,siz.y,intexfmt,texfmt,pic,-1,tsiz.y, dameth | DAMETH_HI | (hicr->flags & HICR_NOCOMPRESS ? DAMETH_NOCOMPRESS : 0)); } // precalculate scaling parameters for replacement if (facen > 0) { - pth->scalex = ((float)tsizx) * (1.0f/64.f); - pth->scaley = ((float)tsizy) * (1.0f/64.f); + pth->scale.x = (float)tsiz.x * (1.0f/64.f); + pth->scale.y = (float)tsiz.y * (1.0f/64.f); } else { - pth->scalex = ((float)tsizx) / ((float)tilesiz[dapic].x); - pth->scaley = ((float)tsizy) / ((float)tilesiz[dapic].y); + pth->scale.x = (float)tsiz.x / (float)tilesiz[dapic].x; + pth->scale.y = (float)tsiz.y / (float)tilesiz[dapic].y; } texture_setup(dameth); DO_FREE_AND_NULL(pic); - if (tsizx>>r_downsize <= tilesiz[dapic].x || tsizy>>r_downsize <= tilesiz[dapic].y) - hicr->flags |= (HICR_NOCOMPRESS + HICR_NOSAVE); + if (tsiz.x>>r_downsize <= tilesiz[dapic].x || tsiz.y>>r_downsize <= tilesiz[dapic].y) + hicr->flags |= HICR_NOCOMPRESS | HICR_NOSAVE; pth->picnum = dapic; pth->effects = effect; - pth->flags = TO_PTH_CLAMPED(dameth) + PTH_HIGHTILE + (facen>0)*PTH_SKYBOX; - if (hasalpha != 255) - pth->flags |= PTH_HASALPHA; + pth->flags = TO_PTH_CLAMPED(dameth) | PTH_HIGHTILE | ((facen>0) * PTH_SKYBOX) | ((hasalpha != 255) ? PTH_HASALPHA : 0); pth->skyface = facen; pth->hicr = hicr; if (glinfo.texcompr && glusetexcompr && glusetexcache && !(hicr->flags & HICR_NOSAVE)) if (!gotcache) { - const int32_t nonpow2 = check_nonpow2(xsiz) || check_nonpow2(ysiz); + const int32_t nonpow2 = check_nonpow2(siz.x) || check_nonpow2(siz.y); // save off the compressed version - if (hicr->flags & HICR_NOCOMPRESS) cachead.quality = 0; - else cachead.quality = r_downsize; - cachead.xdim = tsizx>>cachead.quality; - cachead.ydim = tsizy>>cachead.quality; + cachead.quality = (hicr->flags & HICR_NOCOMPRESS) ? 0 : r_downsize; + cachead.xdim = tsiz.x>>cachead.quality; + cachead.ydim = tsiz.y>>cachead.quality; // handle nocompress: cachead.flags = nonpow2*CACHEAD_NONPOW2 | @@ -1402,7 +1386,10 @@ static float alpha = 0.f; static pthtyp *our_texcache_fetch(int32_t dameth) { // r_usetileshades 1 is TX's method. - return texcache_fetch(globalpicnum, globalpal, getpalookup((r_usetileshades == 1) ? globvis>>3 : 0, globalshade), dameth); + if (r_usetileshades != 1) + return texcache_fetch(globalpicnum, globalpal, globalshade, dameth); + + return texcache_fetch(globalpicnum, globalpal, getpalookup(globvis>>3, globalshade), dameth); } static void drawpoly(float *dpx, float *dpy, int32_t n, int32_t method) @@ -1485,7 +1472,6 @@ static void drawpoly(float *dpx, float *dpy, int32_t n, int32_t method) pthtyp *pth, *detailpth, *glowpth; int32_t texunits = GL_TEXTURE0_ARB; int32_t xx, yy; - int32_t k; int32_t jj = j; @@ -1565,10 +1551,10 @@ static void drawpoly(float *dpx, float *dpy, int32_t n, int32_t method) if (pth && (pth->flags & PTH_HIGHTILE)) { - hackscx = pth->scalex; - hackscy = pth->scaley; - tsiz.x = pth->sizx; - tsiz.y = pth->sizy; + hackscx = pth->scale.x; + hackscy = pth->scale.y; + tsiz.x = pth->siz.x; + tsiz.y = pth->siz.y; } xx = tsiz.x; @@ -2113,7 +2099,7 @@ static void polymost_internal_nonparallaxed(float nx0, float ny0, float nx1, flo //relative alignment fx = (float)(wall[wall[sec->wallptr].point2].x-wall[sec->wallptr].x); fy = (float)(wall[wall[sec->wallptr].point2].y-wall[sec->wallptr].y); - r = 1.f/Bsqrtf(fx*fx+fy*fy); fx *= r; fy *= r; + r = polymost_invsqrt(fx*fx+fy*fy); fx *= r; fy *= r; ft[2] = fcosglobalang*fx + fsinglobalang*fy; ft[3] = fsinglobalang*fx - fcosglobalang*fy; ft[0] = ((float)(globalposx-wall[sec->wallptr].x))*fx + ((float)(globalposy-wall[sec->wallptr].y))*fy; @@ -2152,7 +2138,7 @@ static void polymost_internal_nonparallaxed(float nx0, float ny0, float nx1, flo fy = global_cf_ypanning*((float)(1<<(picsiz[globalpicnum]>>4)))*(1.0f/256.f); if ((globalorientation&(2+64)) == (2+64)) //Hack for panning for slopes w/ relative alignment { - float r = global_cf_heinum * (1.0f/4096.f); r = 1.f/Bsqrtf(r*r+1); + float r = global_cf_heinum * (1.0f/4096.f); r = polymost_invsqrt(r*r+1); if (!(globalorientation&4)) fy *= r; else fx *= r; } guy += gdy*fx; guo += gdo*fx; @@ -3086,7 +3072,7 @@ void polymost_scansector(int32_t sectnum) walltype *wal, *wal2; spritetype *spr; int32_t z, zz, startwall, endwall, numscansbefore, scanfirst, bunchfrst, nextsectnum, sectorbordercnt; - fvec2_t p1, p2, fp1, fp2; + vec2f_t p1, p2, fp1, fp2; float d; if (sectnum < 0) return; @@ -3821,7 +3807,7 @@ void polymost_drawsprite(int32_t snum) { if (usemodels && tile2model[Ptile2tile(tspr->picnum,tspr->pal)].modelid >= 0 && tile2model[Ptile2tile(tspr->picnum,tspr->pal)].framenum >= 0) { - if (mddraw(tspr)) + if (polymost_mddraw(tspr)) return; break; // else, render as flat sprite @@ -3829,14 +3815,14 @@ void polymost_drawsprite(int32_t snum) if (usevoxels && (tspr->cstat&48)!=48 && tiletovox[tspr->picnum] >= 0 && voxmodels[tiletovox[tspr->picnum]]) { - if (voxdraw(voxmodels[tiletovox[tspr->picnum]], tspr)) + if (polymost_voxdraw(voxmodels[tiletovox[tspr->picnum]], tspr)) return; break; // else, render as flat sprite } if ((tspr->cstat&48)==48 && voxmodels[tspr->picnum]) { - voxdraw(voxmodels[tspr->picnum], tspr); + polymost_voxdraw(voxmodels[tspr->picnum], tspr); return; } break; @@ -3846,7 +3832,7 @@ void polymost_drawsprite(int32_t snum) { curpolygonoffset += .25f; bglEnable(GL_POLYGON_OFFSET_FILL); - bglPolygonOffset(-1.f-curpolygonoffset, -1.f); + bglPolygonOffset(-1.f, -1.f-curpolygonoffset); } #endif @@ -4159,7 +4145,7 @@ void polymost_drawsprite(int32_t snum) //copied&modified from relative alignment xv = (float)tspr->x + s*x1 + c*y1; fx = (float)-(x0+x1)*s; yv = (float)tspr->y + s*y1 - c*x1; fy = (float)+(x0+x1)*c; - f = 1.f/Bsqrtf(fx*fx+fy*fy); fx *= f; fy *= f; + f = polymost_invsqrt(fx*fx+fy*fy); fx *= f; fy *= f; ft[2] = singlobalang*fy + cosglobalang*fx; ft[3] = singlobalang*fx - cosglobalang*fy; ft[0] = ((float)(globalposy-yv))*fy + ((float)(globalposx-xv))*fx; @@ -4245,7 +4231,7 @@ void polymost_dorotatespritemodel(int32_t sx, int32_t sy, int32_t z, int16_t a, { int32_t oldviewingrange; float ogxyaspect; - float x1, y1, z1; + vec3f_t vec1; spritetype tspr; memset(&tspr, 0, sizeof(spritetype)); @@ -4262,15 +4248,13 @@ void polymost_dorotatespritemodel(int32_t sx, int32_t sy, int32_t z, int16_t a, ogxyaspect = gxyaspect; gxyaspect = 1.f; oldviewingrange = viewingrange; viewingrange = 65536; - x1 = hudmem[(dastat&4)>>2][picnum].xadd; - y1 = hudmem[(dastat&4)>>2][picnum].yadd; - z1 = hudmem[(dastat&4)>>2][picnum].zadd; + vec1 = hudmem[(dastat&4)>>2][picnum].add; #ifdef POLYMER if (pr_overridehud) { - x1 = pr_hudxadd; - y1 = pr_hudyadd; - z1 = pr_hudzadd; + vec1.x = pr_hudxadd; + vec1.y = pr_hudyadd; + vec1.z = pr_hudzadd; } #endif if (!(hudmem[(dastat&4)>>2][picnum].flags & HUDFLAG_NOBOB)) @@ -4297,13 +4281,13 @@ void polymost_dorotatespritemodel(int32_t sx, int32_t sy, int32_t z, int16_t a, if (!(dastat & RS_AUTO)) { - x1 += fx/((float) (xdim<<15))-1.f; //-1: left of screen, +1: right of screen - y1 += fy/((float) (ydim<<15))-1.f; //-1: top of screen, +1: bottom of screen + vec1.x += fx/((float) (xdim<<15))-1.f; //-1: left of screen, +1: right of screen + vec1.y += fy/((float) (ydim<<15))-1.f; //-1: top of screen, +1: bottom of screen } else { - x1 += fx*(1.0f/160.f)-1.f; //-1: left of screen, +1: right of screen - y1 += fy*(1.0f/100.f)-1.f; //-1: top of screen, +1: bottom of screen + vec1.x += fx*(1.0f/160.f)-1.f; //-1: left of screen, +1: right of screen + vec1.y += fy*(1.0f/100.f)-1.f; //-1: top of screen, +1: bottom of screen } } tspr.ang = hudmem[(dastat&4)>>2][picnum].angadd+globalang; @@ -4314,30 +4298,28 @@ void polymost_dorotatespritemodel(int32_t sx, int32_t sy, int32_t z, int16_t a, } #endif - if (dastat & RS_YFLIP) { x1 = -x1; y1 = -y1; } + if (dastat & RS_YFLIP) { vec1.x = -vec1.x; vec1.y = -vec1.y; } // In Polymost, we don't care if the model is very big if (getrendermode() < REND_POLYMER) { tspr.xrepeat = tspr.yrepeat = 32; - tspr.x = (int32_t) (((float) gcosang*z1 - (float) gsinang*x1)*16384.f + globalposx); - tspr.y = (int32_t) (((float) gsinang*z1 + (float) gcosang*x1)*16384.f + globalposy); - tspr.z = (int32_t) (globalposz + y1*16384.f*0.8f); + tspr.x = globalposx + Blrintf((gcosang*vec1.z - gsinang*vec1.x)*16384.f); + tspr.y = globalposy + Blrintf((gsinang*vec1.z + gcosang*vec1.x)*16384.f); + tspr.z = globalposz + Blrintf(vec1.y * (16384.f * 0.8f)); } else { - float x, y, z; + vec3f_t vec2; tspr.xrepeat = tspr.yrepeat = 5; - x = (float) (((float) gcosang*z1 - (float) gsinang*x1)*2560.f + globalposx); - y = (float) (((float) gsinang*z1 + (float) gcosang*x1)*2560.f + globalposy); - z = (float) (globalposz + y1*2560.f*0.8f); + vec2.x = (float)globalposx + (gcosang*vec1.z - gsinang*vec1.x)*2560.f; + vec2.y = (float)globalposy + (gsinang*vec1.z + gcosang*vec1.x)*2560.f; + vec2.z = (float)globalposz + (vec1.y*(2560.f*0.8f)); - memcpy(&tspr.x, &x, sizeof(float)); - memcpy(&tspr.y, &y, sizeof(float)); - memcpy(&tspr.z, &z, sizeof(float)); + Bmemcpy(&tspr.x, &vec2, sizeof(vec3f_t)); } tspr.picnum = picnum; tspr.shade = dashade; @@ -4346,8 +4328,7 @@ void polymost_dorotatespritemodel(int32_t sx, int32_t sy, int32_t z, int16_t a, // 1 -> 1 // 32 -> 32*16 = 512 // 4 -> 8 - globalorientation = (dastat&RS_TRANS1) + ((dastat&RS_TRANS2)<<4) + ((dastat&RS_YFLIP)<<1); - tspr.cstat = globalorientation; + tspr.cstat = globalorientation = (dastat&RS_TRANS1) | ((dastat&RS_TRANS2)<<4) | ((dastat&RS_YFLIP)<<1); if ((dastat&(RS_AUTO|RS_NOCLIP)) == RS_AUTO) bglViewport(windowx1, yres-(windowy2+1), windowx2-windowx1+1, windowy2-windowy1+1); @@ -4360,10 +4341,10 @@ void polymost_dorotatespritemodel(int32_t sx, int32_t sy, int32_t z, int16_t a, if (getrendermode() < REND_POLYMER) { bglMatrixMode(GL_PROJECTION); - memset(m, 0, sizeof(m)); + Bmemset(m, 0, sizeof(m)); + if ((dastat&(RS_AUTO|RS_NOCLIP)) == RS_AUTO) { - const float ratioratio = 1.f; //(float)xdim/ydim; float f = 1.f; int32_t fov = hudmem[(dastat&4)>>2][picnum].fov; #ifdef POLYMER @@ -4371,16 +4352,11 @@ void polymost_dorotatespritemodel(int32_t sx, int32_t sy, int32_t z, int16_t a, fov = pr_hudfov; #endif if (fov != -1) - { - // XXX: what's the cause for this (half-guessed / - // empirically determined) factor being necessary? - fov = (fov*512)/400; - f = 1.f / tanf((PI * fov)*(1.0f/2048.f)); - } + f = 1.f/tanf(((float)fov * 2.56f) * ((.5f * PI) * (1.0f/2048.f))); - m[0][0] = f*(float) ydimen*(ratioratio >= 1.6 ? 1.2 : 1); m[0][2] = 1.f; + m[0][0] = f*(float) ydimen; m[0][2] = 1.f; m[1][1] = f*(float) xdimen; m[1][2] = 1.f; - m[2][2] = 1.f; m[2][3] = (float) ydimen*(ratioratio >= 1.6 ? 1.2 : 1); + m[2][2] = 1.f; m[2][3] = (float) ydimen; m[3][2] =-1.f; } else @@ -4417,8 +4393,8 @@ void polymost_dorotatespritemodel(int32_t sx, int32_t sy, int32_t z, int16_t a, bglDisable(GL_FOG); - if (getrendermode() < REND_POLYMER) - mddraw(&tspr); + if (getrendermode() == REND_POLYMOST) + polymost_mddraw(&tspr); # ifdef POLYMER else { @@ -4883,7 +4859,7 @@ void polymost_fillpolygon(int32_t npoints) f = getshadefactor(globalshade); - if ((globalorientation>>7)&3 > 1) + if (((globalorientation>>7)&3) > 1) { bglEnable(GL_BLEND); a = float_trans[(globalorientation>>7)&3]; diff --git a/polymer/eduke32/build/src/texcache.c b/polymer/eduke32/build/src/texcache.c index 1f447cc38..46fe8c1c4 100644 --- a/polymer/eduke32/build/src/texcache.c +++ b/polymer/eduke32/build/src/texcache.c @@ -9,6 +9,7 @@ #include "dxtfilter.h" #include "scriptfile.h" #include "xxhash.h" +#include "kplib.h" #define CLEAR_GL_ERRORS() while(bglGetError() != GL_NO_ERROR) { } #define TEXCACHE_FREEBUFS() { Bfree(pic), Bfree(packbuf), Bfree(midbuf); } @@ -70,7 +71,7 @@ pthtyp *texcache_fetchmulti(pthtyp *pth, hicreplctyp *si, int32_t dapicnum, int3 for (pth2=texcache.list[i]; pth2; pth2=pth2->next) { - if (pth2->hicr && pth2->hicr->filename && Bstrcasecmp(pth2->hicr->filename, si->filename) == 0) + if (pth2->hicr && pth2->hicr->filename && filnamcmp(pth2->hicr->filename, si->filename) == 0) { Bmemcpy(pth, pth2, sizeof(pthtyp)); pth->picnum = dapicnum; @@ -151,8 +152,7 @@ pthtyp *texcache_fetch(int32_t dapicnum, int32_t dapalnum, int32_t dashade, int3 pth = (pthtyp *)Xcalloc(1,sizeof(pthtyp)); // possibly fetch an already loaded multitexture :_) - if (dapalnum >= (MAXPALOOKUPS - RESERVEDPALS)) - if (texcache_fetchmulti(pth, si, dapicnum, dameth)) + if (dapalnum >= (MAXPALOOKUPS - RESERVEDPALS) && texcache_fetchmulti(pth, si, dapicnum, dameth)) return pth; tilestat = gloadtile_hi(dapicnum, dapalnum, drawingskybox, si, dameth, pth, 1, (si->palnum>0) ? 0 : hictinting[dapalnum].f); @@ -192,7 +192,7 @@ void texcache_freeptrs(void) { int32_t i; - for (i = texcache.numentries-1; i >= 0; i--) + for (i = 0; i < texcache.numentries; i++) if (texcache.ptrs[i]) { int32_t ii; @@ -760,8 +760,8 @@ int32_t texcache_loadtile(const texcacheheader *head, int32_t *doalloc, pthtyp * texcache_setuptexture(doalloc, &pth->glpic); - pth->sizx = head->xdim; - pth->sizy = head->ydim; + pth->siz.x = head->xdim; + pth->siz.y = head->ydim; CLEAR_GL_ERRORS(); diff --git a/polymer/eduke32/build/src/voxmodel.c b/polymer/eduke32/build/src/voxmodel.c new file mode 100644 index 000000000..6317e6d09 --- /dev/null +++ b/polymer/eduke32/build/src/voxmodel.c @@ -0,0 +1,811 @@ +//--------------------------------------- VOX LIBRARY BEGINS --------------------------------------- + +#ifdef USE_OPENGL + +#include "compat.h" +#include "build.h" +#include "glbuild.h" +#include "pragmas.h" +#include "baselayer.h" +#include "engine_priv.h" +#include "hightile.h" +#include "polymost.h" +#include "texcache.h" +#include "mdsprite.h" +#include "cache1d.h" +#include "kplib.h" + +#include + +//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; +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; +typedef struct { int16_t x, y; } spoint2d; +static spoint2d *shp; +static int32_t *shcntmal, *shcnt = 0, shcntp; +static int32_t mytexo5, *zbit, gmaxx, gmaxy, garea, pow2m1[33]; +static voxmodel_t *gvox; + +//pitch must equal xsiz*4 +uint32_t gloadtex(int32_t *picbuf, int32_t xsiz, int32_t ysiz, int32_t is8bit, int32_t dapal) +{ + uint32_t rtexid; + int32_t i; + + const char *const cptr = &britable[gammabrightness ? 0 : curbrightness][0]; + + // Correct for GL's RGB order; also apply gamma here: + const coltype *const pic = (const coltype *) picbuf; + coltype *pic2 = (coltype *) Xmalloc(xsiz*ysiz*sizeof(coltype)); + + if (!is8bit) + { + for (i=xsiz*ysiz-1; i>=0; i--) + { + pic2[i].b = cptr[pic[i].r]; + pic2[i].g = cptr[pic[i].g]; + pic2[i].r = cptr[pic[i].b]; + pic2[i].a = 255; + } + } + else + { + if (palookup[dapal] == NULL) + dapal = 0; + + for (i=xsiz*ysiz-1; i>=0; i--) + { + const int32_t ii = palookup[dapal][pic[i].a] * 3; + + pic2[i].b = cptr[palette[ii+2]*4]; + pic2[i].g = cptr[palette[ii+1]*4]; + pic2[i].r = cptr[palette[ii+0]*4]; + pic2[i].a = 255; + } + } + + bglGenTextures(1, (GLuint *) &rtexid); + bglBindTexture(GL_TEXTURE_2D, rtexid); + bglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + bglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + bglTexImage2D(GL_TEXTURE_2D, 0, 4, xsiz, ysiz, 0, GL_RGBA, GL_UNSIGNED_BYTE, (char *) pic2); + + Bfree(pic2); + + return rtexid; +} + +static int32_t getvox(int32_t x, int32_t y, int32_t z) +{ + z += x*yzsiz + y*voxsiz.z; + for (x=vcolhashead[(z*214013)&vcolhashsizm1]; x>=0; x=vcol[x].n) + if (vcol[x].p == z) return(vcol[x].c); + return(0x808080); +} + +static void putvox(int32_t x, int32_t y, int32_t z, int32_t col) +{ + if (vnum >= vmax) { vmax = max(vmax<<1, 4096); vcol = (voxcol_t *) Xrealloc(vcol, vmax*sizeof(voxcol_t)); } + + z += x*yzsiz + y*voxsiz.z; + vcol[vnum].p = z; z = ((z*214013)&vcolhashsizm1); + 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) +{ + int32_t z, ze; + if (!((z0^z1)&~31)) { lptr[z0>>5] &= ((~(-1<>5); ze = (z1>>5); + lptr[z] &=~(-1<>5] |= ((~(-1<>5); ze = (z1>>5); + lptr[z] |= (-1<mytexx + x0; + for (dy=0; dy; dy--, i+=gvox->mytexx) + for (x=0; x>5]&(1<>5); dx += x0-1; c = (dx>>5) - (x0>>5); + m = ~pow2m1[x0&31]; m1 = pow2m1[(dx&31)+1]; + if (!c) { for (m&=m1; dy; dy--, i+=mytexo5) if (zbit[i]&m) return(0); } + else + { + for (; dy; dy--, i+=mytexo5) + { + if (zbit[i]&m) return(0); + for (x=1; xmytexx + x0; + for (y=0; ymytexx) + for (x=0; x>5] |= (1<>5); dx += x0-1; c = (dx>>5) - (x0>>5); + m = ~pow2m1[x0&31]; m1 = pow2m1[(dx&31)+1]; + if (!c) { for (m&=m1; dy; dy--, i+=mytexo5) zbit[i] |= m; } + else + { + for (; dy; dy--, i+=mytexo5) + { + zbit[i] |= m; + for (x=1; x gmaxx) gmaxx = x; + if (y > gmaxy) gmaxy = y; + garea += (x+(VOXBORDWIDTH<<1))*(y+(VOXBORDWIDTH<<1)); + gvox->qcnt++; +} + +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) +{ + int32_t i, j, x, y, z, xx, yy, nx = 0, ny = 0, nz = 0, *lptr; + voxrect_t *qptr; + + x = labs(x2-x0); y = labs(y2-y0); z = labs(z2-z0); + if (!x) { x = y; y = z; i = 0; } + else if (!y) { y = z; i = 1; } + else i = 2; + if (x < y) { z = x; x = y; y = z; i += 3; } + z = shcnt[y*shcntp+x]++; + lptr = &gvox->mytex[(shp[z].y+VOXBORDWIDTH)*gvox->mytexx+(shp[z].x+VOXBORDWIDTH)]; + 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; + } + for (yy=0; yymytexx) + for (xx=0; xxmytex[(shp[z].y+yy)*gvox->mytexx+shp[z].x]; + lptr[xx] = lptr[VOXBORDWIDTH]; lptr[xx+x+VOXBORDWIDTH] = lptr[x-1+VOXBORDWIDTH]; + } + //Extend borders vertically + for (yy=0; yymytex[(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); + } + + qptr = &gvox->quad[gvox->qcnt]; + 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; + for (j=0; j<3; j++) { 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; + + 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; + if (gvox->qfacind[face] < 0) gvox->qfacind[face] = gvox->qcnt; + gvox->qcnt++; + +} + +static inline int32_t isolid(int32_t x, int32_t y, int32_t z) +{ + 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<qfacind[i] = -1; + + i = ((max(voxsiz.y, voxsiz.z)+1)<<2); + bx0 = (int32_t *) Xmalloc(i<<1); + by0 = (int32_t *) (((intptr_t) bx0)+i); + + for (cnt=0; cnt<2; cnt++) + { + if (!cnt) daquad = cntquad; + else daquad = addquad; + gvox->qcnt = 0; + + memset(by0, -1, (max(voxsiz.y, voxsiz.z)+1)<<2); v = 0; + + for (i=-1; i<=1; i+=2) + for (y=0; y= 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; } + } + + for (i=-1; i<=1; i+=2) + for (z=0; z= 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; } + } + + for (i=-1; i<=1; i+=2) + for (x=0; x= 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; } + } + + if (!cnt) + { + shp = (spoint2d *) Xmalloc(gvox->qcnt*sizeof(spoint2d)); + + sc = 0; + for (y=gmaxy; y; y--) + for (x=gmaxx; x>=y; x--) + { + 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++; } + } + + for (gvox->mytexx=32; gvox->mytexx<(gmaxx+(VOXBORDWIDTH<<1)); gvox->mytexx<<=1); + for (gvox->mytexy=32; gvox->mytexy<(gmaxy+(VOXBORDWIDTH<<1)); gvox->mytexy<<=1); + while (gvox->mytexx*gvox->mytexy*8 < garea*9) //This should be sufficient to fit most skins... + { + skindidntfit: + ; + if (gvox->mytexx <= gvox->mytexy) gvox->mytexx <<= 1; else gvox->mytexy <<= 1; + } + mytexo5 = (gvox->mytexx>>5); + + i = (((gvox->mytexx*gvox->mytexy+31)>>5)<<2); + zbit = (int32_t *) Xmalloc(i); + memset(zbit, 0, i); + + v = gvox->mytexx*gvox->mytexy; + for (z=0; zmytexx, 255)-dx))>>15); + y0 = (((rand()&32767)*(min(gvox->mytexy, 255)-dy))>>15); +#else + x0 = (((rand()&32767)*(gvox->mytexx+1-dx))>>15); + y0 = (((rand()&32767)*(gvox->mytexy+1-dy))>>15); +#endif + i--; + if (i < 0) //Time-out! Very slow if this happens... but at least it still works :P + { + Bfree(zbit); + + //Re-generate shp[].x/y (box sizes) from shcnt (now head indices) for next pass :/ + j = 0; + for (y=gmaxy; y; y--) + for (x=gmaxx; x>=y; x--) + { + i = shcnt[y*shcntp+x]; + for (; jquad = (voxrect_t *) Xmalloc(gvox->qcnt*sizeof(voxrect_t)); + gvox->mytex = (int32_t *) Xmalloc(gvox->mytexx*gvox->mytexy*sizeof(int32_t)); + } + } + Bfree(shp); Bfree(zbit); Bfree(bx0); + return(gvox); +} + +static int32_t loadvox(const char *filnam) +{ + int32_t i, j, k, x, y, z, pal[256], fil; + char c[3], *tbuf; + + fil = kopen4load(filnam, 0); if (fil < 0) return(-1); + kread(fil, &voxsiz, sizeof(vec3_t)); +#if B_BIG_ENDIAN != 0 + voxsiz.x = B_LITTLE32(voxsiz.x); + voxsiz.y = B_LITTLE32(voxsiz.y); + voxsiz.z = B_LITTLE32(voxsiz.z); +#endif + voxpiv.x = (float) voxsiz.x * .5f; + voxpiv.y = (float) voxsiz.y * .5f; + voxpiv.z = (float) voxsiz.z * .5f; + + klseek(fil, -768, SEEK_END); + for (i=0; i<256; i++) + { + kread(fil, c, 3); pal[i] = (((int32_t) c[0])<<18)+(((int32_t) c[1])<<10)+(((int32_t) c[2])<<2)+(i<<24); + } + pal[255] = -1; + + vcolhashsizm1 = 8192-1; + vcolhashead = (int32_t *) Xmalloc((vcolhashsizm1+1)*sizeof(int32_t)); + memset(vcolhashead, -1, (vcolhashsizm1+1)*sizeof(int32_t)); + + yzsiz = voxsiz.y*voxsiz.z; i = ((voxsiz.x*yzsiz+31)>>3)+1; + vbit = (int32_t *) Xmalloc(i); + memset(vbit, 0, i); + + tbuf = (char *) Xmalloc(voxsiz.z*sizeof(uint8_t)); + + klseek(fil, 12, SEEK_SET); + for (x=0; x=0; z--) + { + if (tbuf[z] != 255) { i = j+z; vbit[i>>5] |= (1<>5]&(1<>5]&(1<>5]&(1<>5]&(1<>5]&(1<>5]&(1<=0; i--) xyoffs[i] = B_LITTLE16(xyoffs[i]); + + klseek(fil, -768, SEEK_END); + for (i=0; i<256; i++) + { + kread(fil, c, 3); +#if B_BIG_ENDIAN != 0 + pal[i] = B_LITTLE32((((int32_t) c[0])<<18)+(((int32_t) c[1])<<10)+(((int32_t) c[2])<<2)+(i<<24)); +#endif + } + + yzsiz = voxsiz.y*voxsiz.z; i = ((voxsiz.x*yzsiz+31)>>3)+1; + vbit = (int32_t *) Xmalloc(i); + memset(vbit, 0, i); + + for (vcolhashsizm1=4096; vcolhashsizm1<(mip1leng>>1); vcolhashsizm1<<=1) + { + /* do nothing */ + } + vcolhashsizm1--; //approx to numvoxs! + vcolhashead = (int32_t *) Xmalloc((vcolhashsizm1+1)*sizeof(int32_t)); + memset(vcolhashead, -1, (vcolhashsizm1+1)*sizeof(int32_t)); + + klseek(fil, 28+((voxsiz.x+1)<<2)+((ysizp1*voxsiz.x)<<1), SEEK_SET); + + i = kfilelength(fil)-ktell(fil); + tbuf = (char *) Xmalloc(i); + kread(fil, tbuf, i); kclose(fil); + + cptr = tbuf; + for (x=0; x=0; i--) ylen[i] = B_LITTLE16(ylen[i]); + klseek(fil, 32, SEEK_SET); + + yzsiz = voxsiz.y*voxsiz.z; i = ((voxsiz.x*yzsiz+31)>>3)+1; + vbit = (int32_t *) Xmalloc(i); + memset(vbit, 0, i); + + for (vcolhashsizm1=4096; vcolhashsizm10; i--) + { + kread(fil, c, 8); //b,g,r,a,z_lo,z_hi,vis,dir + z0 = B_LITTLE16(*(uint16_t *) &c[4]); + if (!(c[6]&16)) setzrange1(vbit, j+z1, j+z0); + vbit[(j+z0)>>5] |= (1<mytex); + DO_FREE_AND_NULL(m->quad); + DO_FREE_AND_NULL(m->texid); + Bfree(m); +} + +voxmodel_t *voxload(const char *filnam) +{ + int32_t i, is8bit, ret; + voxmodel_t *vm; + + i = strlen(filnam)-4; if (i < 0) return NULL; + 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; + if (ret >= 0) vm = vox2poly(); else vm = 0; + 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; + + vm->texid = (uint32_t *) Xcalloc(MAXPALOOKUPS, sizeof(uint32_t)); + } + 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; +} + +//Draw voxel model as perfect cubes +int32_t polymost_voxdraw(voxmodel_t *m, const spritetype *tspr) +{ + vec3f_t m0, a0; + int32_t i, j, fi, xx, yy, zz; + float ru, rv, phack[2]; //, clut[6] = {1.02,1.02,0.94,1.06,0.98,0.98}; + float f, g, k0, mat[16], omat[16], pc[4]; + vert_t *vptr; + + if ((intptr_t) m == (intptr_t) (-1)) // hackhackhack + return 0; + if ((tspr->cstat&48)==32) return 0; + + //updateanimation((md2model *)m,tspr); + + m0.x = m->scale; + m0.y = m->scale; + m0.z = m->scale; + a0.x = a0.y = 0; a0.z = ((globalorientation&8) ? -m->zadd : m->zadd)*m->scale; + + //if (globalorientation&8) //y-flipping + //{ + // m0.z = -m0.z; a0.z = -a0.z; + // //Add height of 1st frame (use same frame to prevent animation bounce) + // a0.z += m->zsiz*m->scale; + //} + //if (globalorientation&4) { m0.y = -m0.y; a0.y = -a0.y; } //x-flipping + + k0 = 1.f/(m->bscale * 64.f); + f = (float) tspr->xrepeat * (256.f/320.f) * k0; + if ((sprite[tspr->owner].cstat&48)==16) + f *= 1.25f; + + 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; + + k0 = (float) tspr->z; + if (globalorientation&128) k0 += (float) ((tilesiz[tspr->picnum].y*tspr->yrepeat)<<1); + + f = (65536.f*512.f)/((float) xdimen*viewingrange); + g = 32.f/((float) xdimen*gxyaspect); + m0.y *= f; a0.y = (((float) (tspr->x-globalposx))* (1.f/1024.f) + a0.y)*f; + m0.x *=-f; a0.x = (((float) (tspr->y-globalposy))* -(1.f/1024.f) + a0.x)*-f; + m0.z *= g; a0.z = (((float) (k0 -globalposz))* -(1.f/16384.f) + a0.z)*g; + + md3_vox_calcmat_common(tspr, &a0, f, mat); + + //Mirrors + if (grhalfxdown10x < 0) { mat[0] = -mat[0]; mat[4] = -mat[4]; mat[8] = -mat[8]; mat[12] = -mat[12]; } + + if (tspr->cstat&CSTAT_SPRITE_MDHACK) + { + bglDepthFunc(GL_LESS); //NEVER,LESS,(,L)EQUAL,GREATER,(NOT,G)EQUAL,ALWAYS + bglDepthRange(0.0, 0.9999); + } + bglPushAttrib(GL_POLYGON_BIT); + if ((grhalfxdown10x >= 0) /*^ ((globalorientation&8) != 0) ^ ((globalorientation&4) != 0)*/) bglFrontFace(GL_CW); else bglFrontFace(GL_CCW); + bglEnable(GL_CULL_FACE); + bglCullFace(GL_BACK); + + bglEnable(GL_TEXTURE_2D); + + pc[0] = pc[1] = pc[2] = ((float) (numshades-min(max((globalshade * shadescale)+m->shadeoff, 0), numshades)))/((float) numshades); + hictinting_apply(pc, globalpal); + + if (tspr->cstat&2) { if (!(tspr->cstat&512)) pc[3] = 0.66f; else pc[3] = 0.33f; } + else pc[3] = 1.0f; + pc[3] *= 1.0f - spriteext[tspr->owner].alpha; + if ((tspr->cstat&2) || spriteext[tspr->owner].alpha > 0.f || pc[3] < 1.0f) bglEnable(GL_BLEND); //else bglDisable(GL_BLEND); + //------------ + + //transform to Build coords + Bmemcpy(omat, mat, sizeof(omat)); + 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; + mat[12] -= (m->piv.x*mat[0] + m->piv.y*mat[4] + (m->piv.z+m->siz.z*.5f)*mat[8]); + mat[13] -= (m->piv.x*mat[1] + m->piv.y*mat[5] + (m->piv.z+m->siz.z*.5f)*mat[9]); + mat[14] -= (m->piv.x*mat[2] + m->piv.y*mat[6] + (m->piv.z+m->siz.z*.5f)*mat[10]); + bglMatrixMode(GL_MODELVIEW); //Let OpenGL (and perhaps hardware :) handle the matrix rotation + mat[3] = mat[7] = mat[11] = 0.f; mat[15] = 1.f; + + bglLoadMatrixf(mat); + + ru = 1.f/((float) m->mytexx); + rv = 1.f/((float) m->mytexy); +#if (VOXBORDWIDTH == 0) + uhack[0] = ru*.125; uhack[1] = -uhack[0]; + vhack[0] = rv*.125; vhack[1] = -vhack[0]; +#endif + phack[0] = 0; phack[1] = 1.f/256.f; + + if (!m->texid[globalpal]) m->texid[globalpal] = gloadtex(m->mytex, m->mytexx, m->mytexy, m->is8bit, globalpal); + else bglBindTexture(GL_TEXTURE_2D, m->texid[globalpal]); + bglBegin(GL_QUADS); + for (i=0, fi=0; iqcnt; i++) + { + if (i == m->qfacind[fi]) { f = 1 /*clut[fi++]*/; bglColor4f(pc[0]*f, pc[1]*f, pc[2]*f, pc[3]*f); } + vptr = &m->quad[i].v[0]; + + xx = vptr[0].x+vptr[2].x; + yy = vptr[0].y+vptr[2].y; + zz = vptr[0].z+vptr[2].z; + + for (j=0; j<4; j++) + { + vec3f_t fp; +#if (VOXBORDWIDTH == 0) + bglTexCoord2f(((float) vptr[j].u)*ru+uhack[vptr[j].u!=vptr[0].u], + ((float) vptr[j].v)*rv+vhack[vptr[j].v!=vptr[0].v]); +#else + bglTexCoord2f(((float) vptr[j].u)*ru, ((float) vptr[j].v)*rv); +#endif + fp.x = ((float) vptr[j].x) - phack[xx>vptr[j].x*2] + phack[xxvptr[j].y*2] + phack[yyvptr[j].z*2] + phack[zzcstat&CSTAT_SPRITE_MDHACK) + { + bglDepthFunc(GL_LESS); //NEVER,LESS,(,L)EQUAL,GREATER,(NOT,G)EQUAL,ALWAYS + bglDepthRange(0.0, 0.99999); + } + bglLoadIdentity(); + return 1; +} +#endif + +//---------------------------------------- VOX LIBRARY ENDS ----------------------------------------