diff options
Diffstat (limited to 'src/engine/material.cpp')
| -rw-r--r-- | src/engine/material.cpp | 336 |
1 files changed, 4 insertions, 332 deletions
diff --git a/src/engine/material.cpp b/src/engine/material.cpp index 54bc4ae..2cc8177 100644 --- a/src/engine/material.cpp +++ b/src/engine/material.cpp @@ -70,33 +70,6 @@ static const bvec4 matnormals[6] = { bvec4(0, 0, 0x7F) }; -static void renderwaterfall(const materialsurface &m, float offset) -{ - if(gle::attribbuf.empty()) - { - gle::defvertex(); - gle::defnormal(4, GL_BYTE); - gle::begin(GL_QUADS); - } - float x = m.o.x, y = m.o.y, zmin = m.o.z, zmax = zmin; - if(m.ends&1) zmin += -WATER_OFFSET-WATER_AMPLITUDE; - if(m.ends&2) zmax += wfwave; - int csize = m.csize, rsize = m.rsize; - switch(m.orient) - { - #define GENFACEORIENT(orient, v0, v1, v2, v3) \ - case orient: v0 v1 v2 v3 break; - #define GENFACEVERT(orient, vert, mx,my,mz, sx,sy,sz) \ - { \ - gle::attribf(mx sx, my sy, mz sz); \ - gle::attrib(matnormals[orient]); \ - } - GENFACEVERTSXY(x, x, y, y, zmin, zmax, /**/, + csize, /**/, + rsize, + offset, - offset) - #undef GENFACEORIENT - #undef GENFACEVERT - } -} - static void drawmaterial(const materialsurface &m, float offset, const bvec4 &color) { if(gle::attribbuf.empty()) @@ -311,7 +284,7 @@ int optimizematsurfs(materialsurface *matbuf, int matsurfs) cur->visible == start->visible && cur->o[dim] == start->o[dim]) ++cur; - if(!isliquid(start->material&MATF_VOLUME) || start->orient != O_TOP || !vertwater) + if(start->orient != O_TOP || !vertwater) { if(start!=matbuf) memmove(matbuf, start, (cur-start)*sizeof(materialsurface)); matbuf += mergemats(matbuf, cur-start); @@ -331,16 +304,9 @@ int optimizematsurfs(materialsurface *matbuf, int matsurfs) return matsurfs - (end-matbuf); } -struct waterinfo -{ - materialsurface *m; - double depth, area; -}; - void setupmaterials(int start, int len) { int hasmat = 0; - vector<waterinfo> water; unionfind uf; if(!len) len = valist.length(); for(int i = start; i < len; i++) @@ -351,64 +317,6 @@ void setupmaterials(int start, int len) { materialsurface &m = va->matbuf[j]; int matvol = m.material&MATF_VOLUME; - if(matvol==MAT_WATER && m.orient==O_TOP) - { - m.index = water.length(); - loopvk(water) - { - materialsurface &n = *water[k].m; - if(m.material!=n.material || m.o.z!=n.o.z) continue; - if(n.o.x+n.rsize==m.o.x || m.o.x+m.rsize==n.o.x) - { - if(n.o.y+n.csize>m.o.y && n.o.y<m.o.y+m.csize) uf.unite(m.index, n.index); - } - else if(n.o.y+n.csize==m.o.y || m.o.y+m.csize==n.o.y) - { - if(n.o.x+n.rsize>m.o.x && n.o.x<m.o.x+m.rsize) uf.unite(m.index, n.index); - } - } - waterinfo &wi = water.add(); - wi.m = &m; - vec center(m.o.x+m.rsize/2, m.o.y+m.csize/2, m.o.z-WATER_OFFSET); - m.light = brightestlight(center, vec(0, 0, 1)); - float depth = raycube(center, vec(0, 0, -1), 10000); - wi.depth = double(depth)*m.rsize*m.csize; - wi.area = m.rsize*m.csize; - } - else if(isliquid(matvol) && m.orient!=O_BOTTOM && m.orient!=O_TOP) - { - m.ends = 0; - int dim = dimension(m.orient), coord = dimcoord(m.orient); - ivec o(m.o); - o.z -= 1; - o[dim] += coord ? 1 : -1; - int minc = o[dim^1], maxc = minc + (C[dim]==2 ? m.rsize : m.csize); - ivec co; - int csize; - while(o[dim^1] < maxc) - { - cube &c = lookupcube(o, 0, co, csize); - if(isliquid(c.material&MATF_VOLUME)) { m.ends |= 1; break; } - o[dim^1] += csize; - } - o[dim^1] = minc; - o.z += R[dim]==2 ? m.rsize : m.csize; - o[dim] -= coord ? 2 : -2; - while(o[dim^1] < maxc) - { - cube &c = lookupcube(o, 0, co, csize); - if(visiblematerial(c, O_TOP, co, csize)) { m.ends |= 2; break; } - o[dim^1] += csize; - } - } - else if(matvol==MAT_GLASS) - { - int dim = dimension(m.orient); - vec center(m.o); - center[R[dim]] += m.rsize/2; - center[C[dim]] += m.csize/2; - m.envmap = closestenvmap(center); - } if(matvol) hasmat |= 1<<m.material; m.skip = 0; if(skip && m.material == skip->material && m.orient == skip->orient && skip->skip < 0xFFFF) @@ -417,34 +325,6 @@ void setupmaterials(int start, int len) skip = &m; } } - loopv(water) - { - int root = uf.find(i); - if(i==root) continue; - materialsurface &m = *water[i].m, &n = *water[root].m; - if(m.light && (!m.light->attr1 || !n.light || (n.light->attr1 && m.light->attr1 > n.light->attr1))) n.light = m.light; - water[root].depth += water[i].depth; - water[root].area += water[i].area; - } - loopv(water) - { - int root = uf.find(i); - water[i].m->light = water[root].m->light; - water[i].m->depth = (short)(water[root].depth/water[root].area); - } - if(hasmat&(0xF<<MAT_WATER)) - { - loadcaustics(true); - preloadwatershaders(true); - loopi(4) if(hasmat&(1<<(MAT_WATER+i))) lookupmaterialslot(MAT_WATER+i); - } - if(hasmat&(0xF<<MAT_LAVA)) - { - useshaderbyname("lava"); - useshaderbyname("lavaglare"); - loopi(4) if(hasmat&(1<<(MAT_LAVA+i))) lookupmaterialslot(MAT_LAVA+i); - } - if(hasmat&(0xF<<MAT_GLASS)) useshaderbyname("glass"); } VARP(showmat, 0, 1, 1); @@ -490,25 +370,22 @@ static inline bool vismatcmp(const materialsurface *xm, const materialsurface *y void sortmaterials(vector<materialsurface *> &vismats) { sortorigin = ivec(camera1->o); - if(reflecting) sortorigin.z = int(reflectz - (camera1->o.z - reflectz)); vec dir; - vecfromyawpitch(camera1->yaw, reflecting ? -camera1->pitch : camera1->pitch, 1, 0, dir); + vecfromyawpitch(camera1->yaw, camera1->pitch, 1, 0, dir); loopi(3) { dir[i] = fabs(dir[i]); sortdim[i] = i; } if(dir[sortdim[2]] > dir[sortdim[1]]) swap(sortdim[2], sortdim[1]); if(dir[sortdim[1]] > dir[sortdim[0]]) swap(sortdim[1], sortdim[0]); if(dir[sortdim[2]] > dir[sortdim[1]]) swap(sortdim[2], sortdim[1]); - for(vtxarray *va = reflecting ? reflectedva : visibleva; va; va = reflecting ? va->rnext : va->next) + for(vtxarray *va = visibleva; va; va = va->next) { if(!va->matsurfs || va->occluded >= OCCLUDE_BB) continue; - if(reflecting || refracting>0 ? va->o.z+va->size <= reflectz : va->o.z >= reflectz) continue; loopi(va->matsurfs) { materialsurface &m = va->matbuf[i]; if(!editmode || !showmat || drawtex) { int matvol = m.material&MATF_VOLUME; - if(matvol==MAT_WATER && (m.orient==O_TOP || (refracting<0 && reflectz>worldsize))) { i += m.skip; continue; } if(m.visible == MATSURF_EDIT_ONLY) { i += m.skip; continue; } if(glaring && matvol!=MAT_LAVA) { i += m.skip; continue; } } @@ -594,8 +471,6 @@ static void drawglass(const materialsurface &m, float offset) } } -VARFP(waterfallenv, 0, 1, 1, preloadwatershaders()); - static inline void changematerial(int mat, int orient) { switch(mat&~MATF_INDEX) @@ -619,19 +494,16 @@ void rendermaterials() glDisable(GL_CULL_FACE); MSlot *mslot = NULL; - int lastorient = -1, lastmat = -1, usedwaterfall = -1; + int lastorient = -1, lastmat = -1; bool depth = true, blended = false; ushort envmapped = EMID_NONE; GLOBALPARAM(camera, camera1->o); - int lastfogtype = 1; if(editmode && showmat && !drawtex) { glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR); glEnable(GL_BLEND); blended = true; - foggednotextureshader->set(); - zerofogcolor(); lastfogtype = 0; bvec4 color(0, 0, 0, 0); loopv(vismats) { @@ -656,214 +528,14 @@ void rendermaterials() } xtraverts += gle::end(); } - else loopv(vismats) - { - const materialsurface &m = *vismats[i]; - int matvol = m.material&~MATF_INDEX; - if(lastmat!=m.material || lastorient!=m.orient || (matvol==MAT_GLASS && envmapped && m.envmap != envmapped)) - { - int fogtype = lastfogtype; - switch(matvol) - { - case MAT_WATER: - if(m.orient == O_TOP) continue; - if(lastmat == m.material) break; - mslot = &lookupmaterialslot(m.material, false); - if(!mslot->loaded || !mslot->sts.inrange(1)) continue; - else - { - changematerial(lastmat, lastorient); - glBindTexture(GL_TEXTURE_2D, mslot->sts[1].t->id); - - bvec wfcol = getwaterfallcolor(m.material); - if(wfcol.iszero()) wfcol = getwatercolor(m.material); - gle::color(wfcol, 192); - - int wfog = getwaterfog(m.material); - if(!wfog && !waterfallenv) - { - foggednotextureshader->set(); - fogtype = 1; - if(blended) { glDisable(GL_BLEND); blended = false; } - if(!depth) { glDepthMask(GL_TRUE); depth = true; } - } - else if((!waterfallrefract || reflecting || refracting) && !waterfallenv) - { - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR); - SETSHADER(waterfall); - fogtype = 0; - if(!blended) { glEnable(GL_BLEND); blended = true; } - if(depth) { glDepthMask(GL_FALSE); depth = false; } - } - else - { - fogtype = 1; - - if(waterfallrefract && wfog && !reflecting && !refracting) - { - if(waterfallenv) SETSHADER(waterfallenvrefract); - else SETSHADER(waterfallrefract); - if(blended) { glDisable(GL_BLEND); blended = false; } - if(!depth) { glDepthMask(GL_TRUE); depth = true; } - } - else - { - SETSHADER(waterfallenv); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - if(wfog) - { - if(!blended) { glEnable(GL_BLEND); blended = true; } - if(depth) { glDepthMask(GL_FALSE); depth = false; } - } - else - { - if(blended) { glDisable(GL_BLEND); blended = false; } - if(!depth) { glDepthMask(GL_TRUE); depth = true; } - } - } - - if(usedwaterfall != m.material) - { - Texture *dudv = mslot->sts.inrange(5) ? mslot->sts[5].t : notexture; - float scale = TEX_SCALE/(dudv->ys*mslot->scale); - LOCALPARAMF(dudvoffset, 0, scale*16*lastmillis/1000.0f); - - glActiveTexture_(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, mslot->sts.inrange(4) ? mslot->sts[4].t->id : notexture->id); - glActiveTexture_(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, mslot->sts.inrange(5) ? mslot->sts[5].t->id : notexture->id); - if(waterfallenv) - { - glActiveTexture_(GL_TEXTURE3); - glBindTexture(GL_TEXTURE_CUBE_MAP, lookupenvmap(*mslot)); - } - if(waterfallrefract && (!reflecting || !refracting) && usedwaterfall < 0) - { - glActiveTexture_(GL_TEXTURE4); - extern void setupwaterfallrefract(); - setupwaterfallrefract(); - } - glActiveTexture_(GL_TEXTURE0); - - usedwaterfall = m.material; - } - } - float angle = fmod(float(lastmillis/600.0f/(2*M_PI)), 1.0f), - s = angle - int(angle) - 0.5f; - s *= 8 - fabs(s)*16; - wfwave = vertwater ? WATER_AMPLITUDE*s-WATER_OFFSET : -WATER_OFFSET; - float scroll = 16.0f*lastmillis/1000.0f; - float xscale = TEX_SCALE/(mslot->sts[1].t->xs*mslot->scale); - float yscale = -TEX_SCALE/(mslot->sts[1].t->ys*mslot->scale); - LOCALPARAMF(waterfalltexgen, xscale, yscale, 0.0f, scroll); - } - break; - - case MAT_LAVA: - if(lastmat==m.material && lastorient!=O_TOP && m.orient!=O_TOP) break; - mslot = &lookupmaterialslot(m.material, false); - if(!mslot->loaded) continue; - else - { - int subslot = m.orient==O_TOP ? 0 : 1; - if(!mslot->sts.inrange(subslot)) continue; - changematerial(lastmat, lastorient); - glBindTexture(GL_TEXTURE_2D, mslot->sts[subslot].t->id); - } - if(lastmat!=m.material) - { - if(!depth) { glDepthMask(GL_TRUE); depth = true; } - if(blended) { glDisable(GL_BLEND); blended = false; } - float t = lastmillis/2000.0f; - t -= floor(t); - t = 1.0f - 2*fabs(t-0.5f); - extern int glare; - if(glare) t = 0.625f + 0.075f*t; - else t = 0.5f + 0.5f*t; - gle::colorf(t, t, t); - if(glaring) SETSHADER(lavaglare); else SETSHADER(lava); - fogtype = 1; - } - if(m.orient!=O_TOP) - { - float angle = fmod(float(lastmillis/2000.0f/(2*M_PI)), 1.0f), - s = angle - int(angle) - 0.5f; - s *= 8 - fabs(s)*16; - wfwave = vertwater ? WATER_AMPLITUDE*s-WATER_OFFSET : -WATER_OFFSET; - float scroll = 16.0f*lastmillis/3000.0f; - float xscale = TEX_SCALE/(mslot->sts[1].t->xs*mslot->scale); - float yscale = -TEX_SCALE/(mslot->sts[1].t->ys*mslot->scale); - LOCALPARAMF(lavatexgen, xscale, yscale, 0.0f, scroll); - } - else setuplava(mslot->sts[0].t, mslot->scale); - break; - - case MAT_GLASS: - if((m.envmap==EMID_NONE || !glassenv || envmapped==m.envmap) && lastmat==m.material) break; - changematerial(lastmat, lastorient); - if(m.envmap!=EMID_NONE && glassenv && envmapped!=m.envmap) - { - glBindTexture(GL_TEXTURE_CUBE_MAP, lookupenvmap(m.envmap)); - envmapped = m.envmap; - } - if(lastmat!=m.material) - { - if(!blended) { glEnable(GL_BLEND); blended = true; } - if(depth) { glDepthMask(GL_FALSE); depth = false; } - const bvec &gcol = getglasscolor(m.material); - if(m.envmap!=EMID_NONE && glassenv) - { - glBlendFunc(GL_ONE, GL_SRC_ALPHA); - gle::color(gcol); - SETSHADER(glass); - } - else - { - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gle::color(gcol, 40); - foggednotextureshader->set(); - fogtype = 1; - } - } - break; - - default: continue; - } - lastmat = m.material; - lastorient = m.orient; - if(fogtype!=lastfogtype) - { - if(fogtype) resetfogcolor(); - else zerofogcolor(); - lastfogtype = fogtype; - } - } - switch(matvol) - { - case MAT_WATER: - renderwaterfall(m, 0.1f); - break; - - case MAT_LAVA: - if(m.orient==O_TOP) renderlava(m); - else renderwaterfall(m, 0.1f); - break; - - case MAT_GLASS: - drawglass(m, 0.1f); - break; - } - } if(lastorient >= 0) changematerial(lastmat, lastorient); if(!depth) glDepthMask(GL_TRUE); if(blended) glDisable(GL_BLEND); - if(!lastfogtype) resetfogcolor(); extern int wireframe; if(editmode && showmat && !drawtex && !wireframe) { - foggednotextureshader->set(); rendermatgrid(vismats); } |
