]> git.mxchange.org Git - flightgear.git/blob - src/Instrumentation/od_gauge.cxx
Tweak ODGauge usage, fix multiple instances of NavDisplay or wxRadar.
[flightgear.git] / src / Instrumentation / od_gauge.cxx
1 // Owner Drawn Gauge helper class
2 //
3 // Written by Harald JOHNSEN, started May 2005.
4 //
5 // Copyright (C) 2005  Harald JOHNSEN
6 //
7 // Ported to OSG by Tim Moore - Jun 2007
8 //
9 // This program is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU General Public License as
11 // published by the Free Software Foundation; either version 2 of the
12 // License, or (at your option) any later version.
13 //
14 // This program is distributed in the hope that it will be useful, but
15 // WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 // General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with this program; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
22 //
23 //
24
25 #ifdef HAVE_CONFIG_H
26 #  include "config.h"
27 #endif
28
29 #include <osg/Texture2D>
30 #include <osg/AlphaFunc>
31 #include <osg/BlendFunc>
32 #include <osg/Camera>
33 #include <osg/Geode>
34 #include <osg/NodeVisitor>
35 #include <osg/Matrix>
36 #include <osg/PolygonMode>
37 #include <osg/ShadeModel>
38 #include <osg/StateSet>
39 #include <osgDB/FileNameUtils>
40
41 #include <simgear/scene/util/RenderConstants.hxx>
42 #include <simgear/debug/logstream.hxx>
43
44 #include <Main/globals.hxx>
45 #include <Main/renderer.hxx>
46 #include <Scenery/scenery.hxx>
47 #include "od_gauge.hxx"
48
49 FGODGauge::FGODGauge() :
50   rtAvailable( false )
51 {
52 }
53
54 void FGODGauge::allocRT ()
55 {
56     camera = new osg::Camera;
57     // Only the far camera should trigger this texture to be rendered.
58     camera->setNodeMask(simgear::BACKGROUND_BIT);
59     camera->setProjectionMatrix(osg::Matrix::ortho2D(-textureWH/2.0, textureWH/2.0, -textureWH/2.0, textureWH/2.0));
60     camera->setViewport(0, 0, textureWH, textureWH);
61     camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
62     camera->setRenderOrder(osg::Camera::PRE_RENDER);
63     camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
64     camera->setClearColor(osg::Vec4(0.0f, 0.0f, 0.0f , 0.0f));
65     camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT, osg::Camera::FRAME_BUFFER);
66     osg::StateSet* stateSet = camera->getOrCreateStateSet();
67     stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
68     stateSet->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);
69     stateSet->setMode(GL_FOG, osg::StateAttribute::OFF);
70     stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
71     stateSet->setAttributeAndModes(new osg::PolygonMode(osg::PolygonMode::FRONT_AND_BACK,
72             osg::PolygonMode::FILL),
73             osg::StateAttribute::ON);
74     stateSet->setAttributeAndModes(new osg::AlphaFunc(osg::AlphaFunc::GREATER,
75             0.0f),
76             osg::StateAttribute::ON);
77     stateSet->setAttribute(new osg::ShadeModel(osg::ShadeModel::FLAT));
78     stateSet->setAttributeAndModes(new osg::BlendFunc(osg::BlendFunc::SRC_ALPHA,
79             osg::BlendFunc::ONE_MINUS_SRC_ALPHA),
80             osg::StateAttribute::ON);
81     if (!texture.valid()) {
82         texture = new osg::Texture2D;
83         texture->setTextureSize(textureWH, textureWH);
84         texture->setInternalFormat(GL_RGBA);
85         texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
86         texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
87     }
88     camera->attach(osg::Camera::COLOR_BUFFER, texture.get());
89     globals->get_renderer()->addCamera(camera.get(), false);
90     rtAvailable = true;
91 }
92
93 FGODGauge::~FGODGauge()
94 {
95     if (camera.valid()) {
96         globals->get_renderer()->removeCamera(camera.get());
97     }
98 }
99
100 void FGODGauge::setSize(int viewSize)
101 {
102     textureWH = viewSize;
103     if (texture.valid()) {
104         texture->setTextureSize(textureWH, textureWH);
105     }
106 }
107
108 bool FGODGauge::serviceable(void) 
109 {
110     return rtAvailable;
111 }
112
113 /**
114  * Replace a texture in the airplane model with the gauge texture.
115  */
116
117 class ReplaceStaticTextureVisitor : public osg::NodeVisitor
118 {
119 public:
120     ReplaceStaticTextureVisitor(const std::string& name,
121         osg::Texture2D* _newTexture) :
122         osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
123         newTexture(_newTexture)
124     {
125         textureFileName = osgDB::getSimpleFileName(name);
126     }
127
128     virtual void apply(osg::Node& node)
129     {
130         osg::StateSet* ss = node.getStateSet();
131         if (ss)
132             changeStateSetTexture(ss);
133         traverse(node);
134     }
135
136     virtual void apply(osg::Geode& node)
137     {
138         int numDrawables = node.getNumDrawables();
139         for (int i = 0; i < numDrawables; i++) {
140             osg::Drawable* drawable = node.getDrawable(i);
141             osg::StateSet* ss = drawable->getStateSet();
142             if (ss)
143                 changeStateSetTexture(ss);
144         }
145         traverse(node);
146 }
147 protected:
148     void changeStateSetTexture(osg::StateSet *ss)
149     {
150         osg::Texture2D* tex
151                 = dynamic_cast<osg::Texture2D*>(ss->getTextureAttribute(0,
152                 osg::StateAttribute::TEXTURE));
153         if (!tex || tex == newTexture || !tex->getImage())
154             return;
155         std::string fileName = tex->getImage()->getFileName();
156         std::string simpleName = osgDB::getSimpleFileName(fileName);
157         if (osgDB::equalCaseInsensitive(textureFileName, simpleName))
158             ss->setTextureAttribute(0, newTexture);
159     }
160     std::string textureFileName;
161     osg::Texture2D* newTexture;
162 };
163
164 void FGODGauge::set_texture(const char * name, osg::Texture2D* new_texture)
165 {
166     osg::Group* root = globals->get_scenery()->get_aircraft_branch();
167     ReplaceStaticTextureVisitor visitor(name, new_texture);
168     root->accept(visitor);
169 }
170