summaryrefslogtreecommitdiff
path: root/src/engine/material.cpp
diff options
context:
space:
mode:
authorxolatile2025-08-06 22:54:55 +0200
committerxolatile2025-08-06 22:54:55 +0200
commit0a1172b75f571685c264a8b9d8ee224bbf11381f (patch)
treed041fdc68a60f0ebb48a3852bbcce6d9432f83d5 /src/engine/material.cpp
parentaffde05dc07a94643f1fd2751b2b441f57f73d7d (diff)
downloadxolatile-badassbug-0a1172b75f571685c264a8b9d8ee224bbf11381f.tar.xz
xolatile-badassbug-0a1172b75f571685c264a8b9d8ee224bbf11381f.tar.zst
Please do not hate me, it makes sense...
Diffstat (limited to 'src/engine/material.cpp')
-rw-r--r--src/engine/material.cpp180
1 files changed, 58 insertions, 122 deletions
diff --git a/src/engine/material.cpp b/src/engine/material.cpp
index e29ccf5..55151a1 100644
--- a/src/engine/material.cpp
+++ b/src/engine/material.cpp
@@ -4,13 +4,9 @@ struct QuadNode {
int x, y, size;
uint filled;
QuadNode *child[4];
-
QuadNode(int x, int y, int size) : x(x), y(y), size(size), filled(0) { loopi(4) child[i] = 0; }
-
void clear() { loopi(4) DELETEP(child[i]); }
-
~QuadNode() { clear(); }
-
void insert(int mx, int my, int msize) {
if(size == msize) {
filled = 0xF;
@@ -25,15 +21,13 @@ struct QuadNode {
}
if(!child[i]) child[i] = new QuadNode(i&1 ? x+csize : x, i&2 ? y+csize : y, csize);
child[i]->insert(mx, my, msize);
- loopj(4) if(child[j])
- {
+ loopj(4) if(child[j]) {
if(child[j]->filled == 0xF) {
DELETEP(child[j]);
filled |= (1 << j);
}
}
}
-
void genmatsurf(ushort mat, uchar orient, uchar visible, int x, int y, int z, int size, materialsurface *&matbuf) {
materialsurface &m = *matbuf++;
m.material = mat;
@@ -46,11 +40,9 @@ struct QuadNode {
m.o[R[dim]] = y;
m.o[dim] = z;
}
-
void genmatsurfs(ushort mat, uchar orient, uchar flags, int z, materialsurface *&matbuf) {
if(filled == 0xF) genmatsurf(mat, orient, flags, x, y, z, size, matbuf);
- else if(filled)
- {
+ else if(filled) {
int csize = size>>1;
loopi(4) if(filled & (1 << i))
genmatsurf(mat, orient, flags, i&1 ? x+csize : x, i&2 ? y+csize : y, z, csize, matbuf);
@@ -68,21 +60,18 @@ static const bvec4 matnormals[6] = {
bvec4(0, 0, 0x7F)
};
-static void drawmaterial(const materialsurface &m, float offset, const bvec4 &color)
-{
- if(gle::attribbuf.empty())
- {
+static void drawmaterial(const materialsurface &m, float offset, const bvec4 &color) {
+ if(gle::attribbuf.empty()) {
gle::defvertex();
gle::defcolor(4, GL_UNSIGNED_BYTE);
gle::begin(GL_QUADS);
}
float x = m.o.x, y = m.o.y, z = m.o.z, csize = m.csize, rsize = m.rsize;
- switch(m.orient)
- {
+ 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) \
- { \
+ #define GENFACEVERT(orient, vert, mx,my,mz, sx,sy,sz) { \
+ \
gle::attribf(mx sx, my sy, mz sz); \
gle::attrib(color); \
}
@@ -92,45 +81,38 @@ static void drawmaterial(const materialsurface &m, float offset, const bvec4 &co
}
}
-const struct material
-{
+const struct material {
const char *name;
ushort id;
-} materials[] =
-{
- {"air", MAT_AIR},
- {"clip", MAT_CLIP},
- {"noclip", MAT_NOCLIP},
- {"gameclip", MAT_GAMECLIP},
- {"death", MAT_DEATH},
- {"alpha", MAT_ALPHA}
+} materials[] = {
+ {
+ "air", MAT_AIR}, {
+ "clip", MAT_CLIP}, {
+ "noclip", MAT_NOCLIP}, {
+ "gameclip", MAT_GAMECLIP}, {
+ "death", MAT_DEATH}, {
+ "alpha", MAT_ALPHA}
};
-int findmaterial(const char *name)
-{
- loopi(sizeof(materials)/sizeof(material))
- {
+int findmaterial(const char *name) {
+ loopi(sizeof(materials)/sizeof(material)) {
if(!strcmp(materials[i].name, name)) return materials[i].id;
}
return -1;
}
-const char *findmaterialname(int mat)
-{
+const char *findmaterialname(int mat) {
loopi(sizeof(materials)/sizeof(materials[0])) if(materials[i].id == mat) return materials[i].name;
return NULL;
}
-const char *getmaterialdesc(int mat, const char *prefix)
-{
+const char *getmaterialdesc(int mat, const char *prefix) {
static const ushort matmasks[] = { MATF_INDEX, MATF_CLIP, MAT_DEATH, MAT_ALPHA };
static string desc;
desc[0] = '\0';
- loopi(sizeof(matmasks)/sizeof(matmasks[0])) if(mat&matmasks[i])
- {
+ loopi(sizeof(matmasks)/sizeof(matmasks[0])) if(mat&matmasks[i]) {
const char *matname = findmaterialname(mat&matmasks[i]);
- if(matname)
- {
+ if(matname) {
concatstring(desc, desc[0] ? ", " : prefix);
concatstring(desc, matname);
}
@@ -138,14 +120,11 @@ const char *getmaterialdesc(int mat, const char *prefix)
return desc;
}
-int visiblematerial(const cube &c, int orient, const ivec &co, int size, ushort matmask)
-{
+int visiblematerial(const cube &c, int orient, const ivec &co, int size, ushort matmask) {
ushort mat = c.material&matmask;
- switch(mat)
- {
+ switch(mat) {
case MAT_AIR:
break;
-
default:
if(visibleface(c, orient, co, size, mat, MAT_AIR, matmask))
return MATSURF_EDIT_ONLY;
@@ -154,17 +133,13 @@ int visiblematerial(const cube &c, int orient, const ivec &co, int size, ushort
return MATSURF_NOT_VISIBLE;
}
-void genmatsurfs(const cube &c, const ivec &co, int size, vector<materialsurface> &matsurfs)
-{
- loopi(6)
- {
+void genmatsurfs(const cube &c, const ivec &co, int size, vector<materialsurface> &matsurfs) {
+ loopi(6) {
static const ushort matmasks[] = { MATF_INDEX, MATF_CLIP, MAT_DEATH, MAT_ALPHA };
- loopj(sizeof(matmasks)/sizeof(matmasks[0]))
- {
+ loopj(sizeof(matmasks)/sizeof(matmasks[0])) {
int matmask = matmasks[j];
int vis = visiblematerial(c, i, co, size, matmask&~MATF_INDEX);
- if(vis != MATSURF_NOT_VISIBLE)
- {
+ if(vis != MATSURF_NOT_VISIBLE) {
materialsurface m;
m.material = c.material&matmask;
m.orient = i;
@@ -179,22 +154,18 @@ void genmatsurfs(const cube &c, const ivec &co, int size, vector<materialsurface
}
}
-static inline bool mergematcmp(const materialsurface &x, const materialsurface &y)
-{
+static inline bool mergematcmp(const materialsurface &x, const materialsurface &y) {
int dim = dimension(x.orient), c = C[dim], r = R[dim];
if(x.o[r] + x.rsize < y.o[r] + y.rsize) return true;
if(x.o[r] + x.rsize > y.o[r] + y.rsize) return false;
return x.o[c] < y.o[c];
}
-static int mergematr(materialsurface *m, int sz, materialsurface &n)
-{
+static int mergematr(materialsurface *m, int sz, materialsurface &n) {
int dim = dimension(n.orient), c = C[dim], r = R[dim];
- for(int i = sz-1; i >= 0; --i)
- {
+ for(int i = sz-1; i >= 0; --i) {
if(m[i].o[r] + m[i].rsize < n.o[r]) break;
- if(m[i].o[r] + m[i].rsize == n.o[r] && m[i].o[c] == n.o[c] && m[i].csize == n.csize)
- {
+ if(m[i].o[r] + m[i].rsize == n.o[r] && m[i].o[c] == n.o[c] && m[i].csize == n.csize) {
n.o[r] = m[i].o[r];
n.rsize += m[i].rsize;
memmove(&m[i], &m[i+1], (sz - (i+1)) * sizeof(materialsurface));
@@ -204,11 +175,9 @@ static int mergematr(materialsurface *m, int sz, materialsurface &n)
return 0;
}
-static int mergematc(materialsurface &m, materialsurface &n)
-{
+static int mergematc(materialsurface &m, materialsurface &n) {
int dim = dimension(n.orient), c = C[dim], r = R[dim];
- if(m.o[r] == n.o[r] && m.rsize == n.rsize && m.o[c] + m.csize == n.o[c])
- {
+ if(m.o[r] == n.o[r] && m.rsize == n.rsize && m.o[c] + m.csize == n.o[c]) {
n.o[c] = m.o[c];
n.csize += m.csize;
return 1;
@@ -216,10 +185,8 @@ static int mergematc(materialsurface &m, materialsurface &n)
return 0;
}
-static int mergemat(materialsurface *m, int sz, materialsurface &n)
-{
- for(bool merged = false; sz; merged = true)
- {
+static int mergemat(materialsurface *m, int sz, materialsurface &n) {
+ for(bool merged = false; sz; merged = true) {
int rmerged = mergematr(m, sz, n);
sz -= rmerged;
if(!rmerged && merged) break;
@@ -232,17 +199,14 @@ static int mergemat(materialsurface *m, int sz, materialsurface &n)
return sz;
}
-static int mergemats(materialsurface *m, int sz)
-{
+static int mergemats(materialsurface *m, int sz) {
quicksort(m, sz, mergematcmp);
-
int nsz = 0;
loopi(sz) nsz = mergemat(m, nsz, m[i]);
return nsz;
}
-static inline bool optmatcmp(const materialsurface &x, const materialsurface &y)
-{
+static inline bool optmatcmp(const materialsurface &x, const materialsurface &y) {
if(x.material < y.material) return true;
if(x.material > y.material) return false;
if(x.orient > y.orient) return true;
@@ -253,13 +217,11 @@ static inline bool optmatcmp(const materialsurface &x, const materialsurface &y)
VARF(optmats, 0, 1, 1, allchanged());
-int optimizematsurfs(materialsurface *matbuf, int matsurfs)
-{
+int optimizematsurfs(materialsurface *matbuf, int matsurfs) {
quicksort(matbuf, matsurfs, optmatcmp);
if(!optmats) return matsurfs;
materialsurface *cur = matbuf, *end = matbuf+matsurfs;
- while(cur < end)
- {
+ while(cur < end) {
materialsurface *start = cur++;
int dim = dimension(start->orient);
while(cur < end &&
@@ -288,17 +250,14 @@ int optimizematsurfs(materialsurface *matbuf, int matsurfs)
return matsurfs - (end-matbuf);
}
-void setupmaterials(int start, int len)
-{
+void setupmaterials(int start, int len) {
int hasmat = 0;
unionfind uf;
if(!len) len = valist.length();
- for(int i = start; i < len; i++)
- {
+ for(int i = start; i < len; i++) {
vtxarray *va = valist[i];
materialsurface *skip = NULL;
- loopj(va->matsurfs)
- {
+ loopj(va->matsurfs) {
materialsurface &m = va->matbuf[j];
int matvol = 0;
if(matvol) hasmat |= 1<<m.material;
@@ -317,12 +276,10 @@ static int sortdim[3];
static ivec sortorigin;
static bool sortedit;
-static inline bool vismatcmp(const materialsurface *xm, const materialsurface *ym)
-{
+static inline bool vismatcmp(const materialsurface *xm, const materialsurface *ym) {
const materialsurface &x = *xm, &y = *ym;
int xdim = dimension(x.orient), ydim = dimension(y.orient);
- loopi(3)
- {
+ loopi(3) {
int dim = sortdim[i], xmin, xmax, ymin, ymax;
xmin = xmax = x.o[dim];
if(dim==C[xdim]) xmax += x.csize;
@@ -346,8 +303,7 @@ static inline bool vismatcmp(const materialsurface *xm, const materialsurface *y
return false;
}
-void sortmaterials(vector<materialsurface *> &vismats)
-{
+void sortmaterials(vector<materialsurface *> &vismats) {
sortorigin = ivec(camera1->o);
vec dir;
vecfromyawpitch(camera1->yaw, camera1->pitch, 1, 0, dir);
@@ -355,15 +311,11 @@ void sortmaterials(vector<materialsurface *> &vismats)
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 = visibleva; va; va = va->next)
- {
+ for(vtxarray *va = visibleva; va; va = va->next) {
if(!va->matsurfs || va->occluded >= OCCLUDE_BB) continue;
- loopi(va->matsurfs)
- {
+ loopi(va->matsurfs) {
materialsurface &m = va->matbuf[i];
- if(!editmode || !showmat || drawtex)
- {
+ if(!editmode || !showmat || drawtex) {
if(m.visible == MATSURF_EDIT_ONLY) { i += m.skip; continue; }
}
vismats.add(&m);
@@ -373,19 +325,15 @@ void sortmaterials(vector<materialsurface *> &vismats)
vismats.sort(vismatcmp);
}
-void rendermatgrid(vector<materialsurface *> &vismats)
-{
+void rendermatgrid(vector<materialsurface *> &vismats) {
enablepolygonoffset(GL_POLYGON_OFFSET_LINE);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
int lastmat = -1;
bvec4 color(0, 0, 0, 0);
- loopvrev(vismats)
- {
+ loopvrev(vismats) {
materialsurface &m = *vismats[i];
- if(m.material != lastmat)
- {
- switch(m.material&~MATF_INDEX)
- {
+ if(m.material != lastmat) {
+ switch(m.material&~MATF_INDEX) {
case MAT_CLIP: color = bvec4(85, 0, 0, 255); break; // red
case MAT_NOCLIP: color = bvec4( 0, 85, 0, 255); break; // green
case MAT_GAMECLIP: color = bvec4(85, 85, 0, 255); break; // yellow
@@ -402,31 +350,22 @@ void rendermatgrid(vector<materialsurface *> &vismats)
disablepolygonoffset(GL_POLYGON_OFFSET_LINE);
}
-void rendermaterials()
-{
+void rendermaterials() {
vector<materialsurface *> vismats;
sortmaterials(vismats);
if(vismats.empty()) return;
-
glDisable(GL_CULL_FACE);
-
int lastorient = -1, lastmat = -1;
bool depth = true, blended = false;
-
GLOBALPARAM(camera, camera1->o);
-
- if(editmode && showmat && !drawtex)
- {
+ if(editmode && showmat && !drawtex) {
glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
glEnable(GL_BLEND); blended = true;
bvec4 color(0, 0, 0, 0);
- loopv(vismats)
- {
+ loopv(vismats) {
const materialsurface &m = *vismats[i];
- if(lastmat!=m.material)
- {
- switch(m.material&~MATF_INDEX)
- {
+ if(lastmat!=m.material) {
+ switch(m.material&~MATF_INDEX) {
case MAT_CLIP: color = bvec4( 0, 255, 255, 255); break; // red
case MAT_NOCLIP: color = bvec4(255, 0, 255, 255); break; // green
case MAT_GAMECLIP: color = bvec4( 0, 0, 255, 255); break; // yellow
@@ -440,16 +379,13 @@ void rendermaterials()
}
xtraverts += gle::end();
}
-
if(lastorient >= 0)
if(lastmat&~MATF_INDEX)
xtraverts += gle::end();
-
if(!depth) glDepthMask(GL_TRUE);
if(blended) glDisable(GL_BLEND);
extern int wireframe;
if(editmode && showmat && !drawtex && !wireframe)
rendermatgrid(vismats);
-
glEnable(GL_CULL_FACE);
}