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 program is free software; you can redistribute it and/or
14 // modify it under the terms of the GNU General Public License as
15 // published by the Free Software Foundation; either version 2 of the
16 // License, or (at your option) any later version.
18 // This program is distributed in the hope that it will be useful, but
19 // WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 // General Public License for more details.
23 // You should have received a copy of the GNU General Public License
24 // along with this program; if not, write to the Free Software
25 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
30 # include <simgear_config.h>
33 #include <osg/Texture2D>
34 #include <osg/AlphaFunc>
35 #include <osg/BlendFunc>
38 #include <osg/PolygonMode>
39 #include <osg/ShadeModel>
40 #include <osg/StateSet>
41 #include <osg/FrameBufferObject> // for GL_DEPTH_STENCIL_EXT on Windows
43 #include <simgear/debug/logstream.hxx>
44 #include <simgear/scene/util/RenderConstants.hxx>
45 #include "ODGauge.hxx"
52 //------------------------------------------------------------------------------
53 ODGauge::ODGauge( const CameraRegistrationCallback& cb_camera_add,
54 const CameraRegistrationCallback& cb_camera_remove ):
59 _use_image_coords( false ),
60 _use_stencil( false ),
61 _use_mipmapping( false ),
62 _coverage_samples( 0 ),
65 _cb_cam_add( cb_camera_add ),
66 _cb_cam_remove( cb_camera_remove )
71 //------------------------------------------------------------------------------
75 _cb_cam_remove(camera.get());
78 //------------------------------------------------------------------------------
79 void ODGauge::setSize(int size_x, int size_y)
82 _size_y = size_y < 0 ? size_x : size_y;
85 texture->setTextureSize(_size_x, _size_x);
88 //----------------------------------------------------------------------------
89 void ODGauge::setViewSize(int width, int height)
92 _view_height = height < 0 ? width : height;
95 updateCoordinateFrame();
98 //------------------------------------------------------------------------------
99 void ODGauge::useImageCoords(bool use)
101 if( use == _use_image_coords )
104 _use_image_coords = use;
107 updateCoordinateFrame();
110 //------------------------------------------------------------------------------
111 void ODGauge::useStencil(bool use)
113 if( use == _use_stencil )
122 //------------------------------------------------------------------------------
123 void ODGauge::setSampling( bool mipmapping,
124 int coverage_samples,
127 if( _use_mipmapping == mipmapping
128 && _coverage_samples == coverage_samples
129 && _color_samples == color_samples )
132 _use_mipmapping = mipmapping;
134 if( color_samples > coverage_samples )
140 "ODGauge::setSampling: color_samples > coverage_samples not allowed!"
142 color_samples = coverage_samples;
145 _coverage_samples = coverage_samples;
146 _color_samples = color_samples;
151 //------------------------------------------------------------------------------
152 void ODGauge::setRender(bool render)
154 // Only the far camera should trigger this texture to be rendered.
155 camera->setNodeMask(render ? simgear::BACKGROUND_BIT : 0);
158 //------------------------------------------------------------------------------
159 bool ODGauge::serviceable(void)
164 //------------------------------------------------------------------------------
165 void ODGauge::allocRT(osg::NodeCallback* camera_cull_callback)
167 camera = new osg::Camera;
168 camera->setDataVariance(osg::Object::DYNAMIC);
169 camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
170 camera->setRenderOrder(osg::Camera::PRE_RENDER);
171 camera->setClearColor(osg::Vec4(0.0f, 0.0f, 0.0f , 0.0f));
172 camera->setClearStencil(0);
173 camera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT,
174 osg::Camera::FRAME_BUFFER );
176 if( camera_cull_callback )
177 camera->setCullCallback(camera_cull_callback);
180 updateCoordinateFrame();
183 osg::StateSet* stateSet = camera->getOrCreateStateSet();
184 stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
185 stateSet->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);
186 stateSet->setMode(GL_FOG, osg::StateAttribute::OFF);
187 stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
188 stateSet->setAttributeAndModes(new osg::PolygonMode(osg::PolygonMode::FRONT_AND_BACK,
189 osg::PolygonMode::FILL),
190 osg::StateAttribute::ON);
191 stateSet->setAttributeAndModes(new osg::AlphaFunc(osg::AlphaFunc::GREATER,
193 osg::StateAttribute::ON);
194 stateSet->setAttribute(new osg::ShadeModel(osg::ShadeModel::FLAT));
195 stateSet->setAttributeAndModes(new osg::BlendFunc(osg::BlendFunc::SRC_ALPHA,
196 osg::BlendFunc::ONE_MINUS_SRC_ALPHA),
197 osg::StateAttribute::ON);
200 texture = new osg::Texture2D;
201 texture->setTextureSize(_size_x, _size_y);
202 texture->setInternalFormat(GL_RGBA);
207 _cb_cam_add(camera.get());
211 //------------------------------------------------------------------------------
212 void ODGauge::updateCoordinateFrame()
216 if( _view_width < 0 )
217 _view_width = _size_x;
218 if( _view_height < 0 )
219 _view_height = _size_y;
221 camera->setViewport(0, 0, _size_x, _size_y);
223 if( _use_image_coords )
224 camera->setProjectionMatrix(
225 osg::Matrix::ortho2D(0, _view_width, _view_height, 0)
228 camera->setProjectionMatrix(
229 osg::Matrix::ortho2D( -_view_width/2., _view_width/2.,
230 -_view_height/2., _view_height/2. )
234 //------------------------------------------------------------------------------
235 void ODGauge::updateStencil()
239 GLbitfield mask = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
243 camera->attach( osg::Camera::PACKED_DEPTH_STENCIL_BUFFER,
244 GL_DEPTH_STENCIL_EXT );
245 mask |= GL_STENCIL_BUFFER_BIT;
249 camera->detach(osg::Camera::PACKED_DEPTH_STENCIL_BUFFER);
252 camera->setClearMask(mask);
255 //------------------------------------------------------------------------------
256 void ODGauge::updateSampling()
262 osg::Texture2D::MIN_FILTER,
263 _use_mipmapping ? osg::Texture2D::LINEAR_MIPMAP_LINEAR
264 : osg::Texture2D::LINEAR
267 osg::Camera::COLOR_BUFFER,
276 } // namespace simgear