Opengl三维地形动态显示程序设计代码

时间: 2023-11-12 20:24:21 浏览: 27
下面是一个OpenGL三维地形动态显示程序的简单代码示例: ```c++ #include <GL/glut.h> #include <cmath> const int WIDTH = 800; const int HEIGHT = 600; // 地形高度图的宽度和高度 const int MAP_WIDTH = 256; const int MAP_HEIGHT = 256; // 地形高度图数据 unsigned char heightMap[MAP_WIDTH][MAP_HEIGHT]; // 地形顶点数组 float vertices[MAP_WIDTH][MAP_HEIGHT][3]; // 地形法向量数组 float normals[MAP_WIDTH][MAP_HEIGHT][3]; // 摄像机位置 float cameraX = 0.0f; float cameraY = 0.0f; float cameraZ = 0.0f; // 摄像机方向 float pitch = 0.0f; float yaw = 0.0f; void generateHeightMap() { // 生成随机高度图 for (int i = 0; i < MAP_WIDTH; i++) { for (int j = 0; j < MAP_HEIGHT; j++) { heightMap[i][j] = rand() % 256; } } } void generateVertices() { // 根据高度图生成顶点数组 for (int i = 0; i < MAP_WIDTH; i++) { for (int j = 0; j < MAP_HEIGHT; j++) { vertices[i][j][0] = i - MAP_WIDTH / 2; vertices[i][j][1] = heightMap[i][j] / 10.0f; vertices[i][j][2] = j - MAP_HEIGHT / 2; } } } void generateNormals() { // 根据顶点数组生成法向量数组 for (int i = 0; i < MAP_WIDTH - 1; i++) { for (int j = 0; j < MAP_HEIGHT - 1; j++) { float x1 = vertices[i][j][0]; float y1 = vertices[i][j][1]; float z1 = vertices[i][j][2]; float x2 = vertices[i+1][j][0]; float y2 = vertices[i+1][j][1]; float z2 = vertices[i+1][j][2]; float x3 = vertices[i][j+1][0]; float y3 = vertices[i][j+1][1]; float z3 = vertices[i][j+1][2]; float ax = x1 - x2; float ay = y1 - y2; float az = z1 - z2; float bx = x3 - x2; float by = y3 - y2; float bz = z3 - z2; float nx = ay * bz - az * by; float ny = az * bx - ax * bz; float nz = ax * by - ay * bx; float length = sqrt(nx * nx + ny * ny + nz * nz); normals[i][j][0] = nx / length; normals[i][j][1] = ny / length; normals[i][j][2] = nz / length; } } } void init() { // 初始化OpenGL窗口 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0, (double)WIDTH / (double)HEIGHT, 0.1, 1000.0); glEnable(GL_DEPTH_TEST); // 生成随机高度图和顶点数组 generateHeightMap(); generateVertices(); generateNormals(); } void display() { // 清除屏幕和深度缓冲区 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 设置摄像机位置和方向 glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(cameraX, cameraY, cameraZ, cameraX + sin(yaw), cameraY - sin(pitch), cameraZ - cos(yaw), 0.0f, 1.0f, 0.0f); // 绘制三角形网格 glBegin(GL_TRIANGLES); for (int i = 0; i < MAP_WIDTH - 1; i++) { for (int j = 0; j < MAP_HEIGHT - 1; j++) { float x1 = vertices[i][j][0]; float y1 = vertices[i][j][1]; float z1 = vertices[i][j][2]; float x2 = vertices[i+1][j][0]; float y2 = vertices[i+1][j][1]; float z2 = vertices[i+1][j][2]; float x3 = vertices[i][j+1][0]; float y3 = vertices[i][j+1][1]; float z3 = vertices[i][j+1][2]; float nx1 = normals[i][j][0]; float ny1 = normals[i][j][1]; float nz1 = normals[i][j][2]; float nx2 = normals[i+1][j][0]; float ny2 = normals[i+1][j][1]; float nz2 = normals[i+1][j][2]; float nx3 = normals[i][j+1][0]; float ny3 = normals[i][j+1][1]; float nz3 = normals[i][j+1][2]; glNormal3f(nx1, ny1, nz1); glVertex3f(x1, y1, z1); glNormal3f(nx2, ny2, nz2); glVertex3f(x2, y2, z2); glNormal3f(nx3, ny3, nz3); glVertex3f(x3, y3, z3); x1 = vertices[i+1][j][0]; y1 = vertices[i+1][j][1]; z1 = vertices[i+1][j][2]; x2 = vertices[i+1][j+1][0]; y2 = vertices[i+1][j+1][1]; z2 = vertices[i+1][j+1][2]; x3 = vertices[i][j+1][0]; y3 = vertices[i][j+1][1]; z3 = vertices[i][j+1][2]; nx1 = normals[i+1][j][0]; ny1 = normals[i+1][j][1]; nz1 = normals[i+1][j][2]; nx2 = normals[i+1][j+1][0]; ny2 = normals[i+1][j+1][1]; nz2 = normals[i+1][j+1][2]; nx3 = normals[i][j+1][0]; ny3 = normals[i][j+1][1]; nz3 = normals[i][j+1][2]; glNormal3f(nx1, ny1, nz1); glVertex3f(x1, y1, z1); glNormal3f(nx2, ny2, nz2); glVertex3f(x2, y2, z2); glNormal3f(nx3, ny3, nz3); glVertex3f(x3, y3, z3); } } glEnd(); // 刷新屏幕 glutSwapBuffers(); } void keyboard(unsigned char key, int x, int y) { // 处理键盘输入 switch (key) { case 'w': cameraX += sin(yaw); cameraZ -= cos(yaw); break; case 's': cameraX -= sin(yaw); cameraZ += cos(yaw); break; case 'a': cameraX += sin(yaw - M_PI / 2); cameraZ -= cos(yaw - M_PI / 2); break; case 'd': cameraX += sin(yaw + M_PI / 2); cameraZ -= cos(yaw + M_PI / 2); break; case 'q': cameraY += 0.1f; break; case 'e': cameraY -= 0.1f; break; } } void mouse(int x, int y) { // 处理鼠标输入 static int lastX = 0; static int lastY = 0; if (lastX != 0 || lastY != 0) { yaw += (x - lastX) * 0.01f; pitch += (y - lastY) * 0.01f; if (pitch > M_PI / 2) { pitch = M_PI / 2; } else if (pitch < -M_PI / 2) { pitch = -M_PI / 2; } } lastX = x; lastY = y; } int main(int argc, char** argv) { // 初始化OpenGL窗口和GLEW库 glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(WIDTH, HEIGHT); glutCreateWindow("Dynamic Terrain"); glewInit(); // 初始化OpenGL状态和数据 init(); // 注册回调函数 glutDisplayFunc(display); glutKeyboardFunc(keyboard); glutPassiveMotionFunc(mouse); // 进入主循环 glutMainLoop(); return 0; } ``` 这个程序使用OpenGL绘制了一个随机生成的三维地形,并且可以使用键盘和鼠标控制摄像机位置和方向。它使用了一个高度图来生成地形,并且计算了每个顶点的法向量,以便在光照计算中使用。

相关推荐

最新推荐

recommend-type

基于OpenGL的海底地形三维渲染方法

在海底地形的三维可视化表达中,三维颜色渐变渲染方法能够直观、方便地...文中基于MFC平台进行了程序实现,并与常见海底地形成图软件的渲染效果进行了比较,对比结果证明本文所提出的渲染方法地形显示准确,渲染效果美观。
recommend-type

基于OpenGL的三维建筑场景模拟

计算机图形学的实验报告 有实验内容 关键技术介绍及核心代码 效果截图、心得体会等
recommend-type

使用PyOpenGL绘制三维坐标系实例

今天小编就为大家分享一篇使用PyOpenGL绘制三维坐标系实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
recommend-type

建梦幻三维OpenGL程序设计轻松入门

建梦幻三维OpenGL程序设计轻松入门 介绍了有关OpenGL的基本知识,主要涉及颜色、绘制几何体、坐标变换、堆栈操作、显示列表、光照和材质、纹理映射、特殊效果、曲面和曲线的绘制、二次几何体绘制、像素操作、如何...
recommend-type

使用OpenGL实现三维坐标的鼠标拣选

opengl实现三维画图窗口,但是他是在二维的屏幕上显示,在交互式程序中经常遇到鼠标的二维坐标操作窗口内三维景象的情况,这篇文章讲的就是二维三维对应求解方法,我的程序就是用这个方法做的。
recommend-type

RTL8188FU-Linux-v5.7.4.2-36687.20200602.tar(20765).gz

REALTEK 8188FTV 8188eus 8188etv linux驱动程序稳定版本, 支持AP,STA 以及AP+STA 共存模式。 稳定支持linux4.0以上内核。
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

实现实时数据湖架构:Kafka与Hive集成

![实现实时数据湖架构:Kafka与Hive集成](https://img-blog.csdnimg.cn/img_convert/10eb2e6972b3b6086286fc64c0b3ee41.jpeg) # 1. 实时数据湖架构概述** 实时数据湖是一种现代数据管理架构,它允许企业以低延迟的方式收集、存储和处理大量数据。与传统数据仓库不同,实时数据湖不依赖于预先定义的模式,而是采用灵活的架构,可以处理各种数据类型和格式。这种架构为企业提供了以下优势: - **实时洞察:**实时数据湖允许企业访问最新的数据,从而做出更明智的决策。 - **数据民主化:**实时数据湖使各种利益相关者都可
recommend-type

去除字符串s="ab23cde"中的数字,构成一个新的字符串"abcde"。

可以使用正则表达式来匹配并替换字符串中的数字: ```python import re s = "ab23cde" new_s = re.sub(r'\d+', '', s) print(new_s) # 输出:abcde ``` 其中,`\d` 表示匹配数字,`+` 表示匹配一个或多个数字,`re.sub()` 函数用来替换匹配到的数字为空字符串。
recommend-type

c++校园超市商品信息管理系统课程设计说明书(含源代码) (2).pdf

校园超市商品信息管理系统课程设计旨在帮助学生深入理解程序设计的基础知识,同时锻炼他们的实际操作能力。通过设计和实现一个校园超市商品信息管理系统,学生掌握了如何利用计算机科学与技术知识解决实际问题的能力。在课程设计过程中,学生需要对超市商品和销售员的关系进行有效管理,使系统功能更全面、实用,从而提高用户体验和便利性。 学生在课程设计过程中展现了积极的学习态度和纪律,没有缺勤情况,演示过程流畅且作品具有很强的使用价值。设计报告完整详细,展现了对问题的深入思考和解决能力。在答辩环节中,学生能够自信地回答问题,展示出扎实的专业知识和逻辑思维能力。教师对学生的表现予以肯定,认为学生在课程设计中表现出色,值得称赞。 整个课程设计过程包括平时成绩、报告成绩和演示与答辩成绩三个部分,其中平时表现占比20%,报告成绩占比40%,演示与答辩成绩占比40%。通过这三个部分的综合评定,最终为学生总成绩提供参考。总评分以百分制计算,全面评估学生在课程设计中的各项表现,最终为学生提供综合评价和反馈意见。 通过校园超市商品信息管理系统课程设计,学生不仅提升了对程序设计基础知识的理解与应用能力,同时也增强了团队协作和沟通能力。这一过程旨在培养学生综合运用技术解决问题的能力,为其未来的专业发展打下坚实基础。学生在进行校园超市商品信息管理系统课程设计过程中,不仅获得了理论知识的提升,同时也锻炼了实践能力和创新思维,为其未来的职业发展奠定了坚实基础。 校园超市商品信息管理系统课程设计的目的在于促进学生对程序设计基础知识的深入理解与掌握,同时培养学生解决实际问题的能力。通过对系统功能和用户需求的全面考量,学生设计了一个实用、高效的校园超市商品信息管理系统,为用户提供了更便捷、更高效的管理和使用体验。 综上所述,校园超市商品信息管理系统课程设计是一项旨在提升学生综合能力和实践技能的重要教学活动。通过此次设计,学生不仅深化了对程序设计基础知识的理解,还培养了解决实际问题的能力和团队合作精神。这一过程将为学生未来的专业发展提供坚实基础,使其在实际工作中能够胜任更多挑战。