From 0a1172b75f571685c264a8b9d8ee224bbf11381f Mon Sep 17 00:00:00 2001 From: xolatile Date: Wed, 6 Aug 2025 22:54:55 +0200 Subject: Please do not hate me, it makes sense... --- src/engine/renderva.cpp | 618 ++++++++++++++---------------------------------- 1 file changed, 175 insertions(+), 443 deletions(-) (limited to 'src/engine/renderva.cpp') diff --git a/src/engine/renderva.cpp b/src/engine/renderva.cpp index 1e33702..cc0b65d 100644 --- a/src/engine/renderva.cpp +++ b/src/engine/renderva.cpp @@ -2,14 +2,12 @@ #include "engine.h" -static inline void drawtris(GLsizei numindices, const GLvoid *indices, ushort minvert, ushort maxvert) -{ +static inline void drawtris(GLsizei numindices, const GLvoid *indices, ushort minvert, ushort maxvert) { glDrawRangeElements_(GL_TRIANGLES, minvert, maxvert, numindices, GL_UNSIGNED_SHORT, indices); glde++; } -static inline void drawvatris(vtxarray *va, GLsizei numindices, const GLvoid *indices) -{ +static inline void drawvatris(vtxarray *va, GLsizei numindices, const GLvoid *indices) { drawtris(numindices, indices, va->minvert, va->maxvert); } @@ -20,48 +18,36 @@ float vfcDnear[5], vfcDfar[5]; vtxarray *visibleva; -int isvisiblesphere(float rad, const vec &cv) -{ +int isvisiblesphere(float rad, const vec &cv) { int v = VFC_FULL_VISIBLE; float dist; - - loopi(5) - { + loopi(5) { dist = vfcP[i].dist(cv); if(dist < -rad) return VFC_NOT_VISIBLE; if(dist < rad) v = VFC_PART_VISIBLE; } - if(dist > -rad) v = VFC_PART_VISIBLE; - return v; } -static inline int ishiddencube(const ivec &o, int size) -{ +static inline int ishiddencube(const ivec &o, int size) { loopi(5) if(o.dist(vfcP[i]) < -vfcDfar[i]*size) return true; return false; } -int isvisiblecube(const ivec &o, int size) -{ +int isvisiblecube(const ivec &o, int size) { int v = VFC_FULL_VISIBLE; float dist; - - loopi(5) - { + loopi(5) { dist = o.dist(vfcP[i]); if(dist < -vfcDfar[i]*size) return VFC_NOT_VISIBLE; if(dist < -vfcDnear[i]*size) v = VFC_PART_VISIBLE; } - if(dist > -vfcDfar[4]*size) v = VFC_PART_VISIBLE; - return v; } -float vadist(vtxarray *va, const vec &p) -{ +float vadist(vtxarray *va, const vec &p) { return p.dist_to_bb(va->bbmin, va->bbmax); } @@ -69,30 +55,23 @@ float vadist(vtxarray *va, const vec &p) static vtxarray *vasort[VASORTSIZE]; -void addvisibleva(vtxarray *va) -{ +void addvisibleva(vtxarray *va) { float dist = vadist(va, camera1->o); va->distance = int(dist); /*cv.dist(camera1->o) - va->size*SQRT3/2*/ - int hash = clamp(int(dist*VASORTSIZE/worldsize), 0, VASORTSIZE-1); vtxarray **prev = &vasort[hash], *cur = vasort[hash]; - - while(cur && va->distance >= cur->distance) - { + while(cur && va->distance >= cur->distance) { prev = &cur->next; cur = cur->next; } - va->next = *prev; *prev = va; } -void sortvisiblevas() -{ +void sortvisiblevas() { visibleva = NULL; vtxarray **last = &visibleva; - loopi(VASORTSIZE) if(vasort[i]) - { + loopi(VASORTSIZE) if(vasort[i]) { vtxarray *va = vasort[i]; *last = va; while(va->next) va = va->next; @@ -100,19 +79,15 @@ void sortvisiblevas() } } -void findvisiblevas(vector &vas, bool resetocclude = false) -{ - loopv(vas) - { +void findvisiblevas(vector &vas, bool resetocclude = false) { + loopv(vas) { vtxarray &v = *vas[i]; int prevvfc = resetocclude ? (int) VFC_NOT_VISIBLE : (int) v.curvfc; v.curvfc = isvisiblecube(v.o, v.size); - if(v.curvfc!=VFC_NOT_VISIBLE) - { + if(v.curvfc!=VFC_NOT_VISIBLE) { addvisibleva(&v); if(v.children.length()) findvisiblevas(v.children, prevvfc>=VFC_NOT_VISIBLE); - if(prevvfc>=VFC_NOT_VISIBLE) - { + if(prevvfc>=VFC_NOT_VISIBLE) { v.occluded = !v.texs ? OCCLUDE_GEOM : OCCLUDE_NOTHING; v.query = NULL; } @@ -120,10 +95,8 @@ void findvisiblevas(vector &vas, bool resetocclude = false) } } -void calcvfcD() -{ - loopi(5) - { +void calcvfcD() { + loopi(5) { plane &p = vfcP[i]; vfcDnear[i] = vfcDfar[i] = 0; loopk(3) if(p[k] > 0) vfcDfar[i] += p[k]; @@ -131,8 +104,7 @@ void calcvfcD() } } -void setvfcP(float z, const vec &bbmin, const vec &bbmax) -{ +void setvfcP(float z, const vec &bbmin, const vec &bbmax) { vec4 px = camprojmatrix.rowx(), py = camprojmatrix.rowy(), pz = camprojmatrix.rowz(), pw = camprojmatrix.roww(); vfcP[0] = plane(vec4(pw).mul(-bbmin.x).add(px)).normalize(); // left plane vfcP[1] = plane(vec4(pw).mul(bbmax.x).sub(px)).normalize(); // right plane @@ -140,41 +112,33 @@ void setvfcP(float z, const vec &bbmin, const vec &bbmax) vfcP[3] = plane(vec4(pw).mul(bbmax.y).sub(py)).normalize(); // top plane vfcP[4] = plane(vec4(pw).add(pz)).normalize(); // near/far planes if(z >= 0) loopi(5) vfcP[i].reflectz(z); - calcvfcD(); } plane oldvfcP[5]; -void savevfcP() -{ +void savevfcP() { memcpy(oldvfcP, vfcP, sizeof(vfcP)); } -void restorevfcP() -{ +void restorevfcP() { memcpy(vfcP, oldvfcP, sizeof(vfcP)); calcvfcD(); } -void visiblecubes(bool cull) -{ +void visiblecubes(bool cull) { memclear(vasort); - - if(cull) - { + if(cull) { setvfcP(); findvisiblevas(varoot); sortvisiblevas(); } - else - { + else { memclear(vfcP); memclear(vfcDnear); memclear(vfcDfar); visibleva = NULL; - loopv(valist) - { + loopv(valist) { vtxarray *va = valist[i]; va->distance = 0; va->curvfc = VFC_FULL_VISIBLE; @@ -186,8 +150,7 @@ void visiblecubes(bool cull) } } -static inline bool insideva(const vtxarray *va, const vec &v, int margin = 2) -{ +static inline bool insideva(const vtxarray *va, const vec &v, int margin = 2) { int size = va->size + margin; return v.x>=va->o.x-margin && v.y>=va->o.y-margin && v.z>=va->o.z-margin && v.x<=va->o.x+size && v.y<=va->o.y+size && v.z<=va->o.z+size; @@ -198,19 +161,13 @@ static inline bool insideva(const vtxarray *va, const vec &v, int margin = 2) #define MAXQUERY 2048 #define MAXQUERYFRAMES 2 -struct queryframe -{ +struct queryframe { int cur, max; occludequery queries[MAXQUERY]; - queryframe() : cur(0), max(0) {} - void flip() { loopi(cur) queries[i].owner = NULL; cur = 0; } - - occludequery *newquery(void *owner) - { - if(cur >= max) - { + occludequery *newquery(void *owner) { + if(cur >= max) { if(max >= MAXQUERY) return NULL; glGenQueries_(1, &queries[max++].id); } @@ -219,13 +176,9 @@ struct queryframe query->fragments = -1; return query; } - void reset() { loopi(max) queries[i].owner = NULL; } - - void cleanup() - { - loopi(max) - { + void cleanup() { + loopi(max) { glDeleteQueries_(1, &queries[i].id); queries[i].owner = NULL; } @@ -236,53 +189,43 @@ struct queryframe static queryframe queryframes[MAXQUERYFRAMES]; static uint flipquery = 0; -int getnumqueries() -{ +int getnumqueries() { return queryframes[flipquery].cur; } -void flipqueries() -{ +void flipqueries() { flipquery = (flipquery + 1) % MAXQUERYFRAMES; queryframes[flipquery].flip(); } -occludequery *newquery(void *owner) -{ +occludequery *newquery(void *owner) { return queryframes[flipquery].newquery(owner); } -void resetqueries() -{ +void resetqueries() { loopi(MAXQUERYFRAMES) queryframes[i].reset(); } -void clearqueries() -{ +void clearqueries() { loopi(MAXQUERYFRAMES) queryframes[i].cleanup(); } VAR(oqfrags, 0, 8, 64); VAR(oqwait, 0, 1, 1); -void startquery(occludequery *query) -{ +void startquery(occludequery *query) { glBeginQuery_(GL_SAMPLES_PASSED, query->id); } -void endquery(occludequery *query) -{ +void endquery(occludequery *query) { glEndQuery_(GL_SAMPLES_PASSED); } -bool checkquery(occludequery *query, bool nowait) -{ +bool checkquery(occludequery *query, bool nowait) { GLuint fragments; if(query->fragments >= 0) fragments = query->fragments; - else - { - if(nowait || !oqwait) - { + else { + if(nowait || !oqwait) { GLint avail; glGetQueryObjectiv_(query->id, GL_QUERY_RESULT_AVAILABLE, &avail); if(!avail) return false; @@ -295,10 +238,8 @@ bool checkquery(occludequery *query, bool nowait) static GLuint bbvbo = 0, bbebo = 0; -static void setupbb() -{ - if(!bbvbo) - { +static void setupbb() { + if(!bbvbo) { glGenBuffers_(1, &bbvbo); gle::bindvbo(bbvbo); vec verts[8]; @@ -306,8 +247,7 @@ static void setupbb() glBufferData_(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW); gle::clearvbo(); } - if(!bbebo) - { + if(!bbebo) { glGenBuffers_(1, &bbebo); gle::bindebo(bbebo); GLushort tris[3*2*6]; @@ -329,41 +269,35 @@ static void setupbb() } } -static void cleanupbb() -{ +static void cleanupbb() { if(bbvbo) { glDeleteBuffers_(1, &bbvbo); bbvbo = 0; } if(bbebo) { glDeleteBuffers_(1, &bbebo); bbebo = 0; } } -void startbb(bool mask) -{ +void startbb(bool mask) { setupbb(); gle::bindvbo(bbvbo); gle::bindebo(bbebo); gle::vertexpointer(sizeof(vec), (const vec *)0); gle::enablevertex(); SETSHADER(bbquery); - if(mask) - { + if(mask) { glDepthMask(GL_FALSE); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); } } -void endbb(bool mask) -{ +void endbb(bool mask) { gle::disablevertex(); gle::clearvbo(); gle::clearebo(); - if(mask) - { + if(mask) { glDepthMask(GL_TRUE); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); } } -void drawbb(const ivec &bo, const ivec &br) -{ +void drawbb(const ivec &bo, const ivec &br) { LOCALPARAMF(bborigin, bo.x, bo.y, bo.z); LOCALPARAMF(bbsize, br.x, br.y, br.z); glDrawRangeElements_(GL_TRIANGLES, 0, 8-1, 3*2*6, GL_UNSIGNED_SHORT, (ushort *)0); @@ -374,53 +308,40 @@ extern int octaentsize; static octaentities *visiblemms, **lastvisiblemms; -static inline bool insideoe(const octaentities *oe, const vec &v, int margin = 1) -{ +static inline bool insideoe(const octaentities *oe, const vec &v, int margin = 1) { return v.x>=oe->bbmin.x-margin && v.y>=oe->bbmin.y-margin && v.z>=oe->bbmin.z-margin && v.x<=oe->bbmax.x+margin && v.y<=oe->bbmax.y+margin && v.z<=oe->bbmax.z+margin; } -void findvisiblemms(const vector &ents, bool doquery) -{ +void findvisiblemms(const vector &ents, bool doquery) { visiblemms = NULL; lastvisiblemms = &visiblemms; - for(vtxarray *va = visibleva; va; va = va->next) - { + for(vtxarray *va = visibleva; va; va = va->next) { if(va->mapmodels.empty() || va->occluded >= OCCLUDE_BB) continue; - loopv(va->mapmodels) - { + loopv(va->mapmodels) { octaentities *oe = va->mapmodels[i]; - bool occluded = doquery && oe->query && oe->query->owner == oe && checkquery(oe->query); - if(occluded) - { + if(occluded) { oe->distance = -1; - oe->next = NULL; *lastvisiblemms = oe; lastvisiblemms = &oe->next; } - else - { + else { int visible = 0; - loopv(oe->mapmodels) - { + loopv(oe->mapmodels) { extentity &e = *ents[oe->mapmodels[i]]; if(e.flags&EF_NOVIS) continue; e.flags |= EF_RENDER; ++visible; } if(!visible) continue; - oe->distance = int(camera1->o.dist_to_bb(oe->o, oe->size)); - octaentities **prev = &visiblemms, *cur = visiblemms; - while(cur && cur->distance >= 0 && oe->distance > cur->distance) - { + while(cur && cur->distance >= 0 && oe->distance > cur->distance) { prev = &cur->next; cur = cur->next; } - if(*prev == NULL) lastvisiblemms = &oe->next; oe->next = *prev; *prev = oe; @@ -431,30 +352,24 @@ void findvisiblemms(const vector &ents, bool doquery) VAR(oqmm, 0, 4, 8); -void rendermapmodel(extentity &e) -{ +void rendermapmodel(extentity &e) { int anim = ANIM_MAPMODEL|ANIM_LOOP, basetime = 0; mapmodelinfo *mmi = getmminfo(e.attr2); if(mmi) rendermodel(&e.light, mmi->name, anim, e.o, e.attr1, 0, MDL_CULL_VFC | MDL_CULL_DIST | MDL_DYNLIGHT, NULL, NULL, basetime); } -void rendermapmodels() -{ +void rendermapmodels() { static int skipoq = 0; bool doquery = !drawtex && oqfrags && oqmm; const vector &ents = entities::getents(); findvisiblemms(ents, doquery); - startmodelbatches(); - for(octaentities *oe = visiblemms; oe; oe = oe->next) if(oe->distance>=0) - { + for(octaentities *oe = visiblemms; oe; oe = oe->next) if(oe->distance>=0) { bool rendered = false; - loopv(oe->mapmodels) - { + loopv(oe->mapmodels) { extentity &e = *ents[oe->mapmodels[i]]; if(!(e.flags&EF_RENDER)) continue; - if(!rendered) - { + if(!rendered) { rendered = true; oe->query = doquery && oe->distance>0 && !(++skipoq%oqmm) ? newquery(oe) : NULL; if(oe->query) startmodelquery(oe->query); @@ -465,14 +380,11 @@ void rendermapmodels() if(rendered && oe->query) endmodelquery(); } endmodelbatches(); - bool queried = true; - for(octaentities *oe = visiblemms; oe; oe = oe->next) if(oe->distance<0) - { + for(octaentities *oe = visiblemms; oe; oe = oe->next) if(oe->distance<0) { oe->query = doquery && !insideoe(oe, camera1->o) ? newquery(oe) : NULL; if(!oe->query) continue; - if(queried) - { + if(queried) { startbb(); queried = false; } @@ -480,25 +392,20 @@ void rendermapmodels() drawbb(oe->bbmin, ivec(oe->bbmax).sub(oe->bbmin)); endquery(oe->query); } - if(!queried) - { + if(!queried) { endbb(); } } -static inline bool bbinsideva(const ivec &bo, const ivec &br, vtxarray *va) -{ +static inline bool bbinsideva(const ivec &bo, const ivec &br, vtxarray *va) { return bo.x >= va->bbmin.x && bo.y >= va->bbmin.y && bo.z >= va->bbmin.z && br.x <= va->bbmax.x && br.y <= va->bbmax.y && br.z <= va->bbmax.z; } -static inline bool bboccluded(const ivec &bo, const ivec &br, cube *c, const ivec &o, int size) -{ - loopoctabox(o, size, bo, br) - { +static inline bool bboccluded(const ivec &bo, const ivec &br, cube *c, const ivec &o, int size) { + loopoctabox(o, size, bo, br) { ivec co(i, o, size); - if(c[i].ext && c[i].ext->va) - { + if(c[i].ext && c[i].ext->va) { vtxarray *va = c[i].ext->va; if(va->occluded >= OCCLUDE_BB && bbinsideva(bo, br, va)) continue; } @@ -508,24 +415,20 @@ static inline bool bboccluded(const ivec &bo, const ivec &br, cube *c, const ive return true; } -bool bboccluded(const ivec &bo, const ivec &br) -{ +bool bboccluded(const ivec &bo, const ivec &br) { int diff = (bo.x^br.x) | (bo.y^br.y) | (bo.z^br.z); if(diff&~((1<ext && c->ext->va) - { + if(c->ext && c->ext->va) { vtxarray *va = c->ext->va; if(va->occluded >= OCCLUDE_BB && bbinsideva(bo, br, va)) return true; } scale--; - while(c->children && !(diff&(1<children && !(diff&(1<children[octastep(bo.x, bo.y, bo.z, scale)]; - if(c->ext && c->ext->va) - { + if(c->ext && c->ext->va) { vtxarray *va = c->ext->va; if(va->occluded >= OCCLUDE_BB && bbinsideva(bo, br, va)) return true; } @@ -539,103 +442,71 @@ VAR(outline, 0, 0, 1); HVARP(outlinecolour, 0, 0, 0xFFFFFF); VAR(dtoutline, 0, 1, 1); -void renderoutline() -{ +void renderoutline() { notextureshader->set(); - gle::enablevertex(); - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); gle::color(vec::hexcolor(outlinecolour)); - enablepolygonoffset(GL_POLYGON_OFFSET_LINE); - if(!dtoutline) glDisable(GL_DEPTH_TEST); - vtxarray *prev = NULL; - for(vtxarray *va = visibleva; va; va = va->next) - { + for(vtxarray *va = visibleva; va; va = va->next) { if(va->occluded >= OCCLUDE_BB) continue; if(!va->alphaback && !va->alphafront && (!va->texs || va->occluded >= OCCLUDE_GEOM)) continue; - - if(!prev || va->vbuf != prev->vbuf) - { + if(!prev || va->vbuf != prev->vbuf) { gle::bindvbo(va->vbuf); gle::bindebo(va->ebuf); const vertex *ptr = 0; gle::vertexpointer(sizeof(vertex), ptr->pos.v); } - - if(va->texs && va->occluded < OCCLUDE_GEOM) - { + if(va->texs && va->occluded < OCCLUDE_GEOM) { drawvatris(va, 3*va->tris, va->edata); xtravertsva += va->verts; } - if(va->alphatris) - { + if(va->alphatris) { drawvatris(va, 3*va->alphatris, &va->edata[3*(va->tris + va->blendtris)]); xtravertsva += 3*va->alphatris; } - prev = va; } - if(!dtoutline) glEnable(GL_DEPTH_TEST); - disablepolygonoffset(GL_POLYGON_OFFSET_LINE); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - gle::clearvbo(); gle::clearebo(); gle::disablevertex(); } -void rendershadowmapreceivers() -{ +void rendershadowmapreceivers() { SETSHADER(shadowmapreceiver); - gle::enablevertex(); - glCullFace(GL_FRONT); glDepthMask(GL_FALSE); glDepthFunc(GL_GREATER); - extern int ati_minmax_bug; if(!ati_minmax_bug) glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_FALSE); - glEnable(GL_BLEND); glBlendEquation_(GL_MAX); glBlendFunc(GL_ONE, GL_ONE); - vtxarray *prev = NULL; - for(vtxarray *va = visibleva; va; va = va->next) - { + for(vtxarray *va = visibleva; va; va = va->next) { if(!va->texs || !isshadowmapreceiver(va)) continue; - - if(!prev || va->vbuf != prev->vbuf) - { + if(!prev || va->vbuf != prev->vbuf) { gle::bindvbo(va->vbuf); gle::bindebo(va->ebuf); const vertex *ptr = 0; gle::vertexpointer(sizeof(vertex), ptr->pos.v); } - drawvatris(va, 3*va->tris, va->edata); xtravertsva += va->verts; - prev = va; } - glDisable(GL_BLEND); glBlendEquation_(GL_FUNC_ADD); - glCullFace(GL_BACK); glDepthMask(GL_TRUE); glDepthFunc(GL_LESS); - if(!ati_minmax_bug) glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - gle::clearvbo(); gle::clearebo(); gle::disablevertex(); @@ -645,8 +516,7 @@ VAR(oqdist, 0, 256, 1024); VAR(zpass, 0, 1, 1); VAR(envpass, 0, 1, 1); -struct renderstate -{ +struct renderstate { bool colormask, depthmask, blending; int alphaing; GLuint vbuf; @@ -660,68 +530,54 @@ struct renderstate int texgendim; int visibledynlights; uint dynlightmask; - - renderstate() : colormask(true), depthmask(true), blending(false), alphaing(0), vbuf(0), vattribs(false), vquery(false), colorscale(1, 1, 1), alphascale(0), slot(NULL), texgenslot(NULL), vslot(NULL), texgenvslot(NULL), texgenscroll(0, 0), texgendim(-1), visibledynlights(0), dynlightmask(0) - { + renderstate() : colormask(true), depthmask(true), blending(false), alphaing(0), vbuf(0), vattribs(false), vquery(false), colorscale(1, 1, 1), alphascale(0), slot(NULL), texgenslot(NULL), vslot(NULL), texgenvslot(NULL), texgenscroll(0, 0), texgendim(-1), visibledynlights(0), dynlightmask(0) { loopk(8) textures[k] = 0; } }; -static inline void disablevbuf(renderstate &cur) -{ +static inline void disablevbuf(renderstate &cur) { gle::clearvbo(); gle::clearebo(); cur.vbuf = 0; } -static inline void enablevquery(renderstate &cur) -{ +static inline void enablevquery(renderstate &cur) { if(cur.colormask) { cur.colormask = false; glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); } if(cur.depthmask) { cur.depthmask = false; glDepthMask(GL_FALSE); } startbb(false); cur.vquery = true; } -static inline void disablevquery(renderstate &cur) -{ +static inline void disablevquery(renderstate &cur) { endbb(false); cur.vquery = false; } -static void renderquery(renderstate &cur, occludequery *query, vtxarray *va, bool full = true) -{ +static void renderquery(renderstate &cur, occludequery *query, vtxarray *va, bool full = true) { if(!cur.vquery) enablevquery(cur); - startquery(query); - if(full) drawbb(ivec(va->bbmin).sub(1), ivec(va->bbmax).sub(va->bbmin).add(2)); else drawbb(va->geommin, ivec(va->geommax).sub(va->geommin)); - endquery(query); } -enum -{ +enum { RENDERPASS_LIGHTMAP = 0, RENDERPASS_Z, RENDERPASS_LIGHTMAP_BLEND }; -struct geombatch -{ +struct geombatch { const elementset &es; VSlot &vslot; ushort *edata; vtxarray *va; int next, batch; - geombatch(const elementset &es, ushort *edata, vtxarray *va) : es(es), vslot(lookupvslot(es.texture)), edata(edata), va(va), - next(-1), batch(-1) - {} - - int compare(const geombatch &b) const - { + next(-1), batch(-1) { + } + int compare(const geombatch &b) const { if(va->vbuf < b.va->vbuf) return -1; if(va->vbuf > b.va->vbuf) return 1; if(va->dynlightmask < b.va->dynlightmask) return -1; @@ -743,73 +599,59 @@ struct geombatch static vector geombatches; static int firstbatch = -1, numbatches = 0; -static void mergetexs(renderstate &cur, vtxarray *va, elementset *texs = NULL, int numtexs = 0, ushort *edata = NULL) -{ - if(!texs) - { +static void mergetexs(renderstate &cur, vtxarray *va, elementset *texs = NULL, int numtexs = 0, ushort *edata = NULL) { + if(!texs) { texs = va->eslist; numtexs = va->texs; edata = va->edata; - if(cur.alphaing) - { + if(cur.alphaing) { texs += va->texs + va->blends; edata += 3*(va->tris + va->blendtris); numtexs = va->alphaback; if(cur.alphaing > 1) numtexs += va->alphafront; } } - - if(firstbatch < 0) - { + if(firstbatch < 0) { firstbatch = geombatches.length(); numbatches = numtexs; - loopi(numtexs-1) - { + loopi(numtexs-1) { geombatches.add(geombatch(texs[i], edata, va)).next = i+1; edata += texs[i].length[1]; } geombatches.add(geombatch(texs[numtexs-1], edata, va)); return; } - int prevbatch = -1, curbatch = firstbatch, curtex = 0; - do - { + do { geombatch &b = geombatches.add(geombatch(texs[curtex], edata, va)); edata += texs[curtex].length[1]; int dir = -1; - while(curbatch >= 0) - { + while(curbatch >= 0) { dir = b.compare(geombatches[curbatch]); if(dir <= 0) break; prevbatch = curbatch; curbatch = geombatches[curbatch].next; } - if(!dir) - { + if(!dir) { int last = curbatch, next; - for(;;) - { + for(;;) { next = geombatches[last].batch; if(next < 0) break; last = next; } - if(last==curbatch) - { + if(last==curbatch) { b.batch = curbatch; b.next = geombatches[curbatch].next; if(prevbatch < 0) firstbatch = geombatches.length()-1; else geombatches[prevbatch].next = geombatches.length()-1; curbatch = geombatches.length()-1; } - else - { + else { b.batch = next; geombatches[last].batch = geombatches.length()-1; } } - else - { + else { numbatches++; b.next = curbatch; if(prevbatch < 0) firstbatch = geombatches.length()-1; @@ -820,11 +662,9 @@ static void mergetexs(renderstate &cur, vtxarray *va, elementset *texs = NULL, i while(++curtex < numtexs); } -static inline void enablevattribs(renderstate &cur, bool all = true) -{ +static inline void enablevattribs(renderstate &cur, bool all = true) { gle::enablevertex(); - if(all) - { + if(all) { gle::enabletexcoord0(); gle::enabletexcoord1(); gle::enablenormal(); @@ -833,11 +673,9 @@ static inline void enablevattribs(renderstate &cur, bool all = true) cur.vattribs = true; } -static inline void disablevattribs(renderstate &cur, bool all = true) -{ +static inline void disablevattribs(renderstate &cur, bool all = true) { gle::disablevertex(); - if(all) - { + if(all) { gle::disabletexcoord0(); gle::disabletexcoord1(); gle::disablenormal(); @@ -846,17 +684,13 @@ static inline void disablevattribs(renderstate &cur, bool all = true) cur.vattribs = false; } -static void changevbuf(renderstate &cur, int pass, vtxarray *va) -{ +static void changevbuf(renderstate &cur, int pass, vtxarray *va) { gle::bindvbo(va->vbuf); gle::bindebo(va->ebuf); cur.vbuf = va->vbuf; - vertex *vdata = (vertex *)0; gle::vertexpointer(sizeof(vertex), vdata->pos.v); - - if(pass==RENDERPASS_LIGHTMAP) - { + if(pass==RENDERPASS_LIGHTMAP) { gle::normalpointer(sizeof(vertex), vdata->norm.v, GL_BYTE); gle::texcoord0pointer(sizeof(vertex), vdata->tc.v); gle::texcoord1pointer(sizeof(vertex), vdata->lm.v, GL_SHORT); @@ -864,86 +698,68 @@ static void changevbuf(renderstate &cur, int pass, vtxarray *va) } } -static void changebatchtmus(renderstate &cur, int pass, geombatch &b) -{ +static void changebatchtmus(renderstate &cur, int pass, geombatch &b) { bool changed = false; extern bool brightengeom; extern int fullbright; int lmid = brightengeom && (b.es.lmid < LMID_RESERVED || (fullbright && editmode)) ? (int) LMID_BRIGHT : (int) b.es.lmid; - if(cur.textures[1]!=lightmaptexs[lmid].id) - { + if(cur.textures[1]!=lightmaptexs[lmid].id) { glActiveTexture_(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, cur.textures[1] = lightmaptexs[lmid].id); changed = true; } int tmu = 2; - if(b.vslot.slot->shader->type&SHADER_NORMALSLMS) - { - if(cur.textures[tmu]!=lightmaptexs[lmid+1].id) - { + if(b.vslot.slot->shader->type&SHADER_NORMALSLMS) { + if(cur.textures[tmu]!=lightmaptexs[lmid+1].id) { glActiveTexture_(GL_TEXTURE0+tmu); glBindTexture(GL_TEXTURE_2D, cur.textures[tmu] = lightmaptexs[lmid+1].id); changed = true; } tmu++; } - if(changed) glActiveTexture_(GL_TEXTURE0); - - if(cur.dynlightmask != b.va->dynlightmask) - { + if(cur.dynlightmask != b.va->dynlightmask) { cur.visibledynlights = setdynlights(b.va); cur.dynlightmask = b.va->dynlightmask; } } -static void changeslottmus(renderstate &cur, int pass, Slot &slot, VSlot &vslot) -{ - if(pass==RENDERPASS_LIGHTMAP) - { +static void changeslottmus(renderstate &cur, int pass, Slot &slot, VSlot &vslot) { + if(pass==RENDERPASS_LIGHTMAP) { GLuint diffusetex = slot.sts.empty() ? notexture->id : slot.sts[0].t->id; if(cur.textures[0]!=diffusetex) glBindTexture(GL_TEXTURE_2D, cur.textures[0] = diffusetex); } - - if(cur.alphaing) - { + if(cur.alphaing) { float alpha = cur.alphaing > 1 ? vslot.alphafront : vslot.alphaback; - if(cur.colorscale != vslot.colorscale || cur.alphascale != alpha) - { + if(cur.colorscale != vslot.colorscale || cur.alphascale != alpha) { cur.colorscale = vslot.colorscale; cur.alphascale = alpha; GLOBALPARAMF(colorparams, 2*alpha*vslot.colorscale.x, 2*alpha*vslot.colorscale.y, 2*alpha*vslot.colorscale.z, alpha); } } - else if(cur.colorscale != vslot.colorscale) - { + else if(cur.colorscale != vslot.colorscale) { cur.colorscale = vslot.colorscale; GLOBALPARAMF(colorparams, 2*vslot.colorscale.x, 2*vslot.colorscale.y, 2*vslot.colorscale.z, 1); } int tmu = 2; if(slot.shader->type&SHADER_NORMALSLMS) tmu++; - loopvj(slot.sts) - { + loopvj(slot.sts) { Slot::Tex &t = slot.sts[j]; if(t.type==TEX_DIFFUSE || t.combined>=0) continue; - if(cur.textures[tmu]!=t.t->id) - { + if(cur.textures[tmu]!=t.t->id) { glActiveTexture_(GL_TEXTURE0+tmu); glBindTexture(GL_TEXTURE_2D, cur.textures[tmu] = t.t->id); } if(++tmu >= 8) break; } glActiveTexture_(GL_TEXTURE0); - cur.slot = &slot; cur.vslot = &vslot; } -static void changeshader(renderstate &cur, Shader *s, Slot &slot, VSlot &vslot, bool shadowed) -{ - if(!cur.blending && !cur.alphaing) - { +static void changeshader(renderstate &cur, Shader *s, Slot &slot, VSlot &vslot, bool shadowed) { + if(!cur.blending && !cur.alphaing) { if(shadowed) s->setvariant(cur.visibledynlights, 3, slot, vslot); else s->setvariant(cur.visibledynlights, 2, slot, vslot); } @@ -952,17 +768,14 @@ static void changeshader(renderstate &cur, Shader *s, Slot &slot, VSlot &vslot, else s->setvariant(cur.visibledynlights-1, 0, slot, vslot); } -static void changetexgen(renderstate &cur, int dim, Slot &slot, VSlot &vslot) -{ - if(cur.texgenslot != &slot || cur.texgenvslot != &vslot) - { +static void changetexgen(renderstate &cur, int dim, Slot &slot, VSlot &vslot) { + if(cur.texgenslot != &slot || cur.texgenvslot != &vslot) { Texture *curtex = !cur.texgenslot || cur.texgenslot->sts.empty() ? notexture : cur.texgenslot->sts[0].t, *tex = slot.sts.empty() ? notexture : slot.sts[0].t; if(!cur.texgenvslot || slot.sts.empty() || (curtex->xs != tex->xs || curtex->ys != tex->ys || cur.texgenvslot->rotation != vslot.rotation || cur.texgenvslot->scale != vslot.scale || - cur.texgenvslot->offset != vslot.offset || cur.texgenvslot->scroll != vslot.scroll)) - { + cur.texgenvslot->offset != vslot.offset || cur.texgenvslot->scroll != vslot.scroll)) { const texrotation &r = texrotations[vslot.rotation]; float xs = r.flipx ? -tex->xs : tex->xs, ys = r.flipy ? -tex->ys : tex->ys; @@ -970,8 +783,7 @@ static void changetexgen(renderstate &cur, int dim, Slot &slot, VSlot &vslot) if(r.swapxy) swap(scroll.x, scroll.y); scroll.x *= lastmillis*tex->xs/xs; scroll.y *= lastmillis*tex->ys/ys; - if(cur.texgenscroll != scroll) - { + if(cur.texgenscroll != scroll) { cur.texgenscroll = scroll; cur.texgendim = -1; } @@ -979,23 +791,18 @@ static void changetexgen(renderstate &cur, int dim, Slot &slot, VSlot &vslot) cur.texgenslot = &slot; cur.texgenvslot = &vslot; } - if(cur.texgendim == dim) return; GLOBALPARAM(texgenscroll, cur.texgenscroll); cur.texgendim = dim; } -static void renderbatch(renderstate &cur, int pass, geombatch &b) -{ +static void renderbatch(renderstate &cur, int pass, geombatch &b) { geombatch *shadowed = NULL; int rendered = -1; - for(geombatch *curbatch = &b;; curbatch = &geombatches[curbatch->batch]) - { + for(geombatch *curbatch = &b;; curbatch = &geombatches[curbatch->batch]) { ushort len = curbatch->es.length[curbatch->va->shadowed ? 0 : 1]; - if(len) - { - if(rendered < 0) - { + if(len) { + if(rendered < 0) { changeshader(cur, b.vslot.slot->shader, *b.vslot.slot, b.vslot, false); rendered = 0; gbatches++; @@ -1008,12 +815,9 @@ static void renderbatch(renderstate &cur, int pass, geombatch &b) if(curbatch->es.length[1] > len && !shadowed) shadowed = curbatch; if(curbatch->batch < 0) break; } - if(shadowed) for(geombatch *curbatch = shadowed;; curbatch = &geombatches[curbatch->batch]) - { - if(curbatch->va->shadowed && curbatch->es.length[1] > curbatch->es.length[0]) - { - if(rendered < 1) - { + if(shadowed) for(geombatch *curbatch = shadowed;; curbatch = &geombatches[curbatch->batch]) { + if(curbatch->va->shadowed && curbatch->es.length[1] > curbatch->es.length[0]) { + if(rendered < 1) { changeshader(cur, b.vslot.slot->shader, *b.vslot.slot, b.vslot, true); rendered = 1; gbatches++; @@ -1026,56 +830,44 @@ static void renderbatch(renderstate &cur, int pass, geombatch &b) } } -static void resetbatches() -{ +static void resetbatches() { geombatches.setsize(0); firstbatch = -1; numbatches = 0; } -static void renderbatches(renderstate &cur, int pass) -{ +static void renderbatches(renderstate &cur, int pass) { cur.slot = NULL; cur.vslot = NULL; int curbatch = firstbatch; - if(curbatch >= 0) - { - if(cur.alphaing) - { + if(curbatch >= 0) { + if(cur.alphaing) { if(cur.depthmask) { cur.depthmask = false; glDepthMask(GL_FALSE); } } else if(!cur.depthmask) { cur.depthmask = true; glDepthMask(GL_TRUE); } if(!cur.colormask) { cur.colormask = true; glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, cur.alphaing ? GL_FALSE : GL_TRUE); } - if(!cur.vattribs) - { + if(!cur.vattribs) { if(cur.vquery) disablevquery(cur); enablevattribs(cur); } } - while(curbatch >= 0) - { + while(curbatch >= 0) { geombatch &b = geombatches[curbatch]; curbatch = b.next; - if(cur.vbuf != b.va->vbuf) changevbuf(cur, pass, b.va); - if(cur.vslot != &b.vslot) - { + if(cur.vslot != &b.vslot) { changeslottmus(cur, pass, *b.vslot.slot, b.vslot); if(cur.texgendim != b.es.dim || (cur.texgendim <= 2 && cur.texgenvslot != &b.vslot)) changetexgen(cur, b.es.dim, *b.vslot.slot, b.vslot); } else if(cur.texgendim != b.es.dim) changetexgen(cur, b.es.dim, *b.vslot.slot, b.vslot); if(pass == RENDERPASS_LIGHTMAP) changebatchtmus(cur, pass, b); - renderbatch(cur, pass, b); } - resetbatches(); } -void renderzpass(renderstate &cur, vtxarray *va) -{ - if(!cur.vattribs) - { +void renderzpass(renderstate &cur, vtxarray *va) { + if(!cur.vattribs) { if(cur.vquery) disablevquery(cur); enablevattribs(cur, false); } @@ -1084,8 +876,7 @@ void renderzpass(renderstate &cur, vtxarray *va) if(cur.colormask) { cur.colormask = false; glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); } int firsttex = 0, numtris = va->tris; ushort *edata = va->edata; - if(cur.alphaing) - { + if(cur.alphaing) { firsttex += va->texs + va->blends; edata += 3*(va->tris + va->blendtris); numtris = va->alphatris; @@ -1098,8 +889,8 @@ void renderzpass(renderstate &cur, vtxarray *va) #define startvaquery(va, flush) \ do { \ - if(va->query) \ - { \ + if(va->query) { \ + \ flush; \ startquery(va->query); \ } \ @@ -1108,8 +899,8 @@ void renderzpass(renderstate &cur, vtxarray *va) #define endvaquery(va, flush) \ do { \ - if(va->query) \ - { \ + if(va->query) { \ + \ flush; \ endquery(va->query); \ } \ @@ -1117,16 +908,13 @@ void renderzpass(renderstate &cur, vtxarray *va) VAR(batchgeom, 0, 1, 1); -void renderva(renderstate &cur, vtxarray *va, int pass = RENDERPASS_LIGHTMAP, bool doquery = false) -{ - switch(pass) - { +void renderva(renderstate &cur, vtxarray *va, int pass = RENDERPASS_LIGHTMAP, bool doquery = false) { + switch(pass) { case RENDERPASS_LIGHTMAP: if(!cur.alphaing) vverts += va->verts; va->shadowed = false; va->dynlightmask = 0; - if(!drawtex && !cur.alphaing) - { + if(!drawtex && !cur.alphaing) { va->shadowed = isshadowmapreceiver(va); calcdynlightmask(va); } @@ -1135,16 +923,13 @@ void renderva(renderstate &cur, vtxarray *va, int pass = RENDERPASS_LIGHTMAP, bo if(doquery) endvaquery(va, { if(geombatches.length()) renderbatches(cur, pass); }); else if(!batchgeom && geombatches.length()) renderbatches(cur, pass); break; - - case RENDERPASS_LIGHTMAP_BLEND: - { + case RENDERPASS_LIGHTMAP_BLEND: { if(doquery) startvaquery(va, { if(geombatches.length()) renderbatches(cur, RENDERPASS_LIGHTMAP); }); mergetexs(cur, va, &va->eslist[va->texs], va->blends, va->edata + 3*va->tris); if(doquery) endvaquery(va, { if(geombatches.length()) renderbatches(cur, RENDERPASS_LIGHTMAP); }); else if(!batchgeom && geombatches.length()) renderbatches(cur, RENDERPASS_LIGHTMAP); break; } - case RENDERPASS_Z: if(doquery) startvaquery(va, ); renderzpass(cur, va); @@ -1153,62 +938,49 @@ void renderva(renderstate &cur, vtxarray *va, int pass = RENDERPASS_LIGHTMAP, bo } } -void cleanupva() -{ +void cleanupva() { clearvas(worldroot); clearqueries(); cleanupbb(); } -void setupgeom(renderstate &cur) -{ +void setupgeom(renderstate &cur) { GLOBALPARAMF(colorparams, 2, 2, 2, 1); GLOBALPARAM(camera, camera1->o); GLOBALPARAMF(ambient, ambientcolor.x/255.0f, ambientcolor.y/255.0f, ambientcolor.z/255.0f); GLOBALPARAMF(millis, lastmillis/1000.0f); - glActiveTexture_(GL_TEXTURE0); } -void cleanupgeom(renderstate &cur) -{ +void cleanupgeom(renderstate &cur) { if(cur.vattribs) disablevattribs(cur); if(cur.vbuf) disablevbuf(cur); } VAR(oqgeom, 0, 1, 1); -void rendergeom(void) -{ +void rendergeom(void) { bool mainpass = !drawtex, doOQ = oqfrags && oqgeom && mainpass, doZP = doOQ && zpass, doSM = shadowmap && !drawtex; renderstate cur; - if(mainpass) - { + if(mainpass) { flipqueries(); vtris = vverts = 0; } - if(!doZP) - { + if(!doZP) { if(shadowmap && mainpass) rendershadowmap(); setupgeom(cur); if(doSM) pushshadowmap(); } - finddynlights(); - resetbatches(); - int blends = 0; - for(vtxarray *va = visibleva; va; va = va->next) - { + for(vtxarray *va = visibleva; va; va = va->next) { if(!va->texs) continue; - if(doOQ && (zpass || va->distance > oqdist) && !insideva(va, camera1->o)) - { - if(va->parent && va->parent->occluded >= OCCLUDE_BB) - { + if(doOQ && (zpass || va->distance > oqdist) && !insideva(va, camera1->o)) { + if(va->parent && va->parent->occluded >= OCCLUDE_BB) { va->query = NULL; va->occluded = OCCLUDE_PARENT; continue; @@ -1217,10 +989,8 @@ void rendergeom(void) va->query = newquery(va); if((!va->query && zpass) || !va->occluded) va->occluded = OCCLUDE_NOTHING; - if(va->occluded >= OCCLUDE_GEOM) - { - if(va->query) - { + if(va->occluded >= OCCLUDE_GEOM) { + if(va->query) { if(!zpass && geombatches.length()) renderbatches(cur, RENDERPASS_LIGHTMAP); if(cur.vattribs) disablevattribs(cur, !doZP); if(cur.vbuf) disablevbuf(cur); @@ -1229,117 +999,85 @@ void rendergeom(void) continue; } } - else - { + else { va->query = NULL; va->occluded = OCCLUDE_NOTHING; } - if(!doZP) blends += va->blends; renderva(cur, va, doZP ? RENDERPASS_Z : RENDERPASS_LIGHTMAP, doOQ); } - if(geombatches.length()) renderbatches(cur, RENDERPASS_LIGHTMAP); - if(cur.vquery) disablevquery(cur); if(cur.vattribs) disablevattribs(cur, !doZP); if(cur.vbuf) disablevbuf(cur); - if(!cur.colormask) { cur.colormask = true; glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); } if(!cur.depthmask) { cur.depthmask = true; glDepthMask(GL_TRUE); } - bool multipassing = false; - - if(doZP) - { + if(doZP) { glFlush(); - if(shadowmap && mainpass) rendershadowmap(); setupgeom(cur); if(doSM) pushshadowmap(); - if(!multipassing) { multipassing = true; glDepthFunc(GL_LEQUAL); } cur.texgendim = -1; - - for(vtxarray *va = visibleva; va; va = va->next) - { + for(vtxarray *va = visibleva; va; va = va->next) { if(!va->texs || va->occluded >= OCCLUDE_GEOM) continue; blends += va->blends; renderva(cur, va, RENDERPASS_LIGHTMAP); } if(geombatches.length()) renderbatches(cur, RENDERPASS_LIGHTMAP); - for(vtxarray *va = visibleva; va; va = va->next) - { + for(vtxarray *va = visibleva; va; va = va->next) { if(!va->texs || va->occluded < OCCLUDE_GEOM) continue; else if((va->parent && va->parent->occluded >= OCCLUDE_BB) || - (va->query && checkquery(va->query))) - { + (va->query && checkquery(va->query))) { va->occluded = OCCLUDE_BB; continue; } - blends += va->blends; renderva(cur, va, RENDERPASS_LIGHTMAP); } if(geombatches.length()) renderbatches(cur, RENDERPASS_LIGHTMAP); } - - if(blends) - { + if(blends) { if(cur.vbuf) disablevbuf(cur); - if(!multipassing) { multipassing = true; glDepthFunc(GL_LEQUAL); } glDepthMask(GL_FALSE); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); - cur.texgendim = -1; cur.blending = true; - for(vtxarray *va = visibleva; va; va = va->next) - { + for(vtxarray *va = visibleva; va; va = va->next) { if(!va->blends) continue; if(va->occluded >= OCCLUDE_GEOM) continue; renderva(cur, va, RENDERPASS_LIGHTMAP_BLEND); } if(geombatches.length()) renderbatches(cur, RENDERPASS_LIGHTMAP); cur.blending = false; - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glDisable(GL_BLEND); glDepthMask(GL_TRUE); } - - if(doSM) popshadowmap(); - if(cur.vattribs) disablevattribs(cur); - if(multipassing) glDepthFunc(GL_LESS); - cleanupgeom(cur); } -void renderalphageom(void) -{ +void renderalphageom(void) { static vector alphavas; alphavas.setsize(0); bool hasback = false; - for(vtxarray *va = visibleva; va; va = va->next) - { + for(vtxarray *va = visibleva; va; va = va->next) { if(!va->alphatris) continue; if(va->occluded >= OCCLUDE_BB) continue; alphavas.add(va); if(va->alphabacktris) hasback = true; } if(alphavas.empty()) return; - resetbatches(); - renderstate cur; cur.alphaing = 1; - - loop(front, 2) if(front || hasback) - { + loop(front, 2) if(front || hasback) { cur.alphaing = front+1; if(!front) glCullFace(GL_FRONT); cur.vbuf = 0; @@ -1348,12 +1086,9 @@ void renderalphageom(void) if(cur.depthmask) { cur.depthmask = false; glDepthMask(GL_FALSE); } cur.colormask = true; glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); - if(cur.vattribs) disablevattribs(cur, false); if(cur.vbuf) disablevbuf(cur); - setupgeom(cur); - glDepthFunc(GL_LEQUAL); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); @@ -1363,14 +1098,11 @@ void renderalphageom(void) cur.alphascale = -1; loopv(alphavas) if(front || alphavas[i]->alphabacktris) renderva(cur, alphavas[i], RENDERPASS_LIGHTMAP); if(geombatches.length()) renderbatches(cur, RENDERPASS_LIGHTMAP); - cleanupgeom(cur); - if(!cur.depthmask) { cur.depthmask = true; glDepthMask(GL_TRUE); } glDisable(GL_BLEND); glDepthFunc(GL_LESS); if(!front) glCullFace(GL_BACK); } - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); } -- cgit v1.2.3