Advertisement
thecplusplusguy

OpenGL calculate normal vectors for heightmap

Mar 31st, 2013
404
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.45 KB | None | 0 0
  1. //http://www.youtube.com/user/thecplusplusguy
  2. //calculate the normal vectors for the terrain
  3. #include <iostream>
  4. #include <SDL/SDL.h>
  5. #include <GL/gl.h>
  6. #include <GL/glu.h>
  7. #include "camera.h"
  8. #include "functions.h"
  9. #include <vector>
  10.  
  11. camera cam;
  12. std::vector<std::vector<float> > heights;
  13. std::vector<std::vector<vector3d> > normal;
  14. bool drawNormal=true;   //draw out the normals as lines, if you want.
  15.  
  16. void loadHeightmap(const char* name)
  17. {
  18.     SDL_Surface* img=SDL_LoadBMP(name);
  19.     if(!img)
  20.     {
  21.         std::cout << "image is not loaded" << std::endl;
  22.         return;
  23.     }
  24.     std::vector<float> tmp;
  25.     for(int i=0;i<img->h;i++)
  26.     {
  27.         tmp.clear();
  28.         for(int j=0;j<img->w;j++)
  29.         {
  30.             Uint32 pixel=((Uint32*)img->pixels)[i*img->pitch/4 + j];
  31.             Uint8 r,g,b;    //unsigned char
  32.             SDL_GetRGB(pixel,img->format,&r,&g,&b);
  33.             tmp.push_back((float)r/255.0);  //0.0,1.0
  34.         }
  35.         heights.push_back(tmp);
  36.     }
  37. }
  38.  
  39. void renderHeightmap(float size,float h)
  40. {
  41.     float dif[]={0.3,0.8,0.3};
  42.     glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,dif);
  43.     for(int i=0;i<heights.size()-1;i++)
  44.         for(int j=0;j<heights[0].size()-1;j++)
  45.         {
  46.                 vector3d v1(i*size,heights[i][j]*h,j*size);             //3 point for a triangle in the terrain
  47.                 vector3d v2((i+1)*size,heights[i+1][j]*h,j*size);
  48.                 vector3d v3(i*size,heights[i][j+1]*h,(j+1)*size);
  49.                 vector3d vec1=v2-v1;    //two vectors from the triangle
  50.                 vector3d vec2=v3-v1;
  51.             //  vec1.normalize();
  52.             //  vec2.normalize();
  53.                 vector3d normal=vec2.crossProduct(vec1);    //cross product gives the normal vector
  54.                 normal.normalize();
  55.             glBegin(GL_TRIANGLE_STRIP);
  56.                 //glColor3f(heights[i][j],heights[i][j],heights[i][j]);
  57.                 glNormal3f(normal.x,normal.y,normal.z);
  58.                 glVertex3f(i*size,heights[i][j]*h,j*size);
  59.                 glVertex3f((i+1)*size,heights[i+1][j]*h,j*size);
  60.                 glVertex3f(i*size,heights[i][j+1]*h,(j+1)*size);
  61.                 glVertex3f((i+1)*size,heights[i+1][j+1]*h,(j+1)*size);
  62.             glEnd();
  63.             if(drawNormal)
  64.             {
  65.                 glDisable(GL_LIGHTING);
  66.                 glBegin(GL_LINES);
  67.                     glColor3f(1.0,0.0,0.0);
  68.                     glVertex3f(i*size,heights[i][j]*h,j*size);
  69.                     normal/=10.0;
  70.                     v1+=normal;
  71.                     glVertex3f(v1.x,v1.y,v1.z);
  72.                 glEnd();
  73.                 glEnable(GL_LIGHTING);
  74.             }
  75.         }
  76. }
  77.  
  78. void init(float angle)
  79. {
  80.     glClearColor(0,0,0,1);
  81.     glMatrixMode(GL_PROJECTION);
  82.         glLoadIdentity();
  83.         gluPerspective(angle,640.0/480.0,0.1,1000);
  84.     glMatrixMode(GL_MODELVIEW);
  85.     //initskybox();
  86.     glEnable(GL_LIGHTING);
  87.     glEnable(GL_LIGHT0);
  88.  
  89.     glEnable(GL_DEPTH_TEST);
  90.     loadHeightmap("heightmap.bmp");
  91. }
  92.  
  93. void display()
  94. {
  95.     glLoadIdentity();
  96.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  97.     cam.Control();
  98.     //drawSkybox(50);
  99.        
  100.     cam.UpdateCamera();
  101.     //float pos[]={0,10,0};
  102.     //glLightfv(GL_LIGHT0,GL_POSITION,pos);
  103.     renderHeightmap(0.1,1.0);
  104.    
  105. }
  106.  
  107. int main()
  108. {
  109.     SDL_Init(SDL_INIT_EVERYTHING);
  110.     SDL_SetVideoMode(640,480,32,SDL_OPENGL);
  111.     Uint32 start;
  112.     SDL_Event event;
  113.     bool running=true;
  114.     float angle=50;
  115.     init(angle);
  116.     bool b=false;
  117.     while(running)
  118.     {
  119.         start=SDL_GetTicks();
  120.         while(SDL_PollEvent(&event))
  121.         {
  122.             switch(event.type)
  123.             {
  124.                 case SDL_QUIT:
  125.                     running=false;
  126.                     break;
  127.                 case SDL_KEYDOWN:
  128.                     switch(event.key.keysym.sym)
  129.                     {
  130.                         case SDLK_ESCAPE:
  131.                             running=false;
  132.                             break;
  133.                     }
  134.                     break;
  135.                 case SDL_MOUSEBUTTONDOWN:
  136.                     cam.mouseIn(true);
  137.                     break;
  138.                    
  139.             }
  140.         }
  141.         display();
  142.         SDL_GL_SwapBuffers();
  143.         if(1000.0/30>SDL_GetTicks()-start)
  144.             SDL_Delay(1000.0/30-(SDL_GetTicks()-start));
  145.     }
  146.     SDL_Quit();
  147. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement