osgEarth 2.1.1

/home/cube/sources/osgearth/src/osgEarthSymbology/GeometryRasterizer.cpp

Go to the documentation of this file.
00001 /* -*-c++-*- */
00002 /* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
00003  * Copyright 2008-2010 Pelican Mapping
00004  * http://osgearth.org
00005  *
00006  * osgEarth is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU Lesser General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public License
00017  * along with this program.  If not, see <http://www.gnu.org/licenses/>
00018  */
00019 #include <osgEarthSymbology/GeometryRasterizer>
00020 #include <osgEarthSymbology/PointSymbol>
00021 #include <osgEarthSymbology/LineSymbol>
00022 #include <osgEarthSymbology/PolygonSymbol>
00023 #include <osgEarthSymbology/AGG.h>
00024 
00025 using namespace osgEarth::Symbology;
00026 
00027 #define LC "[GeometryRasterizer] "
00028 
00029 // --------------------------------------------------------------------------
00030 
00031 struct AggState : public osg::Referenced
00032 {
00033     AggState( osg::Image* image )
00034         : _rbuf( image->data(), image->s(), image->t(), image->s()*4 ),
00035           _ren( _rbuf )
00036     {
00037         _ras.gamma( 1.3 );
00038         _ras.filling_rule( agg::fill_even_odd );
00039 
00040         // pre-clear the buffer....
00041         _ren.clear(agg::rgba8(0,0,0,0));
00042     }
00043 
00044     agg::rendering_buffer           _rbuf;
00045     agg::renderer<agg::span_abgr32> _ren;
00046     agg::rasterizer                 _ras;
00047 };
00048 
00049 // --------------------------------------------------------------------------
00050 
00051 GeometryRasterizer::GeometryRasterizer( int width, int height, const Style& style ) :
00052 _style( style )
00053 {
00054     _image = new osg::Image();
00055     _image->allocateImage( width, height, 1, GL_RGBA, GL_UNSIGNED_BYTE );
00056     _image->setAllocationMode( osg::Image::USE_NEW_DELETE );
00057     _state = new AggState( _image.get() );
00058 }
00059 
00060 osg::Image*
00061 GeometryRasterizer::finalize()
00062 {
00063     //convert from ABGR to RGBA
00064     unsigned char* pixel = _image->data();
00065     for(int i=0; i<_image->s()*_image->t()*4; i+=4, pixel+=4)
00066     {
00067         std::swap( pixel[0], pixel[3] );
00068         std::swap( pixel[1], pixel[2] );
00069     }
00070     osg::Image* result = _image.release();
00071     _image = 0L;
00072     return result;
00073 }
00074 
00075 void
00076 GeometryRasterizer::draw( const Geometry* geom, const osg::Vec4f& c )
00077 {
00078     if ( !_image.valid() ) return;
00079 
00080     AggState* state = static_cast<AggState*>( _state.get() );
00081 
00082     osg::Vec4f color = c;
00083     osg::ref_ptr<const Geometry> geomToRender = geom;
00084 
00085     if ( geom->getType() == Geometry::TYPE_POLYGON )
00086     {
00087         const PolygonSymbol* ps = _style.getSymbol<const PolygonSymbol>();
00088         if ( ps )
00089             color = ps->fill()->color();
00090     }
00091     else
00092     {
00093         const LineSymbol* ls = _style.getSymbol<const LineSymbol>();
00094         float distance = ls ? ls->stroke()->width().value() * 0.5f : 1.0f;
00095         osg::ref_ptr<Geometry> bufferedGeom;
00096         if ( !geom->buffer( distance, bufferedGeom ) )
00097         {
00098             OE_WARN << LC << "Failed to draw line; buffer op not available" << std::endl;
00099             return;
00100         }
00101         geomToRender = bufferedGeom.get();
00102         if ( ls )
00103             color = ls->stroke()->color();
00104     }
00105 
00106     float a = 127+(color.a()*255)/2; // scale alpha up
00107     agg::rgba8 fgColor = agg::rgba8( (unsigned int)(color.r()*255), (unsigned int)(color.g()*255), (unsigned int)(color.b()*255), (unsigned int)a );
00108 
00109     ConstGeometryIterator gi( geomToRender.get() );
00110     while( gi.hasMore() )
00111     {
00112         const Vec3dVector& g = gi.next()->asVector();
00113 
00114         for( Vec3dVector::const_iterator p = g.begin(); p != g.end(); p++ )
00115         {
00116             const osg::Vec3d& p0 = *p;
00117 
00118             if ( p == g.begin() )
00119                 state->_ras.move_to_d( p0.x(), p0.y() );
00120             else
00121                 state->_ras.line_to_d( p0.x(), p0.y() );
00122         }
00123     }
00124     state->_ras.render( state->_ren, fgColor );
00125     state->_ras.reset();
00126 }
00127 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines