Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Jun 8, 2006, 3:44:12 PM (18 years ago)
Author:
bensch
Message:

merged the atmos back with command: https://svn.orxonox.net/orxonox/branches/atmospheric_engine

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/lib/graphics/effects/cloud_effect.cc

    r7810 r8255  
    1111### File Specific:
    1212        main-programmer: hdavid, amaechler
     13
     14        INSPIRED BY http://www.codesampler.com/usersrc/usersrc_6.htm#oglu_sky_dome_shader
    1315*/
    1416
     
    1719#include "util/loading/load_param.h"
    1820#include "util/loading/factory.h"
     21#include "util/loading/resource_manager.h"
    1922
    2023#include "glincl.h"
    21 //#include "graphics_engine.h"
     24#include "material.h"
    2225#include <math.h>
     26#include "state.h"
     27#include "p_node.h"
     28#include "shader.h"
     29#include "shell_command.h"
    2330
    2431#include "parser/tinyxml/tinyxml.h"
    2532
     33#include "sglmodel.h"
     34
    2635using namespace std;
     36
     37SHELL_COMMAND(activate, CloudEffect, activateCloud);
     38SHELL_COMMAND(deactivate, CloudEffect, deactivateCloud);
    2739
    2840CREATE_FACTORY(CloudEffect, CL_CLOUD_EFFECT);
     
    3749                this->loadParams(root);
    3850
    39         this->activate();
     51        if(cloudActivate)
     52                this->activate();
    4053}
    4154
     
    4356{
    4457        this->deactivate();
    45 }
     58
     59        delete this->cloudMaterial;
     60
     61        cloudModel.Delete();
     62        Shader::unload(this->cloudShader);
     63
     64}
     65
     66
     67bool 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
    46101
    47102void CloudEffect::loadParams(const TiXmlElement* root)
     
    49104        WeatherEffect::loadParams(root);
    50105
    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);
    72112        }
    73 }
     113        LOAD_PARAM_END_CYCLE(element);
     114}
     115
    74116
    75117bool CloudEffect::activate()
    76118{
    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       
    86123}
    87124
     
    89126{
    90127        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;
    113130}
    114131
    115132void CloudEffect::draw() const
    116133{
    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);
    119154        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);
    131210
    132211        glPopMatrix();
     212       
    133213}
    134214
    135215void CloudEffect::tick (float dt)
    136216{
    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.