mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-03-13 08:58:54 -05:00
TileProvider enqueues tiles at lower level first
This commit is contained in:
@@ -130,7 +130,9 @@ namespace openspace {
|
||||
else return DO_NOTHING;
|
||||
}
|
||||
|
||||
|
||||
void Chunk::render(const RenderData& data) const {
|
||||
_owner->getPatchRenderer().renderChunk(*this, data);
|
||||
}
|
||||
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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++;
|
||||
}
|
||||
|
||||
|
||||
@@ -135,90 +135,88 @@ namespace openspace {
|
||||
}
|
||||
|
||||
|
||||
Tile TileProvider::getMostHiResTile(ChunkIndex chunkIndex) {
|
||||
std::shared_ptr<Texture> 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<Texture> 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<TextureTileLoadJob> job = std::shared_ptr<TextureTileLoadJob>(
|
||||
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<TextureTileLoadJob> job = std::shared_ptr<TextureTileLoadJob>(
|
||||
new TextureTileLoadJob(this, chunkIndex));
|
||||
|
||||
_tileLoadManager.enqueueJob(job);
|
||||
|
||||
_queuedTileRequests.insert(key);
|
||||
}
|
||||
return !tileHasBeenQueued;
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::shared_ptr<Texture> TileProvider::getDefaultTexture() {
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace openspace {
|
||||
int framesUntilRequestFlush);
|
||||
~TileProvider();
|
||||
|
||||
Tile getMostHiResTile(ChunkIndex chunkIndex);
|
||||
Tile getHighestResolutionTile(ChunkIndex chunkIndex);
|
||||
|
||||
std::shared_ptr<Texture> getOrStartFetchingTile(ChunkIndex chunkIndex);
|
||||
std::shared_ptr<Texture> 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<Texture> initializeTexture(
|
||||
std::shared_ptr<UninitializedTextureTile> uninitedTexture);
|
||||
|
||||
bool enqueueTileRequest(const ChunkIndex& ci);
|
||||
|
||||
void clearRequestQueue();
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user