4
int wx1, wy1, wx2, wy2;
5
float wsx1, wsy1, wsx2, wsy2;
7
VARP(watersubdiv, 1, 4, 64);
8
VARF(waterlevel, -128, -128, 127, if(!noteditmode()) hdr.waterlevel = waterlevel);
10
void setwatercolor(const char *r, const char *g, const char *b, const char *a)
14
hdr.watercolor[0] = ATOI(r);
15
hdr.watercolor[1] = ATOI(g);
16
hdr.watercolor[2] = ATOI(b);
17
hdr.watercolor[3] = a[0] ? ATOI(a) : 178;
21
hdr.watercolor[0] = 20;
22
hdr.watercolor[1] = 25;
23
hdr.watercolor[2] = 20;
24
hdr.watercolor[3] = 178;
28
COMMANDN(watercolour, setwatercolor, ARG_4STR);
30
// renders water for bounding rect area that contains water... simple but very inefficient
32
#define VERTW(vertw, body) \
33
inline void vertw(float v1, float v2, float v3, float t) \
35
float angle = v1*v2*0.1f + t; \
36
float h = 0.3f*sinf(angle); \
38
glVertex3f(v1, v2, v3+h); \
40
#define VERTWT(vertwt, body) VERTW(vertwt, { float v = cosf(angle); float duv = 0.2f*v; body; })
43
float v = cosf(angle);
44
glColor4ub(hdr.watercolor[0], hdr.watercolor[1], hdr.watercolor[2], (uchar)(hdr.watercolor[3] + (max(v, 0.0f) - 0.5f)*51.0f));
47
glTexCoord3f(v1+duv, v2+duv, v3+h);
50
glColor4f(1, 1, 1, 0.15f + max(v, 0.0f)*0.15f);
51
glTexCoord3f(v1+duv, v2+duv, v3+h);
54
glColor4f(1, 1, 1, 0.15f + max(v, 0.0f)*0.15f);
55
glMultiTexCoord3f_(GL_TEXTURE0_ARB, v1-duv, v2+duv, v3+h);
56
glMultiTexCoord3f_(GL_TEXTURE1_ARB, v1+duv, v2+duv, v3+h);
61
#define renderwaterstrips(vertw, hf, t) \
62
for(int x = wx1; x<wx2; x += watersubdiv) \
64
glBegin(GL_TRIANGLE_STRIP); \
65
vertw(x, wy1, hf, t); \
66
vertw(x+watersubdiv, wy1, hf, t); \
67
for(int y = wy1; y<wy2; y += watersubdiv) \
69
vertw(x, y+watersubdiv, hf, t); \
70
vertw(x+watersubdiv, y+watersubdiv, hf, t); \
73
nquads += (wy2-wy1-1)/watersubdiv; \
76
void setprojtexmatrix()
78
glmatrixf projtex = mvpmatrix;
81
glMatrixMode(GL_TEXTURE);
82
glLoadMatrixf(projtex.v);
85
void setupmultitexrefract(GLuint reflecttex, GLuint refracttex)
87
setuptmu(0, "K , T @ Ka");
89
colortmu(0, hdr.watercolor[0]/255.0f, hdr.watercolor[1]/255.0f, hdr.watercolor[2]/255.0f, hdr.watercolor[3]/255.0f);
91
glBindTexture(GL_TEXTURE_2D, refracttex);
94
glActiveTexture_(GL_TEXTURE1_ARB);
95
glEnable(GL_TEXTURE_2D);
97
setuptmu(1, "P , T @ C~a");
99
glBindTexture(GL_TEXTURE_2D, reflecttex);
102
glActiveTexture_(GL_TEXTURE0_ARB);
105
void setupmultitexreflect(GLuint reflecttex)
107
setuptmu(0, "T , K @ Ca", "Ka * P~a");
109
float a = hdr.watercolor[3]/255.0f;
110
colortmu(0, hdr.watercolor[0]/255.0f*a, hdr.watercolor[1]/255.0f*a, hdr.watercolor[2]/255.0f*a, 1.0f-a);
112
glBindTexture(GL_TEXTURE_2D, reflecttex);
116
void cleanupmultitex(GLuint reflecttex, GLuint refracttex)
123
glActiveTexture_(GL_TEXTURE1_ARB);
124
glDisable(GL_TEXTURE_2D);
127
glActiveTexture_(GL_TEXTURE0_ARB);
129
glMatrixMode(GL_MODELVIEW);
132
VARP(mtwater, 0, 1, 1);
134
int renderwater(float hf, GLuint reflecttex, GLuint refracttex)
136
if(wx1<0) return nquads;
138
wx1 -= wx1%watersubdiv;
139
wy1 -= wy1%watersubdiv;
141
float t = lastmillis/300.0f;
143
if(mtwater && maxtmus>=2 && reflecttex)
147
setupmultitexrefract(reflecttex, refracttex);
148
renderwaterstrips(vertwmtc, hf, t);
152
setupmultitexreflect(reflecttex);
153
glDepthMask(GL_FALSE);
155
glBlendFunc(GL_ONE, GL_SRC_ALPHA);
156
renderwaterstrips(vertwtc, hf, t);
158
glDepthMask(GL_TRUE);
160
cleanupmultitex(reflecttex, refracttex);
167
glDisable(GL_TEXTURE_2D);
170
glDepthMask(GL_FALSE);
171
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
177
glColor4ubv(hdr.watercolor);
178
renderwaterstrips(vertw, hf, t);
180
glEnable(GL_TEXTURE_2D);
185
glBindTexture(GL_TEXTURE_2D, refracttex ? refracttex : reflecttex);
191
renderwaterstrips(vertwt, hf, t);
194
glBindTexture(GL_TEXTURE_2D, reflecttex);
195
glDepthMask(GL_TRUE);
197
if(reflecttex) { renderwaterstrips(vertwtc, hf, t); }
198
else { renderwaterstrips(vertwc, hf, t); }
203
glMatrixMode(GL_MODELVIEW);
205
else glEnable(GL_TEXTURE_2D);
208
if(!refracttex) glDepthMask(GL_TRUE);
213
void addwaterquad(int x, int y, int size) // update bounding rect that contains water
233
void calcwaterscissor()
236
float sx1 = 1, sy1 = 1, sx2 = -1, sy2 = -1;
240
mvpmatrix.transform(vec(i&1 ? wx2 : wx1, i&2 ? wy2 : wy1, hdr.waterlevel-0.3f), p);
243
float x = p.x / p.w, y = p.y / p.w;
250
if(sx1 >= sx2 || sy1 >= sy2)
257
const vec4 &p = v[i];
258
if(p.z >= 0) continue;
261
const vec4 &o = v[i^(1<<j)];
262
if(o.z <= 0) continue;
263
float t = p.z/(p.z - o.z),
264
w = p.w + t*(o.w - p.w),
265
x = (p.x + t*(o.x - p.x))/w,
266
y = (p.y + t*(o.y - p.y))/w;
273
wsx1 = max(sx1, -1.0f);
274
wsy1 = max(sy1, -1.0f);
275
wsx2 = min(sx2, 1.0f);
276
wsy2 = min(sy2, 1.0f);
281
if(!reflecting) wx1 = -1;