diff options
Diffstat (limited to 'src/engine/renderva.cpp')
| -rw-r--r-- | src/engine/renderva.cpp | 314 |
1 files changed, 12 insertions, 302 deletions
diff --git a/src/engine/renderva.cpp b/src/engine/renderva.cpp index dc3dca1..e0b74e2 100644 --- a/src/engine/renderva.cpp +++ b/src/engine/renderva.cpp @@ -16,18 +16,10 @@ static inline void drawvatris(vtxarray *va, GLsizei numindices, const GLvoid *in ///////// view frustrum culling /////////////////////// plane vfcP[5]; // perpindictular vectors to view frustrum bounding planes -float vfcDfog; // far plane culling distance (fog limit). float vfcDnear[5], vfcDfar[5]; vtxarray *visibleva; -bool isfoggedsphere(float rad, const vec &cv) -{ - loopi(4) if(vfcP[i].dist(cv) < -rad) return true; - float dist = vfcP[4].dist(cv); - return dist < -rad || dist > vfcDfog + rad; -} - int isvisiblesphere(float rad, const vec &cv) { int v = VFC_FULL_VISIBLE; @@ -40,7 +32,6 @@ int isvisiblesphere(float rad, const vec &cv) if(dist < rad) v = VFC_PART_VISIBLE; } - dist -= vfcDfog; if(dist > rad) return VFC_FOGGED; //VFC_NOT_VISIBLE; // culling when fog is closer than size of world results in HOM if(dist > -rad) v = VFC_PART_VISIBLE; @@ -53,13 +44,6 @@ static inline int ishiddencube(const ivec &o, int size) return false; } -static inline int isfoggedcube(const ivec &o, int size) -{ - loopi(4) if(o.dist(vfcP[i]) < -vfcDfar[i]*size) return true; - float dist = o.dist(vfcP[4]); - return dist < -vfcDfar[4]*size || dist > vfcDfog - vfcDnear[4]*size; -} - int isvisiblecube(const ivec &o, int size) { int v = VFC_FULL_VISIBLE; @@ -72,7 +56,6 @@ int isvisiblecube(const ivec &o, int size) if(dist < -vfcDnear[i]*size) v = VFC_PART_VISIBLE; } - dist -= vfcDfog; if(dist > -vfcDnear[4]*size) return VFC_FOGGED; if(dist > -vfcDfar[4]*size) v = VFC_PART_VISIBLE; @@ -160,7 +143,6 @@ void setvfcP(float z, const vec &bbmin, const vec &bbmax) vfcP[4] = plane(vec4(pw).add(pz)).normalize(); // near/far planes if(z >= 0) loopi(5) vfcP[i].reflectz(z); - vfcDfog = fog; calcvfcD(); } @@ -190,7 +172,6 @@ void visiblecubes(bool cull) else { memclear(vfcP); - vfcDfog = 1000000; memclear(vfcDnear); memclear(vfcDfar); visibleva = NULL; @@ -411,7 +392,6 @@ void findvisiblemms(const vector<extentity *> &ents, bool doquery) loopv(va->mapmodels) { octaentities *oe = va->mapmodels[i]; - if(isfoggedcube(oe->o, oe->size)) continue; bool occluded = doquery && oe->query && oe->query->owner == oe && checkquery(oe->query); if(occluded) @@ -460,56 +440,6 @@ void rendermapmodel(extentity &e) if(mmi) rendermodel(&e.light, mmi->name, anim, e.o, e.attr1, 0, MDL_CULL_VFC | MDL_CULL_DIST | MDL_DYNLIGHT, NULL, NULL, basetime); } -vtxarray *reflectedva; - -void renderreflectedmapmodels() -{ - const vector<extentity *> &ents = entities::getents(); - - octaentities *mms = visiblemms; - if(reflecting) - { - octaentities **lastmms = &mms; - for(vtxarray *va = reflectedva; va; va = va->rnext) - { - if(va->mapmodels.empty() || va->distance > reflectdist) continue; - loopv(va->mapmodels) - { - octaentities *oe = va->mapmodels[i]; - *lastmms = oe; - lastmms = &oe->rnext; - } - } - *lastmms = NULL; - } - for(octaentities *oe = mms; oe; oe = reflecting ? oe->rnext : oe->next) if(reflecting || oe->distance >= 0) - { - if(reflecting || refracting>0 ? oe->bbmax.z <= reflectz : oe->bbmin.z >= reflectz) continue; - if(isfoggedcube(oe->o, oe->size)) continue; - loopv(oe->mapmodels) - { - extentity &e = *ents[oe->mapmodels[i]]; - if(e.flags&(EF_NOVIS | EF_RENDER)) continue; - e.flags |= EF_RENDER; - } - } - if(mms) - { - startmodelbatches(); - for(octaentities *oe = mms; oe; oe = reflecting ? oe->rnext : oe->next) - { - loopv(oe->mapmodels) - { - extentity &e = *ents[oe->mapmodels[i]]; - if(!(e.flags&EF_RENDER)) continue; - rendermapmodel(e); - e.flags &= ~EF_RENDER; - } - } - endmodelbatches(); - } -} - void rendermapmodels() { static int skipoq = 0; @@ -1108,7 +1038,6 @@ static void changeslottmus(renderstate &cur, int pass, Slot &slot, VSlot &vslot) 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); - setfogcolor(vec(curfogcolor).mul(alpha)); } } else if(cur.colorscale != vslot.colorscale) @@ -1149,17 +1078,7 @@ static void changeslottmus(renderstate &cur, int pass, Slot &slot, VSlot &vslot) static void changeshader(renderstate &cur, Shader *s, Slot &slot, VSlot &vslot, bool shadowed) { - if(glaring) - { - static Shader *noglareshader = NULL, *noglareblendshader = NULL, *noglarealphashader = NULL; - Shader *fallback; - if(cur.blending) { if(!noglareblendshader) noglareblendshader = lookupshaderbyname("noglareblendworld"); fallback = noglareblendshader; } - else if(cur.alphaing) { if(!noglarealphashader) noglarealphashader = lookupshaderbyname("noglarealphaworld"); fallback = noglarealphashader; } - else { if(!noglareshader) noglareshader = lookupshaderbyname("noglareworld"); fallback = noglareshader; } - if(s->hasoption(4)) s->setvariant(cur.visibledynlights, 4, slot, vslot, fallback); - else s->setvariant(cur.blending ? 1 : 0, 4, slot, vslot, fallback); - } - else if(fading && !cur.blending && !cur.alphaing) + if(fading && !cur.blending && !cur.alphaing) { if(shadowed) s->setvariant(cur.visibledynlights, 3, slot, vslot); else s->setvariant(cur.visibledynlights, 2, slot, vslot); @@ -1313,8 +1232,6 @@ void renderzpass(renderstate &cur, vtxarray *va) drawvatris(va, 3*numtris, edata); } -vector<vtxarray *> foggedvas; - #define startvaquery(va, flush) \ do { \ if(va->query) \ @@ -1334,29 +1251,6 @@ vector<vtxarray *> foggedvas; } \ } while(0) -void renderfoggedvas(renderstate &cur, bool doquery = false) -{ - static Shader *fogshader = NULL; - if(!fogshader) fogshader = lookupshaderbyname("fogworld"); - if(fading) fogshader->setvariant(0, 2); - else fogshader->set(); - - if(!cur.vattribs) enablevattribs(cur, false); - - loopv(foggedvas) - { - vtxarray *va = foggedvas[i]; - if(cur.vbuf!=va->vbuf) changevbuf(cur, RENDERPASS_FOG, va); - - if(doquery) startvaquery(va, ); - drawvatris(va, 3*va->tris, va->edata); - vtris += va->tris; - if(doquery) endvaquery(va, ); - } - - foggedvas.setsize(0); -} - VAR(batchgeom, 0, 1, 1); void renderva(renderstate &cur, vtxarray *va, int pass = RENDERPASS_LIGHTMAP, bool fogpass = false, bool doquery = false) @@ -1367,11 +1261,6 @@ void renderva(renderstate &cur, vtxarray *va, int pass = RENDERPASS_LIGHTMAP, bo if(!cur.alphaing) vverts += va->verts; va->shadowed = false; va->dynlightmask = 0; - if(fogpass ? va->geommax.z<=reflectz-refractfog || !refractfog : va->curvfc==VFC_FOGGED) - { - if(!cur.alphaing && !cur.blending) foggedvas.add(va); - break; - } if(!drawtex && !glaring && !cur.alphaing) { va->shadowed = isshadowmapreceiver(va); @@ -1398,12 +1287,6 @@ void renderva(renderstate &cur, vtxarray *va, int pass = RENDERPASS_LIGHTMAP, bo xtravertsva += va->verts; break; - case RENDERPASS_CAUSTICS: - if(cur.vbuf!=va->vbuf) changevbuf(cur, pass, va); - drawvatris(va, 3*va->tris, va->edata); - xtravertsva += va->verts; - break; - case RENDERPASS_Z: if(doquery) startvaquery(va, ); renderzpass(cur, va); @@ -1412,55 +1295,11 @@ void renderva(renderstate &cur, vtxarray *va, int pass = RENDERPASS_LIGHTMAP, bo } } -#define NUMCAUSTICS 32 - -static Texture *caustictex[NUMCAUSTICS] = { NULL }; - -void loadcaustics(bool force) -{ - static bool needcaustics = false; - if(force) needcaustics = true; - if(!caustics || !needcaustics) return; - useshaderbyname("caustic"); - if(caustictex[0]) return; - loopi(NUMCAUSTICS) - { - defformatstring(name, "<grey><noswizzle>packages/caustics/caust%.2d.png", i); - caustictex[i] = textureload(name); - } -} - void cleanupva() { clearvas(worldroot); clearqueries(); cleanupbb(); - loopi(NUMCAUSTICS) caustictex[i] = NULL; -} - -VARR(causticscale, 0, 50, 10000); -VARR(causticmillis, 0, 75, 1000); -FVARR(causticcontrast, 0, 0.6f, 1); -VARFP(caustics, 0, 1, 1, loadcaustics()); - -void setupcaustics(float blend) -{ - if(!caustictex[0]) loadcaustics(true); - - vec s = vec(0.011f, 0, 0.0066f).mul(100.0f/causticscale), t = vec(0, 0.011f, 0.0066f).mul(100.0f/causticscale); - int tex = (lastmillis/causticmillis)%NUMCAUSTICS; - float frac = float(lastmillis%causticmillis)/causticmillis; - loopi(2) - { - glActiveTexture_(GL_TEXTURE0+i); - glBindTexture(GL_TEXTURE_2D, caustictex[(tex+i)%NUMCAUSTICS]->id); - } - glActiveTexture_(GL_TEXTURE0); - SETSHADER(caustic); - LOCALPARAM(texgenS, s); - LOCALPARAM(texgenT, t); - blend *= causticcontrast; - LOCALPARAMF(frameblend, blend*(1-frac), blend*frac, blend, 1 - blend); } void setupgeom(renderstate &cur) @@ -1479,28 +1318,15 @@ void cleanupgeom(renderstate &cur) if(cur.vbuf) disablevbuf(cur); } -#define FIRSTVA (reflecting ? reflectedva : visibleva) -#define NEXTVA (reflecting ? va->rnext : va->next) - static void rendergeommultipass(renderstate &cur, int pass, bool fogpass) { if(cur.vbuf) disablevbuf(cur); if(!cur.vattribs) enablevattribs(cur, false); cur.texgendim = -1; - for(vtxarray *va = FIRSTVA; va; va = NEXTVA) + for(vtxarray *va = visibleva; va; va = va->next) { if(!va->texs) continue; - if(refracting) - { - if((refracting < 0 ? va->geommin.z > reflectz : va->geommax.z <= reflectz) || va->occluded >= OCCLUDE_GEOM) continue; - if(ishiddencube(va->o, va->size)) continue; - } - else if(reflecting) - { - if(va->geommax.z <= reflectz) continue; - } - else if(va->occluded >= OCCLUDE_GEOM) continue; - if(fogpass ? va->geommax.z <= reflectz-refractfog || !refractfog : va->curvfc==VFC_FOGGED) continue; + if(va->occluded >= OCCLUDE_GEOM) continue; renderva(cur, va, pass, fogpass); } if(geombatches.length()) renderbatches(cur, pass); @@ -1508,11 +1334,9 @@ static void rendergeommultipass(renderstate &cur, int pass, bool fogpass) VAR(oqgeom, 0, 1, 1); -void rendergeom(float causticspass, bool fogpass) +void rendergeom(bool fogpass) { - if(causticspass && (!causticscale || !causticmillis)) causticspass = 0; - - bool mainpass = !reflecting && !refracting && !drawtex && !glaring, + bool mainpass = !drawtex && !glaring, doOQ = oqfrags && oqgeom && mainpass, doZP = doOQ && zpass, doSM = shadowmap && !drawtex && !glaring; @@ -1534,19 +1358,10 @@ void rendergeom(float causticspass, bool fogpass) resetbatches(); int blends = 0; - for(vtxarray *va = FIRSTVA; va; va = NEXTVA) + for(vtxarray *va = visibleva; va; va = va->next) { if(!va->texs) continue; - if(refracting) - { - if((refracting < 0 ? va->geommin.z > reflectz : va->geommax.z <= reflectz) || va->occluded >= OCCLUDE_GEOM) continue; - if(ishiddencube(va->o, va->size)) continue; - } - else if(reflecting) - { - if(va->geommax.z <= reflectz) continue; - } - else if(doOQ && (zpass || va->distance > oqdist) && !insideva(va, camera1->o)) + if(doOQ && (zpass || va->distance > oqdist) && !insideva(va, camera1->o)) { if(va->parent && va->parent->occluded >= OCCLUDE_BB) { @@ -1637,21 +1452,10 @@ void rendergeom(float causticspass, bool fogpass) cur.texgendim = -1; cur.blending = true; - for(vtxarray *va = FIRSTVA; va; va = NEXTVA) + for(vtxarray *va = visibleva; va; va = va->next) { if(!va->blends) continue; - if(refracting) - { - if(refracting < 0 ? va->geommin.z > reflectz : va->geommax.z <= reflectz) continue; - if(ishiddencube(va->o, va->size)) continue; - if(va->occluded >= OCCLUDE_GEOM) continue; - } - else if(reflecting) - { - if(va->geommax.z <= reflectz) continue; - } - else if(va->occluded >= OCCLUDE_GEOM) continue; - if(fogpass ? va->geommax.z <= reflectz-refractfog || !refractfog : va->curvfc==VFC_FOGGED) continue; + if(va->occluded >= OCCLUDE_GEOM) continue; renderva(cur, va, RENDERPASS_LIGHTMAP_BLEND, fogpass); } if(geombatches.length()) renderbatches(cur, RENDERPASS_LIGHTMAP); @@ -1666,24 +1470,6 @@ void rendergeom(float causticspass, bool fogpass) if(cur.vattribs) disablevattribs(cur); - if(foggedvas.length()) renderfoggedvas(cur, doOQ && !zpass); - - if(causticspass) - { - if(!multipassing) { multipassing = true; glDepthFunc(GL_LEQUAL); } - glDepthMask(GL_FALSE); - glEnable(GL_BLEND); - - setupcaustics(causticspass); - glBlendFunc(GL_ZERO, GL_SRC_COLOR); - if(fading) glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); - rendergeommultipass(cur, RENDERPASS_CAUSTICS, fogpass); - if(fading) glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - - glDisable(GL_BLEND); - glDepthMask(GL_TRUE); - } - if(multipassing) glDepthFunc(GL_LESS); cleanupgeom(cur); @@ -1694,23 +1480,10 @@ void renderalphageom(bool fogpass) static vector<vtxarray *> alphavas; alphavas.setsize(0); bool hasback = false; - for(vtxarray *va = FIRSTVA; va; va = NEXTVA) + for(vtxarray *va = visibleva; va; va = va->next) { if(!va->alphatris) continue; - if(refracting) - { - if((refracting < 0 ? va->geommin.z > reflectz : va->geommax.z <= reflectz) || va->occluded >= OCCLUDE_BB) continue; - if(ishiddencube(va->o, va->size)) continue; - } - else if(reflecting) - { - if(va->geommax.z <= reflectz) continue; - } - else - { - if(va->occluded >= OCCLUDE_BB) continue; - } - if(fogpass ? va->geommax.z <= reflectz-refractfog || !refractfog : va->curvfc==VFC_FOGGED) continue; + if(va->occluded >= OCCLUDE_BB) continue; alphavas.add(va); if(va->alphabacktris) hasback = true; } @@ -1749,7 +1522,6 @@ void renderalphageom(bool fogpass) cleanupgeom(cur); - resetfogcolor(); if(!cur.depthmask) { cur.depthmask = true; glDepthMask(GL_TRUE); } glDisable(GL_BLEND); glDepthFunc(GL_LESS); @@ -1759,47 +1531,6 @@ void renderalphageom(bool fogpass) glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, fading ? GL_FALSE : GL_TRUE); } -void findreflectedvas(vector<vtxarray *> &vas, int prevvfc = VFC_PART_VISIBLE) -{ - loopv(vas) - { - vtxarray *va = vas[i]; - if(prevvfc >= VFC_NOT_VISIBLE) va->curvfc = prevvfc; - if(va->curvfc == VFC_FOGGED || va->curvfc == PVS_FOGGED || va->o.z+va->size <= reflectz || isfoggedcube(va->o, va->size)) continue; - bool render = true; - if(va->curvfc == VFC_FULL_VISIBLE) - { - if(va->occluded >= OCCLUDE_BB) continue; - if(va->occluded >= OCCLUDE_GEOM) render = false; - } - else if(va->curvfc == PVS_FULL_VISIBLE) continue; - if(render) - { - if(va->curvfc >= VFC_NOT_VISIBLE) va->distance = (int)vadist(va, camera1->o); - vtxarray **vprev = &reflectedva, *vcur = reflectedva; - while(vcur && va->distance > vcur->distance) - { - vprev = &vcur->rnext; - vcur = vcur->rnext; - } - va->rnext = *vprev; - *vprev = va; - } - if(va->children.length()) findreflectedvas(va->children, va->curvfc); - } -} - -void renderreflectedgeom(bool causticspass, bool fogpass) -{ - if(reflecting) - { - reflectedva = NULL; - findreflectedvas(varoot); - rendergeom(causticspass ? 1 : 0, fogpass); - } - else rendergeom(causticspass ? 1 : 0, fogpass); -} - static vtxarray *prevskyva = NULL; void renderskyva(vtxarray *va, bool explicitonly = false) @@ -1832,34 +1563,13 @@ static inline void updateskystats(vtxarray *va) else renderedskyclip = 0; } -void renderreflectedskyvas(vector<vtxarray *> &vas, int prevvfc = VFC_PART_VISIBLE) -{ - loopv(vas) - { - vtxarray *va = vas[i]; - if(prevvfc >= VFC_NOT_VISIBLE) va->curvfc = prevvfc; - if((va->curvfc == VFC_FULL_VISIBLE && va->occluded >= OCCLUDE_BB) || va->curvfc==PVS_FULL_VISIBLE) continue; - if(va->o.z+va->size <= reflectz || ishiddencube(va->o, va->size)) continue; - if(va->sky+va->explicitsky) - { - updateskystats(va); - renderskyva(va); - } - if(va->children.length()) renderreflectedskyvas(va->children, va->curvfc); - } -} - bool rendersky(bool explicitonly) { prevskyva = NULL; renderedsky = renderedexplicitsky = renderedskyfaces = 0; renderedskyclip = INT_MAX; - if(reflecting) - { - renderreflectedskyvas(varoot); - } - else for(vtxarray *va = visibleva; va; va = va->next) + for(vtxarray *va = visibleva; va; va = va->next) { if((va->occluded >= OCCLUDE_BB && va->skyfaces&0x80) || !(va->sky+va->explicitsky)) continue; |
