我只是为了好玩,试图在openGL的帮助下制作一个小游戏引擎,我希望它是纯粹的C,但我想用红宝石编写游戏脚本。 所以我做了一个概念证明,知道它是否可能。它似乎还可以,但不完全。
实际上,我有一个用swig包装的C模块,并由ruby脚本加载。 在这个C模块中,我使用包含glutmainloop()的pthread_create()创建一个线程。 这个循环只是加载一个网格绘制它并使它以我们称之为rot_speed的速度转动。
因为我不希望我的ruby等待C互斥锁被解锁,所以我的ruby运行C函数,它创建的线程会改变主循环的某些值(因此它完全是ASYNC)然后就会死掉。< / p>
这是C代码的一部分:
mxfloat_t speed = {
.val = 1.0,
.mx = PTHREAD_MUTEX_INITIALIZER,
};
mxint_t should_exit = {
.val = 0,
.mx = PTHREAD_MUTEX_INITIALIZER,
};
void engine_launch(void)
{
pthread_t graphics;
printf("starting gaphics thread...\n");
pthread_create(&graphics, NULL, launch_graphics, NULL);
}
void engine_stop(void)
{
pthread_t stop_thread;
printf("starting stop thread");
pthread_create(&stop_thread, NULL, engine_stop_thread, NULL);
}
void set_speed(float p)
{
pthread_t speed_thread;
printf("starting set speed thread speed= %f\n", p);
pthread_create(&speed_thread, NULL, set_speed_thread, &p);
}
void *launch_graphics(void *p)
{
int c = 1;
char *v = "Ex";
printf("gaphics thread started\n");
printf("Initializing Glut...\n");
glutInitWindowSize(900,600);
glutInitWindowPosition(100,100);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInit(&c, &v);
printf("Creating window\n");
glutCreateWindow("Assim p - Very simple OpenGL sample");
printf("Assigning callbacks functions\n");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutIdleFunc(idle);
printf("Loading asset...");
if(loadasset( "../../test/models-nonbsd/X/dwarf.x")) {
printf(" ..failed\n");
return NULL;
}
printf(" ..loaded\n");
glClearColor(0.1f,0.1f,0.1f,1.f);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0); // Uses default lighting parameters
glEnable(GL_DEPTH_TEST);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
glEnable(GL_NORMALIZE);
if(getenv("MODEL_IS_BROKEN"))
glFrontFace(GL_CW);
glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
glutGet(GLUT_ELAPSED_TIME);
printf("Starting main GL loop\n");
glutMainLoop();
printf("End of GL loop\n");
printf("releasing imported objects\n");
aiReleaseImport(scene);
printf("End of the graphic thread\n");
return NULL;
}
void *engine_stop_thread(void* p)
{
pthread_mutex_lock(&should_exit.mx);
should_exit.val = 1;
printf("should_exit has been set to 1\n");
pthread_mutex_unlock(&should_exit.mx);
(void)p;
return NULL;
}
void *set_speed_thread(void *p)
{
pthread_mutex_lock(&speed.mx);
speed.val = *(float*)p;
printf("speed has been set to %f\n", *(float*)p);
pthread_mutex_unlock(&speed.mx);
return NULL;
}
mxfloat_t和 mxint_t只是处理互斥锁的类型。
功能: engine_launch() engine_stop()和 set_speed(f),是我可以在ruby中使用的包装函数。
Idle函数是调用glutLeaveMainLoop()的函数,如果是should_exit
现在,一些红宝石代码:
require "ge"
Ge.engine_launch
sleep 1
Ge.set_speed 32.0
sleep 1
Ge.set_speed 32.0
sleep 1
Ge.set_speed 32.0
sleep 1
Ge.set_speed 32.0
sleep 1
Ge.engine_stop
sleep 1
这段代码给了我:
starting gaphics thread...
gaphics thread started
Initializing Glut...
Creating window
Assigning callbacks functions
Loading asset... ..loaded
Starting main GL loop
starting set speed thread speed= 32.000000
speed has been set to 0.000000
starting set speed thread speed= 32.000000
speed has been set to 0.000000
starting set speed thread speed= 32.000000
speed has been set to 0.000000
starting set speed thread speed= 32.000000
speed has been set to 0.000000
starting stop threadshould exit has been set to 1
但如果我在irb中测试:
irb(main):001:0> require 'ge'
=> true
irb(main):002:0> Ge.engine_launch
starting gaphics thread...
gaphics thread started
Initializing Glut...
=> nil
irb(main):003:0> Creating window
Assigning callbacks functions
Loading asset... ..loaded
Starting main GL loop
Ge.set_speed 32
starting set speed thread speed= 32.000000
speed has been set to 32.000000
=> nil
irb(main):004:0> Ge.set_speed 31
starting set speed thread speed= 31.000000
speed has been set to 31.000000
=> nil
(但是,irb似乎发送了某种强制我重置终端的termcap)
有人知道为什么在运行ruby脚本时没有设置速度值吗? 还有其他可能的方法来实现我想要做的事情吗? 感谢您的回答,这将有很大的帮助。