~ubuntu-branches/debian/stretch/assaultcube-data/stretch

« back to all changes in this revision

Viewing changes to source/src/rendercubes.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Gonéri Le Bouder, Ansgar Burchardt, Gonéri Le Bouder
  • Date: 2010-04-02 23:37:55 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20100402233755-kf74fxwlu634o6vg
Tags: 1.0.4+repack1-1
[ Ansgar Burchardt ]
* debian/control: fix typo in short description

[ Gonéri Le Bouder ]
* Upgrade to 1.0.4
* bump standards-version to 3.8.4
* Add Depends: ${misc:Depends} just to avoid a lintian warning
* Add a debian/source/format file for the same reason

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// rendercubes.cpp: sits in between worldrender.cpp and rendergl.cpp and fills the vertex array for different cube surfaces.
 
2
 
 
3
#include "pch.h"
 
4
#include "cube.h"
 
5
 
 
6
vector<vertex> verts;
 
7
 
 
8
void finishstrips();
 
9
 
 
10
void setupstrips()
 
11
{
 
12
    finishstrips();
 
13
 
 
14
    glEnableClientState(GL_VERTEX_ARRAY);
 
15
    glEnableClientState(GL_COLOR_ARRAY);
 
16
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 
17
 
 
18
    vertex *buf = verts.getbuf();
 
19
    glVertexPointer(3, GL_FLOAT, sizeof(vertex), &buf->x);
 
20
    glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(vertex), &buf->r);
 
21
    glTexCoordPointer(2, GL_FLOAT, sizeof(vertex), &buf->u);
 
22
}
 
23
 
 
24
struct strips { vector<GLint> first; vector<GLsizei> count; };
 
25
 
 
26
struct stripbatch
 
27
{
 
28
    int tex;
 
29
    strips tris, tristrips, quads;   
 
30
};
 
31
 
 
32
stripbatch skystrips = { DEFAULT_SKY };
 
33
stripbatch stripbatches[256];
 
34
uchar renderedtex[256];
 
35
int renderedtexs = 0;
 
36
 
 
37
extern int ati_mda_bug;
 
38
 
 
39
#define RENDERSTRIPS(strips, type) \
 
40
    if(strips.first.length()) \
 
41
    { \
 
42
        if(hasMDA && !ati_mda_bug) glMultiDrawArrays_(type, strips.first.getbuf(), strips.count.getbuf(), strips.first.length()); \
 
43
        else loopv(strips.first) glDrawArrays(type, strips.first[i], strips.count[i]); \
 
44
        strips.first.setsizenodelete(0); \
 
45
        strips.count.setsizenodelete(0); \
 
46
    }
 
47
 
 
48
void renderstripssky()
 
49
{
 
50
    if(skystrips.tris.first.empty() && skystrips.tristrips.first.empty() && skystrips.quads.first.empty()) return;
 
51
    glDisable(GL_TEXTURE_2D);
 
52
    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
 
53
    RENDERSTRIPS(skystrips.tris, GL_TRIANGLES);
 
54
    RENDERSTRIPS(skystrips.tristrips, GL_TRIANGLE_STRIP);
 
55
    RENDERSTRIPS(skystrips.quads, GL_QUADS);
 
56
    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
 
57
    glEnable(GL_TEXTURE_2D);
 
58
}
 
59
 
 
60
void renderstrips()
 
61
{
 
62
    loopj(renderedtexs)
 
63
    {
 
64
        stripbatch &sb = stripbatches[j];
 
65
        glBindTexture(GL_TEXTURE_2D, lookupworldtexture(sb.tex)->id);
 
66
        RENDERSTRIPS(sb.tris, GL_TRIANGLES);
 
67
        RENDERSTRIPS(sb.tristrips, GL_TRIANGLE_STRIP);
 
68
        RENDERSTRIPS(sb.quads, GL_QUADS);
 
69
    }
 
70
    renderedtexs = 0;
 
71
 
 
72
    glDisableClientState(GL_VERTEX_ARRAY);
 
73
    glDisableClientState(GL_COLOR_ARRAY);
 
74
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
 
75
}
 
76
 
 
77
void addstrip(int type, int tex, int start, int n)
 
78
{
 
79
    stripbatch *sb = NULL;
 
80
    if(tex==DEFAULT_SKY)
 
81
    {
 
82
        if(minimap) return;
 
83
        sb = &skystrips;
 
84
        loopi(n) skyfloor = min(skyfloor, verts[start + i].z); 
 
85
    }
 
86
    else
 
87
    {
 
88
        sb = &stripbatches[renderedtex[tex]];
 
89
        if(sb->tex!=tex || sb>=&stripbatches[renderedtexs])
 
90
        {
 
91
            sb = &stripbatches[renderedtex[tex] = renderedtexs++];
 
92
            sb->tex = tex;
 
93
        }
 
94
    }
 
95
    strips &s = (type==GL_QUADS ? sb->quads : (type==GL_TRIANGLES ? sb->tris : sb->tristrips));
 
96
    if(type!=GL_TRIANGLE_STRIP && s.first.length() && s.first.last()+s.count.last() == start)
 
97
    {
 
98
        s.count.last() += n;
 
99
        return;
 
100
    }
 
101
    s.first.add(start);
 
102
    s.count.add(n);
 
103
}
 
104
 
 
105
// generating the actual vertices is done dynamically every frame and sits at the
 
106
// leaves of all these functions, and are part of the cpu bottleneck on really slow
 
107
// machines, hence the macros.
 
108
 
 
109
#define vert(v1, v2, v3, ls, t1, t2) { \
 
110
        vertex &v = verts.add(); \
 
111
    v.u = t1; v.v = t2; \
 
112
    v.x = (float)(v1); v.y = (float)(v2); v.z = (float)(v3); \
 
113
    v.r = ls->r; v.g = ls->g; v.b = ls->b; v.a = 255; \
 
114
}
 
115
 
 
116
enum
 
117
{
 
118
    STRIP_FLOOR = 1,
 
119
    STRIP_DELTA,
 
120
    STRIP_WALL
 
121
};
 
122
 
 
123
int nquads;
 
124
const float TEXTURESCALE = 32.0f;
 
125
int striptype = 0, striptex, oh, oy, ox, odir;                         // the o* vars are used by the stripification
 
126
int ol1r, ol1g, ol1b, ol2r, ol2g, ol2b;      
 
127
float ofloor, oceil;
 
128
bool ohf;
 
129
int firstindex;
 
130
bool showm = false;
 
131
 
 
132
void showmip() { showm = !showm; }
 
133
void mipstats(int a, int b, int c) { if(showm) conoutf("1x1/2x2/4x4: %d / %d / %d", a, b, c); }
 
134
 
 
135
COMMAND(showmip, ARG_NONE);
 
136
 
 
137
VAR(mergestrips, 0, 1, 1);
 
138
 
 
139
#define stripend(verts) \
 
140
    if(striptype) { \
 
141
        int type = GL_TRIANGLE_STRIP, len = verts.length()-firstindex; \
 
142
        if(mergestrips) switch(len) { \
 
143
            case 3: type = GL_TRIANGLES; break; \
 
144
            case 4: type = GL_QUADS; swap(verts.last(), verts[verts.length()-2]); break; \
 
145
         } \
 
146
         addstrip(type, striptex, firstindex, len); \
 
147
         striptype = 0; \
 
148
    }
 
149
 
 
150
void finishstrips() { stripend(verts); }
 
151
 
 
152
sqr sbright, sdark;
 
153
VARP(lighterror, 1, 4, 100);
 
154
 
 
155
void render_flat(int wtex, int x, int y, int size, int h, sqr *l1, sqr *l4, sqr *l3, sqr *l2, bool isceil)  // floor/ceil quads
 
156
{
 
157
    if(showm) { l3 = l1 = &sbright; l4 = l2 = &sdark; }
 
158
 
 
159
    Texture *t = lookupworldtexture(wtex);
 
160
    float xf = TEXTURESCALE/t->xs;
 
161
    float yf = TEXTURESCALE/t->ys;
 
162
    float xs = size*xf;
 
163
    float ys = size*yf;
 
164
    float xo = xf*x;
 
165
    float yo = yf*y;
 
166
 
 
167
    bool first = striptype!=STRIP_FLOOR || x!=ox+size || striptex!=wtex || h!=oh || y!=oy;
 
168
 
 
169
    if(first)       // start strip here
 
170
    {
 
171
        stripend(verts);
 
172
        firstindex = verts.length();
 
173
        striptex = wtex;
 
174
        oh = h;
 
175
        oy = y;
 
176
        striptype = STRIP_FLOOR;
 
177
        if(isceil)
 
178
        {
 
179
            vert(x, y,      h, l1, xo, yo);
 
180
            vert(x, y+size, h, l2, xo, yo+ys);
 
181
        }
 
182
        else
 
183
        {
 
184
            vert(x, y+size, h, l2, xo, yo+ys);
 
185
            vert(x, y,      h, l1, xo, yo);
 
186
        }
 
187
        ol1r = l1->r;
 
188
        ol1g = l1->g;
 
189
        ol1b = l1->b;
 
190
        ol2r = l2->r;
 
191
        ol2g = l2->g;
 
192
        ol2b = l2->b;
 
193
    }
 
194
    else        // continue strip
 
195
    {
 
196
        int lighterr = lighterror*2;
 
197
        if((abs(ol1r-l3->r)<lighterr && abs(ol2r-l4->r)<lighterr        // skip vertices if light values are close enough
 
198
        &&  abs(ol1g-l3->g)<lighterr && abs(ol2g-l4->g)<lighterr
 
199
        &&  abs(ol1b-l3->b)<lighterr && abs(ol2b-l4->b)<lighterr) || !wtex)   
 
200
        {
 
201
            verts.setsizenodelete(verts.length()-2);
 
202
            nquads--;
 
203
        }
 
204
        else
 
205
        {
 
206
            uchar *p1 = (uchar *)(&verts[verts.length()-1].r);
 
207
            ol1r = p1[0];  
 
208
            ol1g = p1[1];  
 
209
            ol1b = p1[2];
 
210
            uchar *p2 = (uchar *)(&verts[verts.length()-2].r);  
 
211
            ol2r = p2[0];
 
212
            ol2g = p2[1];
 
213
            ol2b = p2[2];
 
214
        }
 
215
    }
 
216
 
 
217
    if(isceil)
 
218
    {
 
219
        vert(x+size, y,      h, l4, xo+xs, yo);
 
220
        vert(x+size, y+size, h, l3, xo+xs, yo+ys);
 
221
    }
 
222
    else
 
223
    {
 
224
        vert(x+size, y+size, h, l3, xo+xs, yo+ys);
 
225
        vert(x+size, y,      h, l4, xo+xs, yo);
 
226
    }
 
227
 
 
228
    ox = x;
 
229
    nquads++;
 
230
}
 
231
 
 
232
void render_flatdelta(int wtex, int x, int y, int size, float h1, float h4, float h3, float h2, sqr *l1, sqr *l4, sqr *l3, sqr *l2, bool isceil)  // floor/ceil quads on a slope
 
233
{
 
234
    if(showm) { l3 = l1 = &sbright; l4 = l2 = &sdark; }
 
235
 
 
236
    Texture *t = lookupworldtexture(wtex);
 
237
    float xf = TEXTURESCALE/t->xs;
 
238
    float yf = TEXTURESCALE/t->ys;
 
239
    float xs = size*xf;
 
240
    float ys = size*yf;
 
241
    float xo = xf*x;
 
242
    float yo = yf*y;
 
243
 
 
244
    bool first = striptype!=STRIP_DELTA || x!=ox+size || striptex!=wtex || y!=oy; 
 
245
 
 
246
    if(first) 
 
247
    {
 
248
        stripend(verts);
 
249
        firstindex = verts.length();
 
250
        striptex = wtex;
 
251
        oy = y;
 
252
        striptype = STRIP_DELTA;
 
253
        if(isceil)
 
254
        {
 
255
            vert(x, y,      h1, l1, xo, yo);
 
256
            vert(x, y+size, h2, l2, xo, yo+ys);
 
257
        }
 
258
        else
 
259
        {
 
260
            vert(x, y+size, h2, l2, xo, yo+ys);
 
261
            vert(x, y,      h1, l1, xo, yo);
 
262
        }
 
263
    }
 
264
 
 
265
    if(isceil)
 
266
    {
 
267
        vert(x+size, y,      h4, l4, xo+xs, yo);
 
268
        vert(x+size, y+size, h3, l3, xo+xs, yo+ys); 
 
269
    }
 
270
    else
 
271
    {
 
272
        vert(x+size, y+size, h3, l3, xo+xs, yo+ys);
 
273
        vert(x+size, y,      h4, l4, xo+xs, yo);
 
274
    }
 
275
 
 
276
    ox = x;
 
277
    nquads++;
 
278
}
 
279
 
 
280
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
 
281
{
 
282
    stripend(verts);
 
283
 
 
284
    Texture *t = lookupworldtexture(h->ftex);
 
285
    float xf = TEXTURESCALE/t->xs;
 
286
    float yf = TEXTURESCALE/t->ys;
 
287
    vert(x1, y1, h->floor, l1, xf*x1, yf*y1);
 
288
    vert(x2, y2, h->floor, l2, xf*x2, yf*y2);
 
289
    vert(x3, y3, h->floor, l3, xf*x3, yf*y3);
 
290
    addstrip(mergestrips ? GL_TRIANGLES : GL_TRIANGLE_STRIP, h->ftex, verts.length()-3, 3);
 
291
 
 
292
    t = lookupworldtexture(h->ctex);
 
293
    xf = TEXTURESCALE/t->xs;
 
294
    yf = TEXTURESCALE/t->ys;
 
295
 
 
296
    vert(x3, y3, h->ceil, l3, xf*x3, yf*y3);
 
297
    vert(x2, y2, h->ceil, l2, xf*x2, yf*y2);
 
298
    vert(x1, y1, h->ceil, l1, xf*x1, yf*y1);
 
299
    addstrip(mergestrips ? GL_TRIANGLES : GL_TRIANGLE_STRIP, h->ctex, verts.length()-3, 3);
 
300
    nquads++;
 
301
}
 
302
 
 
303
void render_tris(int x, int y, int size, bool topleft,
 
304
                 sqr *h1, sqr *h2, sqr *s, sqr *t, sqr *u, sqr *v)
 
305
{
 
306
    if(topleft)
 
307
    {
 
308
        if(h1) render_2tris(h1, s, x+size, y+size, x, y+size, x, y, u, v, s);
 
309
        if(h2) render_2tris(h2, s, x, y, x+size, y, x+size, y+size, s, t, v);
 
310
    }
 
311
    else
 
312
    {
 
313
        if(h1) render_2tris(h1, s, x, y, x+size, y, x, y+size, s, t, u);
 
314
        if(h2) render_2tris(h2, s, x+size, y, x+size, y+size, x, y+size, t, u, v);
 
315
    }
 
316
}
 
317
 
 
318
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, int dir)   // wall quads
 
319
{
 
320
    if(showm) { l1 = &sbright; l2 = &sdark; }
 
321
 
 
322
    Texture *t = lookupworldtexture(wtex);
 
323
    float xf = TEXTURESCALE/t->xs;
 
324
    float yf = -TEXTURESCALE/t->ys;
 
325
    float xs = size*xf;
 
326
    float xo = xf*(x1==x2 ? min(y1,y2) : min(x1,x2));
 
327
 
 
328
    bool first = striptype!=STRIP_WALL || striptex!=wtex || ox!=x1 || oy!=y1 || ofloor!=floor1 || oceil!=ceil1 || odir!=dir,
 
329
         hf = floor1!=floor2 || ceil1!=ceil2; 
 
330
 
 
331
    if(first)
 
332
    {
 
333
        stripend(verts);
 
334
        firstindex = verts.length();
 
335
        striptex = wtex;
 
336
        striptype = STRIP_WALL;
 
337
 
 
338
        if(!flip)
 
339
        {
 
340
            vert(x1, y1, ceil1,  l1, xo, yf*ceil1);
 
341
            vert(x1, y1, floor1, l1, xo, yf*floor1);
 
342
        }
 
343
        else
 
344
        {
 
345
            vert(x1, y1, floor1, l1, xo, yf*floor1);
 
346
            vert(x1, y1, ceil1,  l1, xo, yf*ceil1);
 
347
        }
 
348
        ol1r = l1->r;
 
349
        ol1g = l1->g;
 
350
        ol1b = l1->b;
 
351
    }
 
352
    else        // continue strip
 
353
    {
 
354
        int lighterr = lighterror*2;
 
355
        if((!hf && !ohf) 
 
356
        && ((abs(ol1r-l2->r)<lighterr && abs(ol1g-l2->g)<lighterr && abs(ol1b-l2->b)<lighterr) || !wtex))       // skip vertices if light values are close enough
 
357
        {
 
358
            verts.setsizenodelete(verts.length()-2);
 
359
            nquads--;
 
360
        }
 
361
        else
 
362
        {
 
363
            uchar *p1 = (uchar *)(&verts[verts.length()-1].r);
 
364
            ol1r = p1[0];
 
365
            ol1g = p1[1];
 
366
            ol1b = p1[2];
 
367
        }
 
368
    }
 
369
 
 
370
    if(!flip)
 
371
    {
 
372
        vert(x2, y2, ceil2,  l2, xo+xs, yf*ceil2);
 
373
        vert(x2, y2, floor2, l2, xo+xs, yf*floor2);
 
374
    }
 
375
    else
 
376
    {
 
377
        vert(x2, y2, floor2, l2, xo+xs, yf*floor2);
 
378
        vert(x2, y2, ceil2,  l2, xo+xs, yf*ceil2);
 
379
    }
 
380
 
 
381
    ox = x2;
 
382
    oy = y2;
 
383
    ofloor = floor2;
 
384
    oceil = ceil2;
 
385
    odir = dir;
 
386
    ohf = hf;
 
387
    nquads++;
 
388
}
 
389
 
 
390
void resetcubes()
 
391
{
 
392
    verts.setsizenodelete(0);
 
393
 
 
394
    striptype = 0;
 
395
    nquads = 0;
 
396
 
 
397
    sbright.r = sbright.g = sbright.b = 255;
 
398
    sdark.r = sdark.g = sdark.b = 0;
 
399
 
 
400
    resetwater();
 
401
}   
 
402
 
 
403
struct shadowvertex { float u, v, x, y, z; };
 
404
vector<shadowvertex> shadowverts;
 
405
 
 
406
static void resetshadowverts()
 
407
{
 
408
    shadowverts.setsizenodelete(0);
 
409
 
 
410
    striptype = 0;
 
411
}
 
412
 
 
413
static void rendershadowstrips()
 
414
{
 
415
    glEnableClientState(GL_VERTEX_ARRAY);
 
416
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 
417
 
 
418
    shadowvertex *buf = shadowverts.getbuf();
 
419
    glVertexPointer(3, GL_FLOAT, sizeof(shadowvertex), &buf->x);
 
420
    glTexCoordPointer(2, GL_FLOAT, sizeof(shadowvertex), &buf->u);
 
421
 
 
422
    loopj(renderedtexs)
 
423
    {
 
424
        stripbatch &sb = stripbatches[j];
 
425
        RENDERSTRIPS(sb.tris, GL_TRIANGLES);
 
426
        RENDERSTRIPS(sb.tristrips, GL_TRIANGLE_STRIP);
 
427
        RENDERSTRIPS(sb.quads, GL_QUADS);
 
428
    }
 
429
    renderedtexs = 0;
 
430
 
 
431
    glDisableClientState(GL_VERTEX_ARRAY);
 
432
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
 
433
 
 
434
    xtraverts += shadowverts.length();
 
435
}
 
436
 
 
437
#define shadowvert(v1, v2, v3) { \
 
438
    shadowvertex &v = shadowverts.add(); \
 
439
    v.x = (float)(v1); v.y = (float)(v2); v.z = (float)(v3); \
 
440
}
 
441
 
 
442
void rendershadow_tri(sqr *h, int x1, int y1, int x2, int y2, int x3, int y3)   // floor tris on a corner cube
 
443
{
 
444
    stripend(shadowverts);
 
445
 
 
446
    shadowvert(x1, y1, h->floor);
 
447
    shadowvert(x2, y2, h->floor);
 
448
    shadowvert(x3, y3, h->floor);
 
449
    addstrip(mergestrips ? GL_TRIANGLES : GL_TRIANGLE_STRIP, DEFAULT_FLOOR, shadowverts.length()-3, 3);
 
450
}
 
451
 
 
452
void rendershadow_tris(int x, int y, bool topleft, sqr *h1, sqr *h2)
 
453
{
 
454
    if(topleft)
 
455
    {
 
456
        if(h1) rendershadow_tri(h1, x+1, y+1, x, y+1, x, y);
 
457
        if(h2) rendershadow_tri(h2, x, y, x+1, y, x+1, y+1);
 
458
    }
 
459
    else
 
460
    {
 
461
        if(h1) rendershadow_tri(h1, x, y, x+1, y, x, y+1);
 
462
        if(h2) rendershadow_tri(h2, x+1, y, x+1, y+1, x, y+1);
 
463
    }
 
464
}
 
465
 
 
466
static void rendershadow_flat(int x, int y, int h) // floor quads
 
467
{
 
468
    bool first = striptype!=STRIP_FLOOR || x!=ox+1 || h!=oh || y!=oy;
 
469
 
 
470
    if(first)       // start strip here
 
471
    {
 
472
        stripend(shadowverts);
 
473
        firstindex = shadowverts.length();
 
474
        striptex = DEFAULT_FLOOR;
 
475
        oh = h;
 
476
        oy = y;
 
477
        striptype = STRIP_FLOOR;
 
478
        shadowvert(x, y+1, h);
 
479
        shadowvert(x, y,   h);
 
480
    }
 
481
    else        // continue strip
 
482
    {
 
483
        shadowverts.setsizenodelete(shadowverts.length()-2);
 
484
    }
 
485
 
 
486
    shadowvert(x+1, y+1, h);
 
487
    shadowvert(x+1, y,   h);
 
488
 
 
489
    ox = x;
 
490
}
 
491
 
 
492
static void rendershadow_flatdelta(int x, int y, float h1, float h4, float h3, float h2)  // floor quads on a slope
 
493
{
 
494
    bool first = striptype!=STRIP_DELTA || x!=ox+1 || y!=oy;
 
495
 
 
496
    if(first)
 
497
    {
 
498
        stripend(shadowverts);
 
499
        firstindex = shadowverts.length();
 
500
        striptex = DEFAULT_FLOOR;
 
501
        oy = y;
 
502
        striptype = STRIP_DELTA;
 
503
        shadowvert(x, y+1, h2);
 
504
        shadowvert(x, y,   h1);
 
505
    }
 
506
 
 
507
    shadowvert(x+1, y+1, h3);
 
508
    shadowvert(x+1, y,   h4);
 
509
 
 
510
    ox = x;
 
511
}
 
512
 
 
513
void rendershadow(int x, int y, int xs, int ys, const vec &texgenS, const vec &texgenT)
 
514
{
 
515
    x = max(x, 1);
 
516
    y = max(y, 1);
 
517
    xs = min(xs, ssize-1);
 
518
    ys = min(ys, ssize-1);
 
519
 
 
520
    resetshadowverts();
 
521
 
 
522
    #define df(x) s->floor-(x->vdelta/4.0f)
 
523
 
 
524
    sqr *w = wmip[0];
 
525
    for(int yy = y; yy<ys; yy++) for(int xx = x; xx<xs; xx++)
 
526
    {
 
527
        sqr *s = SW(w,xx,yy);
 
528
        if(s->type==SPACE || s->type==CHF)
 
529
        {
 
530
            rendershadow_flat(xx, yy, s->floor);
 
531
        }
 
532
        else if(s->type==FHF)
 
533
        {
 
534
            sqr *t = SW(s,1,0), *u = SW(s,1,1), *v = SW(s,0,1);
 
535
            rendershadow_flatdelta(xx, yy, df(s), df(t), df(u), df(v));
 
536
        }
 
537
        else if(s->type==CORNER)
 
538
        {
 
539
            sqr *t = SW(s,1,0), *v = SW(s,0,1), *w = SW(s,0,-1), *z = SW(s,-1,0);
 
540
            bool topleft = true;
 
541
            sqr *h1 = NULL, *h2 = NULL;
 
542
            if(SOLID(z))
 
543
            {
 
544
                if(SOLID(w))      { h2 = s; topleft = false; }
 
545
                else if(SOLID(v)) { h2 = s; }
 
546
            }
 
547
            else if(SOLID(t))
 
548
            {
 
549
                if(SOLID(w))      { h1 = s; }
 
550
                else if(SOLID(v)) { h1 = s; topleft = false; }
 
551
            }
 
552
            else
 
553
            {
 
554
                bool wv = w->ceil-w->floor < v->ceil-v->floor;
 
555
                if(z->ceil-z->floor < t->ceil-t->floor)
 
556
                {
 
557
                    if(wv) { h1 = s; h2 = v; topleft = false; }
 
558
                    else   { h1 = s; h2 = w; }
 
559
                }
 
560
                else
 
561
                {
 
562
                    if(wv) { h2 = s; h1 = v; }
 
563
                    else   { h2 = s; h1 = w; topleft = false; }
 
564
                }
 
565
            }
 
566
            rendershadow_tris(xx, yy, topleft, h1, h2);
 
567
        }
 
568
    }
 
569
 
 
570
    stripend(shadowverts);
 
571
 
 
572
    for(shadowvertex *v = shadowverts.getbuf(), *end = &v[shadowverts.length()]; v < end; v++)
 
573
    {
 
574
        float vx = v->x, vy = v->y;
 
575
        v->u = vx*texgenS.x + vy*texgenS.y + texgenS.z;
 
576
        v->v = vx*texgenT.x + vy*texgenT.y + texgenT.z;
 
577
    }
 
578
 
 
579
    rendershadowstrips();
 
580
}
 
581