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#ifndef OSGEARTH_REX_TILE_RENDER_MODEL 20#define OSGEARTH_REX_TILE_RENDER_MODEL 1 21 22#include "Common" 23#include "RenderBindings" 24#include <osgEarth/Common> 25#include <osgEarth/Containers> // for AutoArray 26#include <osgEarth/Layer> 27#include <osgEarth/ImageLayer> 28#include <osgEarth/PatchLayer> 29#include <osg/Texture> 30#include <osg/Matrix> 31#include <vector> 32 33namespace osgEarth { namespace Drivers { namespace RexTerrainEngine 34{ 35 /** 36 * A single texture and its matrix. This corresponds to a 37 * single SamplerBinding (above). 38 */ 39 struct Sampler 40 { 41 osg::ref_ptr<osg::Texture> _texture; 42 osg::Matrixf _matrix; 43 }; 44 typedef AutoArray<Sampler> Samplers; 45 46 /** 47 * Samplers (one per RenderBinding) specific to one rendering pass of a tile. 48 * Typically this is just the color and color parent samplers. 49 */ 50 struct RenderingPass 51 { 52 public: 53 RenderingPass() : 54 _sourceUID(-1), 55 _samplers(SamplerBinding::COLOR_PARENT+1), 56 _visibleLayer(0L), 57 _terrainLayer(0L) 58 { } 59 60 UID sourceUID() const { return _sourceUID; } 61 Samplers& samplers() { return _samplers; } 62 const Samplers& samplers() const { return _samplers; } 63 const Layer* layer() const { return _layer.get(); } 64 const VisibleLayer* visibleLayer() const { return _visibleLayer; } 65 const TerrainLayer* terrainLayer() const { return _terrainLayer; } 66 67 void releaseGLObjects(osg::State* state) const 68 { 69 for (unsigned s = 0; s<_samplers.size(); ++s) 70 if (_samplers[s]._texture.valid() && _samplers[s]._matrix.isIdentity()) 71 _samplers[s]._texture->releaseGLObjects(state); 72 } 73 74 void resizeGLObjectBuffers(unsigned size) 75 { 76 for (unsigned s = 0; s<_samplers.size(); ++s) 77 if (_samplers[s]._texture.valid() && _samplers[s]._matrix.isIdentity()) 78 _samplers[s]._texture->resizeGLObjectBuffers(size); 79 } 80 81 void setLayer(const Layer* layer) { 82 _layer = layer; 83 if (layer) { 84 _visibleLayer = dynamic_cast<const VisibleLayer*>(layer); 85 _terrainLayer = dynamic_cast<const TerrainLayer*>(layer); 86 _sourceUID = layer->getUID(); 87 } 88 } 89 90 private: 91 /** UID of the layer responsible for this rendering pass (usually an ImageLayer) */ 92 UID _sourceUID; 93 94 /** Samplers specific to this rendering pass (COLOR, COLOR_PARENT) */ 95 Samplers _samplers; 96 97 /** Layer respsonible for this rendering pass */ 98 osg::ref_ptr<const Layer> _layer; 99 100 /** VisibleLayer responsible for this rendering pass (is _layer is a VisibleLayer) */ 101 const VisibleLayer* _visibleLayer; 102 103 /** VisibleLayer responsible for this rendering pass (is _layer is a TerrainLayer) */ 104 const TerrainLayer* _terrainLayer; 105 106 107 }; 108 109 /** 110 * Unordered collection of rendering passes. 111 */ 112 typedef std::vector<RenderingPass> RenderingPasses; 113 114 /** 115 * Everything necessary to render a single terrain tile. 116 * REX renders the terrain in multiple passes, one pass for each visible layer. 117 */ 118 struct TileRenderModel 119 { 120 /** Samplers that are bound for every rendering pass (elevation, normal map, etc.) */ 121 Samplers _sharedSamplers; 122 123 /** Samplers bound for each visible layer (color) */ 124 RenderingPasses _passes; 125 126 /** Add a new rendering pass to the end of the list. */ 127 RenderingPass& addPass() 128 { 129 _passes.resize(_passes.size()+1); 130 return _passes.back(); 131 } 132 133 /** Look up a rendering pass by the corresponding layer ID */ 134 const RenderingPass* getPass(UID uid) const 135 { 136 for (unsigned i = 0; i < _passes.size(); ++i) { 137 if (_passes[i].sourceUID() == uid) 138 return &_passes[i]; 139 } 140 return 0L; 141 } 142 143 /** Look up a rendering pass by the corresponding layer ID */ 144 RenderingPass* getPass(UID uid) 145 { 146 for (unsigned i = 0; i < _passes.size(); ++i) { 147 if (_passes[i].sourceUID() == uid) 148 return &_passes[i]; 149 } 150 return 0L; 151 } 152 153 /** Deallocate GPU objects associated with this model */ 154 void releaseGLObjects(osg::State* state) const 155 { 156 for (unsigned s = 0; s<_sharedSamplers.size(); ++s) 157 if (_sharedSamplers[s]._texture.valid() && _sharedSamplers[s]._matrix.isIdentity()) 158 _sharedSamplers[s]._texture->releaseGLObjects(state); 159 160 for (unsigned p = 0; p<_passes.size(); ++p) 161 _passes[p].releaseGLObjects(state); 162 } 163 164 /** Resize GL buffers associated with this model */ 165 void resizeGLObjectBuffers(unsigned size) 166 { 167 for (unsigned s = 0; s<_sharedSamplers.size(); ++s) 168 if (_sharedSamplers[s]._texture.valid() && _sharedSamplers[s]._matrix.isIdentity()) 169 _sharedSamplers[s]._texture->resizeGLObjectBuffers(size); 170 171 for (unsigned p = 0; p<_passes.size(); ++p) 172 _passes[p].resizeGLObjectBuffers(size); 173 } 174 }; 175 176} } } // namespace osgEarth::Drivers::RexTerrainEngine 177 178#endif // OSGEARTH_REX_TILE_RENDER_MODEL 179