资讯专栏INFORMATION COLUMN

C++ 实现太阳系行星系统

zebrayoung / 1272人阅读

摘要:项目简介使用实现实现一个简单的太阳系行星系统,将涉及一些三维图形技术的数学基础里的三维坐标系里的光照模型的键盘事件处理。基本框架设计一说明实验介绍本次实验将使用编写一个简单的太阳系运行系统。

项目简介:使用 C++实现 OpenGL GLUT 实现一个简单的太阳系行星系统,将涉及一些三维图形技术的数学基础、OpenGL 里的三维坐标系、OpenGL 里的光照模型、GLUT 的键盘事件处理。

本教程由欧龙崎发布在实验楼,完整教程及在线练习地址:C++ 实现太阳系行星系统,可以直接在教程中下载代码使用demo。

基本框架设计 一、说明 实验介绍

本次实验将使用 OpenGL GLUT 编写一个简单的太阳系运行系统。

实验涉及的知识点

C++ 语言基础

基本的 Makefile

基本的 OOP 编程思想

OpenGL GLUT 的结构基本使用

实验效果图

运行效果如图所示:

二、基础知识 认识 OpenGL 和 GLUT

OpenGL 包含了很多渲染函数,但是他们的设计目的是独立于任何窗口系统或操作系统的。因此,它自身并没有包含创建打开窗口或者从键盘或鼠标读取时间的函数,甚至连最基本的显示窗口的功能都没有,所以单纯只使用 OpenGL 是完全不可能创建一个完整的图形程序的。并且绝大多数程序都需要与用户进行交互(响应键盘鼠标等操作)。GLUT 则提供了这一便利。

GLUT 其实是 OpenGL Utility Toolkit 的缩写,它是一个处理 OpenGL 程序的工具库,主要负责处理与底层操作系统的调用及 I/O操作。使用 GLUT 可以屏蔽掉底层操作系统 GUI 实现上的一些细节,仅使用 GLUT 的 API 即可跨平台的创建应用程序窗口、处理鼠标键盘事件等等。

我们先在实验楼环境中安装 GLUT:

sudo apt-get update && sudo apt-get install freeglut3 freeglut3-dev

一个标准的 GLUT 程序结构如下代码所示:

// 使用 GLUT 的基本头文件
#include 

// 创建图形窗口的基本宏
#define WINDOW_X_POS 50
#define WINDOW_Y_POS 50
#define WIDTH 700
#define HEIGHT 700

// 用于注册 GLUT 的回调
void onDisplay(void);
void onUpdate(void);
void onKeyboard(unsigned char key, int x, int y);

int main(int argc, char*  argv[]) {

    // 对 GLUT 进行初始化,并处理所有的命令行参数
    glutInit(&argc, argv);
    // 这个函数指定了使用 RGBA 模式韩式颜色索引模式。另外还可以
    // 指定是使用单缓冲还是双缓冲窗口。这里我们使用 RGBA 和 双缓冲窗口
    glutInitDisplayMode(GLUT_RGBA |  GLUT_DOUBLE);
    // 设置窗口被创建时左上角位于屏幕上的位置
    glutInitWindowPosition(WINDOW_X_POS, WINDOW_Y_POS);
    // 设置窗口被创建时的宽高, 为了简便起见
    glutInitWindowSize(WIDTH, HEIGHT);
    // 创建一个窗口,输入的字符串为窗口的标题
    glutCreateWindow("SolarSystem at Shiyanlou");

    // glutDisplayFunc 的函数原型为 glutDisplayFunc(void (*func)(void))
    // 这是一个回调函数,每当 GLUT 确定一个窗口的内容需要更新显示的时候,
    // glutDisplayFunc 注册的回调函数就会被执行.
    //
    // glutIdleFunc(void (*func)(void)) 将指定一个函数,用于处理当事件循环
    // 处于空闲的时候,就执行这个函数。这个回调函数接受一个函数指针作为它的唯一参数
    //
    // glutKeyboardFunc(void (*func)(unsigned char key, int x, int y))
    // 会将键盘上的键与一个函数关联,当这个键被按下或者释放时,函数就会调用
    //
    // 因此下面的三行实际上是在向 GLUT 注册关键的三个回调函数
    glutDisplayFunc(onDisplay);
    glutIdleFunc(onUpdate);
    glutKeyboardFunc(onKeyboard);

    glutMainLoop();
    return 0;

}

提示

单缓冲,是将所有的绘图指令在窗口上执行,就是直接在窗口上绘图,这样的绘图效率是比较慢的,如果使用单缓冲,而电脑处理性能不够,屏幕会出现闪烁状。

双缓冲,会将绘图指令是在一个缓冲区完成,这里的绘图非常的快,在绘图指令完成之后,再通过交换指令把完成的图形立即显示在屏幕上,进而避免出现绘图的不完整,效率很高。

双缓冲则主要分为前台缓冲和后台缓冲,前台缓冲即我们说看到的屏幕,后台缓冲则维护内存中,对用户不可见。使用双缓冲时所有绘图操作都会在后台进行,当完成绘制后,才会将结果复制到屏幕上。

这么做的好处是,如果我们让绘制操作实时与显卡进行操作,当绘制任务复杂时,IO 操作同样会变得复杂,造成性能较低;而双缓冲只会在交换缓冲区时将绘制完成后的结果直接发送给显卡进行渲染,IO 显著降低。

在 OpenGL 中,推荐使用 GLfloat 来表示浮点数。

三、 详细教程

本项目的详细教程和代码详解,可在实验楼中查看并在线完成。

更多C++项目:C/C++全部 - 课程

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/9405.html

相关文章

  • 用python模拟《流浪地球》的木星引力弹弓效应

    摘要:来源重力助推而在影片中,也就是为了获取更大的速度以脱离太阳系,人类才选择借助木星的引力弹弓效应。引力弹弓的概念在几年前的星际穿越和火星救援中都有提及,我一直想写个模拟,直到这次趁流浪地球热映的机会才动手实现。 本文涉及影片内容,但算不上剧透。想看还未看的同学请谨慎阅读。 春节档的几部电影里,《 流浪地球 》成为一匹黑马,刷爆微博和朋友圈,从最初不高的排片率,一跃上升到票房榜首。 看过影...

    fsmStudy 评论0 收藏0
  • Java™ 教程(枚举类型)

    枚举类型 枚举类型是一种特殊的数据类型,它使变量成为一组预定义的常量,变量必须等于为其预定义的值之一,常见示例包括罗盘方向(NORTH、SOUTH、EAST和WEST的值)和星期。 因为它们是常量,所以枚举类型字段的名称是大写字母。 在Java编程语言中,你可以使用enum关键字定义枚举类型,例如,你可以将星期的枚举类型指定为: public enum Day { SUNDAY, MOND...

    Cristalven 评论0 收藏0
  • 你们要的3D阳系

    摘要:用画一个平面的太阳系得到一些朋友的欣赏,然后有同学提出了绘制三维太阳系的要求。从画图的角度来说,三维太阳系其实并不难,问题在于八大行星对黄道面的倾斜太小,所以尽管画个三维的图,但就观感而言,无非是把二维的嵌入到三维空间罢了。 ...

    MadPecker 评论0 收藏0
  • WebGL three.js学习笔记 纹理贴图模拟阳系运转

    摘要:纹理贴图的应用以及实现一个太阳系的自转公转点击查看演示地址中的纹理纹理贴图是通过将图像应用到对象的一个或多个面,来为对象添加细节的一种方法。 纹理贴图的应用以及实现一个太阳系的自转公转 点击查看demo演示 demo地址:https://nsytsqdtn.github.io/d... three.js中的纹理 纹理贴图是通过将图像应用到对象的一个或多个面,来为3D对象添加细节的一种...

    Pandaaa 评论0 收藏0
  • 12个令人惊叹的CSS实验项目

    摘要:看看这些惊人的纯实验,也许你自己也可以尝试一下。项目链接叠叠高游戏你可以不用来编写一个游戏。这个纯粹用实现的叠叠高游戏看上去很简单,但是很有趣,而且图形也很漂亮。项目链接鬼影渐变效果按钮令人惊讶的是它是只用编写的。 翻译:疯狂的技术宅原文:https://1stwebdesigner.com/12... 本文首发微信公众号:jingchengyideng欢迎关注,每天都给你推送新鲜...

    LiuZh 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<