Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/new_class_id/src/world_entities/weather_effects/cloud_effect.cc @ 9805

Last change on this file since 9805 was 9760, checked in by bensch, 18 years ago

moved around the weather effecs

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