• 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 }
  • 相关阅读:
    [转]移动端实现垂直居中的几种方法
    MySQL常见的两种存储引擎:MyISAM与InnoDB的爱恨情仇
    关于分布式计算的一些概念
    一份最中肯的Java学习路线+资源分享(拒绝傻逼式分享)
    Java多线程学习(八)线程池与Executor 框架
    深入理解工厂模式
    深入理解单例模式
    Java NIO 之 Buffer(缓冲区)
    Java NIO 概览
    分布式系统的经典基础理论
  • 原文地址:https://www.cnblogs.com/yuki8819/p/5245965.html
Copyright © 2020-2023  润新知