Guest User

Hex

a guest
Aug 7th, 2013
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.62 KB | None | 0 0
  1. #include "Window.h"
  2. #include <SDL/SDL_main.h>
  3. #include "Shader.h"
  4. #include <bitset>
  5. #include <vector>
  6. #include <glm/glm.hpp>
  7. #include <glm/gtc/matrix_transform.hpp>
  8.  
  9. #pragma comment(lib, "glu32.lib")
  10.  
  11. GLuint LoadTexture(const char* name)
  12. {  
  13.     GLuint pData = 0;
  14.     SDL_Surface* Image;
  15.  
  16.     Image = IMG_Load(name);
  17.     if (Image)
  18.     {
  19.         glGenTextures(1, &pData);
  20.         glBindTexture(GL_TEXTURE_2D, pData);
  21.         int Mode = GL_RGB;
  22.  
  23.         if(Image->format->BytesPerPixel == 4) {
  24.             Mode = GL_RGBA;
  25.         }
  26.  
  27.         glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
  28.         glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_LINEAR);
  29.  
  30.         gluBuild2DMipmaps( GL_TEXTURE_2D, Image->format->BytesPerPixel, Image->w, Image->h, Mode, GL_UNSIGNED_BYTE, Image->pixels);
  31.     }
  32.  
  33.     return pData;
  34. }
  35.  
  36. float BilinearInterpolation(unsigned char* heights ,float x, float y, float scale,float texw)
  37. {
  38.     float floorx = glm::floor(x);
  39.     float floory = glm::floor(y);
  40.     float ceilx = glm::ceil(x);
  41.     float ceily = glm::ceil(y);
  42.  
  43.     if(floory == ceily)
  44.         ceily += 1.0;
  45.  
  46.     if(floorx == ceilx)
  47.         ceilx += 1.0;
  48.  
  49.     if(ceilx > texw-1)
  50.         ceilx = texw-1;
  51.  
  52.     float h00 = (float)(heights[(int)((floorx * texw + floory))*4]) * scale;
  53.     float h01 = (float)(heights[(int)((floorx * texw + ceily))*4]) * scale;
  54.     float h10 = (float)(heights[(int)((ceilx * texw + floory))*4]) * scale;
  55.     float h11 = (float)(heights[(int)((ceilx * texw + ceily))*4]) * scale;
  56.  
  57.     float fx = x - floorx;
  58.     float fy = y - floory;
  59.  
  60.     float hor0 = h10 * fx + h00 * (1-fx);
  61.     float hor1 = h11 * fx + h01 * (1-fx);
  62.  
  63.     return hor1 * fy + hor0 * (1-fy);
  64. }
  65.  
  66. int main(int argc, char *argv[])
  67. {
  68.     Window window; //create Window
  69.     window.Initialize(); //init it
  70.  
  71.     GLuint shader = LoadShader("terrain.vert","terrain.frag");
  72.  
  73.     int nhexagonsX = 150;
  74.     int nhexagonsY = 200;
  75.     int nhexagons = (nhexagonsX / 2) * nhexagonsY + (nhexagonsY / 2) * (nhexagonsX % 2);
  76.     float hexwidth = 0.2f;
  77.  
  78.     float xdim = (0.5f + nhexagonsX * 1.5f) * hexwidth;
  79.     float ydim = (1.0f + nhexagonsY)  * hexwidth;
  80.  
  81.     xdim = glm::ceil(xdim);
  82.     ydim = glm::ceil(ydim);
  83.  
  84.     float mapres = 1;
  85.  
  86.  
  87.     int texw = (int)(glm::pow(2.0f,glm::ceil(glm::log2(xdim*mapres))));
  88.     int texh = (int)(glm::pow(2.0f,glm::ceil(glm::log2(ydim*mapres))));
  89.  
  90.     GLuint tilemap;
  91.     glGenTextures(1,&tilemap);
  92.     glBindTexture(GL_TEXTURE_2D,tilemap);
  93.  
  94.     unsigned char *tiles = new unsigned char[texw * texh];
  95.  
  96.     srand(SDL_GetTicks());
  97.     for(int n = 0; n < texw * texh; n++)
  98.     {
  99.         tiles[n] = 0xFF * ((float)(rand()) / (float)(RAND_MAX));
  100.     }
  101.  
  102.     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
  103.     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
  104.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  105.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  106.  
  107.  
  108.     glTexImage2D(GL_TEXTURE_2D,0,1,texw,texh,0,GL_RED,GL_UNSIGNED_BYTE,tiles);
  109.  
  110.     delete[] tiles;
  111.  
  112.     GLuint hmap;
  113.     glGenTextures(1,&hmap);
  114.     glBindTexture(GL_TEXTURE_2D,hmap);
  115.  
  116.     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
  117.     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
  118.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  119.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  120.  
  121.     glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,texw,texh,0,GL_RGBA,GL_UNSIGNED_BYTE,NULL);
  122.  
  123.     GLuint shader2 = LoadShader("perlin.vert","perlin.frag");
  124.  
  125.     GLuint FBO;
  126.     glGenFramebuffers(1, &FBO);
  127.     glBindFramebuffer(GL_FRAMEBUFFER,FBO);
  128.     glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,hmap,0);
  129.  
  130.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  131.  
  132.     glUseProgram(shader2);
  133.  
  134.     glActiveTexture(GL_TEXTURE0);
  135.     glBindTexture(GL_TEXTURE_2D,tilemap);
  136.     glUniform1i(glGetUniformLocation(shader2, "map"),0);
  137.  
  138.     glBegin(GL_QUADS);
  139.         glVertex3f(-1.0f,-1.0f,0.0f);
  140.         glVertex3f(1.0f,-1.0f,0.0f);
  141.         glVertex3f(1.0f,1.0f,0.0f);
  142.         glVertex3f(-1.0f,1.0f,0.0f);
  143.     glEnd();
  144.  
  145.     glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,0,0);
  146.     glBindFramebuffer(GL_FRAMEBUFFER,0);
  147.  
  148.     unsigned char* heights = new unsigned char[4 * texw * texh];
  149.     glBindTexture(GL_TEXTURE_2D,hmap);
  150.     glGetTexImage(GL_TEXTURE_2D,0,GL_RGBA,GL_UNSIGNED_BYTE,heights);
  151.  
  152.     std::vector<glm::vec3> mesh;
  153.  
  154.     bool shift = true;
  155.  
  156.     int npoints = (nhexagonsX / 2) + ((nhexagonsX / 2) + (nhexagonsX % 2)) * 2 + 1;
  157.  
  158.     for(int y = 0; y < nhexagonsY + 2; y++)
  159.     {
  160.         for(int x = 0; x < npoints; x++)
  161.         {
  162.             if(x == npoints - 1)
  163.                 y = y;
  164.  
  165.             if(shift)
  166.             {
  167.                 mesh.push_back(glm::vec3((x+0.5) * hexwidth,0.0f,y * hexwidth));
  168.             }
  169.             else
  170.             {
  171.                 mesh.push_back(glm::vec3((x) * hexwidth,0.0f,y * hexwidth));
  172.             }
  173.  
  174.             glm::vec3 last = mesh[mesh.size() -1];
  175.             mesh[mesh.size() -1].y = BilinearInterpolation(heights,last.x * ((float)(texw) / xdim),last.z * ((float)(texh) / ydim),0.1f,texw);
  176.         }
  177.         shift = !shift;
  178.     }
  179.  
  180.     GLuint IBO;
  181.     glGenBuffers(1,&IBO);
  182.     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,IBO);
  183.  
  184.     unsigned int* indices = new unsigned int[nhexagons * 6 * 3];
  185.  
  186.     int i = 0;
  187.  
  188.     for(int yc = 0; yc < nhexagonsY; yc++)
  189.     {
  190.         int xlen = (nhexagonsX / 2) - (yc % 2) * (nhexagonsX % 2);
  191.         for(int xc = 0; xc < xlen; xc++)
  192.         {
  193.             int y = yc;
  194.             glm::ivec3 x = glm::ivec3(3 * xc,3*xc,3*xc);
  195.             if(yc%2)
  196.             {
  197.                 x+=glm::ivec3(2,1,2);
  198.             }
  199.  
  200.             float aveheight = 0.0f;
  201.  
  202.             indices[i++] = (y+1) * npoints + (x[1]+1);
  203.             indices[i++] = y * npoints + (x[0]+1);
  204.             indices[i++] = y * npoints + x[0];
  205.             aveheight += mesh[indices[i-2]].y;
  206.  
  207.             indices[i++] = (y+1) * npoints + (x[1]+1);
  208.             indices[i++] = (y+1) * npoints + (x[1]+2);
  209.             indices[i++] = y * npoints + (x[0]+1);
  210.             aveheight += mesh[indices[i-2]].y;
  211.  
  212.             indices[i++] = (y+1) * npoints + (x[1]+1);
  213.             indices[i++] = (y+2) * npoints + (x[2]+1);
  214.             indices[i++] = (y+1) * npoints + (x[1]+2);
  215.             aveheight += mesh[indices[i-2]].y;
  216.  
  217.             indices[i++] = (y+1) * npoints + (x[1]+1);
  218.             indices[i++] = (y+2) * npoints + x[2];
  219.             indices[i++] = (y+2) * npoints + (x[2]+1);
  220.             aveheight += mesh[indices[i-2]].y;
  221.  
  222.             indices[i++] = (y+1) * npoints + (x[1]+1);
  223.             indices[i++] = (y+1) * npoints + x[1];
  224.             indices[i++] = (y+2) * npoints + x[2];
  225.             aveheight += mesh[indices[i-2]].y;
  226.  
  227.             indices[i++] = (y+1) * npoints + (x[1]+1);
  228.             indices[i++] = y * npoints + x[0];
  229.             indices[i++] = (y+1) * npoints + x[1];
  230.             aveheight += mesh[indices[i-2]].y;
  231.  
  232.             mesh[indices[i-3]].y = aveheight / 6.0f;
  233.         }
  234.     }
  235.  
  236.     glBufferData(GL_ELEMENT_ARRAY_BUFFER,nhexagons * 6 * 3 * sizeof(unsigned int),indices,GL_STATIC_DRAW);
  237.  
  238.     delete[] indices;
  239.  
  240.     GLuint VBO;
  241.  
  242.     glGenBuffers(1,&VBO);
  243.  
  244.     float* data = new float[mesh.size() * 3];
  245.  
  246.     for(int n = 0; n < mesh.size(); n++)
  247.     {
  248.         memcpy(data + 3 * n, &(mesh[n].x),3*sizeof(float));
  249.     }
  250.  
  251.     glBindBuffer(GL_ARRAY_BUFFER,VBO);
  252.     glBufferData(GL_ARRAY_BUFFER,mesh.size() * 3 * sizeof(float),data,GL_STATIC_DRAW);
  253.     delete[] data;
  254.  
  255.     glEnableClientState(GL_VERTEX_ARRAY);
  256.     glVertexPointer(3, GL_FLOAT, 0, ((char*)NULL));  
  257.  
  258.     glm::mat4 P = glm::perspective(60.0f,4.0f/3.0f,0.1f,500.0f);
  259.     glm::mat4 V = glm::rotate(glm::mat4(1.0f),0.0f,glm::vec3(1.0f,0.0f,0.0f)) * glm::rotate(glm::mat4(1.0f),90.0f,glm::vec3(0.0f,1.0f,0.0f));
  260.     V = glm::translate(glm::mat4(1.0f),glm::vec3(0.0f,-3.0f,0.0f)) * V;
  261.     glm::mat4 VP = P * V;
  262.  
  263.     //glPolygonMode(GL_FRONT,GL_LINE);
  264.  
  265.     glBindTexture(GL_TEXTURE_2D,0);
  266.  
  267.     while(true)
  268.     {
  269.         glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
  270.  
  271.         glUseProgram(shader);
  272.  
  273.         glUniformMatrix4fv(glGetUniformLocation(shader,"WVP"),1,GL_FALSE,&(VP[0][0]));
  274.  
  275.         glUniform1i(glGetUniformLocation(shader,"npoints"),npoints);
  276.  
  277.         glDrawElements(GL_TRIANGLES, nhexagons * 6 * 3,GL_UNSIGNED_INT,NULL);
  278.  
  279.         SDL_GL_SwapBuffers();
  280.     }
  281.  
  282.     return 0;
  283. }
Advertisement
Add Comment
Please, Sign In to add comment