]> git.mxchange.org Git - flightgear.git/blobdiff - src/Instrumentation/od_gauge.cxx
Make voiceplayer independent
[flightgear.git] / src / Instrumentation / od_gauge.cxx
index dabf87c3700a4909b21713ae0bcc456dfe7461a1..707030ef6f7e0f6bb955cf5eaeda2ae40cae2b54 100644 (file)
@@ -2,7 +2,9 @@
 //
 // Written by Harald JOHNSEN, started May 2005.
 //
-// Copyright (C) 2005  Harald JOHNSEN - hjohnsen@evc.net
+// Copyright (C) 2005  Harald JOHNSEN
+//
+// Ported to OSG by Tim Moore - Jun 2007
 //
 // This program is free software; you can redistribute it and/or
 // modify it under the terms of the GNU General Public License as
 //
 // You should have received a copy of the GNU General Public License
 // along with this program; if not, write to the Free Software
-// Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 //
 //
 
-#include <plib/ssg.h>
-#include <simgear/screen/extensions.hxx>
-#include <simgear/screen/RenderTexture.h>
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include <osg/AlphaFunc>
+#include <osg/BlendFunc>
+#include <osg/Camera>
+#include <osg/Geode>
+#include <osg/NodeVisitor>
+#include <osg/Matrix>
+#include <osg/PolygonMode>
+#include <osg/ShadeModel>
+#include <osg/StateSet>
+#include <osgDB/FileNameUtils>
+
+#include <simgear/scene/util/RenderConstants.hxx>
 #include <simgear/debug/logstream.hxx>
-#include SG_GLU_H
 
 #include <Main/globals.hxx>
+#include <Main/renderer.hxx>
 #include <Scenery/scenery.hxx>
 #include "od_gauge.hxx"
 
 FGODGauge::FGODGauge() :
-    rtAvailable( false ),
-    rt( 0 )
+    rtAvailable( false )// ,
+//     rt( 0 )
 {
 }
 
-// done here and not in init() so we don't allocate a rendering context if it is
-// never used
 void FGODGauge::allocRT () {
-    GLint colorBits = 0;
-    glGetIntegerv( GL_BLUE_BITS, &colorBits );
-    textureWH = 256;
-    rt = new RenderTexture();
-    if( colorBits < 8 )
-        rt->Reset("rgba=5,5,5,1 ctt");
-    else
-        rt->Reset("rgba ctt");
-
-    if( rt->Initialize(256, 256, true) ) {
-        SG_LOG(SG_ALL, SG_INFO, "FGODGauge:Initialize sucessfull");
-        if (rt->BeginCapture())
-        {
-            SG_LOG(SG_ALL, SG_INFO, "FGODGauge:BeginCapture sucessfull, RTT available");
-            rtAvailable = true;
-            glViewport(0, 0, textureWH, textureWH);
-            glMatrixMode(GL_PROJECTION);
-            glLoadIdentity();
-            gluOrtho2D( -256.0, 256.0, -256.0, 256.0 );
-            glMatrixMode(GL_MODELVIEW);
-            glLoadIdentity();
-            glDisable(GL_LIGHTING);
-            glEnable(GL_COLOR_MATERIAL);
-            glDisable(GL_CULL_FACE);
-            glDisable(GL_FOG);
-            glDisable(GL_DEPTH_TEST);
-            glClearColor(0.0, 0.0, 0.0, 0.0);
-            glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-            glBindTexture(GL_TEXTURE_2D, 0);
-            glEnable(GL_TEXTURE_2D);
-            glEnable(GL_ALPHA_TEST);
-            glAlphaFunc(GL_GREATER, 0.0f);
-            glDisable(GL_SMOOTH);
-            glEnable(GL_BLEND);
-            glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA );
-            rt->EndCapture();
-        } else
-            SG_LOG(SG_ALL, SG_WARN, "FGODGauge:BeginCapture failed, RTT not available, using backbuffer");
-    } else
-        SG_LOG(SG_ALL, SG_WARN, "FGODGauge:Initialize failed, RTT not available, using backbuffer");
+    camera = new osg::Camera;
+    // Only the far camera should trigger this texture to be rendered.
+    camera->setNodeMask(simgear::BACKGROUND_BIT);
+    camera->setProjectionMatrix(osg::Matrix::ortho2D(-textureWH/2.0, textureWH/2.0, -textureWH/2.0, textureWH/2.0));
+    camera->setViewport(0, 0, textureWH, textureWH);
+    camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
+    camera->setRenderOrder(osg::Camera::PRE_RENDER);
+    camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+    camera->setClearColor(osg::Vec4(0.0f, 0.0f, 0.0f , 0.0f));
+    camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT, osg::Camera::FRAME_BUFFER);
+    osg::StateSet* stateSet = camera->getOrCreateStateSet();
+    stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
+    stateSet->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);
+    stateSet->setMode(GL_FOG, osg::StateAttribute::OFF);
+    stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
+    stateSet->setAttributeAndModes(new osg::PolygonMode(osg::PolygonMode::FRONT_AND_BACK,
+            osg::PolygonMode::FILL),
+            osg::StateAttribute::ON);
+    stateSet->setAttributeAndModes(new osg::AlphaFunc(osg::AlphaFunc::GREATER,
+            0.0f),
+            osg::StateAttribute::ON);
+    stateSet->setAttribute(new osg::ShadeModel(osg::ShadeModel::FLAT));
+    stateSet->setAttributeAndModes(new osg::BlendFunc(osg::BlendFunc::SRC_ALPHA,
+            osg::BlendFunc::ONE_MINUS_SRC_ALPHA),
+            osg::StateAttribute::ON);
+    if (!texture.valid()) {
+        texture = new osg::Texture2D;
+        texture->setTextureSize(textureWH, textureWH);
+        texture->setInternalFormat(GL_RGBA);
+        texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
+        texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
+    }
+    camera->attach(osg::Camera::COLOR_BUFFER, texture.get());
+    globals->get_renderer()->addCamera(camera.get(), false);
+    rtAvailable = true;
+
+    // GLint colorBits = 0;
+//     glGetIntegerv( GL_BLUE_BITS, &colorBits );
+//     rt = new RenderTexture();
+//     if( colorBits < 8 )
+//         rt->Reset("rgba=5,5,5,1 ctt");
+//     else
+//         rt->Reset("rgba ctt");
+
+//     if( rt->Initialize(256, 256, true) ) {
+//         SG_LOG(SG_ALL, SG_INFO, "FGODGauge:Initialize sucessfull");
+//         if (rt->BeginCapture())
+//         {
+//             SG_LOG(SG_ALL, SG_INFO, "FGODGauge:BeginCapture sucessfull, RTT available");
+//             rtAvailable = true;
+//             glViewport(0, 0, textureWH, textureWH);
+//             glMatrixMode(GL_PROJECTION);
+//             glLoadIdentity();
+//             gluOrtho2D( -256.0, 256.0, -256.0, 256.0 );
+//             glMatrixMode(GL_MODELVIEW);
+//             glLoadIdentity();
+//             glDisable(GL_LIGHTING);
+//             glEnable(GL_COLOR_MATERIAL);
+//             glDisable(GL_CULL_FACE);
+//             glDisable(GL_FOG);
+//             glDisable(GL_DEPTH_TEST);
+//             glClearColor(0.0, 0.0, 0.0, 0.0);
+//             glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+//             glBindTexture(GL_TEXTURE_2D, 0);
+//             glEnable(GL_TEXTURE_2D);
+//             glEnable(GL_ALPHA_TEST);
+//             glAlphaFunc(GL_GREATER, 0.0f);
+//             glDisable(GL_SMOOTH);
+//             glEnable(GL_BLEND);
+//             glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA );
+//             rt->EndCapture();
+//         } else
+//             SG_LOG(SG_ALL, SG_WARN, "FGODGauge:BeginCapture failed, RTT not available, using backbuffer");
+//     } else
+//         SG_LOG(SG_ALL, SG_WARN, "FGODGauge:Initialize failed, RTT not available, using backbuffer");
 }
 
 FGODGauge::~FGODGauge() {
-    delete rt;
+//     delete rt;
 }
 
 void FGODGauge::init () {
@@ -91,55 +139,10 @@ void FGODGauge::init () {
 void FGODGauge::update (double dt) {
 }
 
-void FGODGauge::beginCapture(int viewSize) {
-    if( ! rt )
-        allocRT();
-    if(rtAvailable) {
-        rt->BeginCapture();
-    }
-    else
-        set2D();
-     textureWH = viewSize;
-    glViewport(0, 0, textureWH, textureWH);
-}
-
-void FGODGauge::beginCapture(void) {
-    if( ! rt )
-        allocRT();
-    if(rtAvailable) {
-        rt->BeginCapture();
-    }
-    else
-        set2D();
-}
-
-void FGODGauge::Clear(void) {
-    if(rtAvailable) {
-        glClear(GL_COLOR_BUFFER_BIT);
-    }
-    else {
-        glDisable(GL_BLEND);
-        glDisable(GL_ALPHA_TEST);
-          glColor4f(0.0f, 0.0f, 0.0f, 0.0f);
-        glRectf(-256.0, -256.0, 256.0, 256.0);
-        glEnable(GL_BLEND);
-        glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA );
-        glEnable(GL_ALPHA_TEST);
-    }
-}
-
-void FGODGauge::endCapture(GLuint texID) {
-    glBindTexture(GL_TEXTURE_2D, texID);
-    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, textureWH, textureWH);
-    if(rtAvailable)
-        rt->EndCapture();
-    else
-        set3D();
-}
 
 void FGODGauge::setSize(int viewSize) {
     textureWH = viewSize;
-    glViewport(0, 0, textureWH, textureWH);
+//     glViewport(0, 0, textureWH, textureWH);
 }
 
 bool FGODGauge::serviceable(void) {
@@ -147,68 +150,60 @@ bool FGODGauge::serviceable(void) {
 }
 
 /**
- * Locate a texture SSG node in a branch.
+ * Replace a texture in the airplane model with the gauge texture.
  */
-static ssgTexture *
-find_texture_node (ssgEntity * node, const char * name)
+
+class ReplaceStaticTextureVisitor : public osg::NodeVisitor
 {
-  if( node->isA( ssgTypeTexture() ) ) {
-    ssgTexture *tex = (ssgTexture *) node;
-    char * texture_name = tex->getFilename();
-    if (texture_name != 0 && !strcmp(name, texture_name))
-      return tex;
-  }
-  else if (node->isAKindOf(ssgTypeBranch())) {
-    int nKids = node->getNumKids();
-    for (int i = 0; i < nKids; i++) {
-      ssgTexture * result =
-        find_texture_node(((ssgBranch*)node)->getKid(i), name);
-      if (result != 0)
-        return result;
+public:
+    ReplaceStaticTextureVisitor(const std::string& name,
+        osg::Texture2D* _newTexture) :
+        osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
+        newTexture(_newTexture)
+    {
+        textureFileName = osgDB::getSimpleFileName(name);
     }
-  } 
-  return 0;
-}
-
-void FGODGauge::set_texture(const char * name, GLuint new_texture) {
-    ssgEntity * root = globals->get_scenery()->get_aircraft_branch();
-    ssgTexture * node = find_texture_node( root, name );
-    if( node )
-        node->setHandle( new_texture );
-}
 
-void FGODGauge::set2D() {
-    glPushAttrib ( GL_ENABLE_BIT | GL_VIEWPORT_BIT  | GL_TRANSFORM_BIT | GL_LIGHTING_BIT ) ;
-
-    glDisable(GL_LIGHTING);
-    glEnable(GL_COLOR_MATERIAL);
-    glDisable(GL_CULL_FACE);
-    glDisable(GL_FOG);
-    glDisable(GL_DEPTH_TEST);
-    glClearColor(0.0, 0.0, 0.0, 0.0);
-    glEnable(GL_TEXTURE_2D);
-    glDisable(GL_SMOOTH);
-    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-    glBindTexture(GL_TEXTURE_2D, 0);
-
-    glViewport ( 0, 0, textureWH, textureWH ) ;
-    glMatrixMode   ( GL_PROJECTION ) ;
-    glPushMatrix   () ;
-    glLoadIdentity () ;
-    gluOrtho2D( -256.0, 256.0, -256.0, 256.0 );
-    glMatrixMode   ( GL_MODELVIEW ) ;
-    glPushMatrix   () ;
-    glLoadIdentity () ;
-
-    glAlphaFunc(GL_GREATER, 0.0f);
+    virtual void apply(osg::Node& node)
+    {
+        osg::StateSet* ss = node.getStateSet();
+        if (ss)
+            changeStateSetTexture(ss);
+        traverse(node);
+    }
 
+    virtual void apply(osg::Geode& node)
+    {
+        int numDrawables = node.getNumDrawables();
+        for (int i = 0; i < numDrawables; i++) {
+            osg::Drawable* drawable = node.getDrawable(i);
+            osg::StateSet* ss = drawable->getStateSet();
+            if (ss)
+                changeStateSetTexture(ss);
+        }
+        traverse(node);
 }
+protected:
+    void changeStateSetTexture(osg::StateSet *ss)
+    {
+        osg::Texture2D* tex
+                = dynamic_cast<osg::Texture2D*>(ss->getTextureAttribute(0,
+                osg::StateAttribute::TEXTURE));
+        if (!tex || tex == newTexture || !tex->getImage())
+            return;
+        std::string fileName = tex->getImage()->getFileName();
+        std::string simpleName = osgDB::getSimpleFileName(fileName);
+        if (osgDB::equalCaseInsensitive(textureFileName, simpleName))
+            ss->setTextureAttribute(0, newTexture);
+    }
+    std::string textureFileName;
+    osg::Texture2D* newTexture;
+};
 
-void FGODGauge::set3D() {
-    glMatrixMode   ( GL_PROJECTION ) ;
-    glPopMatrix    () ;
-    glMatrixMode   ( GL_MODELVIEW ) ;
-    glPopMatrix    () ;
-    glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
-    glPopAttrib    () ;
+void FGODGauge::set_texture(const char * name, osg::Texture2D* new_texture)
+{
+    osg::Group* root = globals->get_scenery()->get_aircraft_branch();
+    ReplaceStaticTextureVisitor visitor(name, new_texture);
+    root->accept(visitor);
 }
+