mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-12 14:40:00 -06:00
199 lines
9.0 KiB
C++
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
|