使用glut(或freeglut)编写OpenGL时处理全局变量

3

我正在使用 glut 库学习 OpenGL。问题是当程序变得复杂时,要处理的 全局变量 太多了。正如许多人所说,在程序中使用过多的 全局变量 是不好的。然而,我无法通过将用户定义参数传递给 glut 定义的回调函数来替换 全局变量。例如:

void display (void)
{
   // How to pass user defined parameters here?
   // some more code
}
int
main(void)
{
    glutDisplayFunc(display);
    // some more code
}

我的问题是:

  1. 写OpenGL和glut时如何处理全局变量?
  2. 除了向函数传递参数,还有什么其他方法可以替代全局变量?
  3. 其他库(而非glut)如何处理OpenGL的输入/输出以处理全局变量?
1个回答

0
“无全局变量”规则是不完整的。实际措辞是“不使用全局变量在函数之间传递参数”。然而,全局变量可用于保存全局、整个程序范围内的状态。
当使用glut编写OpenGL时如何处理全局变量?
如果您正在管理的状态是程序状态,则全局变量是可以使用的。可以使用glutGet来检索与窗口相关的状态。不要忘记,OpenGL本身就是一个大型全局状态机。每个线程都有一个全局OpenGL上下文,并且切换上下文实际上会更改全局变量。
不要在reshape函数中处理与渲染相关的事物,例如不要在reshape中设置视口和投影。应该在display函数中完成。
是否有其他方法替代全局变量而不是将参数传递给函数?
有一些方法,比如使用ffcall库将带参数的函数转换为闭包,然后将其传递给GLUT。
其他库(不是glut)如何处理OpenGL的输入/输出并处理全局变量?
其他库要么允许将数据参数传递给回调函数(GLUT设计上的大型错误,不允许这样做),要么使用基于消息/信号的系统而非回调函数。

实际上,我需要在函数之间传递许多全局变量。例如,当我按下空格键时,会更改定义为全局变量并在“键盘”回调函数中处理的“stepsize”的值。需要将“stepsize”传递到“display”回调函数中,以更改观察者和对象之间的距离(例如)。另一个例子是,在初始化纹理对象(在“init()”函数中)时,必须将其设置为全局变量以传递到“display”函数中。这样处理是否正确?还是有更好的解决方案? - toolchainX
@tlh1987:你的回调函数不应该传递数据以供显示,而是改变程序状态。而程序状态在定义上是全局的。你需要一种真正的函数式语言(如Lisp、Scheme、OCaml或Haskell)来通过函数参数化有效地管理程序状态。但C大多是命令式的,所以你将在某个地方有一些全局状态。 - datenwolf
哦...实际上,我不理解“改变程序状态”的含义,也不知道如何在键盘回调函数中改变“程序状态”。由于我之前提到处理全局变量stepsize不是一个好主意,您能否给我一个实用的解决方案?我刚刚阅读了关于OpenGL的红书,对函数式语言并不了解。 - toolchainX
1
“程序状态”只是一个术语,涵盖了程序所持有的所有数据以及其函数所操作的数据。例如,游戏的程序状态将包括加载的地图、玩家位置和统计信息。在某个时刻,您必须将它们保存在程序范围内的变量中。如果您采用面向文档的方法,您将拥有一些主文档结构,从中分支出其他所有内容。但在GLUT-ish程序的情况下,您没有多个文档或世界或类似的东西。因此,将状态放入全局变量中就可以了。对于任何复杂的事情,您都应该放弃GLUT。 - datenwolf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接