如何在OpenGL中制作立方体

作者: Gregory Harris
创建日期: 12 四月 2021
更新日期: 1 七月 2024
Anonim
【科普】DirectX和OpenGL:游戏为什么离不开它们?
视频: 【科普】DirectX和OpenGL:游戏为什么离不开它们?

内容

OpenGL 是一种 3D 编程工具,可让您从简单的形状创建复杂的 3D 图像。在本文中,您将学习如何在他的帮助下绘制一个可以在三个维度上旋转的简单立方体!

脚步

第 1 部分(共 3 部分):初始安装

  1. 1 安装 OpenGL。 从有关如何在计算机上安装 OpenGL 的教程开始。如果您已经拥有 OpenGL 和 C 编译器,则可以跳过此步骤并继续下一步。
  2. 2 创建文档。 在您最喜欢的代码编辑器中创建一个新文件并将其保存为 mycube.c
  3. 3 添加#includes。 以下是您需要的基本 #include 指令。重要的是要记住,不同操作系统的指令是不同的,因此您需要选择所有内容,以便程序具有通用性并且可以在任何系统上运行。

      // 包含 #include stdio.h> #include stdarg.h> #include math.h> #define GL_GLEXT_PROTOTYPES #ifdef __APPLE__ #include GLUT / glut.h> #else #include GL / glut.h> #endif

  4. 4 添加功能原型和全局变量。 下一步是声明功能原型。

      // 函数原型 void display(); void specialKeys(); // 全局变量 double rotate_y = 0;双旋转_x = 0;

  5. 5 定义main()函数。

      int main (int argc, char * argv []) // 初始化 GLUT 并处理自定义参数 glutInit (& argc, argv); // 请求一个支持双缓冲、Z 缓冲和真彩色 glutInitDisplayMode (GLUT_DOUBLE) 的窗口

第 2 部分(共 3 部分):display() 函数

  1. 1 了解display()函数的用途。 所有渲染立方体的工作都将落在这个函数的脆弱线上。总体思路是这样的:您将绘制立方体的六个独立面并将它们放置在各自的位置。
    • 对于每个面,您将定义四个角,OpenGL 将用线条将它们连接起来,并用您选择的颜色填充它们。下面将解释如何做到这一点。
  2. 2 添加glClear()函数。 首先,在使用这个函数时,我们需要 清晰的颜色和 z 缓冲区...没有这个,旧的会在新的图片下可见,程序绘制的对象会定位不正确。

      void display() // 清除屏幕和 Z 缓冲区 glClear (GL_COLOR_BUFFER_BIT

    • 注意最后两行。这些是功能 glFlush();glutSwapBuffers();,给出了双缓冲的效果,这是上面描述的。

第 3 部分(共 3 部分):程序交互性

  1. 1 添加 specialKeys() 函数。 原则上,一切都差不多准备好了,只是立方体只被绘制,并没有旋转。为此,您需要创建 specialKeys() 函数,这将允许您通过按箭头键来旋转立方体!
    • 正是为此函数声明了全局变量rotate_x 和rotate_y。当您按左右箭头键时,rotate_y 值将增加或减少五度。 rotate_x 的值也会以同样的方式改变,但这次是通过按下上下箭头键。
    • void specialKeys (int key, int x, int y) {// 向右箭头 - 将旋转增加 5 度 if (key == GLUT_KEY_RIGHT)rotate_y + = 5; // 向左箭头 - 将旋转减少 5 度 else if (key == GLUT_KEY_LEFT)rotate_y - = 5;否则 if (key == GLUT_KEY_UP)rotate_x + = 5;否则 if (key == GLUT_KEY_DOWN)rotate_x - = 5; // 请求屏幕刷新 glutPostRedisplay(); }

  2. 2 添加glRotate()。 我们要做的最后一件事是添加一条线,允许我们旋转对象。返回功能 展示 () 在前面的描述之前添加:

      // 重置转换 glLoadIdentity(); // 当用户改变值rotate_x和rotate_y时旋转 glRotatef(rotate_x, 1.0, 0.0, 0.0); glRotatef (rotate_y, 0.0, 1.0, 0.0); // 多色面 - FRONT ....

    • 请注意语法 glRotatef()与 glColor3f() 和 glVertex3f() 的语法类似,但始终需要四个参数。第一个是以度为单位的旋转角度。接下来的三个是发生旋转的轴,顺序为 x、y、z。现在,我们需要沿两个轴 x 和 y 旋转立方体。
    • 我们在程序中定义的所有转换都需要类似的行。基本上,我们将对象沿 x 轴的旋转表示为 rotate_x 值的变化,而沿 y 轴的旋转表示为 rotate_y 值的变化。但是,OpenGL 会将所有内容捆绑到一个转换矩阵中。每次调用 display 时,都会创建一个变换矩阵,并且 glLoadIdentity() 将允许您每次从一个新矩阵开始。
    • 您可能使用过的其他转换函数是 glTranslatef () 和 glScalef ()。它们与glRotatef()类似,不同之处在于它们只需要三个参数:x、y和z值来调整和缩放对象。
    • 为了在将所有三个转换应用于一个对象时正确显示所有内容,您需要以适当的顺序设置转换,即 glTranslate、glRotate、glScale - 从来没有。 OpenGL 通过从下到上读取程序来转换对象。为了更好地理解这一点,想象一下如果 OpenGL 按所示顺序(从上到下)应用它们,1x1x1 立方体将如何处理所有变换,然后考虑 OpenGL 如何通过从下到上读取指令来处理立方体。
  3. 3 添加以下命令,将立方体在 x 和 y 方向缩放两次,将立方体沿 y 轴旋转 180 度,并将立方体沿 x 轴移动 0.1。 确保所有相关命令,包括之前给出的 glRotate() 命令,都按正确的顺序排列。如果您害怕出错,请参阅文末程序的最终版本。

      // 更多变换 glTranslatef (0.1, 0.0, 0.0); glRotatef (180, 0.0, 1.0, 0.0); glScalef (2.0, 2.0, 0.0);

  4. 4 编译并运行代码。 假设您使用 gcc 作为编译器,因此在终端中输入以下命令:

      在 Linux 上:gcc cube.c -o cube -lglut -lGL ./mycube 在 Mac 上:gcc -o foo foo.c -framework GLUT -framework OpenGL ./mycube 在 Windows 上:gcc -Wall -ofoo foo.c -lglut32cu - lglu32 -lopengl32 ./ mycube

  5. 5 检查最终代码。 这里是文章作者最后创建的代码,不翻译注释。

      // // 文件:mycube.c // 作者:Matt Daisley // 创建时间:4/25/2012 // 项目:在 OpenGL 中制作立方体的源代码 // 描述:创建一个 OpenGL 窗口并绘制一个 3D 立方体 / / 用户可以使用箭头键旋转 // // 控件:向左箭头 - 向左旋转 // 向右箭头 - 向右旋转 // 向上箭头 - 向上旋转 // 向下箭头 - 向下旋转 // ------ -------------------------------------------------- - // 包括 // ------------------------------------------- - -------------- #include stdio.h> #include stdarg.h> #include math.h> #define GL_GLEXT_PROTOTYPES #ifdef __APPLE__ #include GLUT / glut.h> #else #include GL / glut.h> #endif // --------------------------------------- - ------------------ // 函数原型 // ------------------------- - -------------------------------- 无效显示(); void specialKeys(); // ------------------------------------------------ ---------- // 全局变量 // ---------------------------------- ------------------------ 双旋转_y = 0;双旋转_x = 0; // ------------------------------------------------ ---------- // display() 回调函数 // ------------------------------- --------------------------- void display() // 清除屏幕和 Z 缓冲区 glClear (GL_COLOR_BUFFER_BIT // ------ -------------------------------------------------- - // specialKeys() 回调函数 // --------------------------------------- - ------------------ void specialKeys (int key, int x, int y) {// 向右箭头 - 将旋转增加 5 度 if (key == GLUT_KEY_RIGHT) rotate_y + = 5; // 向左箭头 - 减少旋转 5 度 else if (key == GLUT_KEY_LEFT)rotate_y - = 5; else if (key == GLUT_KEY_UP)rotate_x + = 5; else if (key == GLUT_KEY_DOWN)rotate_x - = 5; // 请求显示更新 glutPostRedisplay();} // ----------------------------------- - ---------------------- // main() 函数 // ------------------- - -------------------------------------- int main (int argc, char * argv [ ] ) GLUT_RGB