Files
OpenSpace/modules/globebrowsing/src/gpulayergroup.cpp
Alexander Bock 7004c02b86 Happy new year
2021-01-02 15:26:51 +01:00

199 lines
9.0 KiB
C++

/*****************************************************************************************
* *
* 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 <modules/globebrowsing/src/gpulayergroup.h>
#include <modules/globebrowsing/src/layer.h>
#include <modules/globebrowsing/src/layergroup.h>
#include <modules/globebrowsing/src/layermanager.h>
#include <ghoul/misc/profiling.h>
#include <ghoul/opengl/texture.h>
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<Layer*>& 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<Layer*>& 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