1 /* -*-c++-*- */
2 /* osgEarth - Geospatial SDK for OpenSceneGraph
3  * Copyright 2008-2014 Pelican Mapping
4  * http://osgearth.org
5  *
6  * osgEarth is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>
18  */
19 #include "TerrainRenderData"
20 #include "TileNode"
21 #include "SurfaceNode"
22 #include <osgEarth/ClampableNode>
23 
24 using namespace osgEarth::Drivers::RexTerrainEngine;
25 
26 #undef  LC
27 #define LC "[TerrainRenderData] "
28 
29 
30 unsigned
sortDrawCommands()31 TerrainRenderData::sortDrawCommands()
32 {
33     unsigned total = 0;
34     for (LayerDrawableList::iterator i = _layerList.begin(); i != _layerList.end(); ++i)
35     {
36         //TODO: review and benchmark list vs. vector vs. unsorted here.
37         DrawTileCommands& cmds = i->get()->_tiles;
38         std::sort(cmds.begin(), cmds.end());
39         total += i->get()->_tiles.size();
40     }
41     return total;
42 }
43 
44 void
setup(const Map * map,const RenderBindings & bindings,unsigned frameNum,osgUtil::CullVisitor * cv)45 TerrainRenderData::setup(const Map* map,
46                          const RenderBindings& bindings,
47                          unsigned frameNum,
48                          osgUtil::CullVisitor* cv)
49 {
50     _bindings = &bindings;
51 
52     // Create a new State object to track sampler and uniform settings
53     _drawState = new DrawState();
54     _drawState->_frame = frameNum;
55     _drawState->_bindings = &bindings;
56 
57     // Is this a depth camera? Because if it is, we don't need any color layers.
58     const osg::Camera* cam = cv->getCurrentCamera();
59     bool isDepthCamera = ClampableNode::isDepthCamera(cam);
60 
61     // Make a drawable for each rendering pass (i.e. each render-able map layer).
62     LayerVector layers;
63     map->getLayers(layers);
64 
65     for (LayerVector::const_iterator i = layers.begin(); i != layers.end(); ++i)
66     {
67         Layer* layer = i->get();
68         if (layer->getEnabled())
69         {
70             bool render =
71                 (layer->getRenderType() == Layer::RENDERTYPE_TERRAIN_SURFACE) || // && !isDepthCamera) ||
72                 (layer->getRenderType() == Layer::RENDERTYPE_TERRAIN_PATCH);
73 
74             if ( render )
75             {
76                 // If this is an image layer, check the enabled/visible states.
77                 VisibleLayer* visLayer = dynamic_cast<VisibleLayer*>(layer);
78                 if (visLayer)
79                 {
80                     render = visLayer->getVisible();
81                 }
82 
83                 if (render)
84                 {
85                     if (layer->getRenderType() == Layer::RENDERTYPE_TERRAIN_SURFACE)
86                     {
87                         LayerDrawable* ld = addLayerDrawable(layer);
88 
89                         // If the current camera is depth-only, leave this layer in the set
90                         // but mark it as no-draw. We keep it in the set so the culler doesn't
91                         // inadvertently think it's an orphaned layer.
92                         if (isDepthCamera)
93                         {
94                             ld->_draw = false;
95                         }
96                     }
97 
98                     else // if (layer->getRenderType() == Layer::RENDERTYPE_TERRAIN_PATCH)
99                     {
100                         PatchLayer* patchLayer = static_cast<PatchLayer*>(layer); // asumption!
101 
102                         if (patchLayer->getAcceptCallback() != 0L &&
103                             patchLayer->getAcceptCallback()->acceptLayer(*cv, cv->getCurrentCamera()))
104                         {
105                             patchLayers().push_back(dynamic_cast<PatchLayer*>(layer));
106                             addLayerDrawable(layer);
107                         }
108                     }
109                 }
110             }
111         }
112     }
113 
114     // Include a "blank" layer for missing data.
115     LayerDrawable* blank = addLayerDrawable(0L);
116 }
117 
118 namespace
119 {
120     struct DebugCallback : public osg::Drawable::DrawCallback
121     {
122         std::string _s;
DebugCallback__anon593306ce0111::DebugCallback123         DebugCallback(const std::string& s) : _s(s) { }
drawImplementation__anon593306ce0111::DebugCallback124         void drawImplementation(osg::RenderInfo& ri, const osg::Drawable* d) const {
125             OE_WARN << "  Drawing Layer: " << _s << std::endl;
126             d->drawImplementation(ri);
127         }
128 
129     };
130 }
131 
132 LayerDrawable*
addLayerDrawable(const Layer * layer)133 TerrainRenderData::addLayerDrawable(const Layer* layer)
134 {
135     LayerDrawable* drawable = new LayerDrawable();
136     drawable->_drawOrder = _layerList.size();
137     _layerList.push_back(drawable);
138 
139     drawable->_drawState = _drawState.get();
140 
141     if (layer)
142     {
143         _layerMap[layer->getUID()] = drawable;
144         drawable->_layer = layer;
145         drawable->_visibleLayer = dynamic_cast<const VisibleLayer*>(layer);
146         drawable->_imageLayer = dynamic_cast<const ImageLayer*>(layer);
147         drawable->setStateSet(layer->getStateSet());
148         drawable->_renderType = layer->getRenderType();
149     }
150     else
151     {
152         _layerMap[-1] = drawable;
153     }
154 
155     return drawable;
156 }
157