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

« back to all changes in this revision

Viewing changes to source/src/water.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
#include "pch.h"
 
2
#include "cube.h"
 
3
 
 
4
int wx1, wy1, wx2, wy2;
 
5
float wsx1, wsy1, wsx2, wsy2;
 
6
 
 
7
VARP(watersubdiv, 1, 4, 64);
 
8
VARF(waterlevel, -128, -128, 127, if(!noteditmode()) hdr.waterlevel = waterlevel);
 
9
 
 
10
void setwatercolor(const char *r, const char *g, const char *b, const char *a)
 
11
{
 
12
    if(r[0])
 
13
    {
 
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;
 
18
    }
 
19
    else
 
20
    {
 
21
        hdr.watercolor[0] = 20;
 
22
        hdr.watercolor[1] = 25;
 
23
        hdr.watercolor[2] = 20;
 
24
        hdr.watercolor[3] = 178;
 
25
    }
 
26
}
 
27
 
 
28
COMMANDN(watercolour, setwatercolor, ARG_4STR);
 
29
 
 
30
// renders water for bounding rect area that contains water... simple but very inefficient
 
31
 
 
32
#define VERTW(vertw, body) \
 
33
    inline void vertw(float v1, float v2, float v3, float t) \
 
34
    { \
 
35
        float angle = v1*v2*0.1f + t; \
 
36
        float h = 0.3f*sinf(angle); \
 
37
        body; \
 
38
        glVertex3f(v1, v2, v3+h); \
 
39
    }
 
40
#define VERTWT(vertwt, body) VERTW(vertwt, { float v = cosf(angle); float duv = 0.2f*v; body; })
 
41
VERTW(vertw, {})
 
42
VERTW(vertwc, {
 
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));
 
45
})
 
46
VERTWT(vertwt, {
 
47
    glTexCoord3f(v1+duv, v2+duv, v3+h);
 
48
})
 
49
VERTWT(vertwtc, {
 
50
    glColor4f(1, 1, 1, 0.15f + max(v, 0.0f)*0.15f);
 
51
    glTexCoord3f(v1+duv, v2+duv, v3+h);
 
52
})
 
53
VERTWT(vertwmtc, {
 
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);
 
57
})
 
58
 
 
59
extern int nquads;
 
60
 
 
61
#define renderwaterstrips(vertw, hf, t) \
 
62
    for(int x = wx1; x<wx2; x += watersubdiv) \
 
63
    { \
 
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) \
 
68
        { \
 
69
            vertw(x,             y+watersubdiv, hf, t); \
 
70
            vertw(x+watersubdiv, y+watersubdiv, hf, t); \
 
71
        } \
 
72
        glEnd(); \
 
73
        nquads += (wy2-wy1-1)/watersubdiv; \
 
74
    }
 
75
 
 
76
void setprojtexmatrix()
 
77
{
 
78
    glmatrixf projtex = mvpmatrix;
 
79
    projtex.projective();
 
80
 
 
81
    glMatrixMode(GL_TEXTURE);
 
82
    glLoadMatrixf(projtex.v);
 
83
}
 
84
 
 
85
void setupmultitexrefract(GLuint reflecttex, GLuint refracttex)
 
86
{
 
87
    setuptmu(0, "K , T @ Ka");
 
88
    
 
89
    colortmu(0, hdr.watercolor[0]/255.0f, hdr.watercolor[1]/255.0f, hdr.watercolor[2]/255.0f, hdr.watercolor[3]/255.0f);
 
90
 
 
91
    glBindTexture(GL_TEXTURE_2D, refracttex);
 
92
    setprojtexmatrix();
 
93
 
 
94
    glActiveTexture_(GL_TEXTURE1_ARB);
 
95
    glEnable(GL_TEXTURE_2D);
 
96
    
 
97
    setuptmu(1, "P , T @ C~a");
 
98
   
 
99
    glBindTexture(GL_TEXTURE_2D, reflecttex);
 
100
    setprojtexmatrix();
 
101
 
 
102
    glActiveTexture_(GL_TEXTURE0_ARB);
 
103
}
 
104
 
 
105
void setupmultitexreflect(GLuint reflecttex)
 
106
{
 
107
    setuptmu(0, "T , K @ Ca", "Ka * P~a");
 
108
    
 
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);
 
111
 
 
112
    glBindTexture(GL_TEXTURE_2D, reflecttex);
 
113
    setprojtexmatrix();
 
114
}
 
115
 
 
116
void cleanupmultitex(GLuint reflecttex, GLuint refracttex)
 
117
{
 
118
    resettmu(0);
 
119
    glLoadIdentity();
 
120
   
 
121
    if(refracttex)
 
122
    { 
 
123
        glActiveTexture_(GL_TEXTURE1_ARB);
 
124
        glDisable(GL_TEXTURE_2D);
 
125
        resettmu(1);
 
126
        glLoadIdentity();
 
127
        glActiveTexture_(GL_TEXTURE0_ARB);
 
128
    }
 
129
    glMatrixMode(GL_MODELVIEW);
 
130
}
 
131
 
 
132
VARP(mtwater, 0, 1, 1);
 
133
 
 
134
int renderwater(float hf, GLuint reflecttex, GLuint refracttex)
 
135
{
 
136
    if(wx1<0) return nquads;
 
137
    
 
138
    wx1 -= wx1%watersubdiv;
 
139
    wy1 -= wy1%watersubdiv;
 
140
 
 
141
    float t = lastmillis/300.0f;
 
142
 
 
143
    if(mtwater && maxtmus>=2 && reflecttex)
 
144
    {
 
145
        if(refracttex)
 
146
        {
 
147
            setupmultitexrefract(reflecttex, refracttex);        
 
148
            renderwaterstrips(vertwmtc, hf, t);
 
149
        }
 
150
        else
 
151
        {
 
152
            setupmultitexreflect(reflecttex);
 
153
            glDepthMask(GL_FALSE);
 
154
            glEnable(GL_BLEND);
 
155
            glBlendFunc(GL_ONE, GL_SRC_ALPHA);
 
156
            renderwaterstrips(vertwtc, hf, t);
 
157
            glDisable(GL_BLEND);
 
158
            glDepthMask(GL_TRUE);
 
159
        }
 
160
        cleanupmultitex(reflecttex, refracttex);
 
161
        
 
162
        return nquads;
 
163
    }
 
164
 
 
165
    if(!refracttex) 
 
166
    {
 
167
        glDisable(GL_TEXTURE_2D);
 
168
        glEnable(GL_BLEND);
 
169
    }
 
170
    glDepthMask(GL_FALSE);
 
171
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
172
 
 
173
    if(reflecttex)
 
174
    {
 
175
        if(!refracttex)
 
176
        {
 
177
            glColor4ubv(hdr.watercolor);
 
178
            renderwaterstrips(vertw, hf, t);
 
179
        
 
180
            glEnable(GL_TEXTURE_2D);
 
181
        }
 
182
 
 
183
        setprojtexmatrix();
 
184
 
 
185
        glBindTexture(GL_TEXTURE_2D, refracttex ? refracttex : reflecttex);
 
186
    }
 
187
 
 
188
    if(refracttex) 
 
189
    {
 
190
        glColor3f(1, 1, 1);
 
191
        renderwaterstrips(vertwt, hf, t);
 
192
        glEnable(GL_BLEND);
 
193
 
 
194
        glBindTexture(GL_TEXTURE_2D, reflecttex);
 
195
        glDepthMask(GL_TRUE);
 
196
    }
 
197
    if(reflecttex) { renderwaterstrips(vertwtc, hf, t); }
 
198
    else { renderwaterstrips(vertwc, hf, t); }
 
199
 
 
200
    if(reflecttex)
 
201
    {
 
202
        glLoadIdentity();
 
203
        glMatrixMode(GL_MODELVIEW);
 
204
    }
 
205
    else glEnable(GL_TEXTURE_2D);
 
206
 
 
207
    glDisable(GL_BLEND);
 
208
    if(!refracttex) glDepthMask(GL_TRUE);
 
209
   
 
210
    return nquads;
 
211
}
 
212
 
 
213
void addwaterquad(int x, int y, int size)       // update bounding rect that contains water
 
214
{
 
215
    int x2 = x+size;
 
216
    int y2 = y+size;
 
217
    if(wx1<0)
 
218
    {
 
219
        wx1 = x;
 
220
        wy1 = y;
 
221
        wx2 = x2;
 
222
        wy2 = y2;
 
223
    }
 
224
    else
 
225
    {
 
226
        if(x<wx1) wx1 = x;
 
227
        if(y<wy1) wy1 = y;
 
228
        if(x2>wx2) wx2 = x2;
 
229
        if(y2>wy2) wy2 = y2;
 
230
    }
 
231
}
 
232
 
 
233
void calcwaterscissor()
 
234
{
 
235
    vec4 v[4];
 
236
    float sx1 = 1, sy1 = 1, sx2 = -1, sy2 = -1;
 
237
    loopi(4)
 
238
    {
 
239
        vec4 &p = v[i];
 
240
        mvpmatrix.transform(vec(i&1 ? wx2 : wx1, i&2 ? wy2 : wy1, hdr.waterlevel-0.3f), p);
 
241
        if(p.z >= 0)
 
242
        {
 
243
            float x = p.x / p.w, y = p.y / p.w;
 
244
            sx1 = min(sx1, x);
 
245
            sy1 = min(sy1, y);
 
246
            sx2 = max(sx2, x);
 
247
            sy2 = max(sy2, y);
 
248
        }
 
249
    }
 
250
    if(sx1 >= sx2 || sy1 >= sy2) 
 
251
    {
 
252
        sx1 = sy1 = -1;
 
253
        sx2 = sy2 = 1;
 
254
    }
 
255
    else loopi(4)
 
256
    {
 
257
        const vec4 &p = v[i];
 
258
        if(p.z >= 0) continue;
 
259
        loopj(2)
 
260
        {
 
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;
 
267
            sx1 = min(sx1, x);
 
268
            sy1 = min(sy1, y);
 
269
            sx2 = max(sx2, x);
 
270
            sy2 = max(sy2, y);
 
271
        }
 
272
    }
 
273
    wsx1 = max(sx1, -1.0f);
 
274
    wsy1 = max(sy1, -1.0f);
 
275
    wsx2 = min(sx2, 1.0f);
 
276
    wsy2 = min(sy2, 1.0f);
 
277
}
 
278
 
 
279
void resetwater()
 
280
{
 
281
    if(!reflecting) wx1 = -1;
 
282
}
 
283