Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/mountain_lake/src/lib/graphics/effects/cloud_effect.cc @ 8911

Last change on this file since 8911 was 8911, checked in by amaechler, 18 years ago

branches/moutnain_lake: lightning hacking, skycolor not working yet

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