我要发帖 回复

高级会员

5

主题

1013

积分

0

专家分

兴趣点(最多三项):

视景仿真

私信
发表时间 : 2007-10-15 13:08:09 | 浏览 : 9982    评论 : 41
Vega Prime程序与仪表绘制程序的集成要解决的关键问题有三个:第一个要解决的就是接口,也就是说仪表绘制程序代码在那里执行的问题;第二个要解决的问题是两者之间的显示差异如何统一,即如何让OpenGL程序绘制的图形能在Vega Prime中正常显示;第三个要解决的问题是如何保留和恢复Vega Prime的绘制状态。
对于第一个问题,我们知道在Vega Prime主线程开启的同时,还开启了其它一些线程,例如cull、draw等,仪表绘制程序代码只能在draw这个线程里执行,因此找到draw线程的接口才是问题的本质。由于Vega Prime中是采用事件触发方式,draw线程的接口只有跟draw有关的事件:EVENT_PRE_DRAW和EVENT_POST_DRAW。显然应该订购vsChannel的EVENT_POST_DRAW消息,在类vsChannel::Subscriber的派生类 Subscriber里执行仪表绘制程序,详细代码如下:
class Subscriber: public vsChannel::Subscriber
{
  public:
  virtual void notify(vsChannel::Event, const vsChannel *, vsTraversalCull *)
  {
}
virtual void notify(vsChannel::Event event, const vsChannel *chan, vrDrawContext *context)
{
      //执行仪表绘制程序代码;
PostDrawFunc();
}
}
同时在程序初始化的时候增加类Subscriber对象subscriber到通道订购对象列表中,
m_channel->addSubscriber(vsChannel::EVENT_POST_DRAW, &subscriber)。
对于第二个问题,Vega Prime和OpenGL观察方式就不同,Vega Prime默认视线是沿着y轴的,OpenGL是z轴,因此在绘制时坐标应该进行相应的转换。
对于第三个问题可以用glPushAttrib、glGetIntegerv、 glPopMatrix()和glMatrixMode等函数来解决,详细代码如下:
void PostDrawFunc (void)
{
//保存Vega Prime绘制环境;
static int savedmatrix;
glPushAttrib(GL_ALL_ATTRIB_BITS);
glGetIntegerv(GL_MATRIX_MODE, &savedmatrix);
glDisable(GL_DEPTH_TEST);
//设置GL Studio绘制环境
  glDisable(GL_TEXTURE_2D);
glDisable(GL_LIGHTING);
  glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
//执行GL Studio程序代码;
………….
//结束GL Studio程序代码;
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode (savedmatrix);
glPopAttrib();
}
鼠标消息映射的实现
在Vega Prime程序与GL Studio仪表绘制程序的集成的过程中,鼠标消息并不会自动传到GL Studio仪表绘制程序中,结果导致仪表绘制程序无法响应鼠标消息。通过分析Vega Prime与GL Studio的消息处理机制,我们需要解决三个关键问题:一是如何从Vega Prime中获取鼠标消息;二是Vega Prime与GL Studio的消息格式不同,必须进行转化;三是如何把消息传给GL Studio处理。
对于第一个问题,从Vega Prime应用程序的运行机制,我们可以通过在系统控制模块CVPTApp内重载鼠标消息处理虚函数onMouseInput实现。
对于第二个问题,在消息传给GL Studio之前,要进行格式的转化。Vega Prime中鼠标消息定义如下:
struct vrWindow::Mouse
{
   // true if the left, middle, or right buttons are down
   bool m_leftButton;
   bool m_middleButton;
   bool m_rightButton;
   // mouse wheel counter which is incremented / decremented with every
   // move of the mouse wheel
   int m_wheel;
   // mouse position relative to window origin in pixels
   int m_x, m_y;
   // normalized mouse position (-1 to 1) relative to window center
   float m_nx, m_ny;
};
GL Studio鼠标消息定义如下:
class MouseEvent
{
  public:
    int x,y;                     
    float z;
    float lx,ly,lz;      
    unsigned char buttonMask;     
    unsigned short eventType;
    unsigned short eventSubtype
    unsigned char clicks;
    int modifiers;     
};
下面是实现这两种鼠标消息转化程序代码,模拟了鼠标左键按下和弹起操作:
bool MouseEventTransform(const vrWindow::Mouse& mouse, MouseEvent& event)
{
static int x=mouse.m_x;
static int y=mouse.m_y;
static bool leftbutton=false;
bool be;
//鼠标消息
event.eventType=EVENT_MOUSE;
   //鼠标左键按下
if(mouse.m_leftButton)
{
     //确定按下还是按下拉动
  if(leftbutton)
  {
   if(mouse.m_x!=x || mouse.m_y!=y)
   {
    event.eventSubtype=MOUSE_DRAG;
    be=true;
   }
   else
   {
    be=false;
   }
   }
  else
  {
   event.eventSubtype=MOUSE_DOWN;
   be=true;
  }
  //填写标志;
     event.buttonMask=MOUSE_LBUTTON;
       event.x=mouse.m_x;
     event.y=mouse.m_y;
  //记录本次操作;
  leftbutton=mouse.m_leftButton;
}
//鼠标左键弹起;
else
{
  //按下后弹起;
  if(leftbutton)
  {
   event.eventSubtype=MOUSE_UP;
   event.buttonMask=MOUSE_LBUTTON;
          event.x=mouse.m_x;
        event.y=mouse.m_y;
   be=true;
  }
//一直弹起;
  else
  {
            be=false;
  }
  //记录本次操作
  leftbutton=mouse.m_leftButton;
}
//如消息有效则为true
return be;
};
对于第三个问题,只需要依次执行仪表中显示对象DisplayObject的成员函数handle(DisplayEvent *ev)就可以把消息传到GL Studio程序,整个处理代码如下:
virtual void onMouseInput(const vrWindow::Mouse& mouse, int mod)
{
    MouseEvent ev;
    if(MouseEventTransform(mouse,ev))
    {
     DisplayObject->handle(&ev);
    }
}。

评分

参与人数 1积分 +10 收起 理由
独山子 + 10 原创内容

查看全部评分

最近VR访客

stevenww9821307 评论于2007-10-15 23:05:27
问题是插件谁都不共享
cani 评论于2007-10-16 15:46:41
楼主很强,这么底层的用法都研究
yjw1018 评论于2007-10-16 23:03:01
good
努力奋斗!知足常乐!享受生活!
GIS  and  VR
tekcare 评论于2007-11-12 16:19:21
謝謝呀
jingyunlei616 评论于2007-11-13 16:40:18
给楼主顶一下!!
tekcare 评论于2007-11-13 17:15:21
謝謝呀
tan_dunming 评论于2007-11-13 20:05:57
长见识
独山子 评论于2007-11-13 23:34:18
留名,有时间看看。
逆水行舟,不进则退。
5ibluesky专家组 评论于2007-12-9 15:08:24
这么原创的帖子,
斑竹呢,
赶紧加分阿!
LZ:
这个区我没有权限,
纯支持你了
天行健,君子以自强不息!
机器余专家组 认证企业会员 评论于2007-12-9 17:07:17
謝謝呀
wangxueping 评论于2007-12-10 18:10:41
先看看
xinyangmaojian 评论于2007-12-13 11:12:34
好东西!学习
cani 评论于2007-12-29 23:22:21
能解决GLS模型内部代码吗?
wangxueping 评论于2008-1-13 15:37:21
谢谢了
obuil 评论于2008-1-15 12:06:48
好文章, 实际上这种思路可以解决 vp和其他opengl绘图程序的共存问题
david_m 评论于2008-3-31 20:16:48
同意楼上观点,确实为好文,只要与绘图相关的应该都是这样做.
russelcrowe 评论于2008-3-31 21:11:22
支持!
xczhang 评论于2008-3-31 21:43:27
收藏了,慢慢研究!
xczhang 评论于2008-3-31 21:44:15
今天在vrchina上面的收获还是蛮大的,看到了很多多的好贴!

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

GMT+8, 2021-10-29 02:09 AM

返回顶部