void run() { for (;;) { int currentTime = Now(); if (Now() - prevIoUsTime > WAIT_INTERVAL) { prevIoUsTime = currentTime; tick(); } } } void tick() { // critical section begins processor->step() // critical section ends } void receiveMessage(void *data) { processor->changeSomeData(data); }
因此,如果从OpenGL线程调用receiveMessage()并且处理器 – > step()正在运行,则应该推迟对changeSomeData()的调用,因为它会弄乱整个计算.
我想使用以下类来同步线程:
Mutex.h:
#ifndef MUTEX_H #define MUTEX_H #include <Windows.h> class Mutex; #include "Lock.h" class Mutex { public: Mutex(); ~Mutex(); private: void acquire(); void release(); CRITICAL_SECTION criticalSection; friend class Lock; }; #endif
Mutex.cpp:
#include "Mutex.h" Mutex::Mutex() { InitializeCriticalSection(&this->criticalSection); } Mutex::~Mutex() { DeleteCriticalSection(&this->criticalSection); } void Mutex::acquire() { EnterCriticalSection(&this->criticalSection); } void Mutex::release() { LeaveCriticalSection(&this->criticalSection); }
Lock.h:
#ifndef LOCK_H #define LOCK_H class Lock; #include "Mutex.h" class Lock { public: Lock(Mutex& mutex); ~Lock(); private: Mutex &mutex; }; #endif
Lock.cpp
#include "Lock.h" Lock::Lock(Mutex& mutex) : mutex(mutex) { this->mutex.acquire(); } Lock::~Lock () { this->mutex.release(); }
编辑:
这是整个项目:http://upload.visusnet.de/uploads/BlobbyWarriors-rev30.zip(~180 MB)
编辑2:
这是SVN回购:https://projects.fse.uni-due.de/svn/alexander-mueller-bloby-warriors/trunk/
解决方法
你现在正在使用gluT而且你说你需要线程来“避免锁定glutMainLoop().而你不想要锁定,因为你想在此期间进行一些计算.”
现在停下来问自己 – 你确定那些操作需要从OpenGL渲染异步(整体)完成吗?如果是这样,你可能会停止阅读这篇文章并查看其他帖子,但我真诚地相信,对于典型的实时OpenGL应用程序而言可能并非如此.
所以…典型的OpenGL应用程序如下所示:
>处理事件
>刻度计算
>重绘屏幕
大多数GL窗口库允许你将它实现为你自己的主循环,gluT类似于用它的“回调”来混淆,但是这个想法是一样的.
您仍然可以在应用程序中引入并行性,但它应该在步骤2开始和停止,因此它仍然在主循环级别上顺序:“计算一帧计算,然后渲染此帧”.这种方法可能会为您省去很多麻烦.
Protip:改变您的图书馆. gluT已经过时,不再维护了.切换到GLFW(或SDL)以创建窗口不会在代码方面花费太多精力 – 与gluT相反 – 您自己定义主循环,这似乎是您想要在此实现的. (另外,它们往往更便于输入和窗口事件处理等)
一些具有恒定时间步实时物理特性的典型伪代码,不会干扰渲染(假设您通常比渲染更经常运行物理):
var accum = 0 const PHYSICS_timestep = 20 while (runMainLoop) { var dt = getTimeFromLastFrame accum += dt while (accum > PHYSICS_timestep) { accum -= PHYSICS_timestep tickPhysicsSimulation(PHYSICS_timestep) } tickAnyOtherLogic(dt) render() }
可能的扩展是使用accum的值作为附加的“外推”值仅用于渲染,这将允许在视觉上平滑图形表示,同时更少地模拟物理(具有更大的DT),可能比每次渲染更少一次帧.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。