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

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

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

基本框架设计

一、说明

实验介绍

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

实验涉及的知识点

  • C++ 语言基础

  • 基本的 Makefile

  • 基本的 OOP 编程思想

  • OpenGL GLUT 的结构基本使用

实验效果图

运行效果如图所示:

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

二、基础知识

认识 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 <GL/glut.h>

// 创建图形窗口的基本宏
#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;

}

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

提示

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

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

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

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

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

三、 详细教程

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

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

相关推荐