Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/graphics/effects/cloud_effect.cc @ 9064

Last change on this file since 9064 was 9006, checked in by bensch, 18 years ago

orxonox/trunk: merged the mountain_lake branche back to the trunk
merged with command:
svn merge -r8799:HEAD https://svn.orxonox.net/orxonox/branches/mountain_lake .

conflicts in script taken from the branche, since they are indentation-problems.

also fixed the delete-bug for the lightning-effect

File size: 13.5 KB
Line 
1/*
2  orxonox - the future of 3D-vertical-scrollers
3
4  Copyright (C) 2004 orx
5
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2, or (at your option)
9  any later version.
10
11### File Specific:
12  main-programmer: hdavid, amaechler
13
14  INSPIRED BY http://www.codesampler.com/usersrc/usersrc_6.htm#oglu_sky_dome_shader
15*/
16
17#include "cloud_effect.h"
18
19#include "util/loading/load_param.h"
20#include "util/loading/factory.h"
21#include "util/loading/resource_manager.h"
22
23#include "material.h"
24#include "state.h"
25#include "p_node.h"
26#include "shader.h"
27#include "shell_command.h"
28#include "t_animation.h"
29#include "script_class.h"
30
31#include "parser/tinyxml/tinyxml.h"
32
33Vector    CloudEffect::cloudColor;
34Vector    CloudEffect::skyColor;
35Vector    CloudEffect::newCloudColor;
36Vector    CloudEffect::newSkyColor;
37
38bool      CloudEffect::fadeSky;
39bool      CloudEffect::fadeCloud;
40float     CloudEffect::fadeTime;
41bool      CloudEffect::flashSkyActivate;
42float     CloudEffect::localTimer;
43float     CloudEffect::flashTime;
44
45using namespace std;
46
47SHELL_COMMAND(activate, CloudEffect, activateCloud);
48SHELL_COMMAND(deactivate, CloudEffect, deactivateCloud);
49SHELL_COMMAND(skyColor, CloudEffect, shellSkyColor);
50SHELL_COMMAND(cloudColor, CloudEffect, shellCloudColor);
51
52
53CREATE_SCRIPTABLE_CLASS(CloudEffect, CL_CLOUD_EFFECT,
54                        addMethod("skyColor", ExecutorLua4<CloudEffect,float,float,float,float>(&CloudEffect::shellSkyColor))
55                      ->addMethod("cloudColor", ExecutorLua4<CloudEffect,float,float,float,float>(&CloudEffect::shellCloudColor))
56                       );
57
58
59CREATE_FACTORY(CloudEffect, CL_CLOUD_EFFECT);
60
61CloudEffect::CloudEffect(const TiXmlElement* root) {
62    this->setClassID(CL_CLOUD_EFFECT, "CloudEffect");
63
64    this->init();
65
66    if (root != NULL)
67        this->loadParams(root);
68
69    if(cloudActivate)
70        this->activate();
71}
72
73CloudEffect::~CloudEffect() {
74    this->deactivate();
75
76    if (glIsTexture(noise3DTexName))
77        glDeleteTextures(1, &noise3DTexName);
78
79    delete shader;
80}
81
82
83void CloudEffect::init() {
84    PRINTF(0)("Initializing CloudEffect\n");
85
86    // default values
87    this->offsetZ = 0;
88    this->animationSpeed = 2;
89    this->scale = 0.0004f;
90    this->atmosphericRadius = 4000;
91    this->planetRadius = 1500;
92    this->divs = 15;
93    fadeSky = false;
94    fadeCloud = false;
95
96    flashSkyActivate = false;
97    localTimer = 0;
98    flashTime = 0;
99
100    skyColor = Vector(0.0f, 0.0f, 0.8f);
101    cloudColor = Vector(0.8f, 0.8f, 0.8f);
102    newSkyColor = skyColor;
103    newCloudColor = cloudColor;
104
105    this->noise3DTexSize = 128;
106    this->noise3DTexName = 0;
107
108    this->make3DNoiseTexture();
109
110    glGenTextures(1, &noise3DTexName);
111    glBindTexture(GL_TEXTURE_3D, noise3DTexName);
112
113    glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT);
114    glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT);
115    glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT);
116    glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
117    glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
118
119    glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA,
120                 noise3DTexSize, noise3DTexSize, noise3DTexSize,
121                 0, GL_RGBA, GL_UNSIGNED_BYTE, noise3DTexPtr);
122
123    this->skydome = new Skydome();
124    this->skydome->setTexture(noise3DTexName);
125
126    this->shader = new Shader(ResourceManager::getInstance()->getDataDir() + "/shaders/cloud.vert",
127                              ResourceManager::getInstance()->getDataDir() + "/shaders/cloud.frag");
128
129    this->shader->activateShader();
130
131    Shader::Uniform(shader, "Noise").set(0);
132
133    this->offset = new Shader::Uniform(shader, "Offset");
134    this->skycolor = new Shader::Uniform(shader, "SkyColor");
135    this->cloudcolor = new Shader::Uniform(shader, "CloudColor");
136
137    this->shader->deactivateShader();
138
139    this->skydome->setShader(shader);
140}
141
142
143void CloudEffect::loadParams(const TiXmlElement* root) {
144    WeatherEffect::loadParams(root);
145
146    LoadParam(root, "speed", this, CloudEffect, setAnimationSpeed);
147    LoadParam(root, "scale", this, CloudEffect, setCloudScale);
148    LoadParam(root, "cloudcolor", this, CloudEffect, setCloudColor);
149    LoadParam(root, "skycolor", this, CloudEffect, setSkyColor);
150
151    LoadParam(root, "planetRadius", this, CloudEffect, setPlanetRadius);
152    LoadParam(root, "atmosphericRadius", this, CloudEffect, setAtmosphericRadius);
153    LoadParam(root, "divisions", this, CloudEffect, setDivisions);
154
155    LOAD_PARAM_START_CYCLE(root, element);
156    {
157        LoadParam_CYCLE(element, "option", this, CloudEffect, setCloudOption);
158    }
159    LOAD_PARAM_END_CYCLE(element);
160}
161
162
163void CloudEffect::activate() {
164    PRINTF(0)( "Activating\n");
165
166    // Can only be set after the loadParams call
167    this->shader->activateShader();
168    Shader::Uniform(shader, "Scale").set(this->scale);
169    this->skycolor->set
170    (skyColor.x, skyColor.y, skyColor.z);
171    this->cloudcolor->set
172    (cloudColor.x, cloudColor.y, cloudColor.z);
173    this->shader->deactivateShader();
174
175    this->skydome->generateSkyPlane(this->divs, this->planetRadius, this->atmosphericRadius, 1, 1);
176    this->skydome->activate();
177
178    this->cloudActivate = true;
179}
180
181void CloudEffect::deactivate() {
182    PRINTF(0)("Deactivating CloudEffect\n");
183
184    this->skydome->deactivate();
185    this->cloudActivate = false;
186}
187
188void CloudEffect::draw() const {}
189
190void CloudEffect::tick (float dt) {
191
192    if (this->cloudActivate) {
193
194        localTimer += dt;
195
196        this->offsetZ += 0.05 * dt * this->animationSpeed;
197
198        this->shader->activateShader();
199        this->offset->set(0.0f, 0.0f, offsetZ);
200
201        if (flashSkyActivate) {
202
203            this->skycolor->set(1, 1, 1);
204            PRINTF(0)("SkyColor set to white\n");
205
206            if (localTimer > flashTime) {
207                flashSkyActivate = false;
208                this->skycolor->set(this->skyColor.x, this->skyColor.y, this->skyColor.z);
209                PRINTF(0)("SkyColor reset\n");
210            }
211
212        } else {
213
214            if(cloudColor != newCloudColor) {
215
216                if(fadeCloud) {
217
218                    this->cloudColorFadeX = new tAnimation<CloudEffect>(this, &CloudEffect::setColorCloudX);
219                    this->cloudColorFadeX->setInfinity(ANIM_INF_CONSTANT);
220                    this->cloudColorFadeY = new tAnimation<CloudEffect>(this, &CloudEffect::setColorCloudY);
221                    this->cloudColorFadeY->setInfinity(ANIM_INF_CONSTANT);
222                    this->cloudColorFadeZ = new tAnimation<CloudEffect>(this, &CloudEffect::setColorCloudZ);
223                    this->cloudColorFadeZ->setInfinity(ANIM_INF_CONSTANT);
224
225                    this->cloudColorFadeX->addKeyFrame(cloudColor.x, fadeTime, ANIM_LINEAR);
226                    this->cloudColorFadeX->addKeyFrame(newCloudColor.x, 0, ANIM_LINEAR);
227
228                    this->cloudColorFadeY->addKeyFrame(cloudColor.y, fadeTime, ANIM_LINEAR);
229                    this->cloudColorFadeY->addKeyFrame(newCloudColor.y, 0, ANIM_LINEAR);
230
231                    this->cloudColorFadeZ->addKeyFrame(cloudColor.z, fadeTime, ANIM_LINEAR);
232                    this->cloudColorFadeZ->addKeyFrame(newCloudColor.z, 0, ANIM_LINEAR);
233
234                    fadeCloud = false;
235
236                    this->cloudColorFadeX->replay();
237                    this->cloudColorFadeY->replay();
238                    this->cloudColorFadeZ->replay();
239                }
240
241                this->cloudcolor->set(this->cloudColor.x, this->cloudColor.y, this->cloudColor.z);
242            }
243
244            if(skyColor != newSkyColor) {
245
246                if(fadeSky) {
247
248                    this->skyColorFadeX = new tAnimation<CloudEffect>(this, &CloudEffect::setColorSkyX);
249                    this->skyColorFadeX->setInfinity(ANIM_INF_CONSTANT);
250                    this->skyColorFadeY = new tAnimation<CloudEffect>(this, &CloudEffect::setColorSkyY);
251                    this->skyColorFadeY->setInfinity(ANIM_INF_CONSTANT);
252                    this->skyColorFadeZ = new tAnimation<CloudEffect>(this, &CloudEffect::setColorSkyZ);
253                    this->skyColorFadeZ->setInfinity(ANIM_INF_CONSTANT);
254
255                    this->skyColorFadeX->addKeyFrame(skyColor.x, fadeTime, ANIM_LINEAR);
256                    this->skyColorFadeX->addKeyFrame(newSkyColor.x, 0, ANIM_LINEAR);
257
258                    this->skyColorFadeY->addKeyFrame(skyColor.y, fadeTime, ANIM_LINEAR);
259                    this->skyColorFadeY->addKeyFrame(newSkyColor.y, 0, ANIM_LINEAR);
260
261                    this->skyColorFadeZ->addKeyFrame(skyColor.z, fadeTime, ANIM_LINEAR);
262                    this->skyColorFadeZ->addKeyFrame(newSkyColor.z, 0, ANIM_LINEAR);
263
264                    fadeSky = false;
265
266                    this->skyColorFadeX->replay();
267                    this->skyColorFadeY->replay();
268                    this->skyColorFadeZ->replay();
269                }
270
271                this->skycolor->set(this->skyColor.x, this->skyColor.y, this->skyColor.z);
272            }
273        }
274
275        this->shader->deactivateShader();
276    }
277}
278
279
280void CloudEffect::setColorSkyX(float color) {
281    skyColor.x = color;
282}
283void CloudEffect::setColorSkyY(float color) {
284    skyColor.y = color;
285}
286void CloudEffect::setColorSkyZ(float color) {
287    skyColor.z = color;
288}
289void CloudEffect::setColorCloudX(float color) {
290    cloudColor.x = color;
291}
292void CloudEffect::setColorCloudY(float color) {
293    cloudColor.y = color;
294}
295void CloudEffect::setColorCloudZ(float color) {
296    cloudColor.z = color;
297}
298
299void CloudEffect::changeSkyColor(Vector color, float time) {
300    newSkyColor = color;
301    fadeSky = true;
302    fadeTime = time;
303}
304
305
306void CloudEffect::changeCloudColor(Vector color, float time) {
307    newCloudColor = color;
308    fadeCloud = true;
309    fadeTime = time;
310}
311
312void CloudEffect::shellSkyColor(float colorX, float colorY, float colorZ, float time) {
313    changeSkyColor( Vector(colorX, colorY, colorZ), time);
314}
315
316void CloudEffect::shellCloudColor(float colorX, float colorY, float colorZ, float time) {
317    changeCloudColor( Vector(colorX, colorY, colorZ), time);
318}
319
320void CloudEffect::flashSky( float time ) {
321
322  flashSkyActivate = true;
323  localTimer = 0;
324  flashTime = time;
325
326}
327
328
329
330void CloudEffect::make3DNoiseTexture() {
331    int f, i, j, k, inc;
332    int startFrequency = 4;
333    int numOctaves = 4;
334    double ni[3];
335    double inci, incj, inck;
336    int frequency = startFrequency;
337    GLubyte *ptr;
338    double amp = 0.5;
339
340    if ((noise3DTexPtr = (GLubyte *) malloc(noise3DTexSize *
341                                            noise3DTexSize *
342                                            noise3DTexSize * 4)) == NULL)
343        PRINTF(0)("ERROR: Could not allocate 3D noise texture\n");
344
345    for (f=0, inc=0; f < numOctaves;
346            ++f, frequency *= 2, ++inc, amp *= 0.5) {
347        SetNoiseFrequency(frequency);
348        ptr = noise3DTexPtr;
349        ni[0] = ni[1] = ni[2] = 0;
350
351        inci = 1.0 / (noise3DTexSize / frequency);
352        for (i=0; i<noise3DTexSize; ++i, ni[0] += inci) {
353            incj = 1.0 / (noise3DTexSize / frequency);
354            for (j=0; j<noise3DTexSize; ++j, ni[1] += incj) {
355                inck = 1.0 / (noise3DTexSize / frequency);
356                for (k=0; k<noise3DTexSize; ++k, ni[2] += inck, ptr+= 4) {
357                    *(ptr+inc) = (GLubyte) (((noise3(ni)+1.0) * amp)*128.0);
358                }
359            }
360        }
361    }
362}
363
364void CloudEffect::initNoise() {
365    int i, j, k;
366
367    srand(30757);
368    for (i = 0 ; i < B ; i++) {
369        p[i] = i;
370        g1[i] = (double)((rand() % (B + B)) - B) / B;
371
372        for (j = 0 ; j < 2 ; j++)
373            g2[i][j] = (double)((rand() % (B + B)) - B) / B;
374        normalize2(g2[i]);
375
376        for (j = 0 ; j < 3 ; j++)
377            g3[i][j] = (double)((rand() % (B + B)) - B) / B;
378        normalize3(g3[i]);
379    }
380
381    while (--i) {
382        k = p[i];
383        p[i] = p[j = rand() % B];
384        p[j] = k;
385    }
386
387    for (i = 0 ; i < B + 2 ; i++) {
388        p[B + i] = p[i];
389        g1[B + i] = g1[i];
390        for (j = 0 ; j < 2 ; j++)
391            g2[B + i][j] = g2[i][j];
392        for (j = 0 ; j < 3 ; j++)
393            g3[B + i][j] = g3[i][j];
394    }
395}
396
397void CloudEffect::SetNoiseFrequency( int frequency) {
398    start = 1;
399    B = frequency;
400    BM = B-1;
401}
402
403double CloudEffect::noise3( double vec[3]) {
404    int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
405    double rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v;
406    int i, j;
407
408    if (start) {
409        start = 0;
410        initNoise();
411    }
412
413    setup(0, bx0,bx1, rx0,rx1);
414    setup(1, by0,by1, ry0,ry1);
415    setup(2, bz0,bz1, rz0,rz1);
416
417    i = p[ bx0 ];
418    j = p[ bx1 ];
419
420    b00 = p[ i + by0 ];
421    b10 = p[ j + by0 ];
422    b01 = p[ i + by1 ];
423    b11 = p[ j + by1 ];
424
425    t  = s_curve(rx0);
426    sy = s_curve(ry0);
427    sz = s_curve(rz0);
428
429    q = g3[ b00 + bz0 ] ;
430    u = at3(rx0,ry0,rz0);
431    q = g3[ b10 + bz0 ] ;
432    v = at3(rx1,ry0,rz0);
433    a = lerp(t, u, v);
434
435    q = g3[ b01 + bz0 ] ;
436    u = at3(rx0,ry1,rz0);
437    q = g3[ b11 + bz0 ] ;
438    v = at3(rx1,ry1,rz0);
439    b = lerp(t, u, v);
440
441    c = lerp(sy, a, b);
442
443    q = g3[ b00 + bz1 ] ;
444    u = at3(rx0,ry0,rz1);
445    q = g3[ b10 + bz1 ] ;
446    v = at3(rx1,ry0,rz1);
447    a = lerp(t, u, v);
448
449    q = g3[ b01 + bz1 ] ;
450    u = at3(rx0,ry1,rz1);
451    q = g3[ b11 + bz1 ] ;
452    v = at3(rx1,ry1,rz1);
453    b = lerp(t, u, v);
454
455    d = lerp(sy, a, b);
456
457    return lerp(sz, c, d);
458}
459
460void CloudEffect::normalize2( double v[2]) {
461    double s;
462
463    s = sqrt(v[0] * v[0] + v[1] * v[1]);
464    v[0] = v[0] / s;
465    v[1] = v[1] / s;
466}
467
468void CloudEffect::normalize3( double v[3]) {
469    double s;
470
471    s = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
472    v[0] = v[0] / s;
473    v[1] = v[1] / s;
474    v[2] = v[2] / s;
475}
476
Note: See TracBrowser for help on using the repository browser.