Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //http://www.youtube.com/user/thecplusplusguy
- //generate heightmap
- #include <iostream>
- #include <SDL/SDL.h>
- #include <GL/gl.h>
- #include <GL/glu.h>
- #include "camera.h"
- #include "functions.h"
- #include <vector>
- #include <cstdlib>
- #include <ctime>
- camera cam;
- std::vector<std::vector<float> > heights;
- const int MAXWAVELENGTH=20;
- const int MINWAVELENGTH=1;
- const int WIDTH=101; //make sur, this is maxwavelength+1
- const int HEIGHT=101; //and this too
- const float SMOOTHNESS=2.0; //higher the value, smaller bumps has less effect
- const bool SMOOTHING=false; //the smoothing has aweird effect for the edges
- float interpolate(float a,float b, float perc)
- {
- //linear interpolation, cosine or quadric better
- return a*perc+b*(1-perc);
- }
- void generateNoise()
- {
- //create and fill the heights matrix with 0
- int img[HEIGHT][WIDTH];
- for(int i=0;i<HEIGHT;i++)
- {
- std::vector<float> tmp;
- for(int j=0;j<WIDTH;j++)
- {
- tmp.push_back(0);
- }
- heights.push_back(tmp);
- }
- int curwave=MAXWAVELENGTH;
- int lastVval,curVval;
- int lastVp,curpV;
- float perc=1.0;
- int lastHval,curHval;
- int lastpH,curpH;
- while(curwave>MINWAVELENGTH)
- {
- //fill up a the (curwave) rows with random values depending on the wavelength,look something like:
- //1 2 3 4 3 2 1
- //0 0 0 0 0 0 0
- //0 0 0 0 0 0 0
- //0 0 0 0 0 0 0
- //4 5 6 7 6 5 4
- //with 4 wavelength, with height 7x5, the first generated value 1, the next is 4 (interpolation between them give 2,3,)...
- for(int i=0;i<HEIGHT;i+=curwave)
- {
- curpH=lastpH=1;
- curHval=rand()%256;
- for(int j=0;j<WIDTH;j++)
- {
- if((j%curwave)==0)
- {
- lastHval=curHval;
- img[i][j]=curHval;
- curHval=rand()%256;
- lastpH=j%curwave;
- curpH=i+1;
- }else{
- float val=interpolate(lastHval,curHval,(float)1.0-((float)(j%curwave)/curwave));
- img[i][j]=(int)val;
- }
- }
- }
- //fill up the entire image, interpolate between the top and bottom value
- for(int i=0;i<HEIGHT;i++)
- {
- if((i%curwave)==0)
- continue;
- for(int j=0;j<WIDTH;j++)
- {
- float val=interpolate(img[(i/curwave)*curwave][j],img[((i+curwave)/curwave)*curwave][j],1.0-((float)(i%curwave)/curwave));
- img[i][j]=(int)val;
- }
- }
- //calculate an avarage of the images, irst wave has 100%, next 50%,25%...
- for(int i=0;i<HEIGHT;i++)
- {
- for(int j=0;j<WIDTH;j++)
- {
- //putPixel(SDL_GetVideoSurface(),j,i,img[i][j],img[i][j],img[i][j],perc);
- heights[i][j]=((perc*img[i][j]+(1-perc)*heights[i][j]));
- //std::cout << heights[i][j] << std::endl;
- }
- // std::cout << std::endl;
- }
- perc/=SMOOTHNESS;
- curwave/=2;
- }
- for(int i=0;i<HEIGHT;i++)
- {
- for(int j=0;j<WIDTH;j++)
- {
- if(SMOOTHING && i<HEIGHT-1 && j<WIDTH-1 && i>0 && j>0) //if smoothing, smooth
- heights[i][j]=(heights[i-1][j]+heights[i][j-1]+heights[i+1][j]+heights[i][j+1])/4.0;
- heights[i][j]/=255.0; //divide 255, so we get a number between 0,1
- }
- }
- }
- void loadHeightmap(const char* name)
- {
- SDL_Surface* img=SDL_LoadBMP(name);
- if(!img)
- {
- std::cout << "image is not loaded" << std::endl;
- return;
- }
- std::vector<float> tmp;
- for(int i=0;i<img->h;i++)
- {
- tmp.clear();
- for(int j=0;j<img->w;j++)
- {
- Uint32 pixel=((Uint32*)img->pixels)[i*img->pitch/4 + j];
- Uint8 r,g,b; //unsigned char
- SDL_GetRGB(pixel,img->format,&r,&g,&b);
- tmp.push_back((float)r/255.0); //0.0,1.0
- }
- heights.push_back(tmp);
- }
- }
- void renderHeightmap(float size,float h)
- {
- for(int i=0;i<heights.size()-1;i++)
- for(int j=0;j<heights[0].size()-1;j++)
- {
- glBegin(GL_TRIANGLE_STRIP);
- glColor3f(heights[i][j],heights[i][j],heights[i][j]);
- glVertex3f(i*size,heights[i][j]*h,j*size);
- glVertex3f((i+1)*size,heights[i+1][j]*h,j*size);
- glVertex3f(i*size,heights[i][j+1]*h,(j+1)*size);
- glVertex3f((i+1)*size,heights[i+1][j+1]*h,(j+1)*size);
- glEnd();
- }
- }
- void init(float angle)
- {
- glClearColor(0,0,0,1);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluPerspective(angle,640.0/480.0,1,1000);
- glMatrixMode(GL_MODELVIEW);
- initskybox();
- glEnable(GL_DEPTH_TEST);
- // loadHeightmap("heightmap.bmp");
- generateNoise();
- }
- void display()
- {
- glLoadIdentity();
- glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
- cam.Control();
- drawSkybox(50);
- cam.UpdateCamera();
- renderHeightmap(0.1,3);
- }
- int main()
- {
- SDL_Init(SDL_INIT_EVERYTHING);
- SDL_SetVideoMode(640,480,32,SDL_OPENGL);
- Uint32 start;
- SDL_Event event;
- srand(time(0));
- bool running=true;
- float angle=50;
- init(angle);
- bool b=false;
- srand(time(0));
- while(running)
- {
- start=SDL_GetTicks();
- while(SDL_PollEvent(&event))
- {
- switch(event.type)
- {
- case SDL_QUIT:
- running=false;
- break;
- case SDL_KEYDOWN:
- switch(event.key.keysym.sym)
- {
- case SDLK_ESCAPE:
- running=false;
- break;
- }
- break;
- case SDL_MOUSEBUTTONDOWN:
- cam.mouseIn(true);
- break;
- }
- }
- display();
- SDL_GL_SwapBuffers();
- if(1000.0/30>SDL_GetTicks()-start)
- SDL_Delay(1000.0/30-(SDL_GetTicks()-start));
- }
- killskybox();
- SDL_Quit();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement