~helene-verhaeghe27/cairo-dock-core/bugfix

« back to all changes in this revision

Viewing changes to src/water.c

  • Committer: fabounet
  • Date: 2008-11-14 01:51:17 UTC
  • Revision ID: vcs-imports@canonical.com-20081114015117-854dznkw3lfva52x
The commit of the year \!

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
#include <math.h>
 
3
#include <stdio.h>
 
4
#include <stdlib.h>
 
5
#include <jpeglib.h>
 
6
#include <jerror.h>
 
7
#include "noise.h"
 
8
#include <gtk/gtkgl.h>
 
9
#include <GL/gl.h>
 
10
 
 
11
#define         RESOLUTION 64
 
12
 
 
13
static int      wire_frame = 0;
 
14
static int      normals = 0;
 
15
static int      xold = 0;
 
16
static int      yold = 0;
 
17
static float    rotate_x = 30;
 
18
static float    rotate_y = 15;
 
19
static float    translate_z = 4;
 
20
static float    surface[6 * RESOLUTION * (RESOLUTION + 1)];
 
21
static float    normal[6 * RESOLUTION * (RESOLUTION + 1)];
 
22
static int      texture = 0;
 
23
 
 
24
void draw_water_static (void)
 
25
{
 
26
        glBindTexture(GL_TEXTURE_2D, texture);
 
27
}
 
28
static float    z (const float x, const float y, const float t)
 
29
{
 
30
  const float x2 = x - 3;
 
31
  const float y2 = y + 1;
 
32
  const float xx = x2 * x2;
 
33
  const float yy = y2 * y2;
 
34
  return ((2 * sinf (20 * sqrtf (xx + yy) - 4 * t) +
 
35
           Noise (10 * x, 10 * y, t, 0)) / 200);
 
36
}
 
37
 
 
38
 
 
39
/*
 
40
** Function to load a Jpeg file.
 
41
*/
 
42
int             load_texture (const char * filename,
 
43
                              unsigned char * dest,
 
44
                              const int format,
 
45
                              const unsigned int size)
 
46
{
 
47
  FILE *fd;
 
48
  struct jpeg_decompress_struct cinfo;
 
49
  struct jpeg_error_mgr jerr;
 
50
  unsigned char * line;
 
51
 
 
52
  cinfo.err = jpeg_std_error (&jerr);
 
53
  jpeg_create_decompress (&cinfo);
 
54
 
 
55
  if (0 == (fd = fopen(filename, "rb")))
 
56
    return 1;
 
57
 
 
58
  jpeg_stdio_src (&cinfo, fd);
 
59
  jpeg_read_header (&cinfo, TRUE);
 
60
  if ((cinfo.image_width != size) || (cinfo.image_height != size))
 
61
    return 1;
 
62
 
 
63
  if (GL_RGB == format)
 
64
    {
 
65
      if (cinfo.out_color_space == JCS_GRAYSCALE)
 
66
        return 1;
 
67
    }
 
68
  else
 
69
    if (cinfo.out_color_space != JCS_GRAYSCALE)
 
70
      return 1;
 
71
 
 
72
  jpeg_start_decompress (&cinfo);
 
73
 
 
74
  while (cinfo.output_scanline < cinfo.output_height)
 
75
    {
 
76
      line = dest +
 
77
        (GL_RGB == format ? 3 * size : size) * cinfo.output_scanline;
 
78
      jpeg_read_scanlines (&cinfo, &line, 1);
 
79
    }
 
80
  jpeg_finish_decompress (&cinfo);
 
81
  jpeg_destroy_decompress (&cinfo);
 
82
  return 0;
 
83
}
 
84
 
 
85
/*
 
86
** Function called to update rendering
 
87
*/
 
88
void            DisplayFunc (void)
 
89
{
 
90
  const float t = 20. / 1000.;
 
91
  const float delta = 2. / RESOLUTION;
 
92
  const unsigned int length = 2 * (RESOLUTION + 1);
 
93
  const float xn = (RESOLUTION + 1) * delta + 1;
 
94
  unsigned int i;
 
95
  unsigned int j;
 
96
  float x;
 
97
  float y;
 
98
  unsigned int indice;
 
99
  unsigned int preindice;
 
100
 
 
101
  /* Yes, I know, this is quite ugly... */
 
102
  float v1x;
 
103
  float v1y;
 
104
  float v1z;
 
105
 
 
106
  float v2x;
 
107
  float v2y;
 
108
  float v2z;
 
109
 
 
110
  float v3x;
 
111
  float v3y;
 
112
  float v3z;
 
113
 
 
114
  float vax;
 
115
  float vay;
 
116
  float vaz;
 
117
 
 
118
  float vbx;
 
119
  float vby;
 
120
  float vbz;
 
121
 
 
122
  float nx;
 
123
  float ny;
 
124
  float nz;
 
125
 
 
126
  float l;
 
127
 
 
128
 
 
129
  glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
130
 
 
131
  glLoadIdentity ();
 
132
  glTranslatef (0, 0, -translate_z);
 
133
  glRotatef (rotate_y, 1, 0, 0);
 
134
  glRotatef (rotate_x, 0, 1, 0);
 
135
 
 
136
  /* Vertices */
 
137
  for (j = 0; j < RESOLUTION; j++)
 
138
    {
 
139
      y = (j + 1) * delta - 1;
 
140
      for (i = 0; i <= RESOLUTION; i++)
 
141
        {
 
142
          indice = 6 * (i + j * (RESOLUTION + 1));
 
143
 
 
144
          x = i * delta - 1;
 
145
          surface[indice + 3] = x;
 
146
          surface[indice + 4] = z (x, y, t);
 
147
          surface[indice + 5] = y;
 
148
          if (j != 0)
 
149
            {
 
150
              /* Values were computed during the previous loop */
 
151
              preindice = 6 * (i + (j - 1) * (RESOLUTION + 1));
 
152
              surface[indice] = surface[preindice + 3];
 
153
              surface[indice + 1] = surface[preindice + 4];
 
154
              surface[indice + 2] = surface[preindice + 5];
 
155
            }
 
156
          else
 
157
            {
 
158
              surface[indice] = x;
 
159
              surface[indice + 1] = z (x, -1, t);
 
160
              surface[indice + 2] = -1;
 
161
            }
 
162
        }
 
163
    }
 
164
 
 
165
  /* Normals */
 
166
  for (j = 0; j < RESOLUTION; j++)
 
167
    for (i = 0; i <= RESOLUTION; i++)
 
168
      {
 
169
        indice = 6 * (i + j * (RESOLUTION + 1));
 
170
 
 
171
        v1x = surface[indice + 3];
 
172
        v1y = surface[indice + 4];
 
173
        v1z = surface[indice + 5];
 
174
 
 
175
        v2x = v1x;
 
176
        v2y = surface[indice + 1];
 
177
        v2z = surface[indice + 2];
 
178
 
 
179
        if (i < RESOLUTION)
 
180
          {
 
181
            v3x = surface[indice + 9];
 
182
            v3y = surface[indice + 10];
 
183
            v3z = v1z;
 
184
          }
 
185
        else
 
186
          {
 
187
            v3x = xn;
 
188
            v3y = z (xn, v1z, t);
 
189
            v3z = v1z;
 
190
          }
 
191
 
 
192
        vax =  v2x - v1x;
 
193
        vay =  v2y - v1y;
 
194
        vaz =  v2z - v1z;
 
195
 
 
196
        vbx = v3x - v1x;
 
197
        vby = v3y - v1y;
 
198
        vbz = v3z - v1z;
 
199
 
 
200
        nx = (vby * vaz) - (vbz * vay);
 
201
        ny = (vbz * vax) - (vbx * vaz);
 
202
        nz = (vbx * vay) - (vby * vax);
 
203
 
 
204
        l = sqrtf (nx * nx + ny * ny + nz * nz);
 
205
        if (l != 0)
 
206
          {
 
207
            l = 1 / l;
 
208
            normal[indice + 3] = nx * l;
 
209
            normal[indice + 4] = ny * l;
 
210
            normal[indice + 5] = nz * l;
 
211
          }
 
212
        else
 
213
          {
 
214
            normal[indice + 3] = 0;
 
215
            normal[indice + 4] = 1;
 
216
            normal[indice + 5] = 0;
 
217
          }
 
218
 
 
219
 
 
220
        if (j != 0)
 
221
          {
 
222
            /* Values were computed during the previous loop */
 
223
            preindice = 6 * (i + (j - 1) * (RESOLUTION + 1));
 
224
            normal[indice] = normal[preindice + 3];
 
225
            normal[indice + 1] = normal[preindice + 4];
 
226
            normal[indice + 2] = normal[preindice + 5];
 
227
          }
 
228
        else
 
229
          {
 
230
/*          v1x = v1x; */
 
231
            v1y = z (v1x, (j - 1) * delta - 1, t);
 
232
            v1z = (j - 1) * delta - 1;
 
233
 
 
234
/*          v3x = v3x; */
 
235
            v3y = z (v3x, v2z, t);
 
236
            v3z = v2z;
 
237
 
 
238
            vax = v1x - v2x;
 
239
            vay = v1y - v2y;
 
240
            vaz = v1z - v2z;
 
241
 
 
242
            vbx = v3x - v2x;
 
243
            vby = v3y - v2y;
 
244
            vbz = v3z - v2z;
 
245
 
 
246
            nx = (vby * vaz) - (vbz * vay);
 
247
            ny = (vbz * vax) - (vbx * vaz);
 
248
            nz = (vbx * vay) - (vby * vax);
 
249
 
 
250
            l = sqrtf (nx * nx + ny * ny + nz * nz);
 
251
            if (l != 0)
 
252
              {
 
253
                l = 1 / l;
 
254
                normal[indice] = nx * l;
 
255
                normal[indice + 1] = ny * l;
 
256
                normal[indice + 2] = nz * l;
 
257
              }
 
258
            else
 
259
              {
 
260
                normal[indice] = 0;
 
261
                normal[indice + 1] = 1;
 
262
                normal[indice + 2] = 0;
 
263
              }
 
264
          }
 
265
      }
 
266
 
 
267
  /* The ground */
 
268
  glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
 
269
  glDisable (GL_TEXTURE_2D);
 
270
  glColor3f (1, 0.9, 0.7);
 
271
  glBegin (GL_TRIANGLE_FAN);
 
272
  glVertex3f (-1, 0, -1);
 
273
  glVertex3f (-1, 0,  1);
 
274
  glVertex3f ( 1, 0,  1);
 
275
  glVertex3f ( 1, 0, -1);
 
276
  glEnd ();
 
277
 
 
278
  glTranslatef (0, 0.2, 0);
 
279
 
 
280
  /* Render wireframe? */
 
281
  if (wire_frame != 0)
 
282
    glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
 
283
 
 
284
  /* The water */
 
285
  glEnable (GL_TEXTURE_2D);
 
286
  glColor3f (1, 1, 1);
 
287
  glEnableClientState (GL_NORMAL_ARRAY);
 
288
  glEnableClientState (GL_VERTEX_ARRAY);
 
289
  glNormalPointer (GL_FLOAT, 0, normal);
 
290
  glVertexPointer (3, GL_FLOAT, 0, surface);
 
291
  for (i = 0; i < RESOLUTION; i++)
 
292
    glDrawArrays (GL_TRIANGLE_STRIP, i * length, length);
 
293
 
 
294
  /* Draw normals? */
 
295
  if (normals != 0)
 
296
    {
 
297
      glDisable (GL_TEXTURE_2D);
 
298
      glColor3f (1, 0, 0);
 
299
      glBegin (GL_LINES);
 
300
      for (j = 0; j < RESOLUTION; j++)
 
301
        for (i = 0; i <= RESOLUTION; i++)
 
302
          {
 
303
            indice = 6 * (i + j * (RESOLUTION + 1));
 
304
            glVertex3fv (&(surface[indice]));
 
305
            glVertex3f (surface[indice] + normal[indice] / 50,
 
306
                        surface[indice + 1] + normal[indice + 1] / 50,
 
307
                        surface[indice + 2] + normal[indice + 2] / 50);
 
308
          }
 
309
 
 
310
      glEnd ();
 
311
    }
 
312
}
 
313
 
 
314
 
 
315
void init_water (void)
 
316
{
 
317
        unsigned char total_texture[4 * 256 * 256];
 
318
  unsigned char alpha_texture[256 * 256];
 
319
  unsigned char caustic_texture[3 * 256 * 256];
 
320
  unsigned int i;
 
321
 
 
322
  InitNoise ();
 
323
 
 
324
  /* OpenGL settings */
 
325
  glClearColor (0, 0, 0, 0);
 
326
  glEnable (GL_DEPTH_TEST);
 
327
  glEnable (GL_BLEND);
 
328
  glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
329
  glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
 
330
  glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
 
331
 
 
332
  /* Texture loading  */
 
333
  glGenTextures (1, &texture);
 
334
  if (load_texture ("alpha.jpg", alpha_texture, GL_ALPHA, 256) != 0 ||
 
335
      load_texture ("reflection.jpg", caustic_texture, GL_RGB, 256) != 0)
 
336
    return 1;
 
337
  for (i = 0; i < 256 * 256; i++)
 
338
    {
 
339
      total_texture[4 * i] = caustic_texture[3 * i];
 
340
      total_texture[4 * i + 1] = caustic_texture[3 * i + 1];
 
341
      total_texture[4 * i + 2] = caustic_texture[3 * i + 2];
 
342
      total_texture[4 * i + 3] = alpha_texture[i];
 
343
    }
 
344
  glBindTexture (GL_TEXTURE_2D, texture);
 
345
  gluBuild2DMipmaps (GL_TEXTURE_2D, GL_RGBA, 256, 256, GL_RGBA,
 
346
                     GL_UNSIGNED_BYTE,  total_texture);
 
347
  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 
348
  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 
349
  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
 
350
  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
 
351
  glEnable (GL_TEXTURE_GEN_S);
 
352
  glEnable (GL_TEXTURE_GEN_T);
 
353
  glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
 
354
  glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
 
355
}