use projective texturing for blob shadows

git-svn-id: svn://svn.code.sf.net/p/actiongame/code/trunk/ac@2996 e016b1c5-ed68-44aa-a2f7-31cac88cffde
This commit is contained in:
Lee Salzman
2008-10-13 13:31:33 +00:00
parent 13c7f2129f
commit b1cf271061
4 changed files with 189 additions and 27 deletions
+123 -6
View File
@@ -128,7 +128,7 @@ COMMAND(showmip, ARG_NONE);
VAR(mergestrips, 0, 1, 1);
#define stripend() \
#define stripend(verts) \
if(floorstrip || deltastrip) { \
int type = GL_TRIANGLE_STRIP, len = verts.length()-firstindex; \
if(mergestrips) switch(len) { \
@@ -139,7 +139,7 @@ VAR(mergestrips, 0, 1, 1);
floorstrip = deltastrip = false; \
}
void finishstrips() { stripend(); }
void finishstrips() { stripend(verts); }
sqr sbright, sdark;
VARP(lighterror, 1, 4, 100);
@@ -160,7 +160,7 @@ void render_flat(int wtex, int x, int y, int size, int h, sqr *l1, sqr *l2, sqr
if(first) // start strip here
{
stripend();
stripend(verts);
firstindex = verts.length();
striptex = wtex;
oh = h;
@@ -237,7 +237,7 @@ void render_flatdelta(int wtex, int x, int y, int size, float h1, float h2, floa
if(first)
{
stripend();
stripend(verts);
firstindex = verts.length();
striptex = wtex;
ox = x;
@@ -277,7 +277,7 @@ void render_flatdelta(int wtex, int x, int y, int size, float h1, float h2, floa
void render_2tris(sqr *h, sqr *s, int x1, int y1, int x2, int y2, int x3, int y3, sqr *l1, sqr *l2, sqr *l3) // floor/ceil tris on a corner cube
{
stripend();
stripend(verts);
Texture *t = lookupworldtexture(h->ftex);
float xf = TEXTURESCALE/t->xs;
@@ -315,7 +315,7 @@ void render_tris(int x, int y, int size, bool topleft,
void render_square(int wtex, float floor1, float floor2, float ceil1, float ceil2, int x1, int y1, int x2, int y2, int size, sqr *l1, sqr *l2, bool flip) // wall quads
{
stripend();
stripend(verts);
if(showm) { l1 = &sbright; l2 = &sdark; }
Texture *t = lookupworldtexture(wtex);
@@ -350,10 +350,127 @@ void resetcubes()
floorstrip = deltastrip = false;
nquads = 0;
sbright.r = sbright.g = sbright.b = 255;
sdark.r = sdark.g = sdark.b = 0;
resetwater();
}
struct shadowvertex { float u, v, x, y, z; };
vector<shadowvertex> shadowverts;
static void resetshadowverts()
{
shadowverts.setsizenodelete(0);
floorstrip = deltastrip = false;
}
static void rendershadowstrips()
{
stripend(shadowverts);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
shadowvertex *buf = shadowverts.getbuf();
glVertexPointer(3, GL_FLOAT, sizeof(shadowvertex), &buf->x);
glTexCoordPointer(2, GL_FLOAT, sizeof(shadowvertex), &buf->u);
loopj(renderedtexs)
{
stripbatch &sb = stripbatches[j];
RENDERSTRIPS(sb.tris, GL_TRIANGLES);
RENDERSTRIPS(sb.tristrips, GL_TRIANGLE_STRIP);
RENDERSTRIPS(sb.quads, GL_QUADS);
}
renderedtexs = 0;
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
xtraverts += shadowverts.length();
}
#define shadowvert(v1, v2, v3) { \
shadowvertex &v = shadowverts.add(); \
v.x = (float)(v1); v.y = (float)(v2); v.z = (float)(v3); \
v.u = v.x*shadowtexgenS.x + v.y*shadowtexgenS.y + shadowtexgenS.z; \
v.v = v.x*shadowtexgenT.x + v.y*shadowtexgenT.y + shadowtexgenT.z; \
}
vec shadowtexgenS, shadowtexgenT;
static void rendershadow_flat(int x, int y, int h) // floor quads
{
bool first = !floorstrip || y!=oy+1 || h!=oh || x!=ox;
if(first) // start strip here
{
stripend(shadowverts);
firstindex = shadowverts.length();
striptex = DEFAULT_FLOOR;
oh = h;
ox = x;
floorstrip = true;
shadowvert(x, y, h);
shadowvert(x+1, y, h);
}
else // continue strip
{
shadowverts.setsizenodelete(shadowverts.length()-2);
}
shadowvert(x, y+1, h);
shadowvert(x+1, y+1, h);
oy = y;
nquads++;
}
static void rendershadow_flatdelta(int x, int y, float h1, float h2, float h3, float h4) // floor quads on a slope
{
bool first = !deltastrip || y!=oy+1 || x!=ox;
if(first)
{
stripend(shadowverts);
firstindex = shadowverts.length();
striptex = DEFAULT_FLOOR;
ox = x;
deltastrip = true;
shadowvert(x, y, h1);
shadowvert(x+1, y, h2);
}
shadowvert(x, y+1, h4);
shadowvert(x+1, y+1, h3);
oy = y;
}
void rendershadow(int x, int y, int xs, int ys)
{
resetshadowverts();
#define df(x) s->floor-(x->vdelta/4.0f)
sqr *w = wmip[0];
for(int xx = x; xx<xs; xx++) for(int yy = y; yy<ys; yy++)
{
sqr *s = SW(w,xx,yy);
if(s->type==SPACE || s->type==CHF)
{
rendershadow_flat(xx, yy, s->floor);
}
if(s->type==FHF)
{
sqr *t = SW(s,1,0), *u = SW(s,1,1), *v = SW(s,0,1);
rendershadow_flatdelta(xx, yy, df(s), df(t), df(u), df(v));
}
}
rendershadowstrips();
}