Advertisement
Guest User

Untitled

a guest
Oct 27th, 2012
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.91 KB | None | 0 0
  1. #include <algorithm>
  2. #include <fstream>
  3. #include <iostream>
  4. #include <sstream>
  5. #include <stdlib.h>
  6. #include <vector>
  7.  
  8. #include <gl/glut.h> // windows
  9.  
  10. #include "ImageLoader.h"
  11. #include "vec3f.h"
  12.  
  13. using namespace std;
  14.  
  15. int a = 128;
  16.  
  17. // Terrain
  18. class Terrain
  19. {
  20. private:
  21.     int _width;
  22.     int _length;
  23.     float** heights;
  24.     Vec3f** normals;
  25.     bool computedNormals;
  26.  
  27. public:
  28.     Terrain(int width2, int height2)
  29.     {
  30.         _width  = width2;
  31.         _length = height2;
  32.  
  33.         heights = new float*[_length];
  34.  
  35.         for(int i = 0; i < _length; i++)
  36.             heights[i] = new float[_width];
  37.  
  38.         normals = new Vec3f*[_length];
  39.  
  40.         for(int i = 0; i < _length; i++)
  41.             normals[i] = new Vec3f[_width];
  42.  
  43.         computedNormals = false;
  44.     }
  45.  
  46.     ~Terrain()
  47.     {
  48.         for(int i = 0; i < _length; i++)
  49.             delete[] heights[i];
  50.  
  51.         delete[] heights;
  52.  
  53.         for(int i = 0; i < _length; i++)
  54.             delete[] normals[i];
  55.  
  56.         delete[] normals;
  57.     }
  58.  
  59.     int width()  { return _width;  }
  60.     int length() { return _length; }
  61.  
  62.     void setHeight(int x, int z, float y)
  63.     {
  64.         heights[z][x] = y;
  65.         computedNormals = true;
  66.     }
  67.  
  68.     float getHeight(int x, int z) { return heights[z][x]; }
  69.  
  70.     void computeNormals()
  71.     {
  72.         if(computedNormals)
  73.             return;
  74.  
  75.         Vec3f** normals2 = new Vec3f*[_length];
  76.  
  77.         for(int i = 0; i < _length; i++)
  78.             normals2[i] = new Vec3f[_width];
  79.  
  80.         for(int z = 0; z < _length; z++)
  81.         {
  82.             for(int x = 0; x < _width; x++)
  83.             {
  84.                 Vec3f sun(0.0f, 0.0f, 0.0f);
  85.                 Vec3f out;
  86.                 Vec3f in;
  87.                 Vec3f left;
  88.                 Vec3f right;
  89.  
  90.                 if(z > 0)
  91.                     out = Vec3f(0.0f, heights[z - 1][x] - heights[z][x], -1.0f);
  92.                
  93.                 if(z < _length - 1)
  94.                     in = Vec3f(0.0f, heights[z + 1][x] - heights[z][x], 1.0f);
  95.  
  96.                 if(x > 0)
  97.                     left = Vec3f(-1.0f, heights[z][x - 1] - heights[z][x], 0.0f);
  98.  
  99.                 if(x > 0 && z > 0)
  100.                     sun += out.cross(left).normalize();
  101.  
  102.                 if(x > 0 && z < _length - 1)
  103.                     sun += left.cross(in).normalize();
  104.  
  105.                 if(x < _width - 1 && z < _length - 1)
  106.                     sun += in.cross(right).normalize();
  107.  
  108.                 if(x < _width - 1 && z > 0)
  109.                     sun += right.cross(out).normalize();
  110.  
  111.                 normals2[z][x] = sun;
  112.             }
  113.         }
  114.  
  115.         const float FALLOUT_RATIO = 0.5f;
  116.  
  117.         for(int z = 0; z < _length; z++)
  118.         {
  119.             for(int x = 0; x < _width; x++)
  120.             {
  121.                 Vec3f sun = normals2[z][x];
  122.  
  123.                 if(x > 0)
  124.                     sun += normals2[z][x - 1] * FALLOUT_RATIO;
  125.  
  126.                 if(x < _width - 1)
  127.                     sun += normals2[z][x + 1] * FALLOUT_RATIO;
  128.  
  129.                 if(z > 0)
  130.                     sun += normals2[z - 1][x] * FALLOUT_RATIO;
  131.  
  132.                 if(z < 0)
  133.                     sun += normals2[z + 1][x] * FALLOUT_RATIO;
  134.  
  135.                 if(sun.magnitude() == 0)
  136.                     sun = Vec3f(0.0f, 1.0f, 0.0f);
  137.  
  138.                 normals[z][x] = sun;
  139.             }
  140.         }
  141.  
  142.         for(int i = 0; i < _length; i++)
  143.             delete[] normals2[_length];
  144.  
  145.         delete[] normals2;
  146.  
  147.         computedNormals = true;
  148.     }
  149.  
  150.     Vec3f getNormal(int x, int z)
  151.     {
  152.         if(!computedNormals)
  153.             computeNormals();
  154.  
  155.         return normals[z][x];
  156.     }
  157. };
  158.  
  159. Terrain* loadTerrain(const char* fileName, float height)
  160. {
  161.     Bitmap* image = new Bitmap();
  162.     image->loadBMP(fileName);
  163.  
  164.     Terrain* t = new Terrain(image->width, image->height);
  165.  
  166.     for(int y = 0; y < image->height; y++)
  167.     {
  168.         for(int x = 0; x < image->width; x++)
  169.         {
  170.             unsigned char color = (unsigned char)image->data[3 * (y * image->width + x)];
  171.             float h = height * ((color / 255.0f) - 0.5f);
  172.  
  173.             t->setHeight(x, y, h);
  174.         }
  175.     }
  176.  
  177.     delete image;
  178.     t->computeNormals();
  179.  
  180.     return t;
  181. }
  182.  
  183. float _angle = 60.0f;
  184. Terrain* _terrain;
  185.  
  186. void cleanUp() { delete _terrain; }
  187.  
  188. void handleKeyPress(unsigned char key, int x, int y)
  189. {
  190.     switch(key)
  191.     {
  192.         case 27:
  193.             {
  194.                 cleanUp();
  195.                 exit(0);
  196.             }
  197.             break;
  198.     }
  199. }
  200.  
  201. void initRendering()
  202. {
  203.     glEnable(GL_DEPTH_TEST);
  204.     glEnable(GL_COLOR_MATERIAL);
  205.     glEnable(GL_LIGHTING);
  206.     glEnable(GL_NORMALIZE);
  207.     glEnable(GL_LINE_SMOOTH);
  208.     glEnable(GL_BLEND);
  209.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  210.     glShadeModel(GL_SMOOTH);
  211.  
  212.     glLineWidth(2.5f);
  213. }
  214.  
  215. void handleResze(int w, int h)
  216. {
  217.     glViewport(0, 0, w, h);
  218.     glMatrixMode(GL_PROJECTION);
  219.     glLoadIdentity();
  220.     gluPerspective(45.0, (double)w / (double)h, 1.0, 200.0);
  221. }
  222.  
  223. void drawScene()
  224. {
  225.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  226.     glClearColor(0.1f, 0.2f, 1.0f, 1.0f);
  227.  
  228.     glMatrixMode(GL_MODELVIEW);
  229.     glLoadIdentity();
  230.     glTranslatef(0.0f, 0.0f, -5.0f);
  231.     glRotatef(30.0f, 1.0f, 0.0f, 0.0f);
  232.     glRotatef(-_angle, 0.0f, 1.0f, 0.0f);
  233.  
  234.     GLfloat ambientColor[] = {0.4f, 0.4f, 0.4f, 1.0f};
  235.     glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientColor);
  236.  
  237.     GLfloat lightColor0[] = {0.6f, 0.6f, 0.6f, 1.0f};
  238.     GLfloat lightPos0[]   = {1.0f, 1.0f, 1.0f, 1.0f};
  239.     glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor0);
  240.     glLightfv(GL_LIGHT0, GL_POSITION, lightPos0);
  241.  
  242.     float scale = 5.0f / max(_terrain->width() - 1, _terrain->length() - 1);
  243.     glScalef(scale, scale, scale);
  244.     glTranslatef(-(float)(_terrain->width() - 1) / 2, 0.0f, -(float)(_terrain->length() - 1) / 2);
  245.  
  246.     glColor3f(0.0f, 1.0f, 0.0f);
  247.  
  248.     for(int z = 0; z < _terrain->length() - 1; z++)
  249.     {
  250.         glBegin(GL_TRIANGLE_STRIP);
  251.             for(int x = 0; x < _terrain->width(); x++)
  252.             {
  253.                 Vec3f normal = _terrain->getNormal(x, z);
  254.  
  255.                 glNormal3f(normal[0], normal[1], normal[2]);
  256.                 glVertex3f(x, _terrain->getHeight(x, z), z);
  257.                
  258.                 normal = _terrain->getNormal(x, z + 1);
  259.  
  260.                 glNormal3f(normal[0], normal[1], normal[2]);
  261.                 glVertex3f(x, _terrain->getHeight(x, z + 1), z + 1);
  262.             }
  263.         glEnd();
  264.     }
  265.  
  266.     glutSwapBuffers();
  267. }
  268.  
  269. void update(int value)
  270. {
  271.     _angle += 1.0f;
  272.  
  273.     if(_angle > 360)
  274.         _angle -= 360;
  275.  
  276.     glutPostRedisplay();
  277.     glutTimerFunc(25, update, 0);
  278. }
  279.  
  280. int main(int argc, char** argv)
  281. {
  282.     glutInit(&argc, argv);
  283.     glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  284.     glutInitWindowSize(800, 600);
  285.  
  286.     glutCreateWindow("C++ - OpenGL terrain rendering");
  287.     initRendering();
  288.  
  289.     _terrain = loadTerrain("heightmap.png", 10);
  290.  
  291.     glutDisplayFunc(drawScene);
  292.     glutKeyboardFunc(handleKeyPress);
  293.     glutReshapeFunc(handleResze);
  294.     glutTimerFunc(25, update, 0);
  295.  
  296.     glutMainLoop();
  297.  
  298.     return 0;
  299. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement