Remove tile-padding to reduce stair-stepping issues (#2842)

* account for availability of next level in desired level

solves #2834

* remove tile-padding option & functionality

* remove (no longer needed) recursive read function

since we no longer padd tiles we cannot sample outside of a read region
anymore.

* change default tilesize for heightlayers to avoid discontinuities

* make frustum culling control a debug property

* Small style guide fix

* clarify if-statement with comment

* add variable for default height-tile resolution, update comment

---------

Co-authored-by: Alexander Bock <mail@alexanderbock.eu>
This commit is contained in:
Joakim Kilby
2023-08-14 13:38:20 +02:00
committed by GitHub
parent e7cad060c2
commit f179f20c96
17 changed files with 60 additions and 265 deletions

View File

@@ -108,30 +108,23 @@ vec4 performLayerSettings(vec4 value, LayerSettings settings) {
return vec4(v, value.a * settings.opacity);
}
vec2 tileUVToTextureSamplePosition(ChunkTile chunkTile, vec2 tileUV, PixelPadding padding)
vec2 tileUVToTextureSamplePosition(ChunkTile chunkTile, vec2 tileUV)
{
vec2 uv = chunkTile.uvTransform.uvOffset + chunkTile.uvTransform.uvScale * tileUV;
// compensateSourceTextureSampling
ivec2 resolution = textureSize(chunkTile.textureSampler, 0);
vec2 sourceSize = vec2(resolution) + padding.sizeDifference;
vec2 currentSize = vec2(resolution);
vec2 sourceToCurrentSize = currentSize / sourceSize;
return sourceToCurrentSize * (uv - padding.startOffset / sourceSize);
return chunkTile.uvTransform.uvOffset + chunkTile.uvTransform.uvScale * tileUV;
}
vec4 getTexVal(ChunkTilePile chunkTilePile, vec3 w, vec2 uv, PixelPadding padding) {
vec4 getTexVal(ChunkTilePile chunkTilePile, vec3 w, vec2 uv) {
vec4 v1 = texture(
chunkTilePile.chunkTile0.textureSampler,
tileUVToTextureSamplePosition(chunkTilePile.chunkTile0, uv, padding)
tileUVToTextureSamplePosition(chunkTilePile.chunkTile0, uv)
);
vec4 v2 = texture(
chunkTilePile.chunkTile1.textureSampler,
tileUVToTextureSamplePosition(chunkTilePile.chunkTile1, uv, padding)
tileUVToTextureSamplePosition(chunkTilePile.chunkTile1, uv)
);
vec4 v3 = texture(
chunkTilePile.chunkTile2.textureSampler,
tileUVToTextureSamplePosition(chunkTilePile.chunkTile2, uv, padding)
tileUVToTextureSamplePosition(chunkTilePile.chunkTile2, uv)
);
return w.x * v1 + w.y * v2 + w.z * v3;
@@ -147,27 +140,27 @@ vec4 getSample#{layerGroup}#{i}(vec2 uv, vec3 levelWeights,
// All tile layers are the same. Sample from texture
#if (#{#{layerGroup}#{i}LayerType} == 0) // DefaultTileProvider
c = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv, #{layerGroup}[#{i}].padding);
c = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv);
#elif (#{#{layerGroup}#{i}LayerType} == 1) // SingleImageProvider
c = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv, #{layerGroup}[#{i}].padding);
c = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv);
#elif (#{#{layerGroup}#{i}LayerType} == 2) // ImageSequenceTileProvider
c = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv, #{layerGroup}[#{i}].padding);
c = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv);
#elif (#{#{layerGroup}#{i}LayerType} == 3) // SizeReferenceTileProvider
c = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv, #{layerGroup}[#{i}].padding);
c = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv);
#elif (#{#{layerGroup}#{i}LayerType} == 4) // TemporalTileProvider
c = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv, #{layerGroup}[#{i}].padding);
c = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv);
#elif (#{#{layerGroup}#{i}LayerType} == 5) // TileIndexTileProvider
c = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv, #{layerGroup}[#{i}].padding);
c = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv);
#elif (#{#{layerGroup}#{i}LayerType} == 6) // TileProviderByIndex
c = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv, #{layerGroup}[#{i}].padding);
c = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv);
#elif (#{#{layerGroup}#{i}LayerType} == 7) // TileProviderByLevel
c = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv, #{layerGroup}[#{i}].padding);
c = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv);
#elif (#{#{layerGroup}#{i}LayerType} == 8) // SolidColor
c.rgb = #{layerGroup}[#{i}].color;
#elif (#{#{layerGroup}#{i}LayerType} == 9) // SpoutImageProvider
c = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv, #{layerGroup}[#{i}].padding);
c = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv);
#elif (#{#{layerGroup}#{i}LayerType} == 10) // VideoTileProvider
c = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv, #{layerGroup}[#{i}].padding);
c = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv);
#endif
return c;
@@ -332,12 +325,8 @@ vec4 calculateDebugColor(vec2 uv, vec4 fragPos, vec2 vertexResolution) {
}
float tileResolution(vec2 tileUV, ChunkTile chunkTile) {
PixelPadding padding;
padding.startOffset = ivec2(0);
padding.sizeDifference = ivec2(0);
vec2 heightResolution = textureSize(chunkTile.textureSampler, 0);
vec2 uv = tileUVToTextureSamplePosition(chunkTile, tileUV, padding);
vec2 uv = tileUVToTextureSamplePosition(chunkTile, tileUV);
return gridDots(uv, heightResolution);
}

View File

@@ -40,11 +40,6 @@ struct ChunkTile {
TileUvTransform uvTransform;
};
struct PixelPadding {
ivec2 startOffset;
ivec2 sizeDifference;
};
struct ChunkTilePile {
ChunkTile chunkTile0;
ChunkTile chunkTile1;
@@ -69,7 +64,6 @@ struct Layer {
TileDepthTransform depthTransform;
LayerSettings settings;
LayerAdjustment adjustment;
PixelPadding padding;
// Other layer type properties stuff
vec3 color;

View File

@@ -94,12 +94,6 @@ void GPULayerGroup::setValue(ghoul::opengl::ProgramObject& program,
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 layers::Layer::ID::SolidColor:
@@ -166,14 +160,6 @@ void GPULayerGroup::bind(ghoul::opengl::ProgramObject& p, const LayerGroup& laye
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 layers::Layer::ID::SolidColor:

View File

@@ -78,8 +78,7 @@ private:
std::vector<GPUChunkTile> gpuChunkTiles;
UniformCache(opacity, gamma, multiplier, offset, valueBlending, chromaKeyColor,
chromaKeyTolerance, paddingStartOffset, paddingSizeDifference, color,
depthOffset, depthScale) uniformCache;
chromaKeyTolerance, color, depthOffset, depthScale) uniformCache;
bool isHeightLayer = false;
};

View File

@@ -132,10 +132,6 @@ namespace {
// the layer is disabled
std::optional<bool> enabled;
// Determines whether the downloaded tiles should have a padding added to the
// borders
std::optional<bool> padTiles;
// The opacity value of the layer
std::optional<float> opacity [[codegen::inrange(0.0, 1.0)]];
@@ -233,11 +229,7 @@ Layer::Layer(layers::Group::ID id, const ghoul::Dictionary& layerDict, LayerGrou
addProperty(_guiDescription);
}
const bool padTiles = p.padTiles.value_or(true);
TileTextureInitData initData = tileTextureInitData(_layerGroupId, padTiles);
_padTilePixelStartOffset = initData.tilePixelStartOffset;
_padTilePixelSizeDifference = initData.tilePixelSizeDifference;
TileTextureInitData initData = tileTextureInitData(_layerGroupId);
_opacity = p.opacity.value_or(_opacity);
addProperty(Fadeable::_opacity);
@@ -472,25 +464,12 @@ void Layer::update() {
}
}
glm::ivec2 Layer::tilePixelStartOffset() const {
return _padTilePixelStartOffset;
}
glm::ivec2 Layer::tilePixelSizeDifference() const {
return _padTilePixelSizeDifference;
}
glm::vec2 Layer::tileUvToTextureSamplePosition(const TileUvTransform& uvTransform,
const glm::vec2& tileUV,
const glm::uvec2& resolution)
{
glm::vec2 uv = uvTransform.uvOffset + uvTransform.uvScale * tileUV;
const glm::vec2 sourceSize = glm::vec2(resolution) +
glm::vec2(_padTilePixelSizeDifference);
const glm::vec2 currentSize = glm::vec2(resolution);
const glm::vec2 sourceToCurrentSize = currentSize / sourceSize;
return sourceToCurrentSize * (uv - glm::vec2(_padTilePixelStartOffset) / sourceSize);
return uv;
}
void Layer::initializeBasedOnType(layers::Layer::ID id, ghoul::Dictionary initDict) {

View File

@@ -68,8 +68,6 @@ public:
void update();
glm::ivec2 tilePixelStartOffset() const;
glm::ivec2 tilePixelSizeDifference() const;
glm::vec2 tileUvToTextureSamplePosition(const TileUvTransform& uvTransform,
const glm::vec2& tileUV, const glm::uvec2& resolution);
@@ -94,9 +92,6 @@ private:
LayerRenderSettings _renderSettings;
LayerAdjustment _layerAdjustment;
glm::ivec2 _padTilePixelStartOffset = glm::ivec2(0);
glm::ivec2 _padTilePixelSizeDifference = glm::ivec2(0);
const layers::Group::ID _layerGroupId;
std::function<void(Layer*)> _onChangeCallback;

View File

@@ -321,7 +321,7 @@ void MemoryAwareTileCache::createDefaultTextureContainers() {
ZoneScoped;
for (const layers::Group& gi : layers::Groups) {
TileTextureInitData initData = tileTextureInitData(gi.id, true);
TileTextureInitData initData = tileTextureInitData(gi.id);
assureTextureContainerExists(initData);
}
}

View File

@@ -674,7 +674,7 @@ void RawTileDataReader::readImageData(IODescription& io, RawTile::ReadError& wor
switch (_initData.ghoulTextureFormat) {
case ghoul::opengl::Texture::Format::Red: {
char* dest = imageDataDest;
const RawTile::ReadError err = repeatedRasterRead(1, io, dest);
const RawTile::ReadError err = rasterRead(1, io, dest);
worstError = std::max(worstError, err);
break;
}
@@ -686,7 +686,7 @@ void RawTileDataReader::readImageData(IODescription& io, RawTile::ReadError& wor
// The final destination pointer is offsetted by one datum byte size
// for every raster (or data channel, i.e. R in RGB)
char* dest = imageDataDest + (i * _initData.bytesPerDatum);
const RawTile::ReadError err = repeatedRasterRead(1, io, dest);
const RawTile::ReadError err = rasterRead(1, io, dest);
worstError = std::max(worstError, err);
}
}
@@ -695,12 +695,12 @@ void RawTileDataReader::readImageData(IODescription& io, RawTile::ReadError& wor
// The final destination pointer is offsetted by one datum byte size
// for every raster (or data channel, i.e. R in RGB)
char* dest = imageDataDest + (i * _initData.bytesPerDatum);
const RawTile::ReadError err = repeatedRasterRead(1, io, dest);
const RawTile::ReadError err = rasterRead(1, io, dest);
worstError = std::max(worstError, err);
}
// Last read is the alpha channel
char* dest = imageDataDest + (3 * _initData.bytesPerDatum);
const RawTile::ReadError err = repeatedRasterRead(2, io, dest);
const RawTile::ReadError err = rasterRead(2, io, dest);
worstError = std::max(worstError, err);
}
else { // Three or more rasters
@@ -708,7 +708,7 @@ void RawTileDataReader::readImageData(IODescription& io, RawTile::ReadError& wor
// The final destination pointer is offsetted by one datum byte size
// for every raster (or data channel, i.e. R in RGB)
char* dest = imageDataDest + (i * _initData.bytesPerDatum);
const RawTile::ReadError err = repeatedRasterRead(i + 1, io, dest);
const RawTile::ReadError err = rasterRead(i + 1, io, dest);
worstError = std::max(worstError, err);
}
}
@@ -721,7 +721,7 @@ void RawTileDataReader::readImageData(IODescription& io, RawTile::ReadError& wor
// The final destination pointer is offsetted by one datum byte size
// for every raster (or data channel, i.e. R in RGB)
char* dest = imageDataDest + (i * _initData.bytesPerDatum);
const RawTile::ReadError err = repeatedRasterRead(1, io, dest);
const RawTile::ReadError err = rasterRead(1, io, dest);
worstError = std::max(worstError, err);
}
}
@@ -730,12 +730,12 @@ void RawTileDataReader::readImageData(IODescription& io, RawTile::ReadError& wor
// The final destination pointer is offsetted by one datum byte size
// for every raster (or data channel, i.e. R in RGB)
char* dest = imageDataDest + (i * _initData.bytesPerDatum);
const RawTile::ReadError err = repeatedRasterRead(1, io, dest);
const RawTile::ReadError err = rasterRead(1, io, dest);
worstError = std::max(worstError, err);
}
// Last read is the alpha channel
char* dest = imageDataDest + (3 * _initData.bytesPerDatum);
const RawTile::ReadError err = repeatedRasterRead(2, io, dest);
const RawTile::ReadError err = rasterRead(2, io, dest);
worstError = std::max(worstError, err);
}
else { // Three or more rasters
@@ -743,14 +743,14 @@ void RawTileDataReader::readImageData(IODescription& io, RawTile::ReadError& wor
// The final destination pointer is offsetted by one datum byte size
// for every raster (or data channel, i.e. R in RGB)
char* dest = imageDataDest + (i * _initData.bytesPerDatum);
const RawTile::ReadError err = repeatedRasterRead(3 - i, io, dest);
const RawTile::ReadError err = rasterRead(3 - i, io, dest);
worstError = std::max(worstError, err);
}
}
if (nRastersToRead > 3) { // Alpha channel exists
// Last read is the alpha channel
char* dest = imageDataDest + (3 * _initData.bytesPerDatum);
const RawTile::ReadError err = repeatedRasterRead(4, io, dest);
const RawTile::ReadError err = rasterRead(4, io, dest);
worstError = std::max(worstError, err);
}
break;
@@ -773,20 +773,6 @@ IODescription RawTileDataReader::ioDescription(const TileIndex& tileIndex) const
io.read.overview = 0;
io.read.fullRegion.start = glm::ivec2(0, 0);
io.read.fullRegion.numPixels = glm::ivec2(_rasterXSize, _rasterYSize);
// For correct sampling in dataset, we need to pad the texture tile
PixelRegion scaledPadding = {
.start = _initData.tilePixelStartOffset,
.numPixels = _initData.tilePixelSizeDifference
};
const double scale = static_cast<double>(io.read.region.numPixels.x) /
static_cast<double>(io.write.region.numPixels.x);
scaledPadding.numPixels *= scale;
scaledPadding.start *= scale;
io.read.region.start += scaledPadding.start;
io.read.region.numPixels += scaledPadding.numPixels;
io.write.bytesPerLine = _initData.bytesPerLine;
io.write.totalNumBytes = _initData.totalNumBytes;
@@ -811,121 +797,6 @@ glm::ivec2 RawTileDataReader::fullPixelSize() const {
return geodeticToPixel(Geodetic2{ 90.0, 180.0 }, _padfTransform);
}
RawTile::ReadError RawTileDataReader::repeatedRasterRead(int rasterBand,
const IODescription& fullIO,
char* dataDestination,
int depth) const
{
// NOTE:
// Ascii graphics illustrates the implementation details of this method, for one
// specific case. Even though the illustrated case is specific, readers can
// hopefully find it useful to get the general idea.
// Make a copy of the full IO desription as we will have to modify it
IODescription io = fullIO;
// Example:
// We have an io description that defines a WRITE and a READ region.
// In this case the READ region extends outside of the defined io.read.fullRegion,
// meaning we will have to perform wrapping
// io.write.region io.read.region
// | |
// V V
// +-------+ +-------+
// | | | |--------+
// | | | | |
// | | | | |
// +-------+ +-------+ |
// | | <-- io.read.fullRegion
// | |
// +--------------+
RawTile::ReadError worstError = RawTile::ReadError::None;
if (!isInside(io.read.region, io.read.fullRegion)) {
// Loop through each side: left, top, right, bottom
for (int i = 0; i < 4; ++i) {
// Example:
// We are currently considering the left side of the pixel region
const Side side = static_cast<Side>(i);
IODescription cutoff = cutIODescription(
io,
side,
edge(io.read.fullRegion, side)
);
// Example:
// We cut off the left part that was outside the io.read.fullRegion, and we
// now have an additional io description for the cut off region.
// Note that the cut-method used above takes care of the corresponding
// WRITE region for us.
// cutoff.write.region cutoff.read.region
// | io.write.region | io.read.region
// | | | |
// V V V V
// +-+-----+ +-+-----+
// | | | | | |--------+
// | | | | | | |
// | | | | | | |
// +-+-----+ +-+-----+ |
// | | <-- io.read.fullRegion
// | |
// +--------------+
const int area = cutoff.read.region.numPixels.x *
cutoff.read.region.numPixels.y;
if (area > 0) {
// Wrap by repeating
Side oppositeSide = static_cast<Side>((i + 2) % 4);
alignPixelRegion(
cutoff.read.region,
oppositeSide,
edge(io.read.fullRegion, oppositeSide)
);
// Example:
// The cut off region is wrapped to the opposite side of the region,
// i.e. "repeated". Note that we don't want WRITE region to change,
// we're only wrapping the READ region.
// cutoff.write.region io.read.region cutoff.read.region
// | io.write.region | |
// | | V V
// V V +-----+ +-+
// +-+-----+ | |------| |
// | | | | | | |
// | | | | | | |
// | | | +-----+ +-+
// +-+-----+ | | <-- io.read.fullRegion
// | |
// +--------------+
// Example:
// The cutoff region has been repeated along one of its sides, but
// as we can see in this example, it still has a top part outside the
// defined gdal region. This is handled through recursion.
const RawTile::ReadError err = repeatedRasterRead(
rasterBand,
cutoff,
dataDestination,
depth + 1
);
worstError = std::max(worstError, err);
}
}
}
const RawTile::ReadError err = rasterRead(rasterBand, io, dataDestination);
// The return error from a repeated rasterRead is ONLY based on the main region,
// which in the usual case will cover the main area of the patch anyway
return err;
}
TileMetaData RawTileDataReader::tileMetaData(RawTile& rawTile,
const PixelRegion& region) const
{

View File

@@ -79,13 +79,6 @@ private:
IODescription ioDescription(const TileIndex& tileIndex) const;
/**
* A recursive function that is able to perform wrapping in case the read region of
* the given IODescription is outside of the given write region.
*/
RawTile::ReadError repeatedRasterRead(int rasterBand, const IODescription& fullIO,
char* dataDestination, int depth = 0) const;
TileMetaData tileMetaData(RawTile& rawTile, const PixelRegion& region) const;
const std::string _datasetFilePath;

View File

@@ -69,7 +69,6 @@ namespace {
// Global flags to modify the RenderableGlobe
constexpr bool LimitLevelByAvailableData = true;
constexpr bool PerformFrustumCulling = true;
constexpr bool PreformHorizonCulling = true;
// Shadow structure
@@ -98,6 +97,7 @@ namespace {
// time being. --abock 2018-10-30
constexpr int DefaultSkirtedGridSegments = 64;
constexpr int UnknownDesiredLevel = -1;
constexpr int DefaultHeightTileResolution = 512;
const openspace::globebrowsing::GeodeticPatch Coverage =
openspace::globebrowsing::GeodeticPatch(0, 0, 90, 180);
@@ -126,6 +126,13 @@ namespace {
openspace::properties::Property::Visibility::Developer
};
constexpr openspace::properties::Property::PropertyInfo PerformFrustumCullingInfo = {
"PerformFrustumCulling",
"Perform frusum culling",
"If this value is set to 'true', frustum culling will be performed.",
openspace::properties::Property::Visibility::AdvancedUser
};
constexpr openspace::properties::Property::PropertyInfo ResetTileProviderInfo = {
"ResetTileProviders",
"Reset tile providers",
@@ -543,6 +550,7 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
BoolProperty(ShowChunkEdgeInfo, false),
BoolProperty(LevelProjectedAreaInfo, true),
BoolProperty(ResetTileProviderInfo, false),
BoolProperty(PerformFrustumCullingInfo, true),
IntProperty(ModelSpaceRenderingInfo, 14, 1, 22),
IntProperty(DynamicLodIterationCountInfo, 16, 4, 128)
})
@@ -649,6 +657,7 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
_debugPropertyOwner.addProperty(_debugProperties.showChunkEdges);
_debugPropertyOwner.addProperty(_debugProperties.levelByProjectedAreaElseDistance);
_debugPropertyOwner.addProperty(_debugProperties.resetTileProviders);
_debugPropertyOwner.addProperty(_debugProperties.performFrustumCulling);
_debugPropertyOwner.addProperty(_debugProperties.modelSpaceRenderingCutoffLevel);
_debugPropertyOwner.addProperty(_debugProperties.dynamicLodIterationCount);
@@ -1602,11 +1611,11 @@ void RenderableGlobe::setCommonUniforms(ghoul::opengl::ProgramObject& programObj
const glm::mat3& modelViewTransformMat3 = glm::mat3(modelViewTransform);
// This is an assumption that the height tile has a resolution of 64 * 64
// This is an assumption that the height tile has a resolution of 512 * 512
// If it does not it will still produce "correct" normals. If the resolution is
// higher the shadows will be softer, if it is lower, pixels will be visible.
// Since default is 64 this will most likely work fine.
constexpr float TileDelta = 1.f / DefaultSkirtedGridSegments;
// Since default is 512 this will most likely work fine.
constexpr float TileDelta = 1.f / DefaultHeightTileResolution;
const glm::vec3 deltaTheta0 = modelViewTransformMat3 *
(glm::vec3(corner10 - corner00) * TileDelta);
const glm::vec3 deltaTheta1 = modelViewTransformMat3 *
@@ -1890,7 +1899,7 @@ bool RenderableGlobe::testIfCullable(const Chunk& chunk,
ZoneScoped;
return (PreformHorizonCulling && isCullableByHorizon(chunk, renderData, heights)) ||
(PerformFrustumCulling && isCullableByFrustum(chunk, renderData, mvp));
(_debugProperties.performFrustumCulling && isCullableByFrustum(chunk, renderData, mvp));
}
int RenderableGlobe::desiredLevel(const Chunk& chunk, const RenderData& renderData,
@@ -2357,7 +2366,9 @@ int RenderableGlobe::desiredLevelByAvailableTileData(const Chunk& chunk) const {
const std::vector<Layer*>& lyrs = _layerManager.layerGroup(gi.id).activeLayers();
for (Layer* layer : lyrs) {
Tile::Status status = layer->tileStatus(chunk.tileIndex);
if (status == Tile::Status::OK) {
// Ensure that the current tile is OK and that the tileprovider for the current
// layer has enough data to support an additional level.
if (status == Tile::Status::OK && layer->tileProvider()->maxLevel() > currLevel + 1) {
return UnknownDesiredLevel;
}
}

View File

@@ -130,6 +130,7 @@ private:
properties::BoolProperty showChunkEdges;
properties::BoolProperty levelByProjectedAreaElseDistance;
properties::BoolProperty resetTileProviders;
properties::BoolProperty performFrustumCulling;
properties::IntProperty modelSpaceRenderingCutoffLevel;
properties::IntProperty dynamicLodIterationCount;
} _debugProperties;

View File

@@ -82,10 +82,6 @@ namespace {
// [[codegen::verbatim(TilePixelSizeInfo.description)]]
std::optional<int> tilePixelSize;
// Determines whether the tiles should have a padding zone around it, making the
// interpolation between tiles more pleasant
std::optional<bool> padTiles;
// Determines if the tiles should be preprocessed before uploading to the GPU
std::optional<bool> performPreProcessing;
@@ -144,7 +140,6 @@ DefaultTileProvider::DefaultTileProvider(const ghoul::Dictionary& dictionary)
// 2. Initialize default values for any optional Keys
// getValue does not work for integers
int pixelSize = p.tilePixelSize.value_or(0);
_padTiles = p.padTiles.value_or(_padTiles);
// Only preprocess height layers by default
_performPreProcessing = _layerGroupID == layers::Group::ID::HeightLayers;
@@ -193,7 +188,7 @@ DefaultTileProvider::DefaultTileProvider(const ghoul::Dictionary& dictionary)
_cacheProperties.compression = codegen::toString(compression);
TileTextureInitData initData(
tileTextureInitData(_layerGroupID, _padTiles, pixelSize)
tileTextureInitData(_layerGroupID, pixelSize)
);
_tilePixelSize = initData.dimensions.x;
initAsyncTileDataReader(initData, _cacheProperties);
@@ -279,7 +274,7 @@ void DefaultTileProvider::update() {
if (_asyncTextureDataProvider->shouldBeDeleted()) {
initAsyncTileDataReader(
tileTextureInitData(_layerGroupID, _padTiles, _tilePixelSize),
tileTextureInitData(_layerGroupID, _tilePixelSize),
_cacheProperties
);
}

View File

@@ -57,7 +57,6 @@ private:
std::unique_ptr<AsyncTileDataProvider> _asyncTextureDataProvider;
layers::Group::ID _layerGroupID = layers::Group::ID::Unknown;
bool _performPreProcessing = false;
bool _padTiles = true;
TileCacheProperties _cacheProperties;
};

View File

@@ -737,7 +737,6 @@ Tile TemporalTileProvider::InterpolateTileProvider::tile(const TileIndex& tileIn
prev.texture->dimensions().y,
prev.texture->dataType(),
prev.texture->format(),
TileTextureInitData::PadTiles::No,
TileTextureInitData::ShouldAllocateDataOnCPU::No
);

View File

@@ -97,7 +97,6 @@ void TileProvider::initializeDefaultTile() {
8,
GL_UNSIGNED_BYTE,
Texture::Format::RGBA,
TileTextureInitData::PadTiles::No,
TileTextureInitData::ShouldAllocateDataOnCPU::Yes
);
char* pixels = new char[initData.totalNumBytes];

View File

@@ -26,9 +26,6 @@
namespace {
const glm::ivec2 TilePixelStartOffset = glm::ivec2(-2);
const glm::ivec2 TilePixelSizeDifference = glm::ivec2(4);
size_t numberOfRasters(ghoul::opengl::Texture::Format format) {
switch (format) {
case ghoul::opengl::Texture::Format::Red:
@@ -104,18 +101,17 @@ openspace::globebrowsing::TileTextureInitData::HashKey calculateHashKey(
namespace openspace::globebrowsing {
TileTextureInitData tileTextureInitData(layers::Group::ID id, bool shouldPadTiles,
TileTextureInitData tileTextureInitData(layers::Group::ID id,
size_t preferredTileSize)
{
switch (id) {
case layers::Group::ID::HeightLayers: {
const size_t tileSize = preferredTileSize ? preferredTileSize : 64;
const size_t tileSize = preferredTileSize ? preferredTileSize : 512;
return TileTextureInitData(
tileSize,
tileSize,
GL_FLOAT,
ghoul::opengl::Texture::Format::Red,
TileTextureInitData::PadTiles(shouldPadTiles),
TileTextureInitData::ShouldAllocateDataOnCPU::Yes
);
}
@@ -125,8 +121,7 @@ TileTextureInitData tileTextureInitData(layers::Group::ID id, bool shouldPadTile
tileSize,
tileSize,
GL_UNSIGNED_BYTE,
ghoul::opengl::Texture::Format::BGRA,
TileTextureInitData::PadTiles(shouldPadTiles)
ghoul::opengl::Texture::Format::BGRA
);
}
case layers::Group::ID::Overlays: {
@@ -135,8 +130,7 @@ TileTextureInitData tileTextureInitData(layers::Group::ID id, bool shouldPadTile
tileSize,
tileSize,
GL_UNSIGNED_BYTE,
ghoul::opengl::Texture::Format::BGRA,
TileTextureInitData::PadTiles(shouldPadTiles)
ghoul::opengl::Texture::Format::BGRA
);
}
case layers::Group::ID::NightLayers: {
@@ -145,8 +139,7 @@ TileTextureInitData tileTextureInitData(layers::Group::ID id, bool shouldPadTile
tileSize,
tileSize,
GL_UNSIGNED_BYTE,
ghoul::opengl::Texture::Format::BGRA,
TileTextureInitData::PadTiles(shouldPadTiles)
ghoul::opengl::Texture::Format::BGRA
);
}
case layers::Group::ID::WaterMasks: {
@@ -155,8 +148,7 @@ TileTextureInitData tileTextureInitData(layers::Group::ID id, bool shouldPadTile
tileSize,
tileSize,
GL_UNSIGNED_BYTE,
ghoul::opengl::Texture::Format::BGRA,
TileTextureInitData::PadTiles(shouldPadTiles)
ghoul::opengl::Texture::Format::BGRA
);
}
default: {
@@ -167,10 +159,8 @@ TileTextureInitData tileTextureInitData(layers::Group::ID id, bool shouldPadTile
TileTextureInitData::TileTextureInitData(size_t width, size_t height, GLenum type,
ghoul::opengl::Texture::Format textureFormat,
PadTiles pad, ShouldAllocateDataOnCPU allocCpu)
ShouldAllocateDataOnCPU allocCpu)
: dimensions(width, height, 1)
, tilePixelStartOffset(pad ? TilePixelStartOffset : glm::ivec2(0))
, tilePixelSizeDifference(pad ? TilePixelSizeDifference : glm::ivec2(0))
, glType(type)
, ghoulTextureFormat(textureFormat)
, nRasters(numberOfRasters(ghoulTextureFormat))
@@ -179,7 +169,6 @@ TileTextureInitData::TileTextureInitData(size_t width, size_t height, GLenum typ
, bytesPerLine(bytesPerPixel * width)
, totalNumBytes(bytesPerLine * height)
, shouldAllocateDataOnCPU(allocCpu)
, padTiles(pad)
, hashKey(calculateHashKey(dimensions, ghoulTextureFormat, glType))
{}

View File

@@ -39,10 +39,9 @@ class TileTextureInitData {
public:
using HashKey = uint64_t;
BooleanType(ShouldAllocateDataOnCPU);
BooleanType(PadTiles);
TileTextureInitData(size_t width, size_t height, GLenum type,
ghoul::opengl::Texture::Format textureFormat, PadTiles pad,
ghoul::opengl::Texture::Format textureFormat,
ShouldAllocateDataOnCPU allocCpu = ShouldAllocateDataOnCPU::No);
TileTextureInitData(const TileTextureInitData& original) = default;
@@ -54,8 +53,6 @@ public:
~TileTextureInitData() = default;
const glm::ivec3 dimensions;
const glm::ivec2 tilePixelStartOffset;
const glm::ivec2 tilePixelSizeDifference;
const GLenum glType;
const ghoul::opengl::Texture::Format ghoulTextureFormat;
const size_t nRasters;
@@ -64,11 +61,10 @@ public:
const size_t bytesPerLine;
const size_t totalNumBytes;
const bool shouldAllocateDataOnCPU;
const bool padTiles;
const HashKey hashKey;
};
TileTextureInitData tileTextureInitData(layers::Group::ID id, bool shouldPadTiles,
TileTextureInitData tileTextureInitData(layers::Group::ID id,
size_t preferredTileSize = 0);
} // namespace openspace::globebrowsing