10 QuadNode(int x
, int y
, int size
) : x(x
), y(y
), size(size
), filled(0) { loopi(4) child
[i
] = 0; }
14 loopi(4) DELETEP(child
[i
]);
22 void insert(int mx
, int my
, int msize
)
29 int csize
= size
>>1, i
= 0;
30 if(mx
>= x
+csize
) i
|= 1;
31 if(my
>= y
+csize
) i
|= 2;
37 if(!child
[i
]) child
[i
] = new QuadNode(i
&1 ? x
+csize
: x
, i
&2 ? y
+csize
: y
, csize
);
38 child
[i
]->insert(mx
, my
, msize
);
41 if(child
[j
]->filled
== 0xF)
49 void genmatsurf(uchar mat
, uchar orient
, int x
, int y
, int z
, int size
, materialsurface
*&matbuf
)
51 materialsurface
&m
= *matbuf
++;
56 int dim
= dimension(orient
);
62 void genmatsurfs(uchar mat
, uchar orient
, int z
, materialsurface
*&matbuf
)
64 if(filled
== 0xF) genmatsurf(mat
, orient
, x
, y
, z
, size
, matbuf
);
68 loopi(4) if(filled
& (1 << i
))
69 genmatsurf(mat
, orient
, i
&1 ? x
+csize
: x
, i
&2 ? y
+csize
: y
, z
, csize
, matbuf
);
71 loopi(4) if(child
[i
]) child
[i
]->genmatsurfs(mat
, orient
, z
, matbuf
);
75 void renderwaterfall(materialsurface
&m
, Texture
*tex
, float scale
, float offset
, uchar mat
)
77 float xf
= 8.0f
/(tex
->xs
*scale
);
78 float yf
= 8.0f
/(tex
->ys
*scale
);
79 float d
= 16.0f
*lastmillis
;
80 int dim
= dimension(m
.orient
),
81 csize
= C
[dim
]==2 ? m
.rsize
: m
.csize
,
82 rsize
= R
[dim
]==2 ? m
.rsize
: m
.csize
;
87 t
/= renderpath
!=R_FIXEDFUNCTION
? 600.0f
: 300.0f
;
95 float wave
= m
.ends
&2 ? (vertwater
? WATER_AMPLITUDE
*sinf(t
)-WATER_OFFSET
: -WATER_OFFSET
) : 0;
99 v
[dim
] += dimcoord(m
.orient
) ? -offset
: offset
;
100 if(i
==1 || i
==2) v
[dim
^1] += csize
;
101 if(i
<=1) v
.z
+= rsize
;
102 if(m
.ends
&(i
<=1 ? 2 : 1)) v
.z
+= i
<=1 ? wave
: -WATER_OFFSET
-WATER_AMPLITUDE
;
103 glTexCoord2f(xf
*v
[dim
^1], yf
*(v
.z
+d
));
110 void drawmaterial(int orient
, int x
, int y
, int z
, int csize
, int rsize
, float offset
)
112 int dim
= dimension(orient
), c
= C
[dim
], r
= R
[dim
];
115 int coord
= fv
[orient
][i
];
117 v
[c
] += cubecoords
[coord
][c
]/8*csize
;
118 v
[r
] += cubecoords
[coord
][r
]/8*rsize
;
119 v
[dim
] += dimcoord(orient
) ? -offset
: offset
;
132 {"water", MAT_WATER
},
134 {"glass", MAT_GLASS
},
135 {"noclip", MAT_NOCLIP
},
137 {"aiclip", MAT_AICLIP
}
140 int findmaterial(const char *name
)
142 loopi(sizeof(materials
)/sizeof(material
))
144 if(!strcmp(materials
[i
].name
, name
)) return materials
[i
].id
;
149 int visiblematerial(cube
&c
, int orient
, int x
, int y
, int z
, int size
)
151 if(c
.ext
) switch(c
.ext
->material
)
158 if(visibleface(c
, orient
, x
, y
, z
, size
, c
.ext
->material
))
159 return (orient
!= O_BOTTOM
? MATSURF_VISIBLE
: MATSURF_EDIT_ONLY
);
163 if(visibleface(c
, orient
, x
, y
, z
, size
, MAT_GLASS
))
164 return MATSURF_VISIBLE
;
168 if(visibleface(c
, orient
, x
, y
, z
, size
, c
.ext
->material
))
169 return MATSURF_EDIT_ONLY
;
172 return MATSURF_NOT_VISIBLE
;
175 void genmatsurfs(cube
&c
, int cx
, int cy
, int cz
, int size
, vector
<materialsurface
> &matsurfs
)
179 int vis
= visiblematerial(c
, i
, cx
, cy
, cz
, size
);
180 if(vis
!= MATSURF_NOT_VISIBLE
)
183 m
.material
= (vis
== MATSURF_EDIT_ONLY
? c
.ext
->material
+MAT_EDIT
: c
.ext
->material
);
185 m
.o
= ivec(cx
, cy
, cz
);
186 m
.csize
= m
.rsize
= size
;
187 if(dimcoord(i
)) m
.o
[dimension(i
)] += size
;
193 static int mergematcmp(const materialsurface
*x
, const materialsurface
*y
)
195 int dim
= dimension(x
->orient
), c
= C
[dim
], r
= R
[dim
];
196 if(x
->o
[r
] + x
->rsize
< y
->o
[r
] + y
->rsize
) return -1;
197 if(x
->o
[r
] + x
->rsize
> y
->o
[r
] + y
->rsize
) return 1;
198 if(x
->o
[c
] < y
->o
[c
]) return -1;
199 if(x
->o
[c
] > y
->o
[c
]) return 1;
203 static int mergematr(materialsurface
*m
, int sz
, materialsurface
&n
)
205 int dim
= dimension(n
.orient
), c
= C
[dim
], r
= R
[dim
];
206 for(int i
= sz
-1; i
>= 0; --i
)
208 if(m
[i
].o
[r
] + m
[i
].rsize
< n
.o
[r
]) break;
209 if(m
[i
].o
[r
] + m
[i
].rsize
== n
.o
[r
] && m
[i
].o
[c
] == n
.o
[c
] && m
[i
].csize
== n
.csize
)
212 n
.rsize
+= m
[i
].rsize
;
213 memmove(&m
[i
], &m
[i
+1], (sz
- (i
+1)) * sizeof(materialsurface
));
220 static int mergematc(materialsurface
&m
, materialsurface
&n
)
222 int dim
= dimension(n
.orient
), c
= C
[dim
], r
= R
[dim
];
223 if(m
.o
[r
] == n
.o
[r
] && m
.rsize
== n
.rsize
&& m
.o
[c
] + m
.csize
== n
.o
[c
])
232 static int mergemat(materialsurface
*m
, int sz
, materialsurface
&n
)
234 for(bool merged
= false; sz
; merged
= true)
236 int rmerged
= mergematr(m
, sz
, n
);
238 if(!rmerged
&& merged
) break;
240 int cmerged
= mergematc(m
[sz
-1], n
);
248 static int mergemats(materialsurface
*m
, int sz
)
250 qsort(m
, sz
, sizeof(materialsurface
), (int (__cdecl
*)(const void *, const void *))mergematcmp
);
253 loopi(sz
) nsz
= mergemat(m
, nsz
, m
[i
]);
257 static int optmatcmp(const materialsurface
*x
, const materialsurface
*y
)
259 if(x
->material
< y
->material
) return -1;
260 if(x
->material
> y
->material
) return 1;
261 if(x
->orient
> y
->orient
) return -1;
262 if(x
->orient
< y
->orient
) return 1;
263 int dim
= dimension(x
->orient
), xc
= x
->o
[dim
], yc
= y
->o
[dim
];
264 if(xc
< yc
) return -1;
265 if(xc
> yc
) return 1;
269 VARF(optmats
, 0, 1, 1, allchanged());
271 int optimizematsurfs(materialsurface
*matbuf
, int matsurfs
)
273 qsort(matbuf
, matsurfs
, sizeof(materialsurface
), (int (__cdecl
*)(const void*, const void*))optmatcmp
);
274 if(!optmats
) return matsurfs
;
275 materialsurface
*cur
= matbuf
, *end
= matbuf
+matsurfs
;
278 materialsurface
*start
= cur
++;
279 int dim
= dimension(start
->orient
);
281 cur
->material
== start
->material
&&
282 cur
->orient
== start
->orient
&&
283 cur
->o
[dim
] == start
->o
[dim
])
285 if(!isliquid(start
->material
) || start
->orient
!= O_TOP
|| !vertwater
)
287 if(start
!=matbuf
) memmove(matbuf
, start
, (cur
-start
)*sizeof(materialsurface
));
288 matbuf
+= mergemats(matbuf
, cur
-start
);
290 else if(cur
-start
>=4)
292 QuadNode
vmats(0, 0, hdr
.worldsize
);
293 loopi(cur
-start
) vmats
.insert(start
[i
].o
[C
[dim
]], start
[i
].o
[R
[dim
]], start
[i
].csize
);
294 vmats
.genmatsurfs(start
->material
, start
->orient
, start
->o
[dim
], matbuf
);
298 if(start
!=matbuf
) memmove(matbuf
, start
, (cur
-start
)*sizeof(materialsurface
));
302 return matsurfs
- (end
-matbuf
);
305 extern vector
<vtxarray
*> valist
;
313 void setupmaterials()
316 vector
<waterinfo
> water
;
317 hashtable
<ivec
, int> watersets
;
321 vtxarray
*va
= valist
[i
];
322 lodlevel
&lod
= va
->l0
;
325 materialsurface
&m
= lod
.matbuf
[j
];
326 if(m
.material
==MAT_WATER
&& m
.orient
==O_TOP
)
328 m
.index
= water
.length();
331 materialsurface
&n
= *water
[k
].m
;
332 if(m
.o
.z
!=n
.o
.z
) continue;
333 if(n
.o
.x
+n
.rsize
==m
.o
.x
|| m
.o
.x
+m
.rsize
==n
.o
.x
)
335 if(n
.o
.y
+n
.csize
>m
.o
.y
&& n
.o
.y
<m
.o
.y
+m
.csize
) uf
.unite(m
.index
, n
.index
);
337 else if(n
.o
.y
+n
.csize
==m
.o
.y
|| m
.o
.y
+m
.csize
==n
.o
.y
)
339 if(n
.o
.x
+n
.rsize
>m
.o
.x
&& n
.o
.x
<m
.o
.x
+m
.rsize
) uf
.unite(m
.index
, n
.index
);
342 waterinfo
&wi
= water
.add();
344 vec
center(m
.o
.x
+m
.rsize
/2, m
.o
.y
+m
.csize
/2, m
.o
.z
-WATER_OFFSET
);
345 m
.light
= brightestlight(center
, vec(0, 0, 1));
346 float depth
= raycube(center
, vec(0, 0, -1), 10000);
347 wi
.depth
= double(depth
)*m
.rsize
*m
.csize
;
348 wi
.area
= m
.rsize
*m
.csize
;
350 else if(isliquid(m
.material
) && m
.orient
!=O_BOTTOM
&& m
.orient
!=O_TOP
)
353 int dim
= dimension(m
.orient
), coord
= dimcoord(m
.orient
);
356 o
[dim
] += coord
? 1 : -1;
357 int minc
= o
[dim
^1], maxc
= minc
+ (C
[dim
]==2 ? m
.rsize
: m
.csize
);
358 while(o
[dim
^1] < maxc
)
360 cube
&c
= lookupcube(o
.x
, o
.y
, o
.z
);
361 if(c
.ext
&& isliquid(c
.ext
->material
)) { m
.ends
|= 1; break; }
365 o
.z
+= R
[dim
]==2 ? m
.rsize
: m
.csize
;
366 o
[dim
] -= coord
? 2 : -2;
367 while(o
[dim
^1] < maxc
)
369 cube
&c
= lookupcube(o
.x
, o
.y
, o
.z
);
370 if(visiblematerial(c
, O_TOP
, lu
.x
, lu
.y
, lu
.z
, lusize
)) { m
.ends
|= 2; break; }
374 else if(m
.material
==MAT_GLASS
)
376 if(!hasCM
) m
.envmap
= EMID_NONE
;
379 int dim
= dimension(m
.orient
);
380 vec
center(m
.o
.tovec());
381 center
[R
[dim
]] += m
.rsize
/2;
382 center
[C
[dim
]] += m
.csize
/2;
383 m
.envmap
= closestenvmap(center
);
386 hasmat
|= 1<<m
.material
;
391 int root
= uf
.find(i
);
392 if(i
==root
) continue;
393 materialsurface
&m
= *water
[i
].m
, &n
= *water
[root
].m
;
394 if(m
.light
&& (!m
.light
->attr1
|| !n
.light
|| (n
.light
->attr1
&& m
.light
->attr1
> n
.light
->attr1
))) n
.light
= m
.light
;
395 water
[root
].depth
+= water
[i
].depth
;
396 water
[root
].area
+= water
[i
].area
;
400 int root
= uf
.find(i
);
401 water
[i
].m
->light
= water
[root
].m
->light
;
402 water
[i
].m
->depth
= (short)(water
[root
].depth
/water
[root
].area
);
404 if(hasmat
&(1<<MAT_WATER
))
406 extern void loadcaustics();
408 lookuptexture(-MAT_WATER
);
410 if(hasmat
&(1<<MAT_LAVA
)) lookuptexture(-MAT_LAVA
);
413 VARP(showmat
, 0, 1, 1);
415 static int sortdim
[3];
416 static ivec sortorigin
;
418 static int vismatcmp(const materialsurface
** xm
, const materialsurface
** ym
)
420 const materialsurface
&x
= **xm
, &y
= **ym
;
421 int xdim
= dimension(x
.orient
), ydim
= dimension(y
.orient
);
424 int dim
= sortdim
[i
], xmin
, xmax
, ymin
, ymax
;
425 xmin
= xmax
= x
.o
[dim
];
426 if(dim
==C
[xdim
]) xmax
+= x
.csize
;
427 else if(dim
==R
[xdim
]) xmax
+= x
.rsize
;
428 ymin
= ymax
= y
.o
[dim
];
429 if(dim
==C
[ydim
]) ymax
+= y
.csize
;
430 else if(dim
==R
[ydim
]) ymax
+= y
.rsize
;
431 if(xmax
> ymin
&& ymax
> xmin
) continue;
432 int c
= sortorigin
[dim
];
433 if(c
> xmin
&& c
< xmax
) return 1;
434 if(c
> ymin
&& c
< ymax
) return -1;
435 xmin
= abs(xmin
- c
);
436 xmax
= abs(xmax
- c
);
437 ymin
= abs(ymin
- c
);
438 ymax
= abs(ymax
- c
);
439 if(max(xmin
, xmax
) <= min(ymin
, ymax
)) return 1;
440 else if(max(ymin
, ymax
) <= min(xmin
, xmax
)) return -1;
442 if(x
.material
< y
.material
) return 1;
443 if(x
.material
> y
.material
) return -1;
447 extern vtxarray
*visibleva
, *reflectedva
;
449 void sortmaterials(vector
<materialsurface
*> &vismats
, float zclip
, bool refract
)
451 bool reflected
= zclip
&& !refract
&& camera1
->o
.z
>= zclip
;
452 sortorigin
= ivec(camera1
->o
);
453 if(reflected
) sortorigin
.z
= int(zclip
- (camera1
->o
.z
- zclip
));
455 vecfromyawpitch(camera1
->yaw
, reflected
? -camera1
->pitch
: camera1
->pitch
, 1, 0, dir
);
456 loopi(3) { dir
[i
] = fabs(dir
[i
]); sortdim
[i
] = i
; }
457 if(dir
[sortdim
[2]] > dir
[sortdim
[1]]) swap(int, sortdim
[2], sortdim
[1]);
458 if(dir
[sortdim
[1]] > dir
[sortdim
[0]]) swap(int, sortdim
[1], sortdim
[0]);
459 if(dir
[sortdim
[2]] > dir
[sortdim
[1]]) swap(int, sortdim
[2], sortdim
[1]);
461 for(vtxarray
*va
= reflected
? reflectedva
: visibleva
; va
; va
= reflected
? va
->rnext
: va
->next
)
463 lodlevel
&lod
= va
->l0
;
464 if(!lod
.matsurfs
|| va
->occluded
>= OCCLUDE_BB
) continue;
465 if(zclip
&& (refract
? va
->z
>= zclip
: va
->z
+va
->size
<= zclip
)) continue;
468 materialsurface
&m
= lod
.matbuf
[i
];
469 if(!editmode
|| !showmat
)
471 if(m
.material
==MAT_WATER
&& m
.orient
==O_TOP
) continue;
472 if(m
.material
>=MAT_EDIT
) continue;
477 vismats
.sort(vismatcmp
);
480 void rendermatgrid(vector
<materialsurface
*> &vismats
)
482 glEnable(GL_POLYGON_OFFSET_LINE
);
483 glPolygonMode(GL_FRONT_AND_BACK
, GL_LINE
);
484 static uchar cols
[MAT_EDIT
][3] =
486 { 0, 0, 0 }, // MAT_AIR - no edit volume,
487 { 0, 0, 85 }, // MAT_WATER - blue,
488 { 85, 0, 0 }, // MAT_CLIP - red,
489 { 0, 85, 85 }, // MAT_GLASS - cyan,
490 { 0, 85, 0 }, // MAT_NOCLIP - green
491 { 85, 40, 0 }, // MAT_LAVA - orange
492 { 85, 85, 0 }, // MAT_AICLIP - yellow
498 materialsurface
&m
= *vismats
[i
];
499 int curmat
= m
.material
>= MAT_EDIT
? m
.material
-MAT_EDIT
: m
.material
;
500 if(curmat
!= lastmat
)
503 glColor3ubv(cols
[curmat
]);
505 drawmaterial(m
.orient
, m
.o
.x
, m
.o
.y
, m
.o
.z
, m
.csize
, m
.rsize
, -0.1f
);
508 glPolygonMode(GL_FRONT_AND_BACK
, GL_FILL
);
509 glDisable(GL_POLYGON_OFFSET_LINE
);
512 VARP(glassenv
, 0, 1, 1);
514 void drawglass(int orient
, int x
, int y
, int z
, int csize
, int rsize
, float offset
)
516 int dim
= dimension(orient
), c
= C
[dim
], r
= R
[dim
];
519 int coord
= fv
[orient
][i
];
521 v
[c
] += cubecoords
[coord
][c
]/8*csize
;
522 v
[r
] += cubecoords
[coord
][r
]/8*rsize
;
523 v
[dim
] += dimcoord(orient
) ? -offset
: offset
;
526 reflect
.sub(camera1
->o
);
527 reflect
[dim
] = -reflect
[dim
];
529 glTexCoord3f(-reflect
.y
, reflect
.z
, reflect
.x
);
535 void rendermaterials(float zclip
, bool refract
)
537 vector
<materialsurface
*> vismats
;
538 sortmaterials(vismats
, zclip
, refract
);
539 if(vismats
.empty()) return;
541 glDisable(GL_CULL_FACE
);
543 Slot
&wslot
= lookuptexture(-MAT_WATER
), &lslot
= lookuptexture(-MAT_LAVA
);
544 uchar wcol
[4] = { 128, 128, 128, 192 };
545 if(hdr
.watercolour
[0] || hdr
.watercolour
[1] || hdr
.watercolour
[2]) memcpy(wcol
, hdr
.watercolour
, 3);
546 int lastorient
= -1, lastmat
= -1;
547 GLenum textured
= GL_TEXTURE_2D
;
548 bool begin
= false, depth
= true, blended
= false, overbright
= false;
549 ushort envmapped
= EMID_NONE
;
552 static float zerofog
[4] = { 0, 0, 0, 1 };
554 glGetFloatv(GL_FOG_COLOR
, oldfogc
);
558 materialsurface
&m
= *vismats
[editmode
&& showmat
? vismats
.length()-1-i
: i
];
559 int curmat
= !editmode
|| !showmat
|| m
.material
>=MAT_EDIT
? m
.material
: m
.material
+MAT_EDIT
;
560 if(lastmat
!=curmat
|| lastorient
!=m
.orient
|| (curmat
==MAT_GLASS
&& envmapped
&& m
.envmap
!= envmapped
))
562 int fogtype
= lastfogtype
;
566 if(lastmat
==MAT_WATER
&& lastorient
!=O_TOP
&& m
.orient
!=O_TOP
) break;
567 if(begin
) { glEnd(); begin
= false; }
568 if(lastmat
!=MAT_WATER
|| (lastorient
==O_TOP
)!=(m
.orient
==O_TOP
))
570 if(depth
) { glDepthMask(GL_FALSE
); depth
= false; }
571 if(!blended
) { glEnable(GL_BLEND
); blended
= true; }
572 if(overbright
) { resettmu(0); overbright
= false; }
575 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
580 glBlendFunc(GL_ONE
, GL_ONE_MINUS_SRC_COLOR
);
581 glColor3f(wcol
[0]/255.0f
, wcol
[1]/255.0f
, wcol
[2]/255.0f
);
586 if(textured
!=GL_TEXTURE_2D
)
588 if(textured
) glDisable(textured
);
589 glEnable(GL_TEXTURE_2D
);
590 textured
= GL_TEXTURE_2D
;
592 glBindTexture(GL_TEXTURE_2D
, wslot
.sts
[m
.orient
==O_TOP
? 0 : 1].t
->gl
);
596 if(lastmat
==MAT_LAVA
&& lastorient
!=O_TOP
&& m
.orient
!=O_TOP
) break;
597 if(begin
) { glEnd(); begin
= false; }
598 if(lastmat
!=MAT_LAVA
)
600 if(!depth
) { glDepthMask(GL_TRUE
); depth
= true; }
601 if(blended
) { glDisable(GL_BLEND
); blended
= false; }
602 if(renderpath
==R_FIXEDFUNCTION
&& !overbright
) { setuptmu(0, "C * T x 2"); overbright
= true; }
603 float t
= lastmillis
/2000.0f
;
605 t
= 1.0f
- fabs(t
-0.5f
);
607 static Shader
*lavashader
= NULL
;
608 if(!lavashader
) lavashader
= lookupshaderbyname("lava");
612 if(textured
!=GL_TEXTURE_2D
)
614 if(textured
) glDisable(textured
);
615 glEnable(GL_TEXTURE_2D
);
616 textured
= GL_TEXTURE_2D
;
618 glBindTexture(GL_TEXTURE_2D
, lslot
.sts
[m
.orient
==O_TOP
? 0 : 1].t
->gl
);
622 if(m
.envmap
!=EMID_NONE
&& glassenv
&& (lastmat
!=MAT_GLASS
|| lastorient
!=m
.orient
))
623 normal
= vec(dimension(m
.orient
)==0 ? dimcoord(m
.orient
)*2-1 : 0,
624 dimension(m
.orient
)==1 ? dimcoord(m
.orient
)*2-1 : 0,
625 dimension(m
.orient
)==2 ? dimcoord(m
.orient
)*2-1 : 0);
626 if((m
.envmap
==EMID_NONE
|| !glassenv
|| (envmapped
==m
.envmap
&& textured
==GL_TEXTURE_CUBE_MAP_ARB
)) && lastmat
==MAT_GLASS
) break;
627 if(begin
) { glEnd(); begin
= false; }
628 if(m
.envmap
!=EMID_NONE
&& glassenv
)
630 if(textured
!=GL_TEXTURE_CUBE_MAP_ARB
)
632 if(textured
) glDisable(textured
);
633 glEnable(GL_TEXTURE_CUBE_MAP_ARB
);
634 textured
= GL_TEXTURE_CUBE_MAP_ARB
;
636 if(envmapped
!=m
.envmap
)
638 glBindTexture(GL_TEXTURE_CUBE_MAP_ARB
, lookupenvmap(m
.envmap
));
639 if(envmapped
==EMID_NONE
&& renderpath
!=R_FIXEDFUNCTION
)
640 setenvparamf("camera", SHPARAM_VERTEX
, 0, camera1
->o
.x
, camera1
->o
.y
, camera1
->o
.z
);
641 envmapped
= m
.envmap
;
644 if(lastmat
!=MAT_GLASS
)
646 if(!blended
) { glEnable(GL_BLEND
); blended
= true; }
647 if(overbright
) { resettmu(0); overbright
= false; }
648 if(depth
) { glDepthMask(GL_FALSE
); depth
= false; }
649 if(m
.envmap
!=EMID_NONE
&& glassenv
)
651 if(renderpath
==R_FIXEDFUNCTION
)
653 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
654 glColor4f(0.8f
, 0.9f
, 1.0f
, 0.25f
);
659 glBlendFunc(GL_ONE
, GL_SRC_ALPHA
);
660 glColor3f(0, 0.5f
, 1.0f
);
662 static Shader
*glassshader
= NULL
;
663 if(!glassshader
) glassshader
= lookupshaderbyname("glass");
673 glBlendFunc(GL_ZERO
, GL_ONE_MINUS_SRC_COLOR
);
674 glColor3f(0.3f
, 0.15f
, 0.0f
);
675 foggednotextureshader
->set();
683 if(lastmat
==curmat
) break;
686 if(begin
) { glEnd(); begin
= false; }
687 if(!depth
) { glDepthMask(GL_TRUE
); depth
= true; }
688 if(!blended
) { glEnable(GL_BLEND
); blended
= true; }
689 if(overbright
) { resettmu(0); overbright
= false; }
690 glBlendFunc(GL_ZERO
, GL_ONE_MINUS_SRC_COLOR
);
691 if(textured
) { glDisable(GL_TEXTURE_2D
); textured
= 0; }
692 foggednotextureshader
->set();
695 static uchar blendcols
[MAT_EDIT
][3] =
697 { 0, 0, 0 }, // MAT_AIR - no edit volume,
698 { 255, 128, 0 }, // MAT_WATER - blue,
699 { 0, 255, 255 }, // MAT_CLIP - red,
700 { 255, 0, 0 }, // MAT_GLASS - cyan,
701 { 255, 0, 255 }, // MAT_NOCLIP - green
702 { 0, 128, 255 }, // MAT_LAVA - orange
703 { 0, 0, 255 }, // MAT_AICLIP - yellow
705 glColor3ubv(blendcols
[curmat
>= MAT_EDIT
? curmat
-MAT_EDIT
: curmat
]);
710 lastorient
= m
.orient
;
711 if(fogtype
!=lastfogtype
)
713 glFogfv(GL_FOG_COLOR
, fogtype
? oldfogc
: zerofog
);
714 lastfogtype
= fogtype
;
722 if(!begin
) { glBegin(GL_QUADS
); begin
= true; }
723 renderwaterfall(m
, wslot
.sts
[1].t
, wslot
.sts
[1].scale
? wslot
.sts
[1].scale
: 1, 0.1f
, MAT_WATER
);
730 if(!vertwater
&& !begin
) { glBegin(GL_QUADS
); begin
= true; }
731 renderlava(m
, lslot
.sts
[0].t
, lslot
.sts
[0].scale
? lslot
.sts
[0].scale
: 1);
735 if(!begin
) { glBegin(GL_QUADS
); begin
= true; }
736 renderwaterfall(m
, lslot
.sts
[1].t
, lslot
.sts
[1].scale
? lslot
.sts
[1].scale
: 1, 0.1f
, MAT_LAVA
);
741 if(!begin
) { glBegin(GL_QUADS
); begin
= true; }
742 if(m
.envmap
!=EMID_NONE
&& glassenv
)
744 if(renderpath
!=R_FIXEDFUNCTION
) glNormal3fv(normal
.v
);
745 drawglass(m
.orient
, m
.o
.x
, m
.o
.y
, m
.o
.z
, m
.csize
, m
.rsize
, 0.1f
);
747 else drawmaterial(m
.orient
, m
.o
.x
, m
.o
.y
, m
.o
.z
, m
.csize
, m
.rsize
, 0.1f
);
751 if(!begin
) { glBegin(GL_QUADS
); begin
= true; }
752 drawmaterial(m
.orient
, m
.o
.x
, m
.o
.y
, m
.o
.z
, m
.csize
, m
.rsize
, -0.1f
);
758 if(!depth
) glDepthMask(GL_TRUE
);
759 if(blended
) glDisable(GL_BLEND
);
760 if(overbright
) resettmu(0);
761 if(!lastfogtype
) glFogfv(GL_FOG_COLOR
, oldfogc
);
762 if(editmode
&& showmat
)
764 foggednotextureshader
->set();
765 rendermatgrid(vismats
);
768 glEnable(GL_CULL_FACE
);
769 if(textured
!=GL_TEXTURE_2D
)
771 if(textured
) glDisable(textured
);
772 glEnable(GL_TEXTURE_2D
);