Thread: Procedural Noise and OpenGL Help!

  1. #1
    CNewbie
    Join Date
    Nov 2005
    Location
    Oz
    Posts
    31

    Procedural Noise and OpenGL Help!

    I'm wondering if a kind soul, has the source-code to this tutorial.? http://www.gamedev.net/reference/art...rticle2085.asp

    I'm getting a few errors, (something about C99 standards), when compiling in CodeBlocks, when i copied the text from the page. (In the ForLoop mainly)

    I'm fairly much a newbie and have limited C and OGL skills. I do however understand most of what is happening, but i was hoping to compile this example and simplify.... I'm looking for C Source and not C++ which is all i seem to find when looking for similar examples.

    Technically unlike that Tutorial, i just want to render a 32x32 map of noise. No smoothing or octaves or mipmapping is needed. I just need to see something, before i go back and read up on every line of the code.

    The example tutorial is actually a little more advanced than what I'm trying to do. Eventually i would like to do my own terrain displacement, but for now the following would suffice.

    I'm trying to simply:
    1)Make a texture array,
    2)Generate procedural noise
    3)Fill Map array with a random procedural noise,
    4)Display the array via OGL.

    Any help on getting this a step further would be appreciated:

    Basically below i believe i have done steps 1 & 2.
    by declaring a MAP32, and generating a Noise function.

    I would like to now i guess fill the array with the data from noise function. But the pseudo-code gave me compiler errors, so anyone help me add this function....

    Code:
     #include <GL/gl.h> //include the gl header file
    #include <GL/glut.h> //include the glut header file
    
    float map32[32 * 32]; //Texture Array
    float Noise(int x, int y, int random) // Generate Noise
    {
        int n = x + y * 57 + random * 131;
        n = (n<<13) ^ n;
        return (1.0f - ( (n * (n * n * 15731 + 789221) +
                1376312589)&0x7fffffff)* 0.000000000931322574615478515625f);
    
    }
    
    void 
    
    int main (int argc, char **argv) {
    glutInit (&argc, argv); //initialize the program.
    glutInitDisplayMode (GLUT_SINGLE); //set up a basic display buffer (only singular for now)
    glutInitWindowSize (512, 512); //set whe width and height of the window
    glutInitWindowPosition (100, 100); //set the position of the window
    glutCreateWindow ("A basic OpenGL Window"); //set the caption for the window
    glutDisplayFunc (Noise); //call the display function to draw our world
    glutMainLoop (); //initialize the OpenGL loop cycle
    return 0;
     }
    PS No I'm not a student! (They generally have a much better grasp of what they are doing!)

  2. #2
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    void int
    is not a type

    make your main
    int main
    I'm getting a few errors
    show them
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  3. #3
    CNewbie
    Join Date
    Nov 2005
    Location
    Oz
    Posts
    31
    I should of pointed out more clearly. The code above is my beginning attempt it is missing mainly the loop of writing the noise to an array, and the actual GL drawing function. (currently it's pointing to "Noise" and it won't be really)... It should compile at that stage, but totally useless.) (Thanks for the void comment Varz, it was just a Cut and Paste accident

    My own attempt was going to remove the 3 following functions.

    Interpolate
    OverlapOctaves
    ExpFilter

    This would make the code much smaller, and i could add the rest and learn more about each of them individually. But it also seems to give me the 'for' loop initial declaration used outside C99 Mode? Whenever i wrote my own setnoise function.

    Anyway here is the initial code taken from the gamedev tutorial website. Which gives me 28 errors....

    I have included the complete code (well the code i hacked together from that tutorial).

    Code:
    #include <GL/gl.h> //include the gl header file
    #include <GL/glut.h> //include the glut header file
    
    float map32[32 * 32];
    float map256[256 * 256];
    
    float Noise(int x, int y, int random)
    {
        int n = x + y * 57 + random * 131;
        n = (n<<13) ^ n;
        return (1.0f - ( (n * (n * n * 15731 + 789221) +
                1376312589)&0x7fffffff)* 0.000000000931322574615478515625f);
    
    void SetNoise(float  *map)
    {
      float temp[34][34];
    
      int random=rand() % 5000;
    
      for (int y=1; y<33; y++)
      for (int x=1; x<33; x++)
      {
        temp[x][y] = 128.0f + Noise(x,  y,  random)*128.0f;
      }
      for (int x=1; x<33; x++)
      {
        temp[0][x] = temp[32][x];
        temp[33][x] = temp[1][x];
        temp[x][0] = temp[x][32];
        temp[x][33] = temp[x][1];
      }
      temp[0][0] = temp[32][32];
      temp[33][33] = temp[1][1];
      temp[0][33] = temp[32][1];
      temp[33][0] = temp[1][32];
      for (int y=1; y<33; y++)
        for (int x=1; x<33; x++)
        {
          float center = temp[x][y]/4.0f;
          float sides = (temp[x+1][y] + temp[x-1][y] + temp[x][y+1] + temp[x][y-1])/8.0f;
          float corners = (temp[x+1][y+1] + temp[x+1][y-1] + temp[x-1][y+1] + temp[x-1][y-1])/16.0f;
    
          map32[((x-1)*32) + (y-1)] = center + sides + corners;
        }
    }
    
    float Interpolate(float x, float y, float  *map)
    {
      int Xint = (int)x;
      int Yint = (int)y;
    
      float Xfrac = x - Xint;
      float Yfrac = y - Yint;
    
    
      int X0 = Xint % 32;
      int Y0 = Yint % 32;
      int X1 = (Xint + 1) % 32;
      int Y1 = (Yint + 1) % 32;
    
      float bot = map[X0*32 + Y0] + Xfrac * (map[X1*32 + Y0] - map[X0*32 + Y0]);
      float top = map[X0*32 + Y1] + Xfrac * (map[X1*32 +  Y1] - map[X0*32 + Y1]);
    
      return (bot + Yfrac * (top - bot));
    }
    
    void OverlapOctaves(float  *map32, float  *map256)
    {
      for (int x=0; x<256*256; x++)
      {
        map256[x] = 0;
      }
      for (int octave=0; octave<4; octave++)
        for (int x=0; x<256; x++)
          for (int y=0; y<256; y++)
          {
            float scale = 1 / pow(2, 3-octave);
            float noise = Interpolate(x*scale, y*scale , map32);
            map256[(y*256) + x] += noise / pow(2, octave);
          }
    }
    
    The octaves
    
    void ExpFilter(float  *map)
    {
      float cover = 20.0f;
      float sharpness = 0.95f;
    
      for (int x=0; x<256*256; x++)
      {
        float c = map[x] - (255.0f-cover);
        if (c<0)     c = 0;
        map[x] = 255.0f - ((float)(pow(sharpness, c))*255.0f);
      }
    }
    
    float map32[32 * 32];
    float map256[256 * 256];
    
    void Init()
    {
      SetNoise(map32);
    }
    
    void LoopForever()
    {
      OverlapOctaves(map32, map256);
      ExpFilter(map256);
    }
    
    
    void DrawGLScene()
    {
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
      glLoadIdentity();
    
      LoopForever();                   //Our cloud function
    
      char texture[256][256][3];       //Temporary array to hold texture RGB values
    
      for(int i=0; i<256; i++)         //Set cloud color value to temporary array
      for(int j=0; j<256; j++)
      {
        float color = map256[i*256+j];
        texture[i][j][0]=color;
        texture[i][j][1]=color;
        texture[i][j][2]=color;
      }
    
      unsigned int ID;                 //Generate an ID for texture binding
      glGenTextures(1, &ID);           //Texture binding
      glBindTexture(GL_TEXTURE_2D, ID);
    
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    
      gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, 256, 256, GL_RGB, GL_UNSIGNED_BYTE, texture);
    
      glMatrixMode(GL_TEXTURE);        //Let's move the clouds from left to right
      static float x;
      x+=0.01f;
      glTranslatef(x,0,0);
    
      glEnable(GL_TEXTURE_2D);         //Render the cloud texture
      glBegin(GL_QUADS);
      glTexCoord2d(1,1); glVertex3f(0.5f, 0.5f, 0.);
      glTexCoord2d(0,1); glVertex3f(-0.5f, 0.5f, 0.);
      glTexCoord2d(0,0); glVertex3f(-0.5f, -0.5f, 0.);
      glTexCoord2d(1,0); glVertex3f(0.5f, -0.5f, 0.);
      glEnd();
    
    //  SwapBuffers(hDC);
    }
    
    
    int main (int argc, char **argv) {
    glutInit (&argc, argv); //initialize the program.
    glutInitDisplayMode (GLUT_SINGLE); //set up a basic display buffer (only singular for now)
    glutInitWindowSize (512, 512); //set whe width and height of the window
    glutInitWindowPosition (100, 100); //set the position of the window
    glutCreateWindow ("A basic OpenGL Window"); //set the caption for the window
    glutDisplayFunc (DrawGLScene); //call the display function to draw our world
    glutMainLoop (); //initialize the OpenGL loop cycle
    return 0;
     }
    ||In function `SetNoise':|
    |18|warning: implicit declaration of function `rand'|
    |20|error: 'for' loop initial declaration used outside C99 mode|
    |21|error: 'for' loop initial declaration used outside C99 mode|
    |25|error: redefinition of 'x'|
    |21|error: previous definition of 'x' was here|
    |25|error: 'for' loop initial declaration used outside C99 mode|
    |36|error: redefinition of 'y'|
    |20|error: previous definition of 'y' was here|
    |36|error: 'for' loop initial declaration used outside C99 mode|
    |37|error: redefinition of 'x'|
    |25|error: previous definition of 'x' was here|
    |37|error: 'for' loop initial declaration used outside C99 mode|
    ||In function `OverlapOctaves':|
    |69|error: 'for' loop initial declaration used outside C99 mode|
    |73|error: 'for' loop initial declaration used outside C99 mode|
    |74|error: redefinition of 'x'|
    |69|error: previous definition of 'x' was here|
    |74|error: 'for' loop initial declaration used outside C99 mode|
    |75|error: 'for' loop initial declaration used outside C99 mode|
    |77|warning: implicit declaration of function `pow'|
    ||In function `Noise':|
    |83|error: `The' undeclared (first use in this function)|
    |83|error: (Each undeclared identifier is reported only once|
    |83|error: for each function it appears in.)|
    |83|error: syntax error before "octaves"|
    |90|error: 'x' redeclared as different kind of symbol|
    |7|error: previous definition of 'x' was here|
    |90|error: 'for' loop initial declaration used outside C99 mode|
    |92|error: `map' undeclared (first use in this function)|
    |92|error: `cover' undeclared (first use in this function)|
    ||In function `Init':|
    |103|warning: implicit declaration of function `SetNoise'|
    ||In function `LoopForever':|
    |108|warning: implicit declaration of function `OverlapOctaves'|
    |109|warning: implicit declaration of function `ExpFilter'|
    ||In function `DrawGLScene':|
    |122|error: 'for' loop initial declaration used outside C99 mode|
    |123|error: 'for' loop initial declaration used outside C99 mode|
    ||=== Build finished: 28 errors, 5 warnings ===|

  4. #4
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    implicit declaration of function `rand'
    #include <stdlib.h>

    Code:
    for (int y=1; y<33; y++)
    This is C++ or C99
    To compile in C89 mode - declare vars in the beginning of the block

    Code:
    int y;
    for (y=1; y<33; y++)
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  5. #5
    CNewbie
    Join Date
    Nov 2005
    Location
    Oz
    Posts
    31
    Quote Originally Posted by vart View Post
    implicit declaration of function `rand'
    #include <stdlib.h>

    Code:
    for (int y=1; y<33; y++)
    This is C++ or C99
    To compile in C89 mode - declare vars in the beginning of the block

    Code:
    int y;
    for (y=1; y<33; y++)

    Thanks for the explanation of C99, that is the main issue the stopped me from creating my own... So i will try again.

    It seems all code examples are in C++ these days, It would be nice to see some examples in C... It would likely be faster for me to learn more C++ syntax, than try and make simple noise in C and OGL... I

    Anyway it's late, i will try and some of your changes in the morning, i appreciate the quick response.

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    You can almost always use standard C constructs in C++, so if you wish to use a C++ compiler to compile your C code, most things will work - there are a few things that don't work out (and many minor details, but those are mostly unusual):
    1. void pointers need casts to convert them to other pointer types.
    2. private, public, new and delete are keywords (along with a few others, but those are again less likely to cause a problem).

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #7
    Crazy Fool Perspective's Avatar
    Join Date
    Jan 2003
    Location
    Canada
    Posts
    2,640
    I don't think "The octaves" is a valid line of code, not unless you have some clever #defines in one of those headers

  8. #8
    CNewbie
    Join Date
    Nov 2005
    Location
    Oz
    Posts
    31
    Thanks Octaves must of also been copied and pasted..

    Anyway here is revised code (I have tried to simplify) but i seem to be getting further away.. It would be nice to know the code works in the first place.

    Here is the latest:

    Code:
    #include <GL/gl.h> //include the gl header file
    #include <GL/glut.h> //include the glut header file
    #include <stdio.h>
    #include <math.h>
    #include <stdio.h>
    
    int i;
    int j;
    float map32[32 * 32];
    float map256[256 * 256];
    
    float Noise(int x, int y, int random)
    {
        int n = x + y * 57 + random * 131;
        n = (n<<13) ^ n;
        return (1.0f - ( (n * (n * n * 15731 + 789221) +
                1376312589)&0x7fffffff)* 0.000000000931322574615478515625f);
                }
    void SetNoise(float  *map)
    {
      float temp[34][34];
    int y;
    int x;
    
      int random=rand() % 5000;
    
      for (y=1; y<33; y++)
      for (x=1; x<33; x++)
      {
        temp[x][y] = 128.0f + Noise(x,  y,  random)*128.0f;
      }
    
      for (x=1; x<33; x++)
      {
        temp[0][x] = temp[32][x];
        temp[33][x] = temp[1][x];
        temp[x][0] = temp[x][32];
        temp[x][33] = temp[x][1];
      }
      temp[0][0] = temp[32][32];
      temp[33][33] = temp[1][1];
      temp[0][33] = temp[32][1];
      temp[33][0] = temp[1][32];
    
    
    void DrawGLScene()
    {
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
      glLoadIdentity();
    
    //  LoopForever();                   //Our cloud function
    
      char texture[256][256][3];       //Temporary array to hold texture RGB values
    
    for (i=0; i<256; i++)         //Set cloud color value to temporary array //'for' loop initial declaration used outside C99 mode"
    for (j=0; j<256; j++)        //'for' loop initial declaration used outside C99 mode"
      {
        float color = map256[i*256+j];
        texture[i][j][0]=color;
        texture[i][j][1]=color;
        texture[i][j][2]=color;
      }
    
      unsigned int ID;
      {                 //Generate an ID for texture binding
      glGenTextures(1, &ID);           //Texture binding
      glBindTexture(GL_TEXTURE_2D, ID);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    
      glEnable(GL_TEXTURE_2D);         //Render the cloud texture
      glBegin(GL_QUADS);
      glTexCoord2d(1,1); glVertex3f(0.5f, 0.5f, 0.);
      glTexCoord2d(0,1); glVertex3f(-0.5f, 0.5f, 0.);
      glTexCoord2d(0,0); glVertex3f(-0.5f, -0.5f, 0.);
      glTexCoord2d(1,0); glVertex3f(0.5f, -0.5f, 0.);
      glEnd();
      }
    
    int main (int argc, char **argv) {
    glutInit (&argc, argv); //initialize the program.
    glutInitDisplayMode (GLUT_SINGLE); //set up a basic display buffer (only singular for now)
    glutInitWindowSize (768, 768); //set whe width and height of the window
    glutInitWindowPosition (100, 100); //set the position of the window
    glutCreateWindow ("A basic OpenGL Window"); //set the caption for the window
    glutDisplayFunc (DrawGLScene); //call the display function to draw our world
    glutMainLoop (); //initialize the OpenGL loop cycle
    return 0;
    }
    ||In function `SetNoise':|
    |25|warning: implicit declaration of function `rand'|
    ||In function `DrawGLScene':|
    |80|warning: 'main' is normally a non-static function|
    |89|error: syntax error at end of input|
    ||=== Build finished: 1 errors, 2 warnings ===|

    Obviously I reduced the code to more like i was after, but getting some weird errors, if i fix the Syntax error, i get something like "undefined reference to ' WinMain@16'"

    I will look over it again now, but i think going C++, as that way i already have a lot of working example code...It's just a shame as I'm more familiar with C, and i like it that way!

    Thanks for the help so far, much appreciated.

  9. #9
    Nub SWE
    Join Date
    Mar 2008
    Location
    Dallas, TX
    Posts
    133
    You're missing a } at the end of DrawGLScene, if my eyes do not deceive me.

    Also, you're defining a few variables in the middle of your functions, which is not standard C.
    Last edited by JDGATX; 04-18-2008 at 08:11 AM.

Popular pages Recent additions subscribe to a feed