summaryrefslogtreecommitdiff
path: root/src/engine/material.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/material.cpp')
-rw-r--r--src/engine/material.cpp336
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);
}