0

我想从SoQtExaminerViewer. 最初的问题是,当我调用 时SoMpegNavRenderer::stop(),查看器必须等待代码完成。因此,我尝试使用std::thread()std::async()创建新线程来处理 mpeg 视频的录制。我相信,录制已经在后台发生并且能够创建视频。

但是,(这是我需要帮助和理解的)当代码在用户能够控制查看器之前从头开始重播/重绘 mpeg 视频时到达SoMpegNavRenderer::stop()视图/渲染区域。SoQtExaminerViewer我的意图是让用户按下r录制,做一些相机移动,按下c停止录制,保存视频并继续他们的工作。

下面是完整的代码:

#include <Inventor/nodes/SoLightModel.h>
#include <Inventor/nodes/SoOrthographicCamera.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoMaterial.h>
#include <Inventor/nodes/SoTransform.h>
#include <Inventor/nodes/SoCone.h>
#include <Inventor/Qt/viewers/SoQtExaminerViewer.h>
#include <Inventor/events/SoKeyboardEvent.h>
#include <Inventor/nodes/SoEventCallback.h>
#include <Inventor/MPEG/SoMPEGNavRenderer.h>

// Use Open Inventor's portable thread classes
#include <Inventor/threads/SbThread.h>

SoQtExaminerViewer *myViewer;
SoMPEGNavRenderer *MPEGRenderer;

// Forward decls
SoGroup *getConeGroup(SbVec3f color) ;
void myKeyPressCB (void *, SoEventCallback *eventCB); 
void startRecord();
void* stopRecord(void *userData);

int main(int, char **argv)
{
  // Initialize Open Inventor. --------------------------------------
  QWidget *myWindow = SoQt::threadInit(argv[0]); // pass the app name
  myWindow->resize(500,500);    
  if (myWindow == NULL) 
    return 1;

  // Create scene graph ----------------------------------------------
  SoSeparator *root = new SoSeparator();
  root->ref();

  SoLightModel *lModel = new SoLightModel ;
  lModel->model = SoLightModel::BASE_COLOR ;
  root->addChild(lModel) ;

  SoOrthographicCamera *camera = new SoOrthographicCamera();
  camera->ref();
  root->addChild(camera);

  root->addChild(getConeGroup(SbVec3f(1.0,0.0,0.0)));

  SoEventCallback *myEventCB = new SoEventCallback;
  myEventCB->addEventCallback(SoKeyboardEvent::getClassTypeId(),
                               myKeyPressCB, myViewer);
  root->addChild(myEventCB);

  // Create viewer ---------------------------------------------------
  myViewer = new SoQtExaminerViewer(myWindow);
  myViewer->setSceneGraph(root);
  myViewer->setTitle("Movie with thread");
  myViewer->show();

  // Create mpegrenderer ---------------------------------------------
  MPEGRenderer = new SoMPEGNavRenderer (myViewer->getSceneManager()->getSceneGraph());
  MPEGRenderer->setSize (SbVec2s (300, 300));
  MPEGRenderer->adjustNumFramesPerSecond(TRUE);
  MPEGRenderer->setBitPerSec(-1);
  MPEGRenderer->setCompressionRate(0.);
  MPEGRenderer->setShareContext( (myViewer->getShareContext()));

  int i = 0;
  char mpegFileName[20] = "MPEGOutput.mpg";
  while (!MPEGRenderer->openFile(mpegFileName)) 
  {
    sprintf(mpegFileName, "MPEGOutput%d.mpg", i);
    i++;
  }

  SoQt::show(myWindow);  
  SoQt::mainLoop();     
  delete myViewer;
  root->unref();
  SoQt::finish();
  return 0;
}

void* stopRecord(void *userData)
{
  SoDB::threadInit(); 

  // Get pointer to mpegrenderer
  SoMPEGNavRenderer *pMpegRenderer = (SoMPEGNavRenderer *)userData;
  pMpegRenderer->stop();
  pMpegRenderer->closeFile();

  return NULL;
}

void startRecord()
{
  MPEGRenderer->record();
}

void myKeyPressCB (void *, SoEventCallback *eventCB) 
{
  const SoEvent *event = eventCB->getEvent();

  // check for the keys being pressed
  if (SO_KEY_PRESS_EVENT(event, R)) 
  {    
    startRecord();
  } 
  else if (SO_KEY_PRESS_EVENT(event, C)) 
  {
    SbThread *pModifyThread = SbThread::create(stopRecord, (void*)MPEGRenderer);
  }
  else if (SO_KEY_PRESS_EVENT(event, Z)) 
  {
    exit(0);
  }
}

SoGroup *getConeGroup(SbVec3f color) 
{
  SoGroup *grp = new SoSeparator();
  SoMaterial *mat = new SoMaterial();
  SoCone *cone = new SoCone();
  SoTransform *trans = new SoTransform();

  trans->rotation.setValue(1.0,0.0,0.0,-3.14);
  mat->diffuseColor.setValue(color);
  grp->addChild(mat);
  grp->addChild(trans);
  grp->addChild(cone);

  return grp;
} 
4

0 回答 0