使用了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 }
原文链接: https://www.cnblogs.com/yuki8819/p/5245965.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/229662
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!