Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
May 23, 2006, 12:06:44 PM (18 years ago)
Author:
amaechler
Message:

branches/atmospheric_engine: cloud hacking

File:
1 edited

Legend:

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

    r7679 r7768  
    11/*
    2    orxonox - the future of 3D-vertical-scrollers
    3 
    4    Copyright (C) 2004 orx
    5 
    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.
     2        orxonox - the future of 3D-vertical-scrollers
     3
     4        Copyright (C) 2004 orx
     5
     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.
    1010
    1111### File Specific:
    12    main-programmer: hdavid, amaechler
     12        main-programmer: hdavid, amaechler
    1313*/
    1414
     
    1919
    2020#include "glincl.h"
     21#include "graphics_engine.h"
     22
    2123
    2224#include "parser/tinyxml/tinyxml.h"
     
    5254{
    5355        //Default values
     56
     57        CloudEffect::setNoise(map32);
     58
    5459}
    5560
    5661bool CloudEffect::activate()
    5762{
    58         PRINTF(0)( "Activating CloudEffect ");
     63        PRINTF(0)( "Activating CloudEffect\n");
     64
     65        //Our cloud function 
     66        CloudEffect::overlapOctaves(map32, map256);
     67        CloudEffect::expFilter(map256);
     68
     69        for(int i=0; i<256; i++)         //Set cloud color value to temporary array
     70                for(int j=0; j<256; j++)
     71                {
     72                        float color = map256[i*256+j];
     73                        texture[i][j][0] = color;
     74                        texture[i][j][1] = color;
     75                        texture[i][j][2] = color;
     76                }
     77
     78                /* for(int n=0; n<256; n++) {
     79                        for(int i=0; i<256; i++)
     80                                PRINTF(0)("%f ", map256[n*i]);
     81                        PRINTF(0)("\n");
     82                } */
     83
     84        unsigned int ID;                 //Generate an ID for texture binding
     85        glGenTextures(1, &ID);           //Texture binding
     86        glBindTexture(GL_TEXTURE_2D, ID);
     87
     88        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
     89        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
     90        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
     91        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
     92       
     93        gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, 256, 256, GL_RGB, GL_UNSIGNED_BYTE, texture);
     94
    5995}
    6096
     
    65101}
    66102
     103void CloudEffect::draw() const
     104{
     105        glPushAttrib(GL_ENABLE_BIT);
     106        glEnable(GL_TEXTURE_2D);
     107        glMatrixMode(GL_MODELVIEW);
     108        glPushMatrix();
     109
     110        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     111
     112        glEnable(GL_TEXTURE_2D);
     113
     114        //glLoadIdentity();
     115
     116        //glMatrixMode(GL_TEXTURE);        //Let's move the clouds from left to right
     117        //static float x;   
     118        //x+=0.01f;
     119        //glTranslatef(x,0,0);
     120
     121        glBegin(GL_QUADS);
     122                // Front Face
     123                glTexCoord2f(0.0f, 0.0f); glVertex3f(-100.0f, -100.0f,  100.0f);        // Bottom Left Of The Texture and Quad
     124                glTexCoord2f(1.0f, 0.0f); glVertex3f( 100.0f, -100.0f,  100.0f);        // Bottom Right Of The Texture and Quad
     125                glTexCoord2f(1.0f, 1.0f); glVertex3f( 100.0f,  100.0f,  100.0f);        // Top Right Of The Texture and Quad
     126                glTexCoord2f(0.0f, 1.0f); glVertex3f(-100.0f,  100.0f,  100.0f);        // Top Left Of The Texture and Quad
     127        glEnd();
     128
     129        glPopMatrix();
     130        glPopAttrib();
     131
     132}
     133
    67134void CloudEffect::tick (float dt)
    68135{
    69 
    70 }
     136}
     137
     138/*
     139        Random noise generator
     140*/
     141float CloudEffect::noise(int x, int y, int random)
     142{
     143                int n = x + y * 57 + random * 131;
     144                n = (n<<13) ^ n;
     145                return (1.0f - ( (n * (n * n * 15731 + 789221) +
     146                                                1376312589)&0x7fffffff)* 0.000000000931322574615478515625f);
     147}
     148
     149/*
     150        Set noise for the 32*32 noise map:
     151*/
     152void CloudEffect::setNoise(float  *map)
     153{
     154        float temp[34][34];
     155
     156/* We declare a temporary array to make our function cleaner. Why does the array hold 34*34 elements instead of 32*32? This is because we will need extra elements for side and corner mirroring, as we shall see soon. */
     157
     158        int random = rand() % 5000;
     159
     160        for (int y = 1; y < 33; y++)
     161                for (int x = 1; x < 33; x++)
     162                        temp[x][y] = 128.0f + CloudEffect::noise(x,  y,  random) * 128.0f;
     163
     164        // Seamless cloud
     165        for (int x=1; x<33; x++)
     166        {
     167                temp[0][x] = temp[32][x];
     168                temp[33][x] = temp[1][x];
     169                temp[x][0] = temp[x][32];
     170                temp[x][33] = temp[x][1];
     171        }
     172        temp[0][0] = temp[32][32];
     173        temp[33][33] = temp[1][1];
     174        temp[0][33] = temp[32][1];
     175        temp[33][0] = temp[1][32];
     176
     177        // We mirror the side and corner elements so our final cloud will be seamless without any ugly borders showing.
     178        for (int y=1; y<33; y++)
     179                for (int x=1; x<33; x++)
     180                {
     181                        float center = temp[x][y]/4.0f;
     182                        float sides = (temp[x+1][y] + temp[x-1][y] + temp[x][y+1] + temp[x][y-1])/8.0f;
     183                        float corners = (temp[x+1][y+1] + temp[x+1][y-1] + temp[x-1][y+1] + temp[x-1][y-1])/16.0f;
     184
     185                        map32[((x-1)*32) + (y-1)] = center + sides + corners;
     186                }
     187}
     188
     189/*
     190        Interpolation - average the value of each pixel value with that of its neighbors' values.
     191*/
     192float CloudEffect::interpolate(float x, float y, float  *map)
     193{
     194        int Xint = (int)x;
     195        int Yint = (int)y;
     196
     197        float Xfrac = x - Xint;
     198        float Yfrac = y - Yint;
     199
     200        int X0 = Xint % 32;
     201        int Y0 = Yint % 32;
     202        int X1 = (Xint + 1) % 32;
     203        int Y1 = (Yint + 1) % 32;
     204
     205        float bot = map[X0*32 + Y0] + Xfrac * (map[X1*32 + Y0] - map[X0*32 + Y0]);
     206        float top = map[X0*32 + Y1] + Xfrac * (map[X1*32 +  Y1] - map[X0*32 + Y1]);
     207
     208        return (bot + Yfrac * (top - bot));
     209}
     210
     211
     212/*
     213        Octaves are overlapped together to give cloud more turbulence. We will use four octaves for our cloud.
     214*/
     215void CloudEffect::overlapOctaves(float  *map32, float  *map256)
     216{
     217        for (int x=0; x<256*256; x++)
     218        {
     219                map256[x] = 0;
     220        }
     221
     222        for (int octave=0; octave<4; octave++)
     223                for (int x=0; x<256; x++)
     224                        for (int y=0; y<256; y++)
     225                        {
     226                                float scale = 1 / pow(2, 3-octave);
     227                                float noise = CloudEffect::interpolate(x*scale, y*scale , map32);
     228
     229                                //The octaves are added together with the proper weight factors.
     230                                //You could replace pow(2, i) with 1<<i for faster computation
     231                                map256[(y*256) + x] += noise / pow(2, octave);
     232                        }
     233}
     234
     235
     236/*
     237        Filter the noise with exponential function
     238*/
     239void CloudEffect::expFilter(float  *map)
     240{
     241        float cover = 20.0f;
     242        float sharpness = 0.95f;
     243
     244        for (int x=0; x<256*256; x++)
     245        {
     246                float c = map[x] - (255.0f-cover);
     247                if (c<0)     c = 0;
     248                map[x] = 255.0f - ((float)(pow(sharpness, c))*255.0f);
     249        }
     250}
Note: See TracChangeset for help on using the changeset viewer.