1 // Owner Drawn Gauge helper class
3 // Written by Harald JOHNSEN, started May 2005.
5 // Copyright (C) 2005 Harald JOHNSEN
7 // Ported to OSG by Tim Moore - Jun 2007
9 // Heavily modified to be usable for the 2d Canvas by Thomas Geymayer - April 2012
10 // Supports now multisampling/mipmapping, usage of the stencil buffer and placing
11 // the texture in the scene by certain filter criteria
13 // This library is free software; you can redistribute it and/or
14 // modify it under the terms of the GNU Library General Public
15 // License as published by the Free Software Foundation; either
16 // version 2 of the License, or (at your option) any later version.
18 // This library is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 // Library General Public License for more details.
23 // You should have received a copy of the GNU Library General Public
24 // License along with this library; if not, write to the Free Software
25 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
28 # include <simgear_config.h>
31 #include "ODGauge.hxx"
32 #include "CanvasSystemAdapter.hxx"
34 #include <simgear/debug/logstream.hxx>
35 #include <simgear/scene/util/RenderConstants.hxx>
37 #include <osg/Texture2D>
38 #include <osg/AlphaFunc>
39 #include <osg/BlendFunc>
42 #include <osg/PolygonMode>
43 #include <osg/ShadeModel>
44 #include <osg/StateSet>
45 #include <osg/FrameBufferObject> // for GL_DEPTH_STENCIL_EXT on Windows
54 //----------------------------------------------------------------------------
60 _use_image_coords( false ),
61 _use_stencil( false ),
62 _use_mipmapping( false ),
63 _coverage_samples( 0 ),
70 //----------------------------------------------------------------------------
76 //----------------------------------------------------------------------------
77 void ODGauge::setSystemAdapter(const SystemAdapterPtr& system_adapter)
79 _system_adapter = system_adapter;
82 //----------------------------------------------------------------------------
83 void ODGauge::setSize(int size_x, int size_y)
86 _size_y = size_y < 0 ? size_x : size_y;
91 texture->setTextureSize(_size_x, _size_y);
94 //----------------------------------------------------------------------------
95 void ODGauge::setViewSize(int width, int height)
98 _view_height = height < 0 ? width : height;
101 updateCoordinateFrame();
104 //----------------------------------------------------------------------------
105 void ODGauge::useImageCoords(bool use)
107 if( use == _use_image_coords )
110 _use_image_coords = use;
113 updateCoordinateFrame();
116 //----------------------------------------------------------------------------
117 void ODGauge::useStencil(bool use)
119 if( use == _use_stencil )
128 //----------------------------------------------------------------------------
129 void ODGauge::setSampling( bool mipmapping,
130 int coverage_samples,
133 if( _use_mipmapping == mipmapping
134 && _coverage_samples == coverage_samples
135 && _color_samples == color_samples )
138 _use_mipmapping = mipmapping;
140 if( color_samples > coverage_samples )
146 "ODGauge::setSampling: color_samples > coverage_samples not allowed!"
148 color_samples = coverage_samples;
151 _coverage_samples = coverage_samples;
152 _color_samples = color_samples;
157 //----------------------------------------------------------------------------
158 void ODGauge::setRender(bool render)
160 // Only the far camera should trigger this texture to be rendered.
161 camera->setNodeMask(render ? simgear::BACKGROUND_BIT : 0);
164 //----------------------------------------------------------------------------
165 bool ODGauge::serviceable(void)
170 //----------------------------------------------------------------------------
171 void ODGauge::allocRT(osg::NodeCallback* camera_cull_callback)
173 camera = new osg::Camera;
174 camera->setDataVariance(osg::Object::DYNAMIC);
175 camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
176 camera->setRenderOrder(osg::Camera::PRE_RENDER);
177 camera->setClearColor(osg::Vec4(0.0f, 0.0f, 0.0f , 0.0f));
178 camera->setClearStencil(0);
179 camera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT,
180 osg::Camera::FRAME_BUFFER );
182 if( camera_cull_callback )
183 camera->setCullCallback(camera_cull_callback);
186 updateCoordinateFrame();
189 osg::StateSet* stateSet = camera->getOrCreateStateSet();
190 stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
191 stateSet->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);
192 stateSet->setMode(GL_FOG, osg::StateAttribute::OFF);
193 stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
194 stateSet->setAttributeAndModes(
195 new osg::PolygonMode( osg::PolygonMode::FRONT_AND_BACK,
196 osg::PolygonMode::FILL ),
197 osg::StateAttribute::ON );
198 stateSet->setAttributeAndModes(
199 new osg::AlphaFunc(osg::AlphaFunc::GREATER, 0.0f),
200 osg::StateAttribute::ON );
201 stateSet->setAttribute(new osg::ShadeModel(osg::ShadeModel::FLAT));
202 stateSet->setAttributeAndModes(
203 new osg::BlendFunc( osg::BlendFunc::SRC_ALPHA,
204 osg::BlendFunc::ONE_MINUS_SRC_ALPHA),
205 osg::StateAttribute::ON );
208 texture = new osg::Texture2D;
209 texture->setTextureSize(_size_x, _size_y);
210 texture->setInternalFormat(GL_RGBA);
215 if( _system_adapter )
216 _system_adapter->addCamera(camera.get());
221 //----------------------------------------------------------------------------
222 void ODGauge::reinit()
224 osg::NodeCallback* cull_callback = camera ? camera->getCullCallback() : 0;
226 allocRT(cull_callback);
229 //----------------------------------------------------------------------------
230 void ODGauge::clear()
232 if( camera.valid() && _system_adapter )
233 _system_adapter->removeCamera(camera.get());
240 //----------------------------------------------------------------------------
241 void ODGauge::updateCoordinateFrame()
245 if( _view_width < 0 )
246 _view_width = _size_x;
247 if( _view_height < 0 )
248 _view_height = _size_y;
250 camera->setViewport(0, 0, _size_x, _size_y);
252 if( _use_image_coords )
253 camera->setProjectionMatrix(
254 osg::Matrix::ortho2D(0, _view_width, _view_height, 0)
257 camera->setProjectionMatrix(
258 osg::Matrix::ortho2D( -_view_width/2., _view_width/2.,
259 -_view_height/2., _view_height/2. )
263 //----------------------------------------------------------------------------
264 void ODGauge::updateStencil()
268 GLbitfield mask = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
272 camera->attach( osg::Camera::PACKED_DEPTH_STENCIL_BUFFER,
273 GL_DEPTH_STENCIL_EXT );
274 mask |= GL_STENCIL_BUFFER_BIT;
278 camera->detach(osg::Camera::PACKED_DEPTH_STENCIL_BUFFER);
281 camera->setClearMask(mask);
284 //----------------------------------------------------------------------------
285 void ODGauge::updateSampling()
291 osg::Texture2D::MIN_FILTER,
292 _use_mipmapping ? osg::Texture2D::LINEAR_MIPMAP_LINEAR
293 : osg::Texture2D::LINEAR
296 osg::Camera::COLOR_BUFFER,
305 } // namespace canvas
306 } // namespace simgear