我要发帖 回复

管理员

735

主题

2万

积分

30

专家分

忠于职守杰出贡献鼓励

兴趣点(最多三项):

建模技术

私信
发表时间 : 2007-2-4 13:05:14 | 浏览 : 4029    评论 : 18
PagingService.h
  1. #ifndef PAGINGSERVICE_H
  2. #define PAGINGSERVICE_H

  3. #include "vsgs.h"
  4. #include "vsService.h"
  5. #include "vsThread.h"
  6. #include "vuField.h"
  7. #include "vuSema.h"
  8. #include "vsNode.h"

  9. class PagingService : public vsService {
  10. public:

  11.     PagingService();

  12.     virtual int     configure();

  13.     virtual int     onFirstFrame();

  14.     virtual int     onLastFrame();

  15.     virtual int     beginFrame(uint frame, double des, double beg);

  16.     virtual int     endFrame();

  17.     /*
  18.      * adds a paging request
  19.      */
  20.     void            addPageRequest(vsNode* root);

  21. private:

  22.     /*
  23.      * the 'thread' function: the main paging thread loop is in there
  24.      */
  25.     static void*    pageFunc(void* );

  26.     /*
  27.      * the actual 'page' or scene graph generation
  28.      */
  29.     void            page();

  30.     /*
  31.      * the paging worker thread
  32.      */
  33.     vuField  m_pager;

  34.     /*
  35.      * data structure for the paging thread local thread storage
  36.      */
  37.     vsThread::FrameStorage* m_frameStorage;

  38.     /*
  39.      * paging semaphore that controls the paging thread
  40.      */
  41.     vuField    m_pageSema;

  42.     bool                m_bLastFrame;

  43.     bool                m_bPaging;

  44.     bool                m_bDonePaging;

  45.     vsNode*             m_parent;

  46.     vsNode*             m_pagedRoot;

  47.     /*
  48.      * a thread buffer for the paging thread
  49.      */
  50.     vuField    m_buffer;

  51.     /*
  52.      * the main application thread buffer
  53.      */
  54.     vuField    m_appBuffer;

  55.     VUMEMBASE_HEADER_INCLUDES(PagingService)

  56. };
  57. #endif
复制代码
PagingService.cpp
  1. #include "vsgs.h"
  2. #include "PagingService.h"
  3. #include "vsBillboard.h"
  4. #include "vsGeometry.h"
  5. #include "vrGeometry.h"
  6. #include "vsThread.h"
  7. #include "vsServiceMgr.h"

  8. PagingService::PagingService() : m_bPaging(false),
  9.                                  m_bDonePaging(false),
  10.                                  m_frameStorage(NULL),
  11.                                  m_bLastFrame(false),
  12.                                  m_parent(NULL),
  13.                                  m_pagedRoot(NULL)
  14. {
  15. }

  16. PagingService::~PagingService()
  17. {
  18.     delete m_frameStorage;
  19. }

  20. int PagingService::configure()
  21. {
  22.     //create the pager thread
  23.     m_pager = new vsThread();

  24.     m_pager->setName("Paging thread");

  25.     // create local thread storage for the paging thread
  26.     m_frameStorage = new vsThread::FrameStorage();

  27.     // set the clone index to 0 since the service doesn't require a clone
  28.     m_frameStorage->m_cloneIndex = 0;

  29.     vsServiceMgr* mgr = vsThread::resolveServiceMgr();

  30.     assert(mgr);

  31.     // set the service manager in case some application call needs to
  32.     // resolve the service manager from the context of the paging thread
  33.     m_frameStorage->m_serviceMgr = mgr;

  34.     // assign the thread local storage to the paging thread.
  35.     m_pager->setFrameStorage(m_frameStorage);

  36.     // create the semaphore to control execution of the thread
  37.     m_pageSema = new vuSema();

  38.     // paging thread requires a thread buffer
  39.     m_buffer = mgr->obtainThreadBuffer(true);

  40.     // the thread buffer is used for paging
  41.     int res = m_buffer->setPagingModeEnable(true);

  42.     assert(res == vsgu::SUCCESS);

  43.     // make the thread local storage point to the buffer
  44.     m_frameStorage->m_buffer = m_buffer.get();

  45.     // need to know the main application thread buffer.
  46.     m_appBuffer = vsThread::resolveThreadBuffer();

  47.     assert(m_appBuffer.get());

  48.     return vsgu::SUCCESS;
  49. }

  50. int PagingService::onFirstFrame()
  51. {
  52.     m_bLastFrame = false;

  53.     // set the thread function
  54.     m_pager->setFunc(pageFunc);

  55.     // set the thread data
  56.     m_pager->setData(this);

  57.     // set frame number to 1 in the thread local storage
  58.     m_frameStorage->m_frameNumber = 1;

  59.     // spawn the actual OS thread
  60.     m_pager->spawn();

  61.     return vsgu::SUCCESS;
  62. }

  63. int PagingService::onLastFrame()
  64. {
  65.     m_bLastFrame = true;
  66.    
  67.     // let the paging thread go if it was waiting.
  68.     // the semaphore needs to be released to avoid a dead-lock.
  69.     m_pageSema->release();
  70.         
  71.     // the paging thread will exit the loop and terminate
  72.     // wait for it to happen.
  73.     if(m_pager->join() != vsgu::SUCCESS) {

  74.         vuNotify::print(vuNotify::LEVEL_DEBUG,NULL,
  75.         "PagingService::breakFrameLoop: join on thread failed");

  76.         return vsgu::FAILURE;
  77.     }
  78.     return vsgu::SUCCESS;
  79. }

  80. int PagingService::beginFrame(uint frame, double des, double beg)
  81. {
  82.     // if the paging thread is working, return immediately
  83.     if(m_bPaging) {
  84.      
  85.         // indicate that paging is in effect...
  86.         crt::printf(".");
  87.         
  88.         return vsgu::SUCCESS;
  89.     }
  90.    
  91.     // if we have a new paging request
  92.     if(m_parent) {

  93.         // update the local thread storage data
  94.         m_frameStorage->m_frameNumber = frame;
  95.    
  96.         m_frameStorage->m_simulationTime = beg;

  97.         m_bPaging = true;

  98.         // let the thread go to service the new paging request
  99.         m_pageSema->release();
  100.     }
  101.     return vsgu::SUCCESS;
  102. }

  103. int PagingService::endFrame()
  104. {
  105.     // if the paging thread is done, process the results
  106.     if(m_bDonePaging) {

  107.         // merge the result into the main tree
  108.         m_parent->push_back_child(m_pagedRoot);

  109.         // reset all the control variables to 'idle' position.
  110.         m_parent = NULL;

  111.         m_pagedRoot = NULL;

  112.         m_bPaging = false;

  113.         m_bDonePaging = false;

  114.     }

  115.     return vsgu::SUCCESS;
  116. }

  117. void PagingService::addPageRequest(vsNode* root)
  118. {
  119.     if(m_bPaging) {

  120.         vuNotify::print(vuNotify::LEVEL_INFO,NULL,
  121.             "PagingService::addPageRequest: can't service request while paging\n");

  122.         return;
  123.     }
  124.    
  125.     assert(m_parent == NULL);

  126.     m_parent = root;
  127. }

  128. //static
  129. void* PagingService::pageFunc(void* psrv)
  130. {
  131.     PagingService* srv = static_cast(psrv);

  132.     assert(srv);

  133.     while (1) {

  134.         // Wait until APP tells us there is a new paging request
  135.         srv->m_pageSema->wait();

  136.         vuNotify::print(vuNotify::LEVEL_INFO,NULL,
  137.            "\nPagingService: semaphore was released");
  138.       

  139.         if(srv->m_bLastFrame) {
  140.          
  141.             vuThread::exit(vsThread::EXITCODE_NORMAL);
  142.         }

  143.         if(srv->m_parent) {

  144.             assert(srv->m_bPaging);
  145.         
  146.             // generate the tree
  147.             srv->page();

  148.             vuNotify::print(vuNotify::LEVEL_INFO,NULL,
  149.                 "\nPagingService: done with paging");

  150.             // recompute bounding spheres
  151.             srv->m_buffer->processDirty();

  152.             vuNotify::print(vuNotify::LEVEL_INFO,NULL,
  153.                 "\nPagingService: done with bounding sphere update");

  154.             //first, we need to go over the main clone and do
  155.             //thread buffer substitution.
  156.             srv->m_buffer->replaceBuffer(srv->m_appBuffer.get());

  157.             //for each other clone, process to create the clone
  158.             //and synch it with the master clone
  159.             int numClones = srv->m_buffer->getNumClones();
  160.             for(int i = 1; i < numClones; ++i) {

  161.                 srv->m_buffer->process(i);
  162.             }

  163.             vuNotify::print(vuNotify::LEVEL_INFO,NULL,
  164.                 "\nPagingService: done with clone generation");

  165.             //done paging
  166.             srv->m_bDonePaging = true;
  167.         }
  168.     }
  169.     return NULL;
  170. }

  171. void PagingService::page()
  172. {
  173.     //do the actual paging
  174.     vuNotify::print(vuNotify::LEVEL_INFO,NULL,"PagingService: paging...");
  175.    
  176.     //the root is a billboard to orient wrt the user
  177.     m_pagedRoot = new vsBillboard();

  178.     //the geometry is a square made of a triangle strip

  179.     vrState* state = new vrState();
  180.    
  181.     int* length = vuAllocArray::malloc(1);
  182.     length[0] = 4;
  183.    
  184.     vsGeometry* gnode = new vsGeometry();
  185.    
  186.     vrGeometry* geom = new vrGeometry();
  187.    
  188.     vuVec3* verts = vuAllocArray >::malloc(4);
  189.     vuVec4* colors = vuAllocArray >::malloc(4);
  190.    
  191.     colors[0].set(1.0f,0.0f,0.0f,0.0f);
  192.     colors[1].set(0.0f,1.0f,0.0f,0.0f);
  193.     colors[2].set(0.0f,0.0f,1.0f,0.0f);
  194.     colors[3].set(1.0f,1.0f,1.0f,0.0f);
  195.    
  196.     verts[0].set(-3.0f,0.0f,-3.0f);
  197.     verts[1].set(3.0f,0.0f,-3.0f);  
  198.     verts[2].set(-3.0f,0.0f,3.0f);
  199.     verts[3].set(3.0f,0.0f,3.0f);
  200.    
  201.     geom->setVertices(verts);
  202.     geom->setColors(colors,vrGeometry::BINDING_VERTEX);
  203.     geom->setPrimitive(vrGeometry::PRIMITIVE_TRIANGLE_STRIP);
  204.     geom->setPrimitiveLengths(length);
  205.     geom->setNumPrimitives(1);
  206.    
  207.     gnode->setGeometry(geom);
  208.     gnode->setState(state);
  209.    
  210.     //add geometry to the root
  211.     m_pagedRoot->push_back_child(gnode);   
  212.    
  213.     //pretend that paging takes a long time to test its effect
  214.     //on the frame rate.
  215.     vuThread::suspend(2,0);
  216. }
复制代码
vsgs_paging_service.cpp
  1. #include "vsgs.h"
  2. #include "PagingService.h"
  3. #include "vsApp.h"

  4. #include "vuAllocTracer.h"
  5. vuAllocTracer allocTracer;

  6. class vsPagingApp : public vsApp {
  7. public:

  8.     vsPagingApp();
  9.    
  10.     virtual void    run();

  11. protected:
  12.    
  13.     virtual void    onKeyInput(vrWindow::Key key, int mod);

  14.     vuField m_pagingSrv;

  15.     VUMEMBASE_HEADER_INCLUDES(vsPagingApp)

  16. };

  17. vsPagingApp::vsPagingApp() : m_pagingSrv(new PagingService())
  18. {
  19.     /*
  20.      * Register the service with the service manager
  21.      */
  22.     m_srvMgr->registerService(m_pagingSrv.get());
  23. }

  24. vsPagingApp::~vsPagingApp(){}

  25. void vsPagingApp::onKeyInput(vrWindow::Key key, int mod)
  26. {
  27.     switch( key ) {
  28.         case vrWindow::KEY_ESCAPE:
  29.             m_srvMgr->breakFrameLoop();
  30.             break;
  31.         case 'P' :
  32.             //add paging request
  33.             m_pagingSrv->addPageRequest(m_root);
  34.             break;
  35.         case 'p' :
  36.             //remove all children from the root
  37.             while( !m_root->empty_child()) {
  38.                
  39.                 m_root->erase_child(m_root->begin_child());
  40.             }
  41.             break;
  42.         default:
  43.             vsApp::onKeyInput(key, mod);
  44.             break;
  45.     }
  46. }

  47. void vsPagingApp::run()
  48. {
  49.     // set the desired frame rate to 30 Hz
  50.     m_srvMgr->setDesiredFrameRate(30.0f);

  51.     // set the view matrix
  52.     vuMatrixAffine viewMat;
  53.     viewMat.setTranslate(14.0, 0.0, 0.0);
  54.     viewMat.setRotate(90.0, 0.0, 0.0);
  55.     m_chan->setViewMatrix(viewMat);

  56.     uint iFrame;
  57.     // the frame loop
  58.     while ( (iFrame = m_srvMgr->beginFrame()) != 0 ) {

  59.         m_srvMgr->endFrame();
  60.     }
  61. }


  62. int main(int argc, char *argv[])
  63. {
  64.    
  65.     vsgs::initialize(argc, argv);
  66.    
  67.     vuNotify::setLevel(vuNotify::LEVEL_INFO);
  68.    
  69.     vuNotify::print(vuNotify::LEVEL_INFO,NULL,
  70.     "Use 'P' to addPageRequest in, 'p' to addPageRequest out, 'esc' to quit");
  71.    
  72.     vsPagingApp* app = new vsPagingApp();
  73.    
  74.     //use MT mode that requeries a cull clone
  75.     //to test the clone generation by the paging service
  76.     app->configure(vsPipeline::MULTITHREAD_CULL_DRAW);
  77.    
  78.     app->run();
  79.    
  80.     app->unconfigure();
  81.    
  82.     app->unref();
  83.    
  84.     vsgs::shutdown();
  85.    
  86.     return(0);
  87.    
  88. }
复制代码

[ 本帖最后由 obuil 于 2007-9-5 11:00 AM 编辑 ]

最近VR访客

huangex 评论于2007-2-4 13:14:55

回复 #1 obuil 的帖子

谢谢 老大!

这厢有礼了!
obuil 评论于2007-2-4 13:36:07
在Extending_Vega_Scene_Graph.pdf中 有类似的代码 你可以看看
yin_ke 评论于2007-5-19 21:19:27
太好了
yin_ke 评论于2007-8-15 07:08:46
谢谢!!!
wenxuanwenya 评论于2007-8-15 09:00:21
很有用,谢谢了
lxhlxh 评论于2007-8-23 22:56:48
ding,thank
yjw1018 评论于2007-8-27 10:30:59
很好的学习资料!
努力奋斗!知足常乐!享受生活!
GIS  and  VR
wenxuanwenya 评论于2007-8-27 12:38:51
谢谢 老大!
小生子这厢有礼了!!!
步怀真 评论于2007-9-17 09:00:35
请教一下版主,这个例子是给哪个版本的VP的,貌似用2.01编不通

还有这个例子是完整的么,onKeyInput这个是不是用来开关新线程的?在哪里调到它的呢?

谢谢了先···
步怀真 评论于2007-9-17 09:02:08
请教一下版主,这个例子是给哪个版本的VP的,貌似用2.01编不通

还有这个例子是完整的么,onKeyInput这个是不是用来开关新线程的?在哪里调到它的呢?

谢谢了先···
xulide 评论于2007-9-18 08:25:59
ding,thank
wakexie 评论于2008-3-5 21:53:06
jazzy001 评论于2008-3-9 09:36:37
谢谢
renzhijun 评论于2008-3-30 21:47:08
老大,在那里能找到完整的WEB SANMPLE 呀
zhurains 评论于2008-4-8 13:19:41
evidence 评论于2008-6-13 14:12:12
收集学习
menghewei 评论于2008-9-9 12:00:41
jialoveli 评论于2014-7-29 09:08:42
为什么编译时总是提醒vuField是类模板,但是定义对象时没有参数列表??

手机版|VR开发网 统计 津ICP备18009691号
网安备12019202000257

GMT+8, 2021-4-18 08:04 AM

返回顶部