GLUT是一个很棒的API,它很容易使用,但我对它如何处理范围有一些困难。在定义回调时,没有传递参数的选项,所以在我看来好像程序员被迫依赖全局变量,我觉得很难接受。现在我将所有GLUT代码放在它自己的模块中,在它自己的线程上运行,并定义一个静态指针,我在模块的入口点分配,如下所示:
主要模块
int main( int argc, char** argv ) {
int foo;
boost::thread graphicsThread(glutMain, argc, argv, &foo);
//...
graphicsThread.join();
return 0;
}
GLUT模块
static int* FOO_REF;
int glutMain( int argc, char** argv, int* foo ) {
FOO_REF = foo;
glutInit(&argc, argv);
//etc...
有比这更好的解决方案吗?
答案 0 :(得分:1)
如果您正在使用freeglut或衍生产品并且愿意将自己限制在freeglut衍生品中,那么它只有非标准扩展来解决问题。您可以将void*
与每个窗口关联起来。如果你创建一个包含你想要的所有每个窗口数据的结构,你可以完全避免使用全局变量。
梗概:
#include <GL/glut.h>
#include <GL/freeglut_ext.h>
void * glutGetWindowData();
glutSetWindowData(void *data);
答案 1 :(得分:0)
我所做的是为所有全局变量声明一个global.h。并在main中初始化它们。对于我的“基本/一般”变量(即相机,位置,迭代号,......),它们都是单独声明的。主要:
include "global.h"
Vector position_g = ...
Vector angles_g = ...
int time_g = 0;
int main () {
...
}
但是对于“特定部分”的变量,即仅在一个游戏模式/级别中,我创建了一个联合和一个枚举。
enum mainGame{skipLevel, ...};
enum mainMenu {viewingSettings, ...};
typedef union generic_union {
int i;
char c;
bool b;
char s[100]; // or char * s;
float f;
} generic;
并声明了一个globalData变量。
extern generic * globalData; // in global.h
generic * globalData = NULL; // in main
现在可以使用:
int main () {
...
globalData = malloc (sizeof (generic)*numGlobals);
globalData[skipLevel].b = false;
...
}
现在,在按键处理功能中,您可以指定一个键来切换globalData [skipLevel]。在任何其他文件中,您只需要包含global.h。
include "global.h"
void onKeyPress (... ) {
If (inMainGame) {
If (key == SPACE) {
globalData [skipLevel] = true;
}
}
最后使用:
include "global.h"
void levelManager () {
...
if (globalData[skipLevel]) level++;
...
}
<强>赞成强> 只需要围绕 1 变量和一个包含。
您可以释放不再需要或正在该实例中使用的变量。 (非常有助于减少“污染”)。如果一个游戏模式只需要1个变量,那就是你需要存储的所有内容,如果它需要48个,那就简单了!
可以轻松处理任何变量类型,方法是将它添加到union中。
完全便携
<强>缺点强> 必须记住变量类型以取消引用通用联合(不那么难)
注意使用的枚举(您可以使用类似mainMenu_e的枚举样式来解决此问题)
增加了复杂性,但随着变量数量的增加,这样的系统非常值得。
就我个人而言,尽管没有多少额外的活动部件,但我发现它非常整洁。 如果不清楚,请告诉我,我会尝试解决它:)