/***************************************************************************************** * * * OpenSpace * * * * Copyright (c) 2014-2021 * * * * Permission is hereby granted, free of charge, to any person obtaining a copy of this * * software and associated documentation files (the "Software"), to deal in the Software * * without restriction, including without limitation the rights to use, copy, modify, * * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * * permit persons to whom the Software is furnished to do so, subject to the following * * conditions: * * * * The above copyright notice and this permission notice shall be included in all copies * * or substantial portions of the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ #include #include #include #include #include #include namespace openspace::globebrowsing { void GPULayerGroup::setValue(ghoul::opengl::ProgramObject& program, const LayerGroup& layerGroup, const TileIndex& tileIndex) { ZoneScoped ghoul_assert( layerGroup.activeLayers().size() == _gpuActiveLayers.size(), "GPU and CPU active layers must have same size!" ); const std::vector& activeLayers = layerGroup.activeLayers(); for (unsigned int i = 0; i < activeLayers.size(); ++i) { const GPULayer& gal = _gpuActiveLayers[i]; auto& galuc = gal.uniformCache; const Layer& al = *activeLayers[i]; program.setUniform(galuc.opacity, al.renderSettings().opacity); program.setUniform(galuc.gamma, al.renderSettings().gamma); program.setUniform(galuc.multiplier, al.renderSettings().multiplier); program.setUniform(galuc.offset, al.renderSettings().offset); if (al.layerAdjustment().type() == layergroupid::AdjustmentTypeID::ChromaKey) { program.setUniform( galuc.chromaKeyColor, al.layerAdjustment().chromaKeyColor() ); program.setUniform( galuc.chromaKeyTolerance, al.layerAdjustment().chromaKeyTolerance() ); } switch (al.type()) { // Intentional fall through. Same for all tile layers case layergroupid::TypeID::DefaultTileLayer: case layergroupid::TypeID::SingleImageTileLayer: case layergroupid::TypeID::SizeReferenceTileLayer: case layergroupid::TypeID::TemporalTileLayer: case layergroupid::TypeID::TileIndexTileLayer: case layergroupid::TypeID::ByIndexTileLayer: case layergroupid::TypeID::ByLevelTileLayer: { const ChunkTilePile& ctp = al.chunkTilePile( tileIndex, layerGroup.pileSize() ); for (size_t j = 0; j < _gpuActiveLayers[i].gpuChunkTiles.size(); ++j) { GPULayer::GPUChunkTile& t = _gpuActiveLayers[i].gpuChunkTiles[j]; ghoul_assert(ctp[j].has_value(), "Wrong ChunkTiles number in pile"); const ChunkTile& ct = *ctp[j]; t.texUnit.activate(); if (ct.tile.texture) { ct.tile.texture->bind(); } program.setUniform(t.uniformCache.texture, t.texUnit); program.setUniform(t.uniformCache.uvOffset, ct.uvTransform.uvOffset); program.setUniform(t.uniformCache.uvScale, ct.uvTransform.uvScale); } program.setUniform(galuc.paddingStartOffset, al.tilePixelStartOffset()); program.setUniform( galuc.paddingSizeDifference, al.tilePixelSizeDifference() ); break; } case layergroupid::TypeID::SolidColor: program.setUniform(galuc.color, al.solidColor()); break; default: break; } if (gal.isHeightLayer) { program.setUniform(galuc.depthOffset, al.depthTransform().offset); program.setUniform(galuc.depthScale, al.depthTransform().scale); } } } void GPULayerGroup::bind(ghoul::opengl::ProgramObject& p, const LayerGroup& layerGroup, const std::string& nameBase, int category) { const std::vector& activeLayers = layerGroup.activeLayers(); _gpuActiveLayers.resize(activeLayers.size()); const int pileSize = layerGroup.pileSize(); for (size_t i = 0; i < _gpuActiveLayers.size(); ++i) { GPULayer& gal = _gpuActiveLayers[i]; auto& galuc = gal.uniformCache; const Layer& al = *activeLayers[i]; std::string name = nameBase + "[" + std::to_string(i) + "]."; if (category == layergroupid::GroupID::HeightLayers) { gal.isHeightLayer = true; } galuc.opacity = p.uniformLocation(name + "settings.opacity"); galuc.gamma = p.uniformLocation(name + "settings.gamma"); galuc.multiplier = p.uniformLocation(name + "settings.multiplier"); galuc.offset = p.uniformLocation(name + "settings.offset"); if (al.layerAdjustment().type() == layergroupid::AdjustmentTypeID::ChromaKey) { galuc.chromaKeyColor = p.uniformLocation( name + "adjustment.chromaKeyColor" ); galuc.chromaKeyTolerance = p.uniformLocation( name + "adjustment.chromaKeyTolerance" ); } switch (al.type()) { // Intentional fall through. Same for all tile layers case layergroupid::TypeID::DefaultTileLayer: case layergroupid::TypeID::SingleImageTileLayer: case layergroupid::TypeID::SizeReferenceTileLayer: case layergroupid::TypeID::TemporalTileLayer: case layergroupid::TypeID::TileIndexTileLayer: case layergroupid::TypeID::ByIndexTileLayer: case layergroupid::TypeID::ByLevelTileLayer: { gal.gpuChunkTiles.resize(pileSize); for (size_t j = 0; j < gal.gpuChunkTiles.size(); ++j) { GPULayer::GPUChunkTile& t = gal.gpuChunkTiles[j]; auto& tuc = t.uniformCache; std::string n = name + "pile.chunkTile" + std::to_string(j) + "."; tuc.texture = p.uniformLocation(n + "textureSampler"); tuc.uvOffset = p.uniformLocation(n + "uvTransform.uvOffset"); tuc.uvScale = p.uniformLocation(n + "uvTransform.uvScale"); } galuc.paddingStartOffset = p.uniformLocation( name + "padding.startOffset" ); galuc.paddingSizeDifference = p.uniformLocation( name + "padding.sizeDifference" ); break; } case layergroupid::TypeID::SolidColor: galuc.color = p.uniformLocation(name + "color"); break; default: break; } if (gal.isHeightLayer) { galuc.depthOffset = p.uniformLocation(name + "depthTransform.depthOffset"); galuc.depthScale = p.uniformLocation(name + "depthTransform.depthScale"); } } } void GPULayerGroup::deactivate() { for (GPULayer& gal : _gpuActiveLayers) { for (GPULayer::GPUChunkTile& t : gal.gpuChunkTiles) { t.texUnit.deactivate(); } } } } // namespace openspace::globebrowsing