Add the layer types water mask, nighttexture, and overlay as well as the option to toggle atmosphere.

This commit is contained in:
Kalle Bladin
2016-06-08 21:30:19 -04:00
parent 6f6e9b3e1d
commit 3980aeff57
14 changed files with 747 additions and 26 deletions
+16 -10
View File
@@ -40,10 +40,6 @@ return {
Name = "Temporal MODIS Aqua CorrectedRecflectance TrueColor",
FilePath = "map_service_configs/Temporal_MODIS_Aqua_CorrectedReflectance_TrueColor.xml"
},
{
Name = "Temporal Aqua Orbit Asc",
FilePath = "map_service_configs/Temporal_Aqua_Orbit_Asc.xml"
},
{
Name = "MODIS_Terra_CorrectedReflectance_TrueColor",
FilePath = "map_service_configs/MODIS_Terra_CorrectedReflectance_TrueColor.xml"
@@ -52,10 +48,26 @@ return {
Name = "ESRI Imagery World 2D",
FilePath = "map_service_configs/ESRI_Imagery_World_2D.wms",
},
},
NightTextures = {
{
Name = "Earth at Night 2012",
FilePath = "map_service_configs/VIIRS_CityLights_2012.xml",
},
},
HeightMaps = {
{
Name = "Terrain tileset",
FilePath = "map_service_configs/TERRAIN.wms",
},
},
WaterMasks = {
{
Name = "MODIS_Water_Mask",
FilePath = "map_service_configs/MODIS_Water_Mask.xml"
},
},
Overlays = {
{
Name = "Coastlines",
FilePath = "map_service_configs/Coastlines.xml",
@@ -69,12 +81,6 @@ return {
FilePath = "map_service_configs/Reference_Labels.xml",
},
},
HeightMaps = {
{
Name = "Terrain tileset",
FilePath = "map_service_configs/TERRAIN.wms",
},
},
},
},
--[[
@@ -100,6 +100,10 @@ namespace openspace {
// Layered rendering
bool blendHeightMap;
bool blendColorMap;
bool blendNightTexture;
bool blendWaterMask;
bool blendOverlay;
bool atmosphereEnabled;
private:
@@ -64,6 +64,10 @@ namespace openspace {
, chunkHeight(properties::FloatProperty("chunkHeight", "chunkHeight", 8700.0f, 0.0f, 8700.0f))
, blendHeightMap(properties::BoolProperty("blendHeightMap", "blendHeightMap", true))
, blendColorMap(properties::BoolProperty("blendColorMap", "blendColorMap", true))
, blendNightTexture(properties::BoolProperty("blendNightTexture", "blendNightTexture", true))
, blendOverlay(properties::BoolProperty("blendOverlay", "blendOverlay", true))
, blendWaterMask(properties::BoolProperty("blendWaterMask", "blendWaterMask", true))
, atmosphereEnabled(properties::BoolProperty("atmosphereEnabled", "atmosphereEnabled", false))
{
setName("RenderableGlobe");
@@ -78,6 +82,10 @@ namespace openspace {
addProperty(blendHeightMap);
addProperty(blendColorMap);
addProperty(blendNightTexture);
addProperty(blendOverlay);
addProperty(blendWaterMask);
addProperty(atmosphereEnabled);
doFrustumCulling.setValue(true);
doHorizonCulling.setValue(true);
@@ -103,10 +111,16 @@ namespace openspace {
new TileProviderManager(texturesDictionary));
auto colorProviders = _tileProviderManager->colorTextureProviders();
auto nightProviders = _tileProviderManager->nightTextureProviders();
auto overlayProviders = _tileProviderManager->overlayProviders();
auto heightProviders = _tileProviderManager->heightMapProviders();
auto waterProviders = _tileProviderManager->waterMaskProviders();
addToggleLayerProperties(colorProviders, _activeColorLayers);
addToggleLayerProperties(nightProviders, _activeNightLayers);
addToggleLayerProperties(overlayProviders, _activeOverlays);
addToggleLayerProperties(heightProviders, _activeHeightMapLayers);
addToggleLayerProperties(waterProviders, _activeWaterMaskLayers);
_chunkedLodGlobe = std::shared_ptr<ChunkedLodGlobe>(
new ChunkedLodGlobe(_ellipsoid, patchSegments, _tileProviderManager));
@@ -182,18 +196,37 @@ namespace openspace {
_chunkedLodGlobe->blendHeightMap = blendHeightMap.value();
_chunkedLodGlobe->blendColorMap = blendColorMap.value();
_chunkedLodGlobe->blendNightTexture = blendNightTexture.value();
_chunkedLodGlobe->blendOverlay = blendOverlay.value();
_chunkedLodGlobe->blendWaterMask = blendWaterMask.value();
_chunkedLodGlobe->atmosphereEnabled = atmosphereEnabled.value();
std::vector<TileProviderManager::TileProviderWithName>& colorTextureProviders =
_tileProviderManager->colorTextureProviders();
std::vector<TileProviderManager::TileProviderWithName>& nightTextureProviders =
_tileProviderManager->nightTextureProviders();
std::vector<TileProviderManager::TileProviderWithName>& overlayProviders =
_tileProviderManager->overlayProviders();
std::vector<TileProviderManager::TileProviderWithName>& heightMapProviders =
_tileProviderManager->heightMapProviders();
std::vector<TileProviderManager::TileProviderWithName>& waterMaskProviders =
_tileProviderManager->waterMaskProviders();
for (size_t i = 0; i < colorTextureProviders.size(); i++) {
colorTextureProviders[i].isActive = _activeColorLayers[i].value();
}
for (size_t i = 0; i < nightTextureProviders.size(); i++) {
nightTextureProviders[i].isActive = _activeNightLayers[i].value();
}
for (size_t i = 0; i < overlayProviders.size(); i++) {
overlayProviders[i].isActive = _activeOverlays[i].value();
}
for (size_t i = 0; i < heightMapProviders.size(); i++) {
heightMapProviders[i].isActive = _activeHeightMapLayers[i].value();
}
for (size_t i = 0; i < waterMaskProviders.size(); i++) {
waterMaskProviders[i].isActive = _activeWaterMaskLayers[i].value();
}
// Update this after active layers have been updated
_tileProviderManager->prerender();
@@ -78,6 +78,10 @@ public:
// Layered rendering
properties::BoolProperty blendHeightMap;
properties::BoolProperty blendColorMap;
properties::BoolProperty blendNightTexture;
properties::BoolProperty blendOverlay;
properties::BoolProperty blendWaterMask;
properties::BoolProperty atmosphereEnabled;
private:
std::string _frame;
@@ -100,7 +104,10 @@ private:
properties::BoolProperty _saveOrThrowCamera;
std::vector<properties::BoolProperty> _activeColorLayers;
std::vector<properties::BoolProperty> _activeNightLayers;
std::vector<properties::BoolProperty> _activeOverlays;
std::vector<properties::BoolProperty> _activeHeightMapLayers;
std::vector<properties::BoolProperty> _activeWaterMaskLayers;
DistanceSwitch _distanceSwitch;
};
@@ -32,7 +32,10 @@ namespace {
const std::string _loggerCat = "TileProviderManager";
const std::string keyColorTextures = "ColorTextures";
const std::string keyNightTextures = "NightTextures";
const std::string keyOverlays = "Overlays";
const std::string keyHeightMaps = "HeightMaps";
const std::string keyWaterMasks = "WaterMasks";
}
@@ -55,6 +58,31 @@ namespace openspace {
initTexures(_colorTextureProviders, colorTexturesDict, colorInitData);
ghoul::Dictionary nightTexturesDict;
texDict.getValue(keyNightTextures, nightTexturesDict);
TileProviderInitData nightInitData;
nightInitData.minimumPixelSize = 1024;
nightInitData.threads = 1;
nightInitData.cacheSize = 500;
nightInitData.framesUntilRequestQueueFlush = 60;
nightInitData.preprocessTiles = false;
initTexures(_nightTextureProviders, nightTexturesDict, nightInitData);
ghoul::Dictionary overlaysDict;
texDict.getValue(keyOverlays, overlaysDict);
TileProviderInitData overlayInitData;
overlayInitData.minimumPixelSize = 1024;
overlayInitData.threads = 1;
overlayInitData.cacheSize = 500;
overlayInitData.framesUntilRequestQueueFlush = 60;
overlayInitData.preprocessTiles = false;
initTexures(_overlayProviders, overlaysDict, overlayInitData);
ghoul::Dictionary heightTexturesDict;
texDict.getValue(keyHeightMaps, heightTexturesDict);
@@ -67,6 +95,18 @@ namespace openspace {
heightInitData.preprocessTiles = true;
initTexures(_heightMapProviders, heightTexturesDict, heightInitData);
ghoul::Dictionary waterMaskDict;
texDict.getValue(keyWaterMasks, waterMaskDict);
TileProviderInitData waterInitData;
waterInitData.minimumPixelSize = 2048;
waterInitData.threads = 1;
waterInitData.cacheSize = 500;
waterInitData.framesUntilRequestQueueFlush = 60;
waterInitData.preprocessTiles = false;
initTexures(_waterMaskProviders, waterMaskDict, waterInitData);
}
TileProviderManager::~TileProviderManager()
@@ -134,6 +174,24 @@ namespace openspace {
return _colorTextureProviders;
}
std::vector<TileProviderManager::TileProviderWithName>&
TileProviderManager::nightTextureProviders()
{
return _nightTextureProviders;
}
std::vector<TileProviderManager::TileProviderWithName>&
TileProviderManager::overlayProviders()
{
return _overlayProviders;
}
std::vector<TileProviderManager::TileProviderWithName>&
TileProviderManager::waterMaskProviders()
{
return _waterMaskProviders;
}
void TileProviderManager::prerender() {
for (auto it = _colorTextureProviders.begin(); it != _colorTextureProviders.end(); it++) {
if (it->isActive) {
@@ -141,11 +199,30 @@ namespace openspace {
}
}
for (auto it = _nightTextureProviders.begin(); it != _nightTextureProviders.end(); it++) {
if (it->isActive) {
it->tileProvider->prerender();
}
}
for (auto it = _overlayProviders.begin(); it != _overlayProviders.end(); it++) {
if (it->isActive) {
it->tileProvider->prerender();
}
}
for (auto it = _heightMapProviders.begin(); it != _heightMapProviders.end(); it++){
if (it->isActive) {
it->tileProvider->prerender();
}
}
for (auto it = _waterMaskProviders.begin(); it != _waterMaskProviders.end(); it++) {
if (it->isActive) {
it->tileProvider->prerender();
}
}
}
@@ -175,5 +252,44 @@ namespace openspace {
return tileProviders;
}
const std::vector<std::shared_ptr<TileProvider> >
TileProviderManager::getActiveNightTextureProviders()
{
std::vector<std::shared_ptr<TileProvider> > tileProviders;
for (auto it = _nightTextureProviders.begin(); it != _nightTextureProviders.end(); it++)
{
if (it->isActive) {
tileProviders.push_back(it->tileProvider);
}
}
return tileProviders;
}
const std::vector<std::shared_ptr<TileProvider> >
TileProviderManager::getActiveOverlayProviders()
{
std::vector<std::shared_ptr<TileProvider> > tileProviders;
for (auto it = _overlayProviders.begin(); it != _overlayProviders.end(); it++)
{
if (it->isActive) {
tileProviders.push_back(it->tileProvider);
}
}
return tileProviders;
}
const std::vector<std::shared_ptr<TileProvider> >
TileProviderManager::getActiveWaterMaskProviders()
{
std::vector<std::shared_ptr<TileProvider> > tileProviders;
for (auto it = _waterMaskProviders.begin(); it != _waterMaskProviders.end(); it++)
{
if (it->isActive) {
tileProviders.push_back(it->tileProvider);
}
}
return tileProviders;
}
} // namespace openspace
@@ -55,9 +55,15 @@ namespace openspace {
const std::vector<std::shared_ptr<TileProvider> > getActiveHeightMapProviders();
const std::vector<std::shared_ptr<TileProvider> > getActiveColorTextureProviders();
const std::vector<std::shared_ptr<TileProvider> > getActiveNightTextureProviders();
const std::vector<std::shared_ptr<TileProvider> > getActiveOverlayProviders();
const std::vector<std::shared_ptr<TileProvider> > getActiveWaterMaskProviders();
std::vector<TileProviderWithName>& heightMapProviders();
std::vector<TileProviderWithName>& colorTextureProviders();
std::vector<TileProviderWithName>& nightTextureProviders();
std::vector<TileProviderWithName>& overlayProviders();
std::vector<TileProviderWithName>& waterMaskProviders();
void prerender();
@@ -70,6 +76,9 @@ namespace openspace {
std::vector<TileProviderWithName> _heightMapProviders;
std::vector<TileProviderWithName> _colorTextureProviders;
std::vector<TileProviderWithName> _nightTextureProviders;
std::vector<TileProviderWithName> _overlayProviders;
std::vector<TileProviderWithName> _waterMaskProviders;
};
} // namespace openspace
@@ -51,17 +51,19 @@ namespace openspace {
const LayeredTexturePreprocessingData& other) const
{
if (layeredTextureInfo.size() != other.layeredTextureInfo.size())
{
if (layeredTextureInfo.size() != other.layeredTextureInfo.size() ||
keyValuePairs.size() != other.keyValuePairs.size()) {
return false;
}
else
{
bool equal = true;
for (size_t i = 0; i < layeredTextureInfo.size(); i++)
{
for (size_t i = 0; i < layeredTextureInfo.size(); i++) {
equal = equal && (layeredTextureInfo[i] == other.layeredTextureInfo[i]);
}
for (size_t i = 0; i < keyValuePairs.size(); i++) {
equal = equal && (keyValuePairs[i] == other.keyValuePairs[i]);
}
return equal;
}
}
@@ -116,7 +118,12 @@ namespace openspace {
shaderDictionary.setValue(
textureTypes[i].keyLayerBlendingEnabled, textureTypes[i].layerBlendingEnabled);
}
// Other settings such as "useAtmosphere"
auto keyValuePairs = _preprocessingData.keyValuePairs;
for (size_t i = 0; i < keyValuePairs.size(); i++) {
shaderDictionary.setValue(keyValuePairs[i].first, keyValuePairs[i].second);
}
// Remove old program
_programObject.release();
@@ -51,7 +51,7 @@ namespace openspace {
struct LayeredTexturePreprocessingData
{
std::vector<LayeredTextureInfo> layeredTextureInfo;
std::vector<std::pair<std::string, std::string> > keyValuePairs;
bool operator==(const LayeredTexturePreprocessingData& other) const;
};
@@ -142,10 +142,19 @@ namespace openspace {
auto heightMapProviders = _tileProviderManager->getActiveHeightMapProviders();
auto colorTextureProviders = _tileProviderManager->getActiveColorTextureProviders();
auto nightTextureProviders = _tileProviderManager->getActiveNightTextureProviders();
auto overlayProviders = _tileProviderManager->getActiveOverlayProviders();
auto waterMaskProviders = _tileProviderManager->getActiveWaterMaskProviders();
// TODO: This does not need to be updated every time. Maybe flag as dirty when
// needing update instead.
// Create information for the shader provider
LayeredTextureInfo layeredTextureInfoHeight;
LayeredTextureInfo layeredTextureInfoColor;
LayeredTextureInfo layeredTextureInfoNight;
LayeredTextureInfo layeredTextureInfoOverlay;
LayeredTextureInfo layeredTextureInfoWater;
layeredTextureInfoHeight.keyLastLayerIndex = "lastLayerIndexHeight";
layeredTextureInfoHeight.lastLayerIndex = heightMapProviders.size() - 1;
layeredTextureInfoHeight.keyUseThisLayerType = "useHeightMap";
@@ -158,11 +167,40 @@ namespace openspace {
layeredTextureInfoColor.keyLayerBlendingEnabled = "colorTextureBlendingEnabled";
layeredTextureInfoColor.layerBlendingEnabled = chunk.owner()->blendColorMap;
layeredTextureInfoNight.keyLastLayerIndex = "lastLayerIndexNight";
layeredTextureInfoNight.lastLayerIndex = nightTextureProviders.size() - 1;
layeredTextureInfoNight.keyUseThisLayerType = "useNightTexture";
layeredTextureInfoNight.keyLayerBlendingEnabled = "nightTextureBlendingEnabled";
layeredTextureInfoNight.layerBlendingEnabled = chunk.owner()->blendNightTexture;
layeredTextureInfoOverlay.keyLastLayerIndex = "lastLayerIndexOverlay";
layeredTextureInfoOverlay.lastLayerIndex = overlayProviders.size() - 1;
layeredTextureInfoOverlay.keyUseThisLayerType = "useOverlay";
layeredTextureInfoOverlay.keyLayerBlendingEnabled = "overlayBlendingEnabled";
layeredTextureInfoOverlay.layerBlendingEnabled = chunk.owner()->blendOverlay;
layeredTextureInfoWater.keyLastLayerIndex = "lastLayerIndexWater";
layeredTextureInfoWater.lastLayerIndex = waterMaskProviders.size() - 1;
layeredTextureInfoWater.keyUseThisLayerType = "useWaterMask";
layeredTextureInfoWater.keyLayerBlendingEnabled = "waterMaskBlendingEnabled";
layeredTextureInfoWater.layerBlendingEnabled = chunk.owner()->blendWaterMask;
LayeredTexturePreprocessingData layeredTexturePreprocessingData;
layeredTexturePreprocessingData.layeredTextureInfo.push_back(
layeredTextureInfoHeight);
layeredTexturePreprocessingData.layeredTextureInfo.push_back(
layeredTextureInfoColor);
layeredTexturePreprocessingData.layeredTextureInfo.push_back(
layeredTextureInfoNight);
layeredTexturePreprocessingData.layeredTextureInfo.push_back(
layeredTextureInfoOverlay);
layeredTexturePreprocessingData.layeredTextureInfo.push_back(
layeredTextureInfoWater);
layeredTexturePreprocessingData.keyValuePairs.push_back(
std::pair<std::string, std::string>(
"useAtmosphere",
std::to_string(chunk.owner()->atmosphereEnabled)));
// Now the shader program can be accessed
ProgramObject* programObject =
@@ -191,9 +229,33 @@ namespace openspace {
texUnitColorParent1.resize(colorTextureProviders.size());
texUnitColorParent2.resize(colorTextureProviders.size());
std::vector<ghoul::opengl::TextureUnit> texUnitNight;
std::vector<ghoul::opengl::TextureUnit> texUnitNightParent1;
std::vector<ghoul::opengl::TextureUnit> texUnitNightParent2;
texUnitNight.resize(nightTextureProviders.size());
texUnitNightParent1.resize(nightTextureProviders.size());
texUnitNightParent2.resize(nightTextureProviders.size());
std::vector<ghoul::opengl::TextureUnit> texUnitOverlay;
std::vector<ghoul::opengl::TextureUnit> texUnitOverlayParent1;
std::vector<ghoul::opengl::TextureUnit> texUnitOverlayParent2;
texUnitOverlay.resize(overlayProviders.size());
texUnitOverlayParent1.resize(overlayProviders.size());
texUnitOverlayParent2.resize(overlayProviders.size());
std::vector<ghoul::opengl::TextureUnit> texUnitWater;
std::vector<ghoul::opengl::TextureUnit> texUnitWaterParent1;
std::vector<ghoul::opengl::TextureUnit> texUnitWaterParent2;
texUnitWater.resize(waterMaskProviders.size());
texUnitWaterParent1.resize(waterMaskProviders.size());
texUnitWaterParent2.resize(waterMaskProviders.size());
// Go through all the color texture providers
// Go through all the height map providers
int i = 0;
for (auto it = heightMapProviders.begin(); it != heightMapProviders.end(); it++)
{
@@ -273,12 +335,132 @@ namespace openspace {
}
i++;
}
// Go through all the night texture providers
i = 0;
for (auto it = nightTextureProviders.begin(); it != nightTextureProviders.end(); it++)
{
auto tileProvider = *it;
TileAndTransform tileAndTransform = tileProvider->getHighestResolutionTile(chunkIndex);
if (tileAndTransform.tile.status == Tile::Status::Unavailable) {
// don't render if no tile was available
programObject->deactivate();
return nullptr;
}
std::string indexedTileKey = "nightTiles[" + std::to_string(i) + "]";
// Blend tile with two parents
// The texture needs a unit to sample from
activateTileAndSetTileUniforms(programObject, texUnitNight[i], indexedTileKey, tileAndTransform);
// If blending is enabled, two more textures are needed
if (layeredTextureInfoNight.layerBlendingEnabled) {
TileAndTransform tileAndTransformParent1 = tileProvider->getHighestResolutionTile(chunkIndex, 1);
if (tileAndTransformParent1.tile.status == Tile::Status::Unavailable) {
tileAndTransformParent1 = tileAndTransform;
}
std::string indexedTileKeyParent1 = "nightTilesParent1[" + std::to_string(i) + "]";
activateTileAndSetTileUniforms(programObject, texUnitNightParent1[i], indexedTileKeyParent1, tileAndTransformParent1);
TileAndTransform tileAndTransformParent2 = tileProvider->getHighestResolutionTile(chunkIndex, 2);
if (tileAndTransformParent2.tile.status == Tile::Status::Unavailable) {
tileAndTransformParent2 = tileAndTransformParent1;
}
std::string indexedTileKeyParent2 = "nightTilesParent2[" + std::to_string(i) + "]";
activateTileAndSetTileUniforms(programObject, texUnitNightParent2[i], indexedTileKeyParent2, tileAndTransformParent2);
}
i++;
}
// Go through all the overlay providers
i = 0;
for (auto it = overlayProviders.begin(); it != overlayProviders.end(); it++)
{
auto tileProvider = *it;
TileAndTransform tileAndTransform = tileProvider->getHighestResolutionTile(chunkIndex);
if (tileAndTransform.tile.status == Tile::Status::Unavailable) {
// don't render if no tile was available
programObject->deactivate();
return nullptr;
}
std::string indexedTileKey = "overlayTiles[" + std::to_string(i) + "]";
// Blend tile with two parents
// The texture needs a unit to sample from
activateTileAndSetTileUniforms(programObject, texUnitOverlay[i], indexedTileKey, tileAndTransform);
// If blending is enabled, two more textures are needed
if (layeredTextureInfoOverlay.layerBlendingEnabled) {
TileAndTransform tileAndTransformParent1 = tileProvider->getHighestResolutionTile(chunkIndex, 1);
if (tileAndTransformParent1.tile.status == Tile::Status::Unavailable) {
tileAndTransformParent1 = tileAndTransform;
}
std::string indexedTileKeyParent1 = "overlayTilesParent1[" + std::to_string(i) + "]";
activateTileAndSetTileUniforms(programObject, texUnitOverlayParent1[i], indexedTileKeyParent1, tileAndTransformParent1);
TileAndTransform tileAndTransformParent2 = tileProvider->getHighestResolutionTile(chunkIndex, 2);
if (tileAndTransformParent2.tile.status == Tile::Status::Unavailable) {
tileAndTransformParent2 = tileAndTransformParent1;
}
std::string indexedTileKeyParent2 = "overlayTilesParent2[" + std::to_string(i) + "]";
activateTileAndSetTileUniforms(programObject, texUnitOverlayParent2[i], indexedTileKeyParent2, tileAndTransformParent2);
}
i++;
}
// Go through all the water mask providers
i = 0;
for (auto it = waterMaskProviders.begin(); it != waterMaskProviders.end(); it++)
{
auto tileProvider = *it;
TileAndTransform tileAndTransform = tileProvider->getHighestResolutionTile(chunkIndex);
if (tileAndTransform.tile.status == Tile::Status::Unavailable) {
// don't render if no tile was available
programObject->deactivate();
return nullptr;
}
std::string indexedTileKey = "waterTiles[" + std::to_string(i) + "]";
// Blend tile with two parents
// The texture needs a unit to sample from
activateTileAndSetTileUniforms(programObject, texUnitWater[i], indexedTileKey, tileAndTransform);
// If blending is enabled, two more textures are needed
if (layeredTextureInfoWater.layerBlendingEnabled) {
TileAndTransform tileAndTransformParent1 = tileProvider->getHighestResolutionTile(chunkIndex, 1);
if (tileAndTransformParent1.tile.status == Tile::Status::Unavailable) {
tileAndTransformParent1 = tileAndTransform;
}
std::string indexedTileKeyParent1 = "waterTilesParent1[" + std::to_string(i) + "]";
activateTileAndSetTileUniforms(programObject, texUnitWaterParent1[i], indexedTileKeyParent1, tileAndTransformParent1);
TileAndTransform tileAndTransformParent2 = tileProvider->getHighestResolutionTile(chunkIndex, 2);
if (tileAndTransformParent2.tile.status == Tile::Status::Unavailable) {
tileAndTransformParent2 = tileAndTransformParent1;
}
std::string indexedTileKeyParent2 = "waterTilesParent2[" + std::to_string(i) + "]";
activateTileAndSetTileUniforms(programObject, texUnitWaterParent2[i], indexedTileKeyParent2, tileAndTransformParent2);
}
i++;
}
// The length of the skirts is proportional to its size
programObject->setUniform("skirtLength", static_cast<float>(chunk.surfacePatch().halfSize().lat * 1000000));
programObject->setUniform("xSegments", _grid->xSegments());
return programObject;
}
@@ -291,11 +473,17 @@ namespace openspace {
auto heightMapProviders = _tileProviderManager->getActiveHeightMapProviders();
auto colorTextureProviders = _tileProviderManager->getActiveColorTextureProviders();
auto nightTextureProviders = _tileProviderManager->getActiveNightTextureProviders();
auto overlayProviders = _tileProviderManager->getActiveOverlayProviders();
auto waterMaskProviders = _tileProviderManager->getActiveWaterMaskProviders();
const Ellipsoid& ellipsoid = chunk.owner()->ellipsoid();
// This information is only needed when doing blending
if ((heightMapProviders.size() > 0 && chunk.owner()->blendHeightMap) ||
(colorTextureProviders.size() > 0 && chunk.owner()->blendColorMap)) {
(colorTextureProviders.size() > 0 && chunk.owner()->blendColorMap) ||
(nightTextureProviders.size() > 0 && chunk.owner()->blendNightTexture) ||
(overlayProviders.size() > 0 && chunk.owner()->blendOverlay) ||
(waterMaskProviders.size() > 0 && chunk.owner()->blendWaterMask)) {
float distanceScaleFactor = chunk.owner()->lodScaleFactor * ellipsoid.minimumRadius();
programObject->setUniform("cameraPosition", vec3(data.camera.positionVec3()));
programObject->setUniform("distanceScaleFactor", distanceScaleFactor);
@@ -310,11 +498,12 @@ namespace openspace {
dmat4 modelTransform = dmat4(chunk.owner()->stateMatrix()); // Rotation
modelTransform = translate(dmat4(1), data.position.dvec3()) * modelTransform; // Translation
dmat4 viewTransform = data.camera.combinedViewMatrix();
mat4 modelViewProjectionTransform = data.camera.projectionMatrix()
* mat4(viewTransform * modelTransform);
mat4 modelViewTransform = mat4(viewTransform * modelTransform);
mat4 modelViewProjectionTransform = data.camera.projectionMatrix() * modelViewTransform;
// Upload the uniform variables
programObject->setUniform("modelViewProjectionTransform", modelViewProjectionTransform);
programObject->setUniform("modelViewTransform", modelViewTransform);
programObject->setUniform("minLatLon", vec2(swCorner.toLonLatVec2()));
programObject->setUniform("lonLatScalingFactor", vec2(patchSize.toLonLatVec2()));
programObject->setUniform("radiiSquared", vec3(ellipsoid.radiiSquared()));
@@ -343,11 +532,19 @@ namespace openspace {
}
using namespace glm;
const Ellipsoid& ellipsoid = chunk.owner()->ellipsoid();
auto heightMapProviders = _tileProviderManager->getActiveHeightMapProviders();
auto colorTextureProviders = _tileProviderManager->getActiveColorTextureProviders();
auto nightTextureProviders = _tileProviderManager->getActiveNightTextureProviders();
auto overlayProviders = _tileProviderManager->getActiveOverlayProviders();
auto waterMaskProviders = _tileProviderManager->getActiveWaterMaskProviders();
const Ellipsoid& ellipsoid = chunk.owner()->ellipsoid();
if ((heightMapProviders.size() > 0 && chunk.owner()->blendHeightMap) ||
(colorTextureProviders.size() > 0 && chunk.owner()->blendColorMap)) {
(colorTextureProviders.size() > 0 && chunk.owner()->blendColorMap) ||
(nightTextureProviders.size() > 0 && chunk.owner()->blendNightTexture) ||
(overlayProviders.size() > 0 && chunk.owner()->blendOverlay) ||
(waterMaskProviders.size() > 0 && chunk.owner()->blendWaterMask)) {
float distanceScaleFactor = chunk.owner()->lodScaleFactor * chunk.owner()->ellipsoid().minimumRadius();
programObject->setUniform("distanceScaleFactor", distanceScaleFactor);
programObject->setUniform("chunkLevel", chunk.index().level);
@@ -34,6 +34,29 @@ uniform TextureTile colorTilesParent1[NUMLAYERS_COLORTEXTURE];
uniform TextureTile colorTilesParent2[NUMLAYERS_COLORTEXTURE];
#endif // USE_COLORTEXTURE
#if USE_NIGHTTEXTURE
uniform TextureTile nightTiles[NUMLAYERS_NIGHTTEXTURE];
uniform TextureTile nightTilesParent1[NUMLAYERS_NIGHTTEXTURE];
uniform TextureTile nightTilesParent2[NUMLAYERS_NIGHTTEXTURE];
#endif // USE_NIGHTTEXTURE
#if USE_OVERLAY
uniform TextureTile overlayTiles[NUMLAYERS_OVERLAY];
uniform TextureTile overlayTilesParent1[NUMLAYERS_OVERLAY];
uniform TextureTile overlayTilesParent2[NUMLAYERS_OVERLAY];
#endif // USE_OVERLAY
#if USE_WATERMASK
uniform TextureTile waterTiles[NUMLAYERS_WATERMASK];
uniform TextureTile waterTilesParent1[NUMLAYERS_WATERMASK];
uniform TextureTile waterTilesParent2[NUMLAYERS_WATERMASK];
#endif // USE_WATERMASK
#if USE_ATMOSPHERE
// TODO atmosphere uniforms here
#endif // USE_ATMOSPHERE
in vec3 ellipsoidNormalCameraSpace;
in vec4 fs_position;
in vec2 fs_uv;
@@ -42,7 +65,7 @@ in float tileInterpolationParameter;
Fragment getFragment() {
Fragment frag;
frag.color = vec4(1,1,1,1);
frag.color = vec4(0.1,0.1,0.1,1);
#if USE_COLORTEXTURE
@@ -55,6 +78,47 @@ Fragment getFragment() {
#endif // USE_COLORTEXTURE
#if USE_WATERMASK
// TODO: This function needs more parameters and should update the fragment color for water
frag.color = calculateWater(
frag.color,
fs_uv,
tileInterpolationParameter,
waterTiles,
waterTilesParent1,
waterTilesParent2);
#endif // USE_WATERMASK
#if USE_NIGHTTEXTURE
// TODO: This function needs more parameters and should update the fragment color for night texture
frag.color = calculateNight(
frag.color,
fs_uv,
tileInterpolationParameter,
nightTiles,
nightTilesParent1,
nightTilesParent2,
ellipsoidNormalCameraSpace);
#endif // USE_NIGHTTEXTURE
#if USE_ATMOSPHERE
// TODO: Jonathas magic goes here here
frag.color = frag.color + vec4(0.5,0.5,1,0) * 0.3; // Just to see something for now
#endif // USE_ATMOSPHERE
#if USE_OVERLAY
frag.color = calculateOverlay(
frag.color,
fs_uv,
tileInterpolationParameter,
overlayTiles,
overlayTilesParent1,
overlayTilesParent2);
#endif // USE_OVERLAY
//frag.color += patchBorderOverlay(fs_uv, vec3(0,1,0), 0.02);
frag.depth = fs_position.w;
@@ -30,6 +30,7 @@
#include <${MODULE_GLOBEBROWSING}/shaders/texturetilemapping.hglsl>
uniform mat4 modelViewProjectionTransform;
uniform mat4 modelViewTransform;
uniform vec3 radiiSquared;
uniform vec2 minLatLon;
@@ -52,6 +53,7 @@ layout(location = 1) in vec2 in_uv;
out vec2 fs_uv;
out vec4 fs_position;
out vec3 ellipsoidNormalCameraSpace;
// tileInterpolationParameter is used to interpolate between a tile and its parent tiles
// The value increases with the distance from the vertex (or fragment) to the camera
out float tileInterpolationParameter;
@@ -106,4 +108,5 @@ void main()
fs_uv = in_uv;
fs_position = z_normalization(positionClippingSpace);
gl_Position = fs_position;
ellipsoidNormalCameraSpace = mat3(modelViewTransform) * pair.normal;
}
@@ -39,6 +39,7 @@ in float tileInterpolationParameter;
in vec4 fs_position;
in vec2 fs_uv;
in vec3 ellipsoidNormalCameraSpace;
Fragment getFragment() {
Fragment frag;
@@ -56,6 +57,49 @@ Fragment getFragment() {
#endif // USE_COLORTEXTURE
#if USE_WATERMASK
// TODO: Jonathas magic goes here here
// TODO: This function needs more parameters and should update the fragment color for water
frag.color = calculateWater(
frag.color,
fs_uv,
tileInterpolationParameter,
waterTiles,
waterTilesParent1,
waterTilesParent2);
#endif // USE_WATERMASK
#if USE_NIGHTTEXTURE
// TODO: Jonathas magic goes here here
// TODO: This function needs more parameters and should update the fragment color for night texture
frag.color = calculateNight(
frag.color,
fs_uv,
tileInterpolationParameter,
nightTiles,
nightTilesParent1,
nightTilesParent2,
ellipsoidNormalCameraSpace);
#endif // USE_NIGHTTEXTURE
#if USE_ATMOSPHERE
// TODO: Jonathas magic goes here here
frag.color = frag.color + vec4(0.5,0.5,1,0) * 0.3; // Just to see something for now
#endif // USE_ATMOSPHERE
#if USE_OVERLAY
frag.color = calculateOverlay(
frag.color,
fs_uv,
tileInterpolationParameter,
overlayTiles,
overlayTilesParent1,
overlayTilesParent2);
#endif // USE_OVERLAY
//frag.color += patchBorderOverlay(fs_uv, vec3(1,0,0), 0.02);
frag.depth = fs_position.w;
@@ -57,6 +57,8 @@ layout(location = 1) in vec2 in_uv;
out vec2 fs_uv;
out vec4 fs_position;
out vec3 ellipsoidNormalCameraSpace;
// tileInterpolationParameter is used to interpolate between a tile and its parent tiles
// The value increases with the distance from the vertex (or fragment) to the camera
out float tileInterpolationParameter;
@@ -114,4 +116,5 @@ void main()
fs_uv = in_uv;
fs_position = z_normalization(positionClippingSpace);
gl_Position = fs_position;
ellipsoidNormalCameraSpace = patchNormalCameraSpace;
}
@@ -28,7 +28,7 @@
#include <${MODULE_GLOBEBROWSING}/shaders/texturetile.hglsl>
#include <${MODULE_GLOBEBROWSING}/shaders/blending.hglsl>
// First layer type from LayeredTextureShaderProvider
// First layer type from LayeredTextureShaderProvider is height map
#ifndef NUMLAYERS_HEIGHTMAP
#define NUMLAYERS_HEIGHTMAP #{lastLayerIndexHeight} + 1
#endif // NUMLAYERS_HEIGHTMAP
@@ -41,7 +41,7 @@
#define HEIGHTMAP_BLENDING_ENABLED #{heightMapBlendingEnabled}
#endif // HEIGHTMAP_BLENDING_ENABLED
// Second layer type from LayeredTextureShaderProvider
// Second layer type from LayeredTextureShaderProvider is color texture
#ifndef NUMLAYERS_COLORTEXTURE
#define NUMLAYERS_COLORTEXTURE #{lastLayerIndexColor} + 1
#endif // NUMLAYERS_COLORTEXTURE
@@ -54,6 +54,50 @@
#define COLORTEXTURE_BLENDING_ENABLED #{colorTextureBlendingEnabled}
#endif // COLORTEXTURE_BLENDING_ENABLED
// Third layer type from LayeredTextureShaderProvider is water mask
#ifndef NUMLAYERS_WATERMASK
#define NUMLAYERS_WATERMASK #{lastLayerIndexWater} + 1
#endif // NUMLAYERS_WATERMASK
#ifndef USE_WATERMASK
#define USE_WATERMASK #{useWaterMask}
#endif // USE_WATERMASK
#ifndef WATERMASK_BLENDING_ENABLED
#define WATERMASK_BLENDING_ENABLED #{waterMaskBlendingEnabled}
#endif // WATERMASK_BLENDING_ENABLED
// Fourth layer type from LayeredTextureShaderProvider is night texture
#ifndef NUMLAYERS_NIGHTTEXTURE
#define NUMLAYERS_NIGHTTEXTURE #{lastLayerIndexNight} + 1
#endif // NUMLAYERS_NIGHTTEXTURE
#ifndef USE_NIGHTTEXTURE
#define USE_NIGHTTEXTURE #{useNightTexture}
#endif // USE_NIGHTTEXTURE
#ifndef NIGHTTEXTURE_BLENDING_ENABLED
#define NIGHTTEXTURE_BLENDING_ENABLED #{nightTextureBlendingEnabled}
#endif // NIGHTTEXTURE_BLENDING_ENABLED
// Fifth layer type from LayeredTextureShaderProvider is overlay
#ifndef NUMLAYERS_OVERLAY
#define NUMLAYERS_OVERLAY #{lastLayerIndexOverlay} + 1
#endif // NUMLAYERS_OVERLAY
#ifndef USE_OVERLAY
#define USE_OVERLAY #{useOverlay}
#endif // USE_OVERLAY
#ifndef OVERLAY_BLENDING_ENABLED
#define OVERLAY_BLENDING_ENABLED #{overlayBlendingEnabled}
#endif // OVERLAY_BLENDING_ENABLED
// Other key value pairs used for settings
#ifndef USE_ATMOSPHERE
#define USE_ATMOSPHERE #{useAtmosphere}
#endif // USE_ATMOSPHERE
float calculateHeight(
const vec2 uv,
const float tileInterpolationParameter,
@@ -173,4 +217,188 @@ vec4 calculateColor(
return color;
}
vec4 calculateNight(
const vec4 currentColor,
const vec2 uv,
const float tileInterpolationParameter,
const TextureTile nightTiles[NUMLAYERS_NIGHTTEXTURE],
const TextureTile nightTilesParent1[NUMLAYERS_NIGHTTEXTURE],
const TextureTile nightTilesParent2[NUMLAYERS_NIGHTTEXTURE],
const vec3 ellipsoidNormalCameraSpace) {
vec3 lightDirection = normalize(vec3(-1,-1,-1));
float cosineFactor = clamp(dot(-lightDirection, ellipsoidNormalCameraSpace), 0, 1);
vec4 nightColor = vec4(0,0,0,0);
// The shader compiler will remove unused code when variables are multiplied by
// a constant 0
#if NIGHTTEXTURE_BLENDING_ENABLED
float w1 = clamp(1 - tileInterpolationParameter, 0 , 1);
float w2 = (clamp(tileInterpolationParameter, 0 , 1) - clamp(tileInterpolationParameter - 1, 0 , 1));
float w3 = clamp(tileInterpolationParameter - 1, 0 , 1);
#else // NIGHTTEXTURE_BLENDING_ENABLED
float w1 = 1;
float w2 = 0;
float w3 = 0;
#endif // NIGHTTEXTURE_BLENDING_ENABLED
#for i in 0..#{lastLayerIndexNight}
{
vec2 samplePos =
nightTiles[#{i}].uvTransform.uvScale * uv +
nightTiles[#{i}].uvTransform.uvOffset;
vec2 samplePosParent1 =
nightTilesParent1[#{i}].uvTransform.uvScale * uv +
nightTilesParent1[#{i}].uvTransform.uvOffset;
vec2 samplePosParent2 =
nightTilesParent2[#{i}].uvTransform.uvScale * uv +
nightTilesParent2[#{i}].uvTransform.uvOffset;
/*
vec4 colorSample =
w1 * textureLod(nightTiles[#{i}].textureSampler, samplePos, 0) +
w2 * textureLod(nightTilesParent1[#{i}].textureSampler, samplePosParent1, 0) +
w3 * textureLod(nightTilesParent2[#{i}].textureSampler, samplePosParent2, 0);
*/
/*
vec4 colorSample =
w1 * textureGrad(nightTiles[#{i}].textureSampler, samplePos, vec2(0), vec2(0)) +
w2 * textureGrad(nightTilesParent1[#{i}].textureSampler, samplePosParent1, vec2(0), vec2(0)) +
w3 * textureGrad(nightTilesParent2[#{i}].textureSampler, samplePosParent2, vec2(0), vec2(0));
*/
vec4 colorSample =
w1 * texture(nightTiles[#{i}].textureSampler, samplePos) +
w2 * texture(nightTilesParent1[#{i}].textureSampler, samplePosParent1) +
w3 * texture(nightTilesParent2[#{i}].textureSampler, samplePosParent2);
nightColor = blendOver(nightColor, colorSample);
}
#endfor
// Blend night color with base color
vec4 color = vec4(cosineFactor * vec3(currentColor) + (1 - cosineFactor) * vec3(nightColor), currentColor.a);
return color;
}
vec4 calculateOverlay(
const vec4 currentColor,
const vec2 uv,
const float tileInterpolationParameter,
const TextureTile overlayTiles[NUMLAYERS_OVERLAY],
const TextureTile overlayTilesParent1[NUMLAYERS_OVERLAY],
const TextureTile overlayTilesParent2[NUMLAYERS_OVERLAY]) {
vec4 color = currentColor;
// The shader compiler will remove unused code when variables are multiplied by
// a constant 0
#if OVERLAY_BLENDING_ENABLED
float w1 = clamp(1 - tileInterpolationParameter, 0 , 1);
float w2 = (clamp(tileInterpolationParameter, 0 , 1) - clamp(tileInterpolationParameter - 1, 0 , 1));
float w3 = clamp(tileInterpolationParameter - 1, 0 , 1);
#else // OVERLAY_BLENDING_ENABLED
float w1 = 1;
float w2 = 0;
float w3 = 0;
#endif // OVERLAY_BLENDING_ENABLED
#for i in 0..#{lastLayerIndexOverlay}
{
vec2 samplePos =
overlayTiles[#{i}].uvTransform.uvScale * uv +
overlayTiles[#{i}].uvTransform.uvOffset;
vec2 samplePosParent1 =
overlayTilesParent1[#{i}].uvTransform.uvScale * uv +
overlayTilesParent1[#{i}].uvTransform.uvOffset;
vec2 samplePosParent2 =
overlayTilesParent2[#{i}].uvTransform.uvScale * uv +
overlayTilesParent2[#{i}].uvTransform.uvOffset;
/*
vec4 colorSample =
w1 * textureLod(overlayTiles[#{i}].textureSampler, samplePos, 0) +
w2 * textureLod(overlayTilesParent1[#{i}].textureSampler, samplePosParent1, 0) +
w3 * textureLod(overlayTilesParent2[#{i}].textureSampler, samplePosParent2, 0);
*/
/*
vec4 colorSample =
w1 * textureGrad(overlayTiles[#{i}].textureSampler, samplePos, vec2(0), vec2(0)) +
w2 * textureGrad(overlayTilesParent1[#{i}].textureSampler, samplePosParent1, vec2(0), vec2(0)) +
w3 * textureGrad(overlayTilesParent2[#{i}].textureSampler, samplePosParent2, vec2(0), vec2(0));
*/
vec4 colorSample =
w1 * texture(overlayTiles[#{i}].textureSampler, samplePos) +
w2 * texture(overlayTilesParent1[#{i}].textureSampler, samplePosParent1) +
w3 * texture(overlayTilesParent2[#{i}].textureSampler, samplePosParent2);
color = blendOver(color, colorSample);
}
#endfor
return color;
}
vec4 calculateWater(
const vec4 currentColor,
const vec2 uv,
const float tileInterpolationParameter,
const TextureTile waterTiles[NUMLAYERS_WATERMASK],
const TextureTile waterTilesParent1[NUMLAYERS_WATERMASK],
const TextureTile waterTilesParent2[NUMLAYERS_WATERMASK]) {
vec4 color = currentColor;
// The shader compiler will remove unused code when variables are multiplied by
// a constant 0
#if WATERMASK_BLENDING_ENABLED
float w1 = clamp(1 - tileInterpolationParameter, 0 , 1);
float w2 = (clamp(tileInterpolationParameter, 0 , 1) - clamp(tileInterpolationParameter - 1, 0 , 1));
float w3 = clamp(tileInterpolationParameter - 1, 0 , 1);
#else // WATERMASK_BLENDING_ENABLED
float w1 = 1;
float w2 = 0;
float w3 = 0;
#endif // WATERMASK_BLENDING_ENABLED
#for i in 0..#{lastLayerIndexWater}
{
vec2 samplePos =
waterTiles[#{i}].uvTransform.uvScale * uv +
waterTiles[#{i}].uvTransform.uvOffset;
vec2 samplePosParent1 =
waterTilesParent1[#{i}].uvTransform.uvScale * uv +
waterTilesParent1[#{i}].uvTransform.uvOffset;
vec2 samplePosParent2 =
waterTilesParent2[#{i}].uvTransform.uvScale * uv +
waterTilesParent2[#{i}].uvTransform.uvOffset;
/*
vec4 colorSample =
w1 * textureLod(waterTiles[#{i}].textureSampler, samplePos, 0) +
w2 * textureLod(waterTilesParent1[#{i}].textureSampler, samplePosParent1, 0) +
w3 * textureLod(waterTilesParent2[#{i}].textureSampler, samplePosParent2, 0);
*/
/*
vec4 colorSample =
w1 * textureGrad(waterTiles[#{i}].textureSampler, samplePos, vec2(0), vec2(0)) +
w2 * textureGrad(waterTilesParent1[#{i}].textureSampler, samplePosParent1, vec2(0), vec2(0)) +
w3 * textureGrad(waterTilesParent2[#{i}].textureSampler, samplePosParent2, vec2(0), vec2(0));
*/
vec4 colorSample =
w1 * texture(waterTiles[#{i}].textureSampler, samplePos) +
w2 * texture(waterTilesParent1[#{i}].textureSampler, samplePosParent1) +
w3 * texture(waterTilesParent2[#{i}].textureSampler, samplePosParent2);
color = blendOver(color, colorSample);
}
#endfor
return color;
}
#endif // TEXTURETILEMAPPING_HGLSL