diff --git a/modules/globebrowsing/globes/chunk.cpp b/modules/globebrowsing/globes/chunk.cpp index 9ee0df61b1..7044d95971 100644 --- a/modules/globebrowsing/globes/chunk.cpp +++ b/modules/globebrowsing/globes/chunk.cpp @@ -130,7 +130,9 @@ namespace openspace { else return DO_NOTHING; } - + void Chunk::render(const RenderData& data) const { + _owner->getPatchRenderer().renderChunk(*this, data); + } } // namespace openspace diff --git a/modules/globebrowsing/globes/chunk.h b/modules/globebrowsing/globes/chunk.h index 5582d90f49..a5f095e1f2 100644 --- a/modules/globebrowsing/globes/chunk.h +++ b/modules/globebrowsing/globes/chunk.h @@ -54,6 +54,7 @@ namespace openspace { /// Updates chunk internally and returns a desired level Status update(const RenderData& data); + void render(const RenderData& data) const; const GeodeticPatch& surfacePatch() const; ChunkedLodGlobe* const owner() const; diff --git a/modules/globebrowsing/globes/chunknode.cpp b/modules/globebrowsing/globes/chunknode.cpp index cba8d660dd..60d70ddebf 100644 --- a/modules/globebrowsing/globes/chunknode.cpp +++ b/modules/globebrowsing/globes/chunknode.cpp @@ -119,15 +119,15 @@ void ChunkNode::renderReversedBreadthFirst(const RenderData& data) { } } } + while (S.size() > 0) { - S.top()->renderThisChunk(data); + S.top()->renderThisChunk(data); S.pop(); } } void ChunkNode::renderThisChunk(const RenderData& data) { - ChunkRenderer& patchRenderer = _chunk.owner()->getPatchRenderer(); - patchRenderer.renderChunk(_chunk, data); + _chunk.render(data); ChunkNode::renderedChunks++; } diff --git a/modules/globebrowsing/other/tileprovider.cpp b/modules/globebrowsing/other/tileprovider.cpp index d4e6a9c691..601c9ee660 100644 --- a/modules/globebrowsing/other/tileprovider.cpp +++ b/modules/globebrowsing/other/tileprovider.cpp @@ -135,90 +135,88 @@ namespace openspace { } - Tile TileProvider::getMostHiResTile(ChunkIndex chunkIndex) { - std::shared_ptr tex = nullptr; - glm::vec2 uvOffset(0, 0); - glm::vec2 uvScale(1, 1); - - // Check if we are trying to get a texture for a very small patch. - // In that case, use the biggest one defined for the dataset. - int maximumAllowedLevel = - _gdalDataSet->GetRasterBand(1)->GetOverviewCount() - 1; - int levelInDataset = chunkIndex.level + _tileLevelDifference; - int timesToStepUp = levelInDataset - maximumAllowedLevel; - for (int i = 0; i < timesToStepUp; i++) - { - uvScale *= 0.5; - uvOffset *= 0.5; - - if (chunkIndex.isEastChild()) { - uvOffset.x += 0.5; - } - - // In OpenGL, positive y direction is up - if (chunkIndex.isNorthChild()) { - uvOffset.y += 0.5; - } + Tile TileProvider::getHighestResolutionTile(ChunkIndex chunkIndex) { + TileUvTransform uvTransform; + uvTransform.uvOffset = glm::vec2(0, 0); + uvTransform.uvScale = glm::vec2(1, 1); + int numOverviews = _gdalDataSet->GetRasterBand(1)->GetOverviewCount(); + int maximumLevel = numOverviews - 1 - _tileLevelDifference; + while(chunkIndex.level > maximumLevel){ + transformFromParent(chunkIndex, uvTransform); chunkIndex = chunkIndex.parent(); } - // We also need to check if the wanted texture is available. If not, go up a level - while (true) { - tex = getOrStartFetchingTile(chunkIndex); - - if (tex != nullptr) { - break; - } - - if (chunkIndex.level <= 1) { - tex = getDefaultTexture(); - break; - } - - // If we have a parent, calculate the UV offset and scale from the chunkIndex - else { - uvScale *= 0.5; - uvOffset *= 0.5; - - if (chunkIndex.isEastChild()) { - uvOffset.x += 0.5; - } - - // In OpenGL, positive y direction is up - if (chunkIndex.isNorthChild()) { - uvOffset.y += 0.5; - } - - chunkIndex = chunkIndex.parent(); - } - } - - return{ tex, {uvOffset, uvScale } }; + return getOrEnqueueHighestResolutionTile(chunkIndex, uvTransform); } + Tile TileProvider::getOrEnqueueHighestResolutionTile(const ChunkIndex& chunkIndex, + TileUvTransform& uvTransform) + { + HashKey key = chunkIndex.hashKey(); + if (_tileCache.exist(key)) { + return { _tileCache.get(key), uvTransform }; + } + else if (chunkIndex.level <= 1) { + return { getDefaultTexture(), uvTransform }; + } + else { + // We don't have the tile for the requested level + // --> check if the parent has a tile we can use + transformFromParent(chunkIndex, uvTransform); + Tile tile = getOrEnqueueHighestResolutionTile(chunkIndex.parent(), uvTransform); + + // As we didn't have this tile, push it to the request queue + // post order enqueueing tiles --> enqueue tiles at low levels first + enqueueTileRequest(chunkIndex); + + return tile; + } + } + + + + void TileProvider::transformFromParent(const ChunkIndex& chunkIndex, TileUvTransform& uv) const { + uv.uvOffset *= 0.5; + uv.uvScale *= 0.5; + + if (chunkIndex.isEastChild()) { + uv.uvOffset.x += 0.5; + } + + // In OpenGL, positive y direction is up + if (chunkIndex.isNorthChild()) { + uv.uvOffset.y += 0.5; + } + } + + std::shared_ptr TileProvider::getOrStartFetchingTile(ChunkIndex chunkIndex) { - HashKey hashkey = chunkIndex.hashKey(); - if (_tileCache.exist(hashkey)) { return _tileCache.get(hashkey); } else { - bool tileHasBeenQueued = _queuedTileRequests.find(hashkey) != _queuedTileRequests.end(); - if (!tileHasBeenQueued) { - // enque load job - std::shared_ptr job = std::shared_ptr( - new TextureTileLoadJob(this, chunkIndex)); - - _tileLoadManager.enqueueJob(job); - - _queuedTileRequests.insert(hashkey); - } + enqueueTileRequest(chunkIndex); return nullptr; } } + bool TileProvider::enqueueTileRequest(const ChunkIndex& chunkIndex) { + HashKey key = chunkIndex.hashKey(); + bool tileHasBeenQueued = _queuedTileRequests.find(key) != _queuedTileRequests.end(); + if (!tileHasBeenQueued) { + // enque load job + std::shared_ptr job = std::shared_ptr( + new TextureTileLoadJob(this, chunkIndex)); + + _tileLoadManager.enqueueJob(job); + + _queuedTileRequests.insert(key); + } + return !tileHasBeenQueued; + } + std::shared_ptr TileProvider::getDefaultTexture() { diff --git a/modules/globebrowsing/other/tileprovider.h b/modules/globebrowsing/other/tileprovider.h index 6a5f46dcf8..422c702db6 100644 --- a/modules/globebrowsing/other/tileprovider.h +++ b/modules/globebrowsing/other/tileprovider.h @@ -74,7 +74,7 @@ namespace openspace { int framesUntilRequestFlush); ~TileProvider(); - Tile getMostHiResTile(ChunkIndex chunkIndex); + Tile getHighestResolutionTile(ChunkIndex chunkIndex); std::shared_ptr getOrStartFetchingTile(ChunkIndex chunkIndex); std::shared_ptr getDefaultTexture(); @@ -91,8 +91,11 @@ namespace openspace { ////////////////////////////////////////////////////////////////////////////////// // Helper functions // ////////////////////////////////////////////////////////////////////////////////// + Tile getOrEnqueueHighestResolutionTile(const ChunkIndex& ci, TileUvTransform& uvTransform); + void transformFromParent(const ChunkIndex& ci, TileUvTransform& uv) const; + /** Fetches all the needeed texture data from the GDAL dataset. */ @@ -105,6 +108,7 @@ namespace openspace { std::shared_ptr initializeTexture( std::shared_ptr uninitedTexture); + bool enqueueTileRequest(const ChunkIndex& ci); void clearRequestQueue(); diff --git a/modules/globebrowsing/rendering/patchrenderer.cpp b/modules/globebrowsing/rendering/patchrenderer.cpp index ac406d91cc..b99d87e7ce 100644 --- a/modules/globebrowsing/rendering/patchrenderer.cpp +++ b/modules/globebrowsing/rendering/patchrenderer.cpp @@ -172,7 +172,7 @@ namespace openspace { { auto tileProvider = it->second; // Get the texture that should be used for rendering - Tile tile = tileProvider->getMostHiResTile(chunk.index()); + Tile tile = tileProvider->getHighestResolutionTile(chunk.index()); TileDepthTransform depthTransform = tileProvider->depthTransform(); // The texture needs a unit to sample from @@ -206,7 +206,7 @@ namespace openspace { { auto tileProvider = it->second; // Get the texture that should be used for rendering - Tile tile = tileProvider->getMostHiResTile(chunk.index()); + Tile tile = tileProvider->getHighestResolutionTile(chunk.index()); // The texture needs a unit to sample from texUnitColor.activate(); @@ -271,7 +271,7 @@ namespace openspace { //auto tileProviderHeight = heightMapProviders.begin()->second; // Get the textures that should be used for rendering - Tile heightTile = tileProviderHeight->getMostHiResTile(chunk.index()); + Tile heightTile = tileProviderHeight->getHighestResolutionTile(chunk.index()); // Bind and use the texture @@ -291,7 +291,7 @@ namespace openspace { // Pick the first color texture auto colorTextureProviders = _tileProviderManager->colorTextureProviders(); auto tileProviderColor = colorTextureProviders.begin()->second; - Tile colorTile = tileProviderColor->getMostHiResTile(chunk.index()); + Tile colorTile = tileProviderColor->getHighestResolutionTile(chunk.index()); // Bind and use the texture @@ -364,7 +364,7 @@ namespace openspace { { auto tileProvider = it->second; // Get the texture that should be used for rendering - Tile tile = tileProvider->getMostHiResTile(chunk.index()); + Tile tile = tileProvider->getHighestResolutionTile(chunk.index()); TileDepthTransform depthTransform = tileProvider->depthTransform(); // The texture needs a unit to sample from @@ -398,7 +398,7 @@ namespace openspace { { auto tileProvider = it->second; // Get the texture that should be used for rendering - Tile tile = tileProvider->getMostHiResTile(chunk.index()); + Tile tile = tileProvider->getHighestResolutionTile(chunk.index()); // The texture needs a unit to sample from texUnitColor.activate(); @@ -502,7 +502,7 @@ namespace openspace { auto tileProviderHeight = heightMapProviders.begin()->second; // Get the textures that should be used for rendering - Tile heightTile = tileProviderHeight->getMostHiResTile(chunk.index()); + Tile heightTile = tileProviderHeight->getHighestResolutionTile(chunk.index()); // Bind and use the texture ghoul::opengl::TextureUnit texUnitHeight; @@ -519,7 +519,7 @@ namespace openspace { // Pick the first color texture auto colorTextureProviders = _tileProviderManager->colorTextureProviders(); auto tileProviderColor = colorTextureProviders.begin()->second; - Tile colorTile = tileProviderColor->getMostHiResTile(chunk.index()); + Tile colorTile = tileProviderColor->getHighestResolutionTile(chunk.index()); // Bind and use the texture