TileProvider enqueues tiles at lower level first

This commit is contained in:
Erik Broberg
2016-05-16 19:10:39 -04:00
parent 33d1d1a31d
commit 025a221df2
6 changed files with 86 additions and 81 deletions

View File

@@ -130,7 +130,9 @@ namespace openspace {
else return DO_NOTHING;
}
void Chunk::render(const RenderData& data) const {
_owner->getPatchRenderer().renderChunk(*this, data);
}
} // namespace openspace

View File

@@ -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;

View File

@@ -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++;
}

View File

@@ -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() {

View File

@@ -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();

View File

@@ -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