我是新来的,不熟悉显示编程。 我有一个每40ms调用一次doStep函数的c-Program。在这个函数中,我有C ++代码,它运行过剩显示以可视化3D环境。 doStep函数将我的3D对象的新位置信息从外部传递到我的C ++ 3D环境中。
问题是,我的c代码被过剩显示循环锁定,因此我无法再更新环境中的位置。我应该使用单独的线程来显示循环来解决这个问题吗? 我知道glutPostRedisplay()可以用来重绘我的场景,但我不知道如何分离我的显示循环以保持对doStep函数的控制。
提前致谢
好的,因为我的帖子不清楚,没有代码,我会尝试指出问题。我使用Nvidia OptiX Raytracing渲染场景。视觉输出由C ++中的GLUTDisplay类创建。我为我的显示器创建了一个单独的线程并将其分离,以便我可以进一步控制该程序。我知道可以在线程之间共享一个类,所以我可以为显示创建一个单独的线程,并在我的另一个线程中调用GLUTDisplay::postRedisplay();
来更新上下文。要运行我的程序,我使用3个c函数:
extern "C" {
extern void* create(const char* filename, double* inputArray, double* outputArray, int argc, char** argv);
extern void trace(void* scene_obj);
extern void exitScene(void* scene_obj);
}
以下是我对它们的实施:
void * create( const char* filename, double* inputArray, double* outputArray, int argc, char** argv ){
OptixScene* scene = new OptixScene(filename);
scene->routeInput(inputArray); //routing my inputs and outputs
scene->routeOutput(outputArray); //from a simulation model
std::thread display_thread(&OptixScene::createDisplayThread, scene, argc, argv); // this starts the display loop
display_thread.detach(); // detach display thread to get control back
return (void *)scene;
}
void trace( void* scene_obj ){
OptixScene* scene = static_cast<OptixScene*> (scene_obj);
scene->readInputs();
scene->updateMatrix();
scene->renderImage(); // GLUTDisplay::postRedisplay() in here
scene->writeOutputs();
}
void exitScene(void* scene_obj){
OptixScene* scene = static_cast<OptixScene*> (sensor);
try{
scene->cleanUp();
if (scene->getContext().get() != 0)
{
sutilReportError( "Scene class failed to clean up!" );
exit(2);
}
exit(0);
}
catch( Exception& e ){
sutilReportError( e.getErrorString().c_str() );
exit(2);
}
}
一开始我拨打create()
一次,然后每隔40ms拨打trace()
来更新我的场景。这是dislay循环的安全线程实现吗?经过一段时间运行我的程序,我的场景不再自我更新。只有当我将鼠标移到窗口上时,场景才会更新。这是由我的线程实现引起的吗?
答案 0 :(得分:1)
要将C
代码与C++
代码混合,请使用extern
关键字。
extern "C"{
void externalDoStep() {
// your algorithm here
}
}
但是当你说你的功能被阻止时,我认为你应该这样做:
尝试将doStep()
函数插入此GLUT
回调函数,只是为了查看..
glutIdleFunc( doStep );
或任何其他GLUT
回调函数。
如果您不将功能放在GLUT
回调函数中,则GLUT
不会运行您的函数。
GLUT
的主要重要部分是callbacks
。这些函数可以处理更改窗口大小或按键时生成的GLUT
事件。
它的工作原理如下。您可以创建自己的功能并插入这些功能
进入这些主要的GLUT
回调函数。它们必须位于main()
glutReshapeFunc(your reshape function);
glutDisplayFunc(your display function);
glutIdleFunc(your idle function);
glutKeyboardFunc(your keyboard function);
完整代码清单:
#include <windows.h>
#include <string.h>
#include <GL\glut.h>
#include <iostream.h>
#include <fstream.h>
#pragma comment(lib, "glu32.lib")
int ii=0;
int iex=0;
extern "C"{
void externalDoStep() {
// your algorithm here
iex++;
cout<<iex<<" externalDoStep \n";
}
}
void doStep (void){
// your algorithm here
ii++;
cout<<ii<<" doStep () is running \n";
glutPostRedisplay();
}
void RenderToDisplay(){
// your algorithm here
}
void myDisplayFunction(void){
// your algorithm here
}
void myReshapeFunction(int w, int h){
// your algorithm here
}
int main(){
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(800, 400);
glutCreateWindow("dostep");
glClearColor(0.0, 0.0, 0.0, 1.0);
glLineWidth(3);
glutDisplayFunc( myDisplayFunction );
glutReshapeFunc( myReshapeFunction );
glutIdleFunc( doStep );
glutMainLoop();
return 0;
}