Changeset 9006 in orxonox.OLD for trunk/src/lib/graphics/effects/cloud_effect.cc
- Timestamp:
- Jul 2, 2006, 2:11:59 PM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/lib/graphics/effects/cloud_effect.cc
r8793 r9006 1 1 /* 2 2 orxonox - the future of 3D-vertical-scrollers 3 3 4 4 Copyright (C) 2004 orx 5 5 6 6 This program is free software; you can redistribute it and/or modify 7 7 it under the terms of the GNU General Public License as published by 8 8 the Free Software Foundation; either version 2, or (at your option) 9 9 any later version. 10 10 11 11 ### File Specific: 12 12 main-programmer: hdavid, amaechler 13 13 14 14 INSPIRED BY http://www.codesampler.com/usersrc/usersrc_6.htm#oglu_sky_dome_shader 15 15 */ … … 26 26 #include "shader.h" 27 27 #include "shell_command.h" 28 #include "t_animation.h" 29 #include "script_class.h" 28 30 29 31 #include "parser/tinyxml/tinyxml.h" 30 32 31 Vector CloudEffect::cloudColor; 32 Vector CloudEffect::skyColor; 33 Vector CloudEffect::newCloudColor; 34 Vector CloudEffect::newSkyColor; 33 Vector CloudEffect::cloudColor; 34 Vector CloudEffect::skyColor; 35 Vector CloudEffect::newCloudColor; 36 Vector CloudEffect::newSkyColor; 37 38 bool CloudEffect::fadeSky; 39 bool CloudEffect::fadeCloud; 40 float CloudEffect::fadeTime; 41 bool CloudEffect::flashSkyActivate; 42 float CloudEffect::localTimer; 43 float CloudEffect::flashTime; 35 44 36 45 using namespace std; … … 38 47 SHELL_COMMAND(activate, CloudEffect, activateCloud); 39 48 SHELL_COMMAND(deactivate, CloudEffect, deactivateCloud); 49 SHELL_COMMAND(skyColor, CloudEffect, shellSkyColor); 50 SHELL_COMMAND(cloudColor, CloudEffect, shellCloudColor); 51 52 53 CREATE_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 40 58 41 59 CREATE_FACTORY(CloudEffect, CL_CLOUD_EFFECT); 42 60 43 CloudEffect::CloudEffect(const TiXmlElement* root) 44 { 45 this->setClassID(CL_CLOUD_EFFECT, "CloudEffect"); 46 47 this->init(); 48 49 if (root != NULL) 50 this->loadParams(root); 51 52 if(cloudActivate) 53 this->activate(); 54 } 55 56 CloudEffect::~CloudEffect() 57 { 58 this->deactivate(); 59 60 if (glIsTexture(noise3DTexName)) 61 glDeleteTextures(1, &noise3DTexName); 62 63 delete shader; 64 } 65 66 67 void CloudEffect::init() 68 { 69 PRINTF(0)("Initializing CloudEffect\n"); 70 71 this->offsetZ = 0; 72 this->animationSpeed = 2; 73 this->scale = 0.0004f; 74 this->atmosphericRadius = 4000; 75 this->planetRadius = 1500; 76 this->divs = 50; 77 78 skyColor = Vector(0.0f, 0.0f, 0.8f); 79 cloudColor = Vector(0.8f, 0.8f, 0.8f); 80 newSkyColor = skyColor; 81 newCloudColor = cloudColor; 82 this->fadeTime = 3; 83 84 this->noise3DTexSize = 128; 85 this->noise3DTexName = 0; 86 87 this->make3DNoiseTexture(); 88 89 glGenTextures(1, &noise3DTexName); 90 glBindTexture(GL_TEXTURE_3D, noise3DTexName); 91 92 glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT); 93 glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT); 94 glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT); 95 glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 96 glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 97 98 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 99 noise3DTexSize, noise3DTexSize, noise3DTexSize, 100 0, GL_RGBA, GL_UNSIGNED_BYTE, noise3DTexPtr); 101 102 this->skydome = new Skydome(); 103 this->skydome->setTexture(noise3DTexName); 104 105 this->shader = new Shader(ResourceManager::getInstance()->getDataDir() + "/shaders/cloud.vert", 106 ResourceManager::getInstance()->getDataDir() + "/shaders/cloud.frag"); 107 108 this->shader->activateShader(); 109 110 Shader::Uniform(shader, "Noise").set(0); 111 112 this->offset = new Shader::Uniform(shader, "Offset"); 113 this->skycolor = new Shader::Uniform(shader, "SkyColor"); 114 this->cloudcolor = new Shader::Uniform(shader, "CloudColor"); 115 116 this->shader->deactivateShader(); 117 118 this->skydome->setShader(shader); 119 } 120 121 122 void CloudEffect::loadParams(const TiXmlElement* root) 123 { 124 WeatherEffect::loadParams(root); 125 126 LoadParam(root, "speed", this, CloudEffect, setAnimationSpeed); 127 LoadParam(root, "scale", this, CloudEffect, setCloudScale); 128 LoadParam(root, "cloudcolor", this, CloudEffect, setCloudColor); 129 LoadParam(root, "skycolor", this, CloudEffect, setSkyColor); 130 131 LoadParam(root, "planetRadius", this, CloudEffect, setPlanetRadius); 132 LoadParam(root, "atmosphericRadius", this, CloudEffect, setAtmosphericRadius); 133 LoadParam(root, "divisions", this, CloudEffect, setDivisions); 134 135 LOAD_PARAM_START_CYCLE(root, element); 136 { 137 LoadParam_CYCLE(element, "option", this, CloudEffect, setCloudOption); 138 } 139 LOAD_PARAM_END_CYCLE(element); 140 } 141 142 143 void CloudEffect::activate() 144 { 145 PRINTF(0)( "Activating\n"); 146 147 // Can only be set after the loadParams call 148 this->shader->activateShader(); 149 Shader::Uniform(shader, "Scale").set(this->scale); 150 this->skycolor->set(skyColor.x, skyColor.y, skyColor.z); 151 this->cloudcolor->set(cloudColor.x, cloudColor.y, cloudColor.z); 152 this->shader->deactivateShader(); 153 154 this->skydome->generateSkyPlane(this->divs, this->planetRadius, this->atmosphericRadius, 1, 1); 155 156 this->cloudActivate = true; 157 } 158 159 void CloudEffect::deactivate() 160 { 161 PRINTF(0)("Deactivating CloudEffect\n"); 162 163 this->cloudActivate = false; 164 } 165 166 void CloudEffect::draw() const 167 {} 168 169 void CloudEffect::tick (float dt) 170 { 171 if (this->cloudActivate) 172 { 173 this->offsetZ += 0.05 * dt * this->animationSpeed; 61 CloudEffect::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 73 CloudEffect::~CloudEffect() { 74 this->deactivate(); 75 76 if (glIsTexture(noise3DTexName)) 77 glDeleteTextures(1, &noise3DTexName); 78 79 delete shader; 80 } 81 82 83 void 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"); 174 128 175 129 this->shader->activateShader(); 176 this->offset->set(0.0f, 0.0f, offsetZ); 177 178 //if(cloudColor != newCloudColor) 179 //{ 180 // TODO: fade from cloudColor to newCloudColor 181 cloudColor = newCloudColor; 182 this->cloudcolor->set(this->cloudColor.x, this->cloudColor.y, this->cloudColor.z); 183 //} 184 //if(cloudColor != newCloudColor) 185 //{ 186 // TODO: fade from skyColor to newSkyColor 187 skyColor = newSkyColor; 188 this->skycolor->set(this->skyColor.x, this->skyColor.y, this->skyColor.z); 189 //} 190 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 191 137 this->shader->deactivateShader(); 192 } 193 } 194 195 196 void CloudEffect::changeSkyColor(Vector color) 197 { 198 newSkyColor = color; 199 } 200 201 202 void CloudEffect::changeCloudColor(Vector color) 203 { 204 newCloudColor = color; 205 } 206 207 208 void CloudEffect::make3DNoiseTexture() 209 { 210 int f, i, j, k, inc; 211 int startFrequency = 4; 212 int numOctaves = 4; 213 double ni[3]; 214 double inci, incj, inck; 215 int frequency = startFrequency; 216 GLubyte *ptr; 217 double amp = 0.5; 218 219 if ((noise3DTexPtr = (GLubyte *) malloc(noise3DTexSize * 220 noise3DTexSize * 221 noise3DTexSize * 4)) == NULL) 222 PRINTF(0)("ERROR: Could not allocate 3D noise texture\n"); 223 224 for (f=0, inc=0; f < numOctaves; 225 ++f, frequency *= 2, ++inc, amp *= 0.5) 226 { 227 SetNoiseFrequency(frequency); 228 ptr = noise3DTexPtr; 229 ni[0] = ni[1] = ni[2] = 0; 230 231 inci = 1.0 / (noise3DTexSize / frequency); 232 for (i=0; i<noise3DTexSize; ++i, ni[0] += inci) 138 139 this->skydome->setShader(shader); 140 } 141 142 143 void 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); 233 156 { 234 incj = 1.0 / (noise3DTexSize / frequency); 235 for (j=0; j<noise3DTexSize; ++j, ni[1] += incj) 236 { 237 inck = 1.0 / (noise3DTexSize / frequency); 238 for (k=0; k<noise3DTexSize; ++k, ni[2] += inck, ptr+= 4) 239 { 240 *(ptr+inc) = (GLubyte) (((noise3(ni)+1.0) * amp)*128.0); 157 LoadParam_CYCLE(element, "option", this, CloudEffect, setCloudOption); 158 } 159 LOAD_PARAM_END_CYCLE(element); 160 } 161 162 163 void 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 181 void CloudEffect::deactivate() { 182 PRINTF(0)("Deactivating CloudEffect\n"); 183 184 this->skydome->deactivate(); 185 this->cloudActivate = false; 186 } 187 188 void CloudEffect::draw() const {} 189 190 void 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 } 241 273 } 242 } 243 } 244 } 245 } 246 247 void CloudEffect::initNoise() 248 { 249 int i, j, k; 250 251 srand(30757); 252 for (i = 0 ; i < B ; i++) 253 { 254 p[i] = i; 255 g1[i] = (double)((rand() % (B + B)) - B) / B; 256 257 for (j = 0 ; j < 2 ; j++) 258 g2[i][j] = (double)((rand() % (B + B)) - B) / B; 259 normalize2(g2[i]); 260 261 for (j = 0 ; j < 3 ; j++) 262 g3[i][j] = (double)((rand() % (B + B)) - B) / B; 263 normalize3(g3[i]); 264 } 265 266 while (--i) 267 { 268 k = p[i]; 269 p[i] = p[j = rand() % B]; 270 p[j] = k; 271 } 272 273 for (i = 0 ; i < B + 2 ; i++) 274 { 275 p[B + i] = p[i]; 276 g1[B + i] = g1[i]; 277 for (j = 0 ; j < 2 ; j++) 278 g2[B + i][j] = g2[i][j]; 279 for (j = 0 ; j < 3 ; j++) 280 g3[B + i][j] = g3[i][j]; 281 } 282 } 283 284 void CloudEffect::SetNoiseFrequency( int frequency) 285 { 286 start = 1; 287 B = frequency; 288 BM = B-1; 289 } 290 291 double CloudEffect::noise3( double vec[3]) 292 { 293 int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11; 294 double rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v; 295 int i, j; 296 297 if (start) 298 { 299 start = 0; 300 initNoise(); 301 } 302 303 setup(0, bx0,bx1, rx0,rx1); 304 setup(1, by0,by1, ry0,ry1); 305 setup(2, bz0,bz1, rz0,rz1); 306 307 i = p[ bx0 ]; 308 j = p[ bx1 ]; 309 310 b00 = p[ i + by0 ]; 311 b10 = p[ j + by0 ]; 312 b01 = p[ i + by1 ]; 313 b11 = p[ j + by1 ]; 314 315 t = s_curve(rx0); 316 sy = s_curve(ry0); 317 sz = s_curve(rz0); 318 319 q = g3[ b00 + bz0 ] ; u = at3(rx0,ry0,rz0); 320 q = g3[ b10 + bz0 ] ; v = at3(rx1,ry0,rz0); 321 a = lerp(t, u, v); 322 323 q = g3[ b01 + bz0 ] ; u = at3(rx0,ry1,rz0); 324 q = g3[ b11 + bz0 ] ; v = at3(rx1,ry1,rz0); 325 b = lerp(t, u, v); 326 327 c = lerp(sy, a, b); 328 329 q = g3[ b00 + bz1 ] ; u = at3(rx0,ry0,rz1); 330 q = g3[ b10 + bz1 ] ; v = at3(rx1,ry0,rz1); 331 a = lerp(t, u, v); 332 333 q = g3[ b01 + bz1 ] ; u = at3(rx0,ry1,rz1); 334 q = g3[ b11 + bz1 ] ; v = at3(rx1,ry1,rz1); 335 b = lerp(t, u, v); 336 337 d = lerp(sy, a, b); 338 339 return lerp(sz, c, d); 340 } 341 342 void CloudEffect::normalize2( double v[2]) 343 { 344 double s; 345 346 s = sqrt(v[0] * v[0] + v[1] * v[1]); 347 v[0] = v[0] / s; 348 v[1] = v[1] / s; 349 } 350 351 void CloudEffect::normalize3( double v[3]) 352 { 353 double s; 354 355 s = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); 356 v[0] = v[0] / s; 357 v[1] = v[1] / s; 358 v[2] = v[2] / s; 359 } 360 274 275 this->shader->deactivateShader(); 276 } 277 } 278 279 280 void CloudEffect::setColorSkyX(float color) { 281 skyColor.x = color; 282 } 283 void CloudEffect::setColorSkyY(float color) { 284 skyColor.y = color; 285 } 286 void CloudEffect::setColorSkyZ(float color) { 287 skyColor.z = color; 288 } 289 void CloudEffect::setColorCloudX(float color) { 290 cloudColor.x = color; 291 } 292 void CloudEffect::setColorCloudY(float color) { 293 cloudColor.y = color; 294 } 295 void CloudEffect::setColorCloudZ(float color) { 296 cloudColor.z = color; 297 } 298 299 void CloudEffect::changeSkyColor(Vector color, float time) { 300 newSkyColor = color; 301 fadeSky = true; 302 fadeTime = time; 303 } 304 305 306 void CloudEffect::changeCloudColor(Vector color, float time) { 307 newCloudColor = color; 308 fadeCloud = true; 309 fadeTime = time; 310 } 311 312 void CloudEffect::shellSkyColor(float colorX, float colorY, float colorZ, float time) { 313 changeSkyColor( Vector(colorX, colorY, colorZ), time); 314 } 315 316 void CloudEffect::shellCloudColor(float colorX, float colorY, float colorZ, float time) { 317 changeCloudColor( Vector(colorX, colorY, colorZ), time); 318 } 319 320 void CloudEffect::flashSky( float time ) { 321 322 flashSkyActivate = true; 323 localTimer = 0; 324 flashTime = time; 325 326 } 327 328 329 330 void 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 364 void 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 397 void CloudEffect::SetNoiseFrequency( int frequency) { 398 start = 1; 399 B = frequency; 400 BM = B-1; 401 } 402 403 double 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 460 void 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 468 void 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 TracChangeset
for help on using the changeset viewer.