zoukankan      html  css  js  c++  java
  • OpenGL地形建模

    使用了OpenGL 3.0以及freeglut进行的C++编程,地形数据读取于一个DEM模型

    地形效果如下,使用了基本的三角形进行绘图,外加一点简单的光照。贴图没有搞上,正在研究

    第一次用OpenGL编程,还有很多地方需要提高,源码见后

      1 #include <iostream>
      2 #include <fstream>
      3 #include <string>
      4 #include <sstream>
      5 #include <soil.h>
      6 
      7 using namespace std;
      8 
      9 #include <gl/freeglut.h>
     10 //#include <gl/glaux.h>
     11 
     12 #pragma comment(lib, "soil.lib")
     13 
     14 #define C 2701
     15 #define R 1801
     16 #define CELLSIZE 50
     17 
     18 #define W 256
     19 #define H 256
     20 
     21 //=========================================3-1 P.80
     22 
     23 static GLfloat spin = 0;
     24 static GLfloat spin_x = 0;
     25 static GLfloat spin_y = 0;
     26 static GLfloat old_x = 0;
     27 static GLfloat old_y = 0;
     28 
     29 static GLfloat camerap[3] = {0, 1000, 0};
     30 static GLfloat cameras[3] = {5000, 0, 0};
     31 
     32 static int datas [R][C];
     33 static float vectors [(R - 1) * 2][C - 1][3];//The [3] in the last is for x, y and z
     34 static float normals [R][C][3];
     35 
     36 static GLuint texName;
     37 //static GLubyte grassImage [H][W][4];
     38 
     39 void init (void)
     40 {
     41     //Light
     42     GLfloat mat_specular[] = {1, 1, 1, 0};
     43     GLfloat mat_shininess[] = {1000};
     44     GLfloat light_position[] = {5000, 5000, 5000, 0};
     45     GLfloat a_light[] = {1.0f, 1.0f, 1.0f, 1};
     46     GLfloat lmodel_ambient[] = {0.8, 0.8, 0.8, 1};
     47 
     48     glClearColor(1, 1, 1, 0);
     49     glShadeModel(GL_SMOOTH);//----------------
     50     glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
     51     glLightfv(GL_LIGHT0, GL_POSITION, light_position);
     52     glLightfv(GL_LIGHT0, GL_DIFFUSE, a_light);
     53     glLightfv(GL_LIGHT0, GL_SPECULAR, a_light);
     54     glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
     55 
     56     glEnable(GL_LIGHTING);
     57     glEnable(GL_LIGHT0);
     58     glEnable(GL_DEPTH_TEST);
     59     glShadeModel(GL_FLAT);
     60     
     61     //Load terrain data
     62     char str[C * 4 + 1];
     63     string sdatas;
     64     ifstream terrainFile(".\\res\\dem.asc");
     65     if(!terrainFile)
     66     {
     67         cerr<<"File is not opened."<<endl;
     68     }
     69     cout<<"Terrain file is opened."<<endl<<endl;
     70     for (int i = 1; i <= 13; i++)
     71     {
     72         terrainFile.getline(str, C * 4 + 1);
     73         cout<<str<<endl;
     74     }
     75     cout<<endl<<"Loading terrain data...";
     76     for (int i = 0; i < R; i++)
     77     {
     78         terrainFile.getline(str, C * 4 + 1);
     79         sdatas = str;
     80         istringstream datastream(sdatas);
     81         for (int j = 0; j < C; j++)
     82         {
     83             datastream>>datas[i][j];
     84             //cout<<datas[i][j]<<" ";//just for testing
     85         }
     86     }
     87     cout<<endl<<"Terrain data is loaded."<<endl;
     88     
     89     cout<<endl<<"Setting triangle normal vectors...";
     90     int uy, vy;
     91     for (int i = 0; i < (R - 1) * 2; i++)
     92     {
     93         if (i % 2 == 0)
     94         {
     95             for (int j = 0; j < C - 1; j++)
     96             {
     97                 uy = datas[i / 2][j] - datas[i / 2][j + 1];
     98                 vy = datas[(i / 2) + 1][j] - datas[i / 2][j];
     99                 vectors[i][j][0] = uy;//
    100                 vectors[i][j][1] = 1;//
    101                 vectors[i][j][2] = -vy;//
    102             }
    103         }
    104         else
    105         {
    106             for (int j = 0; j < C - 1; j++)
    107             {
    108                 uy = datas[(i / 2) + 1][j + 1] - datas[(i / 2) + 1][j];
    109                 vy = datas[i / 2][j + 1] - datas[(i / 2) + 1][j + 1];
    110                 vectors[i][j][0] = -uy;//
    111                 vectors[i][j][1] = 1;//
    112                 vectors[i][j][2] = vy;//
    113             }
    114         }
    115     }
    116     cout<<endl<<"Triangle normal vectors set."<<endl;
    117 
    118     cout<<endl<<"Setting vertex normal vectors...";
    119 
    120     //4 vertexs of the matrix, which need 1 or 2 triangles to define the normal
    121     //Left top
    122     normals[0][0][0] = vectors[0][0][0];
    123     normals[0][0][1] = vectors[0][0][1];
    124     normals[0][0][2] = vectors[0][0][2];
    125     //Right bottom
    126     normals[R - 1][C - 1][0] = vectors[(R - 1) * 2 - 1][C - 2][0];
    127     normals[R - 1][C - 1][1] = vectors[(R - 1) * 2 - 1][C - 2][1];
    128     normals[R - 1][C - 1][2] = vectors[(R - 1) * 2 - 1][C - 2][2];
    129     //Left bottom
    130     normals[R - 1][0][0] = (vectors[(R - 1) * 2 - 2][0][0] + vectors[(R - 1) * 2 - 1][0][0]) / 2;
    131     normals[R - 1][0][1] = (vectors[(R - 1) * 2 - 2][0][1] + vectors[(R - 1) * 2 - 1][0][1]) / 2;
    132     normals[R - 1][0][2] = (vectors[(R - 1) * 2 - 2][0][2] + vectors[(R - 1) * 2 - 1][0][2]) / 2;
    133     //Right top
    134     normals[0][0][0] = (vectors[0][C - 2][0] + vectors[1][C - 2][0]) / 2;
    135     normals[0][0][0] = (vectors[1][C - 2][0] + vectors[1][C - 2][1]) / 2;
    136     normals[0][0][0] = (vectors[2][C - 2][0] + vectors[1][C - 2][2]) / 2;
    137 
    138     //4 edges of the matrix, which need 4 triangles to define the normal
    139     //Top
    140     for (int c = 1; c < C - 1; c++)
    141     {
    142         normals[0][c][0] = (vectors[0][c - 1][0]
    143                             + vectors[1][c - 1][0] 
    144                             + vectors[0][c][0] 
    145                             + vectors[1][c][0]) / 4;
    146         normals[0][c][1] = (vectors[0][c - 1][1] 
    147                             + vectors[1][c - 1][1] 
    148                             + vectors[0][c][1] 
    149                             + vectors[1][c][1]) / 4;
    150         normals[0][c][2] = (vectors[0][c - 1][2] 
    151                             + vectors[1][c - 1][2] 
    152                             + vectors[0][c][2] 
    153                             + vectors[1][c][2]) / 4;
    154     }
    155     //Bottom
    156     for (int c = 1; c < C - 1; c++)
    157     {
    158         normals[R - 1][c][0] = (vectors[(R - 1) * 2 - 1][c - 1][0] 
    159                                 + vectors[(R - 1) * 2 - 2][c - 1][0] 
    160                                 + vectors[(R - 1) * 2 - 1][c][0]
    161                                 + vectors[(R - 1) * 2 - 2][c][0]) / 4;
    162         normals[R - 1][c][1] = (vectors[(R - 1) * 2 - 1][c - 1][1] 
    163                                 + vectors[(R - 1) * 2 - 2][c - 1][1] 
    164                                 + vectors[(R - 1) * 2 - 1][c][1] 
    165                                 + vectors[(R - 1) * 2 - 2][c][1]) / 4;
    166         normals[R - 1][c][2] = (vectors[(R - 1) * 2 - 1][c - 1][2] 
    167                                 + vectors[(R - 1) * 2 - 2][c - 1][2] 
    168                                 + vectors[(R - 1) * 2 - 1][c][2] 
    169                                 + vectors[(R - 1) * 2 - 2][c][2]) / 4;
    170     }
    171     //Left
    172     for (int r = 1; r < R - 1; r++)
    173     {
    174         normals[r][0][0] = (vectors[r * 2 - 2][0][0]
    175                             + vectors[r * 2 - 1][0][0]
    176                             + vectors[r * 2][0][0]
    177                             + vectors[r * 2 + 1][0][0]) / 4;
    178         normals[r][0][1] = (vectors[r * 2 - 2][0][1]
    179                             + vectors[r * 2 - 1][0][1]
    180                             + vectors[r * 2][0][1]
    181                             + vectors[r * 2 + 1][0][1]) / 4;
    182         normals[r][0][2] = (vectors[r * 2 - 2][0][2]
    183                             + vectors[r * 2 - 1][0][2]
    184                             + vectors[r * 2][0][2]
    185                             + vectors[r * 2 + 1][0][2]) / 4;
    186     }
    187     //Right
    188     for (int r = 1; r < R - 1; r++)
    189     {
    190         normals[r][0][0] = (vectors[r * 2 - 2][C - 2][0]
    191                             + vectors[r * 2 - 1][C - 2][0]
    192                             + vectors[r * 2][C - 2][0]
    193                             + vectors[r * 2 + 1][C - 2][0]) / 4;
    194         normals[r][0][1] = (vectors[r * 2 - 2][C - 2][1]
    195                             + vectors[r * 2 - 1][C - 2][1]
    196                             + vectors[r * 2][C - 2][1]
    197                             + vectors[r * 2 + 1][C - 2][1]) / 4;
    198         normals[r][0][2] = (vectors[r * 2 - 2][C - 2][2]
    199                             + vectors[r * 2 - 1][C - 2][2]
    200                             + vectors[r * 2][C - 2][2]
    201                             + vectors[r * 2 + 1][C - 2][2]) / 4;
    202     }
    203 
    204     //The rest of the martix, 6 triangles are needed for each
    205     for (int r = 1; r < R - 1; r++)
    206     {
    207         for (int c = 1; c < C - 1; c++)
    208         {
    209             normals[r][c][0] = (vectors[r * 2][c][0]
    210                                 + vectors[r * 2 - 1][c - 1][0]
    211                                 + vectors[r * 2 - 1][c][0]
    212                                 + vectors[r * 2][c - 1][0]
    213                                 + vectors[r * 2][c][0]
    214                                 + vectors[r * 2 + 1][c - 1][0]) / 6;
    215             normals[r][c][1] = (vectors[r * 2][c][1]
    216                                 + vectors[r * 2 - 1][c - 1][1]
    217                                 + vectors[r * 2 - 1][c][1]
    218                                 + vectors[r * 2][c - 1][1]
    219                                 + vectors[r * 2][c][1]
    220                                 + vectors[r * 2 + 1][c - 1][1]) / 6;
    221             normals[r][c][2] = (vectors[r * 2][c][2]
    222                                 + vectors[r * 2 - 1][c - 1][2]
    223                                 + vectors[r * 2 - 1][c][2]
    224                                 + vectors[r * 2][c - 1][2]
    225                                 + vectors[r * 2][c][2]
    226                                 + vectors[r * 2 + 1][c - 1][2]) / 6;
    227         }
    228     }
    229     cout<<endl<<"Vertex normal vectors set."<<endl;
    230 
    231     //Enable normalize vector
    232     glEnable(GL_NORMALIZE);
    233 
    234     //Load Texture
    235     int width, height;
    236     unsigned char* image = SOIL_load_image(".\\res\\terrain.bmp", &width, &height, 0, SOIL_LOAD_RGBA);
    237     glGenTextures(1, &texName);
    238     glBindTexture(GL_TEXTURE_2D, texName);
    239     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    240     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    241     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    242     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    243     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
    244     glEnable(GL_TEXTURE_2D);
    245 }
    246 
    247 /*
    248 void spindisplay (void)
    249 {
    250     
    251     glutPostRedisplay();
    252 }
    253 */
    254 
    255 void processMouse(int button, int state, int x, int y)  
    256 {  
    257     if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)  
    258     {  
    259         old_x = x; 
    260         old_y = y;  
    261     }
    262 }  
    263 
    264 void onMouseMove(int x, int y)  
    265 {  
    266     spin_x += y - old_y;
    267     spin_y += x - old_x;
    268     spin = sqrt(spin_x*spin_x + spin_y*spin_y);
    269     if (spin > 360)
    270     {
    271         spin -= 360;
    272     }
    273 
    274     glutPostRedisplay();  
    275 
    276     old_x = x;  
    277     old_y = y;  
    278 }  
    279 
    280 void onKeyboardType(unsigned char key, int x, int y)
    281 {
    282     if (key == 'r' || key == 'R')
    283     {
    284         spin_x = 10;
    285         spin_y = 0;
    286         spin = 0;
    287         glutPostRedisplay();  
    288     }
    289 
    290     if (key == 'w' || key == 'W')
    291     {
    292         camerap[0] += 1000;
    293         glutPostRedisplay();  
    294     }
    295     if (key == 's' || key == 'S')
    296     {
    297         camerap[0] -= 1000;
    298         glutPostRedisplay();  
    299     }
    300     if (key == 'a' || key == 'A')
    301     {
    302         camerap[2] -= 1000;
    303         glutPostRedisplay();  
    304     }
    305     if (key == 'd' || key == 'D')
    306     {
    307         camerap[2] += 1000;
    308         glutPostRedisplay();  
    309     }
    310 }
    311 
    312 void display (void)
    313 {
    314     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    315     glColor3f(1, 0.25, 0.25);
    316     glLoadIdentity();
    317 
    318     //Moving camera
    319     gluLookAt(camerap[0], camerap[1], camerap[2], 5000 + camerap[0], 0 + camerap[1], 0 + camerap[2], 0, 1, 0);
    320     glScalef(1, 1, 1);
    321     glRotatef(spin, spin_x, spin_y, 0);
    322 
    323     //Drawing loop
    324     for (int r = 0; r < R - 1; r++)
    325     {
    326         glBegin(GL_TRIANGLE_STRIP);
    327             for (int c = 0; c < C - 1; c++)
    328             {
    329                 //Normal Vector
    330                 glNormal3f(normals[r][c][0], normals[r][c][1], normals[r][c][2]);
    331                 //glTexCoord2d(c/C, 1 - r / R);
    332                 glVertex3f(c * 50,datas[r][c],r * 50);
    333                 
    334                 //Normal Vector
    335                 glNormal3f(normals[r + 1][c][0], normals[r][c][1], normals[r][c][2]);
    336                 //glTexCoord2d(c/C, 1 - (r + 1) / R);
    337                 glVertex3f(c * 50,datas[r + 1][c],r * 50 + 50);
    338             }
    339         glEnd();
    340     }
    341     glFlush();
    342 }
    343 
    344 void reshape(int w, int h)
    345 {
    346     glViewport(0, 0, (GLsizei)w, (GLsizei)h);
    347     glMatrixMode(GL_PROJECTION);
    348     glLoadIdentity();
    349     //glFrustum(-1, 1, -1, 1, 1.5, 20);
    350     gluPerspective(60, 1, 1, 99999);
    351     glMatrixMode(GL_MODELVIEW);
    352 }
    353 
    354 int main (int argc, char** argv)
    355 {
    356     glutInit(&argc,argv);
    357     glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
    358     glutInitWindowSize(1280, 720);
    359     glutInitWindowPosition(100, 100);
    360     glutCreateWindow(argv[0]);
    361     init();
    362     glutDisplayFunc(display);
    363     //glutIdleFunc(spindisplay);
    364     glutReshapeFunc(reshape);
    365     glutMotionFunc(onMouseMove);
    366     glutMouseFunc(processMouse);
    367     glutKeyboardFunc(onKeyboardType);
    368     glutMainLoop();
    369     return 0;
    370 }
  • 相关阅读:
    【Android Developers Training】 73. 布局变化的动画
    【Android Developers Training】 72. 缩放一个视图
    【Android Developers Training】 71. 显示翻牌动画
    svn更改地址怎么办
    python学习手册
    failed to bind pixmap to texture
    Ubuntu 12.04安装Google Chrome
    svn update 时总是提示 Password for '默认密钥' GNOME keyring: 输入密码
    重设SVN 的GNOME keyring [(null)] 的密码
    Nginx + uWSGI + web.py 搭建示例
  • 原文地址:https://www.cnblogs.com/yuki8819/p/5245965.html
Copyright © 2011-2022 走看看