/* -*-c++-*- */ /* osgEarth - Geospatial SDK for OpenSceneGraph * Copyright 2008-2014 Pelican Mapping * http://osgearth.org * * osgEarth is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see */ #ifndef OSGEARTH_REX_TILE_RENDER_MODEL #define OSGEARTH_REX_TILE_RENDER_MODEL 1 #include "Common" #include "RenderBindings" #include #include // for AutoArray #include #include #include #include #include #include namespace osgEarth { namespace Drivers { namespace RexTerrainEngine { /** * A single texture and its matrix. This corresponds to a * single SamplerBinding (above). */ struct Sampler { osg::ref_ptr _texture; osg::Matrixf _matrix; }; typedef AutoArray Samplers; /** * Samplers (one per RenderBinding) specific to one rendering pass of a tile. * Typically this is just the color and color parent samplers. */ struct RenderingPass { public: RenderingPass() : _sourceUID(-1), _samplers(SamplerBinding::COLOR_PARENT+1), _visibleLayer(0L), _terrainLayer(0L) { } UID sourceUID() const { return _sourceUID; } Samplers& samplers() { return _samplers; } const Samplers& samplers() const { return _samplers; } const Layer* layer() const { return _layer.get(); } const VisibleLayer* visibleLayer() const { return _visibleLayer; } const TerrainLayer* terrainLayer() const { return _terrainLayer; } void releaseGLObjects(osg::State* state) const { for (unsigned s = 0; s<_samplers.size(); ++s) if (_samplers[s]._texture.valid() && _samplers[s]._matrix.isIdentity()) _samplers[s]._texture->releaseGLObjects(state); } void resizeGLObjectBuffers(unsigned size) { for (unsigned s = 0; s<_samplers.size(); ++s) if (_samplers[s]._texture.valid() && _samplers[s]._matrix.isIdentity()) _samplers[s]._texture->resizeGLObjectBuffers(size); } void setLayer(const Layer* layer) { _layer = layer; if (layer) { _visibleLayer = dynamic_cast(layer); _terrainLayer = dynamic_cast(layer); _sourceUID = layer->getUID(); } } private: /** UID of the layer responsible for this rendering pass (usually an ImageLayer) */ UID _sourceUID; /** Samplers specific to this rendering pass (COLOR, COLOR_PARENT) */ Samplers _samplers; /** Layer respsonible for this rendering pass */ osg::ref_ptr _layer; /** VisibleLayer responsible for this rendering pass (is _layer is a VisibleLayer) */ const VisibleLayer* _visibleLayer; /** VisibleLayer responsible for this rendering pass (is _layer is a TerrainLayer) */ const TerrainLayer* _terrainLayer; }; /** * Unordered collection of rendering passes. */ typedef std::vector RenderingPasses; /** * Everything necessary to render a single terrain tile. * REX renders the terrain in multiple passes, one pass for each visible layer. */ struct TileRenderModel { /** Samplers that are bound for every rendering pass (elevation, normal map, etc.) */ Samplers _sharedSamplers; /** Samplers bound for each visible layer (color) */ RenderingPasses _passes; /** Add a new rendering pass to the end of the list. */ RenderingPass& addPass() { _passes.resize(_passes.size()+1); return _passes.back(); } /** Look up a rendering pass by the corresponding layer ID */ const RenderingPass* getPass(UID uid) const { for (unsigned i = 0; i < _passes.size(); ++i) { if (_passes[i].sourceUID() == uid) return &_passes[i]; } return 0L; } /** Look up a rendering pass by the corresponding layer ID */ RenderingPass* getPass(UID uid) { for (unsigned i = 0; i < _passes.size(); ++i) { if (_passes[i].sourceUID() == uid) return &_passes[i]; } return 0L; } /** Deallocate GPU objects associated with this model */ void releaseGLObjects(osg::State* state) const { for (unsigned s = 0; s<_sharedSamplers.size(); ++s) if (_sharedSamplers[s]._texture.valid() && _sharedSamplers[s]._matrix.isIdentity()) _sharedSamplers[s]._texture->releaseGLObjects(state); for (unsigned p = 0; p<_passes.size(); ++p) _passes[p].releaseGLObjects(state); } /** Resize GL buffers associated with this model */ void resizeGLObjectBuffers(unsigned size) { for (unsigned s = 0; s<_sharedSamplers.size(); ++s) if (_sharedSamplers[s]._texture.valid() && _sharedSamplers[s]._matrix.isIdentity()) _sharedSamplers[s]._texture->resizeGLObjectBuffers(size); for (unsigned p = 0; p<_passes.size(); ++p) _passes[p].resizeGLObjectBuffers(size); } }; } } } // namespace osgEarth::Drivers::RexTerrainEngine #endif // OSGEARTH_REX_TILE_RENDER_MODEL