OsgApp.h

Go to the documentation of this file.
00001 /*************** <auto-copyright.pl BEGIN do not edit this line> **************
00002  *
00003  * VR Juggler is (C) Copyright 1998-2005 by Iowa State University
00004  *
00005  * Original Authors:
00006  *   Allen Bierbaum, Christopher Just,
00007  *   Patrick Hartling, Kevin Meinert,
00008  *   Carolina Cruz-Neira, Albert Baker
00009  *
00010  * This library is free software; you can redistribute it and/or
00011  * modify it under the terms of the GNU Library General Public
00012  * License as published by the Free Software Foundation; either
00013  * version 2 of the License, or (at your option) any later version.
00014  *
00015  * This library is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018  * Library General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU Library General Public
00021  * License along with this library; if not, write to the
00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00023  * Boston, MA 02111-1307, USA.
00024  *
00025  * -----------------------------------------------------------------
00026  * File:          $RCSfile$
00027  * Date modified: $Date: 2006-11-14 13:22:08 -0600 (Tue, 14 Nov 2006) $
00028  * Version:       $Revision: 19509 $
00029  * -----------------------------------------------------------------
00030  *
00031  *************** <auto-copyright.pl END do not edit this line> ***************/
00032 
00033 #ifndef _VRJ_OSG_APP_H_
00034 #define _VRJ_OSG_APP_H_
00035 
00036 #include <vrj/vrjConfig.h>
00037 
00038 #include <vrj/Draw/OGL/GlApp.h>
00039 #include <vrj/Draw/OGL/GlContextData.h>
00040 #include <vrj/Draw/OGL/GlWindow.h>
00041 
00042 #include <vrj/Display/CameraProjection.h>
00043 
00044 #include <osg/Vec3>
00045 #include <osg/Matrix>
00046 #include <osg/Transform>
00047 #include <osg/Group>
00048 
00049 #include <osgUtil/SceneView>
00050 #include <osgUtil/UpdateVisitor>
00051 
00052 
00053 namespace vrj
00054 {
00055 
00068 class OsgApp : public GlApp
00069 {
00070 public:
00071    OsgApp(Kernel* kern = NULL)
00072       : GlApp(kern)
00073       , mFrameNumber(0)
00074    {
00075       ;
00076    }
00077 
00078    virtual ~OsgApp()
00079    {
00080       ;
00081    }
00082 
00087    virtual void initScene() = 0;
00088 
00093    virtual osg::Group* getScene() = 0;
00094 
00103    virtual void configSceneView(osgUtil::SceneView* newSceneViewer)
00104    {
00105       newSceneViewer->setDefaults();
00106       newSceneViewer->init();
00107       newSceneViewer->setClearColor(osg::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
00108 
00109       // Needed for stereo to work.
00110       newSceneViewer->setDrawBufferValue(GL_NONE);
00111    }
00112 
00127    virtual void latePreFrame()
00128    {
00129       update();
00130    }
00131 
00140    virtual void draw();
00141 
00151    virtual void init()
00152    {
00153       mUpdateVisitor = new osgUtil::UpdateVisitor();
00154       mFrameStamp    = new osg::FrameStamp();
00155       mUpdateVisitor->setFrameStamp(mFrameStamp.get());
00156 
00157       GlApp::init();
00158 
00159       mHead.init("VJHead");
00160 
00161       //Create the scene
00162       this->initScene();
00163    }
00164 
00174    void contextInit();
00175 
00180    virtual void contextClose()
00181    {
00182       ;
00183    }
00184 
00196    virtual void contextPreDraw()
00197    {
00198       ;
00199    }
00200 
00216    virtual void bufferPreDraw()
00217    {
00218       ;
00219    }
00220 
00230    virtual void pipePreDraw()
00231    {
00232       ;
00233    }
00234 
00235 protected:
00253    void update()
00254    {
00255       ++mFrameNumber;
00256 
00257       // Update the frame stamp with information from this frame.
00258       mFrameStamp->setFrameNumber(mFrameNumber);
00259       mFrameStamp->setReferenceTime(mHead->getTimeStamp().secd());
00260 
00261       // Set up the time and frame number so time-dependent things (animations,
00262       // particle system) function correctly.
00263       // XXX: This may not be necessary.
00264       mUpdateVisitor->setTraversalNumber(mFrameNumber);
00265 
00266       // Update the scene by traversing it with the the update visitor which
00267       // will call all node update callbacks and animations. This is
00268       // equivalent to calling osgUtil::SceneView::update() but does not
00269       // require access to the context-specific osgUtil::SceneView instance.
00270       getScene()->accept(*mUpdateVisitor);
00271    }
00272 
00273    vrj::GlContextData< osg::ref_ptr<osgUtil::SceneView> > sceneViewer;
00274 
00275 private:
00276    osg::ref_ptr<osg::NodeVisitor> mUpdateVisitor;
00277    osg::ref_ptr<osg::FrameStamp> mFrameStamp;
00278 
00279    int mFrameNumber;
00280    gadget::PositionInterface mHead;
00281 };
00282 
00283 inline void OsgApp::contextInit()
00284 {
00285    unsigned int unique_context_id = GlDrawManager::instance()->getCurrentContext();
00286 
00287    // --- Create new context specific scene viewer -- //
00288    osg::ref_ptr<osgUtil::SceneView> new_sv(new osgUtil::SceneView);
00289    this->configSceneView(new_sv.get());            // Configure the new viewer
00290    new_sv->getState()->setContextID(unique_context_id);
00291 
00292    // This will eventually be changed to no light and all lighting will be handled
00293    // by the application.  For the time being it fixes the lighting inconsistanies
00294    // over multiple screens
00295    new_sv->setLightingMode(osgUtil::SceneView::SKY_LIGHT);
00296 
00297    (*sceneViewer) = new_sv;
00298 
00299    //Setup OpenGL light
00300    //This should actualy be done in the simulator code
00301    GLfloat light0_ambient[] = { 0.1f,  0.1f,  0.1f,  1.0f};
00302    GLfloat light0_diffuse[] = { 0.8f,  0.8f,  0.8f,  1.0f};
00303    GLfloat light0_specular[] = { 1.0f,  1.0f,  1.0f,  1.0f};
00304    GLfloat light0_position[] = {0.0f, 0.75f, 0.75f, 0.0f};
00305 
00306    GLfloat mat_ambient[] = { 0.7f, 0.7f,  0.7f,  1.0f};
00307    GLfloat mat_diffuse[] = { 1.0f,  0.5f,  0.8f,  1.0f};
00308    GLfloat mat_specular[] = { 1.0f,  1.0f,  1.0f,  1.0f};
00309    GLfloat mat_shininess[] = { 50.0f};
00310    //GLfloat mat_emission[] = { 1.0f,  1.0f,  1.0f,  1.0f};
00311    GLfloat no_mat[] = { 0.0f,  0.0f,  0.0f,  1.0f};
00312 
00313    glLightfv(GL_LIGHT0, GL_AMBIENT,  light0_ambient);
00314    glLightfv(GL_LIGHT0, GL_DIFFUSE,  light0_diffuse);
00315    glLightfv(GL_LIGHT0, GL_SPECULAR,  light0_specular);
00316    glLightfv(GL_LIGHT0, GL_POSITION,  light0_position);
00317 
00318    glMaterialfv( GL_FRONT, GL_AMBIENT, mat_ambient );
00319    glMaterialfv( GL_FRONT,  GL_DIFFUSE, mat_diffuse );
00320    glMaterialfv( GL_FRONT, GL_SPECULAR, mat_specular );
00321    glMaterialfv( GL_FRONT,  GL_SHININESS, mat_shininess );
00322    glMaterialfv( GL_FRONT,  GL_EMISSION, no_mat);
00323 
00324    glEnable(GL_DEPTH_TEST);
00325    glEnable(GL_NORMALIZE);
00326    glEnable(GL_LIGHTING);
00327    glEnable(GL_LIGHT0);
00328    glEnable(GL_COLOR_MATERIAL);
00329    glShadeModel(GL_SMOOTH);
00330 }
00331 
00332 
00333 inline void OsgApp::draw()
00334 {
00335    glClear(GL_DEPTH_BUFFER_BIT);
00336 
00337    // Users have reported problems with OpenGL reporting stack underflow
00338    // problems when the texture attribute bit is pushed here, so we push all
00339    // attributes *except* GL_TEXTURE_BIT.
00340    glPushAttrib(GL_ALL_ATTRIB_BITS & ~GL_TEXTURE_BIT);
00341    glPushAttrib(GL_TRANSFORM_BIT);
00342    glPushAttrib(GL_VIEWPORT_BIT);
00343 
00344    glMatrixMode(GL_MODELVIEW);
00345    glPushMatrix();
00346 
00347    glMatrixMode(GL_PROJECTION);
00348    glPushMatrix();
00349 
00350    glMatrixMode(GL_TEXTURE);
00351    glPushMatrix();
00352 
00353 
00354    osg::ref_ptr<osgUtil::SceneView> sv;
00355    sv = (*sceneViewer);    // Get context specific scene viewer
00356    vprASSERT(sv.get() != NULL);
00357 
00358    // Set the timing information in the scene view.
00359    sv->setFrameStamp(mFrameStamp.get());
00360 
00361    GlDrawManager*    gl_manager;    
00362    gl_manager = GlDrawManager::instance();
00363 
00364    // Set the up the viewport (since OSG clears it out)
00365    float vp_ox, vp_oy, vp_sx, vp_sy;   // The float vrj sizes of the view ports
00366    int w_ox, w_oy, w_width, w_height;  // Origin and size of the window
00367    gl_manager->currentUserData()->getViewport()->getOriginAndSize(vp_ox, vp_oy, vp_sx, vp_sy);
00368    gl_manager->currentUserData()->getGlWindow()->getOriginSize(w_ox, w_oy, w_width, w_height);
00369 
00370    // compute unsigned versions of the viewport info (for passing to glViewport)
00371    unsigned ll_x = unsigned(vp_ox*float(w_width));
00372    unsigned ll_y = unsigned(vp_oy*float(w_height));
00373    unsigned x_size = unsigned(vp_sx*float(w_width));
00374    unsigned y_size = unsigned(vp_sy*float(w_height));
00375 
00376    // Add the tree to the scene viewer and set properties
00377    sv->setSceneData(getScene());
00378    //sv->setCalcNearFar(false);
00379    sv->setComputeNearFarMode(osgUtil::CullVisitor::DO_NOT_COMPUTE_NEAR_FAR);
00380    sv->setViewport(ll_x, ll_y, x_size, y_size);
00381 
00382    //Get the view matrix and the frustrum form the draw manager
00383    GlDrawManager* drawMan = dynamic_cast<GlDrawManager*>(this->getDrawManager());
00384    vprASSERT(drawMan != NULL);
00385    GlUserData* userData = drawMan->currentUserData();
00386 
00387    //Get the frustrum
00388    Projection* project = userData->getProjection();
00389    Frustum frustum = project->getFrustum();
00390    sv->setProjectionMatrixAsFrustum(frustum[Frustum::VJ_LEFT],
00391                                     frustum[Frustum::VJ_RIGHT],
00392                                     frustum[Frustum::VJ_BOTTOM],
00393                                     frustum[Frustum::VJ_TOP],
00394                                     frustum[Frustum::VJ_NEAR],
00395                                     frustum[Frustum::VJ_FAR]);
00396 
00397    // Copy the view matrix
00398    sv->setViewMatrix(osg::Matrix(project->getViewMatrix().mData));
00399 
00400    //Draw the scene
00401    // NOTE: It is not safe to call osgUtil::SceneView::update() here; it
00402    // should only be called by a single thread. The equivalent of calling
00403    // osgUtil::SceneView::update() is in vrj::OsgApp::update().
00404    sv->cull();
00405    sv->draw();
00406 
00407    glMatrixMode(GL_TEXTURE);
00408    glPopMatrix();
00409 
00410    glMatrixMode(GL_PROJECTION);
00411    glPopMatrix();
00412 
00413    glMatrixMode(GL_MODELVIEW);
00414    glPopMatrix();
00415 
00416    glPopAttrib();
00417    glPopAttrib();
00418    glPopAttrib();
00419 }
00420 
00421 }
00422 
00423 
00424 #endif /* _VRJ_OSG_APP_H_ */

Generated on Thu Jan 4 10:56:51 2007 for VR Juggler by  doxygen 1.5.1