Changeset 8255 in orxonox.OLD for trunk/src/lib/graphics/effects/cloud_effect.cc
- Timestamp:
- Jun 8, 2006, 3:44:12 PM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/lib/graphics/effects/cloud_effect.cc
r7810 r8255 11 11 ### File Specific: 12 12 main-programmer: hdavid, amaechler 13 14 INSPIRED BY http://www.codesampler.com/usersrc/usersrc_6.htm#oglu_sky_dome_shader 13 15 */ 14 16 … … 17 19 #include "util/loading/load_param.h" 18 20 #include "util/loading/factory.h" 21 #include "util/loading/resource_manager.h" 19 22 20 23 #include "glincl.h" 21 //#include "graphics_engine.h"24 #include "material.h" 22 25 #include <math.h> 26 #include "state.h" 27 #include "p_node.h" 28 #include "shader.h" 29 #include "shell_command.h" 23 30 24 31 #include "parser/tinyxml/tinyxml.h" 25 32 33 #include "sglmodel.h" 34 26 35 using namespace std; 36 37 SHELL_COMMAND(activate, CloudEffect, activateCloud); 38 SHELL_COMMAND(deactivate, CloudEffect, deactivateCloud); 27 39 28 40 CREATE_FACTORY(CloudEffect, CL_CLOUD_EFFECT); … … 37 49 this->loadParams(root); 38 50 39 this->activate(); 51 if(cloudActivate) 52 this->activate(); 40 53 } 41 54 … … 43 56 { 44 57 this->deactivate(); 45 } 58 59 delete this->cloudMaterial; 60 61 cloudModel.Delete(); 62 Shader::unload(this->cloudShader); 63 64 } 65 66 67 bool CloudEffect::init() 68 { 69 PRINTF(1)("Initializing CloudEffect\n"); 70 71 // Default values 72 this->cloudActivate = false; 73 this->cloudTint[4] = ( 0.9f, 0.7f, 0.7f, 1.0f ); 74 this->cloudScroll = 1.0f; 75 this->time = 0.0f; 76 //g_cloud_texture = 0; 77 78 this->cloudTexture = "pictures/sky/cloud1.jpg"; 79 80 cloudModel.Load("sky.sgl"); 81 cloudModel.Unitize(); 82 83 // Get the bounding box of the sky dome 84 float bbox[3] = {0}; 85 cloudModel.GetDimensions(bbox[0], bbox[1], bbox[2]); 86 87 // Load Shaders 88 this->cloudShader = new Shader( ResourceManager::getInstance()->getDataDir() + "/shaders/sky.vert", ResourceManager::getInstance()->getDataDir() +"/shaders/sky.frag"); 89 90 // Tell the shader the bounding box of the sky dome 91 this->cloudShader->bindShader("bbox", bbox, 4); 92 93 // Initialze Cloud Material 94 this->cloudMaterial = new Material("Sky"); 95 this->cloudMaterial->setIllum(3); 96 this->cloudMaterial->setAmbient(1.0, 1.0, 1.0); 97 this->cloudMaterial->setDiffuseMap(this->cloudTexture); 98 99 } 100 46 101 47 102 void CloudEffect::loadParams(const TiXmlElement* root) … … 49 104 WeatherEffect::loadParams(root); 50 105 51 LoadParam(root, "animSpeed", this, CloudEffect, setCloudAnimation); 52 53 } 54 55 56 bool CloudEffect::init() 57 { 58 // default values 59 this->cloudAnimTimeStep = 0; 60 61 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 62 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 63 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 64 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 65 66 // Generate noise map a 67 CloudEffect::genNoiseMap(cloudMap32_a); 68 69 if (this->cloudAnimTimeStep > 0) { 70 // Generate noise map b 71 CloudEffect::genNoiseMap(cloudMap32_b); 106 // LoadParam(root, "speed", this, CloudEffect, setCloudAnimation); 107 // LoadParam(root, "texture", this, CloudEffect, setCloudTexture); 108 109 LOAD_PARAM_START_CYCLE(root, element); 110 { 111 LoadParam_CYCLE(element, "option", this, CloudEffect, setCloudOption); 72 112 } 73 } 113 LOAD_PARAM_END_CYCLE(element); 114 } 115 74 116 75 117 bool CloudEffect::activate() 76 118 { 77 PRINTF(0)( "Activating CloudEffect\n"); 78 if (this->cloudAnimTimeStep == 0) { 79 for (int i = 0; i < 32*32; i++) 80 cloudMap32_c[i] = cloudMap32_a[i]; 81 82 CloudEffect::overlapOctaves(); 83 CloudEffect::expFilter(); 84 CloudEffect::genCloudTexture(); 85 } 119 PRINTF(0)( "Activating CloudEffect with Material %s\n", this->cloudTexture.c_str()); 120 121 this->cloudActivate = true; 122 86 123 } 87 124 … … 89 126 { 90 127 PRINTF(0)("Deactivating CloudEffect\n"); 91 } 92 93 void CloudEffect::genCloudTexture() { 94 for(int i=0; i<256; i++) 95 for(int j=0; j<256; j++) 96 { 97 float color = cloudMap256[i*256+j]; 98 cloudTexture[i][j][0] = (char) color; 99 cloudTexture[i][j][1] = (char) color; 100 cloudTexture[i][j][2] = (char) color; 101 } 102 103 glGenTextures(2, &texID[0]); 104 glBindTexture(GL_TEXTURE_2D, texID[0]); 105 gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, 256, 256, GL_RGB, GL_UNSIGNED_BYTE, cloudTexture); 106 } 107 108 void CloudEffect::calcAnimMap(float timer) { 109 110 for (int x=0; x<32*32; x++) 111 cloudMap32_c[x] = (cloudMap32_a[x] * ((this->cloudAnimTimeStep - timer) / this->cloudAnimTimeStep)) + (cloudMap32_b[x] * (timer / this->cloudAnimTimeStep)); 112 128 129 this->cloudActivate = false; 113 130 } 114 131 115 132 void CloudEffect::draw() const 116 133 { 117 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 118 134 if (!this->cloudActivate) 135 return; 136 137 // glMatrixMode(GL_MODELVIEW); 138 // glPushMatrix(); 139 // 140 // // Move sphere along with the camera 141 // Vector r = State::getCameraNode()->getAbsCoor(); 142 // glTranslatef(r.x, r.y, r.z); 143 // 144 // // Sky movement 145 // glRotatef(mover, 0, 0, 1); 146 // 147 // cloudMaterial->select(); 148 // gluSphere(this->sphereObj, this->sphereRadius, 20, 20); 149 // glPopMatrix(); 150 151 // ****** 152 153 glMatrixMode(GL_MODELVIEW); 119 154 glPushMatrix(); 120 glEnable(GL_TEXTURE_2D); 121 122 glBindTexture(GL_TEXTURE_2D, texID[0]); 123 124 // FIXME : Bind this to the sky - how do I do this? 125 glBegin(GL_QUADS); 126 glTexCoord2f(0.0f, 0.0f); glVertex3f(20, 20, 60); // Bottom Left Of The Texture and Quad 127 glTexCoord2f(1.0f, 0.0f); glVertex3f(60, 20, 60); // Bottom Right Of The Texture and Quad 128 glTexCoord2f(1.0f, 1.0f); glVertex3f(60, 60, 60); // Top Right Of The Texture and Quad 129 glTexCoord2f(0.0f, 1.0f); glVertex3f(20, 60, 60); // Top Left Of The Texture and Quad 130 glEnd(); 155 156 // glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 157 // glShadeModel(GL_SMOOTH); 158 // glEnable(GL_DEPTH_TEST); 159 // glEnable(GL_CULL_FACE); 160 // glCullFace(GL_BACK); 161 // glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); 162 163 // glLineWidth(3.0f); 164 165 static float time = 0.0f; 166 // static vector3f eye = {0.0f, 0.0f, 0.0f}, look = {0.0f, 0.0f, 1.0f}, up = {0.0f, 1.0f, 0.0f}; 167 168 // glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 169 // glLoadIdentity(); 170 // gluLookAt(eye[x], eye[y], eye[z], look[x], look[y], look[z], up[x], up[y], up[z]); 171 172 // Turn off the depth buffer when rendering the background 173 // glDisable(GL_DEPTH_TEST); 174 175 this->cloudShader->activateShader(); 176 177 /* Select the shader program and update parameters. */ 178 /* The "time" parameter controls the cloud scrolling. */ 179 this->cloudShader->bindShader("time", &time, 1); 180 /* The "horizon" parameter controls the sky tinting. */ 181 this->cloudShader->bindShader("horizon", cloudTint, 4); 182 183 glActiveTexture(GL_TEXTURE0 + 0); 184 glActiveTexture(GL_TEXTURE0 + 1); 185 186 // Load the cloud texture 187 //glBindTexture(GL_TEXTURE_2D, g_cloud_texture); 188 this->cloudMaterial->select(); 189 190 // Render the sky dome 191 cloudModel.Render(); 192 193 // Unselect the shader 194 Shader::deactivateShader(); 195 196 /* Turn on the depth buffer when rendering the foreground. */ 197 // glEnable(GL_DEPTH_TEST); 198 199 /* Render the forground, for example, a teapot or bunny. */ 200 // glEnable(GL_LIGHTING); 201 // glColor3f(0.0f, 1.0f, 0.0f); 202 // glBegin(GL_QUADS); 203 // glNormal3f( 0.0f, 1.0f, 0.0f); 204 // glVertex3f( 20.0f, -1.0f, 20.0f); 205 // glVertex3f( 20.0f, -1.0f, -20.0f); 206 // glVertex3f(-20.0f, -1.0f, -20.0f); 207 // glVertex3f(-20.0f, -1.0f, 20.0f); 208 // glEnd(); 209 // glDisable(GL_LIGHTING); 131 210 132 211 glPopMatrix(); 212 133 213 } 134 214 135 215 void CloudEffect::tick (float dt) 136 216 { 137 if (this->cloudAnimTimeStep > 0) { 138 if (timer >= this->cloudAnimTimeStep) { 139 timer -= this->cloudAnimTimeStep; 140 for (int i = 0; i < 32*32; i++) 141 cloudMap32_a[i] = cloudMap32_b[i]; 142 CloudEffect::genNoiseMap(cloudMap32_b); 143 } 144 145 //map32anim = (map32a * (10 - timer)) + (map32b * timer); 146 CloudEffect::calcAnimMap(timer); 147 148 CloudEffect::overlapOctaves(); 149 CloudEffect::expFilter(); 150 CloudEffect::genCloudTexture(); 151 152 timer += dt; 153 } 154 } 155 156 /* 157 Random noise generator 158 */ 159 float CloudEffect::noise(int x, int y, int random) 160 { 161 int n = x + y * 57 + random * 131; 162 n = (n<<13) ^ n; 163 return (1.0f - ( (n * (n * n * 15731 + 789221) + 164 1376312589)&0x7fffffff)* 0.000000000931322574615478515625f); 165 } 166 167 /* 168 Set noise for the 32*32 noise map: 169 */ 170 void CloudEffect::genNoiseMap(float *map) 171 { 172 float temp[34][34]; 173 174 int random = rand() % 5000; 175 176 for (int y = 1; y < 33; y++) 177 for (int x = 1; x < 33; x++) 178 temp[x][y] = 128.0f + CloudEffect::noise(x, y, random) * 128.0f; 179 180 // Seamless cloud 181 for (int x=1; x<33; x++) 182 { 183 temp[0][x] = temp[32][x]; 184 temp[33][x] = temp[1][x]; 185 temp[x][0] = temp[x][32]; 186 temp[x][33] = temp[x][1]; 187 } 188 temp[0][0] = temp[32][32]; 189 temp[33][33] = temp[1][1]; 190 temp[0][33] = temp[32][1]; 191 temp[33][0] = temp[1][32]; 192 193 // We mirror the side and corner elements so our final cloud will be seamless without any ugly borders showing. 194 for (int y=1; y<33; y++) 195 for (int x=1; x<33; x++) 196 { 197 float center = temp[x][y]/4.0f; 198 float sides = (temp[x+1][y] + temp[x-1][y] + temp[x][y+1] + temp[x][y-1])/8.0f; 199 float corners = (temp[x+1][y+1] + temp[x+1][y-1] + temp[x-1][y+1] + temp[x-1][y-1])/16.0f; 200 201 map[((x-1)*32) + (y-1)] = center + sides + corners; 202 } 203 } 204 205 /* 206 Interpolation - average the value of each pixel value with that of its neighbors' values. 207 */ 208 float CloudEffect::interpolate(float x, float y, float *map) 209 { 210 int Xint = (int)x; 211 int Yint = (int)y; 212 213 float Xfrac = x - Xint; 214 float Yfrac = y - Yint; 215 216 int X0 = Xint % 32; 217 int Y0 = Yint % 32; 218 int X1 = (Xint + 1) % 32; 219 int Y1 = (Yint + 1) % 32; 220 221 float bot = map[X0*32 + Y0] + Xfrac * (map[X1*32 + Y0] - map[X0*32 + Y0]); 222 float top = map[X0*32 + Y1] + Xfrac * (map[X1*32 + Y1] - map[X0*32 + Y1]); 223 224 return (bot + Yfrac * (top - bot)); 225 } 226 227 228 /* 229 Octaves are overlapped together to give cloud more turbulence. We will use four octaves for our cloud. 230 */ 231 void CloudEffect::overlapOctaves() 232 { 233 for (int x=0; x<256*256; x++) 234 { 235 cloudMap256[x] = 0; 236 } 237 238 for (int octave=0; octave<4; octave++) 239 for (int x=0; x<256; x++) 240 for (int y=0; y<256; y++) 241 { 242 float scale = 1 / pow(2.0f, (float) 3-octave); 243 float noise = CloudEffect::interpolate(x*scale, y*scale , cloudMap32_c); 244 245 //The octaves are added together with the proper weight factors. 246 //You could replace pow(2, i) with 1<<i for faster computation 247 cloudMap256[(y*256) + x] += noise / pow(2.0f, (float) octave); 248 } 249 } 250 251 252 /* 253 Filter the noise with exponential function 254 */ 255 void CloudEffect::expFilter() 256 { 257 float cover = 20.0f; 258 float sharpness = 0.95f; 259 260 for (int x=0; x<256*256; x++) 261 { 262 float c = cloudMap256[x] - (255.0f-cover); 263 if (c<0) c = 0; 264 cloudMap256[x] = 255.0f - ((float)(pow(sharpness, c))*255.0f); 265 } 266 } 267 268 217 if (!this->cloudActivate) 218 return; 219 220 // Update the timer for scrolling the clouds 221 time = time + ((1.0f / 2000.0f) * cloudScroll); 222 } 223
Note: See TracChangeset
for help on using the changeset viewer.