如何调用外部c函数,而GLUT显示循环锁定我的c ++ main?

时间:2016-08-24 10:31:46

标签: c++ c multithreading loops glut

我是新来的,不熟悉显示编程。 我有一个每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循环的安全线程实现吗?经过一段时间运行我的程序,我的场景不再自我更新。只有当我将鼠标移到窗口上时,场景才会更新。这是由我的线程实现引起的吗?

1 个答案:

答案 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;
}