home *** CD-ROM | disk | FTP | other *** search
/ ftp.hitl.washington.edu / ftp.hitl.washington.edu.tar / ftp.hitl.washington.edu / pub / people / peter / ER / VideoObject.cxx < prev   
C/C++ Source or Header  |  1998-07-07  |  8KB  |  279 lines

  1. /*
  2.   VideoObject.cxx
  3.  
  4.     The VideoObject class is implemented with the dmuVideoIn and
  5.     dmuGLTex2d classes from the Digital Media Utility library.
  6.     Documentation can be found with the classes, but basically the
  7.     process for using the classes is as follows:
  8.  
  9.         A dmuVideoIn object is created that monitors the O2's video
  10.         input for new data.  This class is wired to a dmuGLTex2d
  11.         object.  When new data arrives, a callback is invoked which
  12.         checks to see if the new frame is valid, and if so it dumps
  13.         the frame to the GL texture memory stored in the dmuGLTex2d
  14.         object.
  15.  
  16.     The video object registers a callback with WTK's 3D predraw sender,
  17.     and uses OpenGL commands to draw the texture in the simulation.
  18.     However, since this is done before the scene graph is traversed
  19.     (instead of texturing during scene graph traversal, as can be done
  20.     in OpenInventor), a dummy object must be added to the simulation to
  21.     keep track of the position and extents of the video window.  This
  22.     dummy object is queried in the predraw callback for its position,
  23.     size, and orientation, and this data is used to draw the OpenGL
  24.     texture in the proper place.  Since the VideoObject is a subclass of
  25.     v3dObject, the dummy object in this case is simply a block object
  26.     created with the v3dObject implementation.
  27.  
  28. */
  29.  
  30. #include "VideoObject.h"
  31.  
  32. #include "wt.h"
  33.  
  34. #define dmuCheck(dmFunc) { \
  35.     int dmuErrID; \
  36.     if ((dmuErrID = (dmFunc)) != DMU_OK) \
  37.        fprintf(stderr,"*Error:%d:%s\n", dmuErrID, \
  38.                getErrorString(dmuErrID) ); \
  39.  }
  40.  
  41. VideoObject* VideoObject::TheVideoObject_ = 0;
  42.  
  43.  
  44. // VideoObject::GetInstance
  45. //    Returns a pointer to the video object singleton.
  46. //    If the singleton doesn't exist, it creates one.
  47. VideoObject *
  48. VideoObject::GetInstance()
  49. {
  50.     if (TheVideoObject_ == 0)
  51.         TheVideoObject_ = new VideoObject;
  52.  
  53.     return TheVideoObject_;
  54. }
  55.  
  56.  
  57. // VideoObject::VideoObject
  58. //    Initializes the video and texture objects, and sets the callbacks
  59. //    needed to update the displays.
  60. VideoObject::VideoObject ()
  61. {
  62.     create_bounding_box();
  63.     initialize_video();
  64.     RegisterEventHandler(PredrawSender::GetInstance(),
  65.         PredrawSender::PREDRAW_EVENT,
  66.         &video_GL_draw_CB, 0);
  67.     handle_event_ = false;
  68. }
  69.  
  70. void
  71. VideoObject::create_bounding_box()
  72. {
  73.     // Create the dummy object to keep track of the size and position
  74.     // of the video window.  The initial size in unimportant, since the
  75.     // client should scale the object to fit the simulation.
  76.     imp_->CreateBlock(5, 5, 0.1, false);
  77.  
  78.     // The dummy object is invisible, but still interacts with the
  79.     // rest of the simulation.  It can be scaled, rotated, collided with,
  80.     // attached, etc.
  81.     v3dObject::Hide();
  82. }
  83.  
  84. void
  85. VideoObject::initialize_video()
  86. {
  87. ////////////////////////////////////////////////////////////////////////////////
  88.  
  89.     /////////////////////////////////////////////////////////////////
  90.     // Set up video texture mapping.
  91.     // -- Construction --
  92.     video_in_ = new dmuVideoIn;
  93.     video_in_->setName("Video In ");
  94.  
  95.     texture_ = new dmuGLTex2d;
  96.     texture_->setName("Texture");
  97.  
  98.     // -- Wire --
  99.     video_in_->addObject(texture_);
  100.  
  101.     // -- Setup --
  102.  
  103.     // Use current vcp setting for video source
  104.     dmuCheck(video_in_->setup(VL_ANY));
  105.  
  106.     // Use ABGR_8 packing and formatting texture mapping
  107.     dmuCheck(video_in_->setPacking(VL_PACKING_ABGR_8));
  108.     dmuCheck(video_in_->setCaptureType(VL_CAPTURE_INTERLEAVED));
  109.     dmuCheck(video_in_->setFormat(VL_FORMAT_RGB));
  110.  
  111.     // Texture maps need to be powers of 2.
  112.     dmuCheck(video_in_->setSize(512,512));
  113.     dmuCheck(video_in_->setOrigin(0,32));
  114.  
  115.     // Use graphics layout for texture maps
  116.     dmuCheck(video_in_->setLayout(VL_LAYOUT_GRAPHICS));
  117.  
  118.     fprintf (stderr, "Getting video dimensions: ");
  119.     int size_X, size_Y;
  120.     video_in_->getImageDimensions(&size_X, &size_Y);
  121.     fprintf (stderr, "Video dimensions: %d, %d\n\n", size_X, size_Y);
  122.  
  123.     // Set up the texture object to have the same size
  124.     Widget window_widget = WTwindow_getwidget(WTuniverse_getwindows());
  125.     dmuCheck(texture_->setup(XtDisplay(window_widget), size_X, size_Y));
  126.  
  127.     // -- Init --
  128.     fprintf (stderr, "Initializing: \n\n");
  129.     dmuCheck(video_in_->init());
  130.  
  131.     // -- Start --
  132.     fprintf (stderr, "Fire it up!\n");
  133.     dmuCheck(video_in_->start());
  134.  
  135.     glMatrixMode( GL_MODELVIEW );
  136.     glLoadIdentity();
  137.  
  138.     glEnable(GL_TEXTURE_2D);
  139.     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  140.     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  141.     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  142.     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  143.     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE_EXT);
  144.  
  145.     XtAppContext    app;
  146.     app = XtWidgetToApplicationContext(window_widget);
  147.     XtInputId inputID = XtAppAddInput(app, video_in_->getFD(),
  148.         (XtPointer) XtInputReadMask, handle_dmu_events_CB, NULL);
  149.  
  150. }
  151.  
  152. void
  153. VideoObject::video_GL_draw_CB(const v3dEventMessage *message)
  154. {
  155.     TheVideoObject_->video_GL_draw();
  156. }
  157.  
  158. void
  159. VideoObject::video_GL_draw()
  160. {
  161.     if (handle_event_) {
  162.  
  163.         dmuCheck(texture_->defineTex2D());
  164. //        handle_event_ = false;
  165.  
  166.         glPushMatrix();
  167.  
  168.         glColor3f(1.0,1.0,1.0);
  169.         glEnable( GL_TEXTURE_2D );
  170.  
  171.         v3dDim obj_dim = GetSize();
  172.         v3dPos obj_pos = GetAbsolutePosition(),
  173.             top_left = v3dPos(- obj_dim.x() / 2, - obj_dim.y() / 2, 0),
  174.             top_right = top_left + v3dPos(obj_dim.x(), 0, 0),
  175.             bottom_left = top_left + v3dPos(0, obj_dim.y(), 0),
  176.             bottom_right = top_left + v3dPos(obj_dim.x(), obj_dim.y(), 0);
  177.         v3dCoordSystem obj_coord (obj_pos, GetAbsoluteOrientation());
  178.             top_left = obj_coord.LocalPosToAbsolute(top_left);
  179.             top_right = obj_coord.LocalPosToAbsolute(top_right);
  180.             bottom_left = obj_coord.LocalPosToAbsolute(bottom_left);
  181.             bottom_right = obj_coord.LocalPosToAbsolute(bottom_right);
  182.  
  183.         glBegin(GL_QUADS);
  184.  
  185.             glTexCoord2d(0.0,0.0); glVertex3f(bottom_left.x(),bottom_left.y(),bottom_left.z());
  186.             glTexCoord2d(1.0,0.0); glVertex3f(bottom_right.x(),bottom_right.y(),bottom_right.z());
  187.             glTexCoord2d(1.0,1.0); glVertex3f(top_right.x(),top_right.y(),top_right.z());
  188.             glTexCoord2d(0.0,1.0); glVertex3f(top_left.x(),top_left.y(),top_left.z());
  189.  
  190.         glEnd();
  191.         glDisable(GL_TEXTURE_2D);
  192.  
  193.         glPopMatrix();
  194.  
  195.  
  196.     }
  197. }
  198.  
  199. void
  200. VideoObject::handle_dmu_events_CB(XtPointer*, int *fd, XtInputId*)
  201. {
  202.     TheVideoObject_->handle_dmu_events();
  203. }
  204.  
  205. void
  206. VideoObject::handle_dmu_events()
  207. {
  208.     fd_set readFDSet;
  209.     int maxFD;
  210.  
  211.     FD_ZERO(&readFDSet);
  212.     video_in_->setFD(&readFDSet, &maxFD);
  213.  
  214.     int error = video_in_->handleEvents(readFDSet);
  215.  
  216.     // This handles the temporary video_in_ return values.  We only want
  217.     // to redraw the screen if we have a new video frame waiting for us
  218.     if (error != VIDEOIN_TRANSFER_COMPLETE) {
  219.         return;
  220.     }
  221.  
  222.     // Tell the texture to setup Open GL to use the latest
  223.     // video frame as a texture map.
  224.     handle_event_ = true;
  225. }
  226.  
  227. // VideoObject::~VideoObject
  228. //    Deletes the video object object.
  229. VideoObject::~VideoObject ()
  230. {
  231.     delete texture_;
  232.     delete video_in_;
  233. }
  234.  
  235. void
  236. VideoObject::Hide()
  237. {
  238.     UnregisterEventHandler(PredrawSender::GetInstance(),
  239.         PredrawSender::PREDRAW_EVENT,
  240.         &video_GL_draw_CB);
  241.  
  242.     hidden_ = true;
  243. }
  244.  
  245. void
  246. VideoObject::Show()
  247. {
  248.     RegisterEventHandler(PredrawSender::GetInstance(),
  249.         PredrawSender::PREDRAW_EVENT,
  250.         &video_GL_draw_CB, 0);
  251.  
  252.     hidden_ = false;
  253. }
  254.  
  255. void
  256. VideoObject::Enable()
  257. {
  258.     RegisterEventHandler(PredrawSender::GetInstance(),
  259.         PredrawSender::PREDRAW_EVENT,
  260.         &video_GL_draw_CB, 0);
  261.  
  262.     // Re-enable the bounding box so it can interact with the simulation,
  263.     // but hide it so it can't be seen.
  264.     v3dObject::Enable();
  265.     v3dObject::Hide();
  266.     disabled_ = false;
  267. }
  268.  
  269. void
  270. VideoObject::Disable()
  271. {
  272.     UnregisterEventHandler(PredrawSender::GetInstance(),
  273.         PredrawSender::PREDRAW_EVENT,
  274.         &video_GL_draw_CB);
  275.  
  276.     v3dObject::Disable();
  277. }
  278.  
  279.