TileProvider serves tiles with highest available resolution and a corresponding translation and scaling, given a tileIndex

This commit is contained in:
Erik Broberg
2016-05-09 22:12:19 -04:00
parent a816b71a5a
commit f8d257b5bc
7 changed files with 118 additions and 45 deletions
@@ -135,6 +135,26 @@ struct GeodeticTileIndex {
return GeodeticTileIndex(x / 2, y / 2, level - 1);
}
bool isWestChild() const {
return x % 2 == 0;
}
bool isEastChild() const {
return x % 2 == 1;
}
bool isNorthChild() const {
return y % 2 == 0;
}
bool isSouthChild() const {
return y % 2 == 1;
}
bool hasParent() const {
return level > 0;
}
/**
Gets the tile at a specified offset from this tile.
Accepts delta indices ranging from [-2^level, Infinity[
@@ -146,7 +146,7 @@ namespace openspace {
for (int j = numLevelsToLoop; j >= 0; j--)
{
// Try if the texture exists
std::shared_ptr<Texture> tile = tileProvider->getTile(positiveTileIndex);
std::shared_ptr<Texture> tile = tileProvider->getOrStartFetchingTile(positiveTileIndex);
if (tile == nullptr)
{ // If it doesn't exist, go down a level
tileIndex.x /= 2;
@@ -165,7 +165,7 @@ namespace openspace {
if (patchCoverageToReturn.textureTransformPairs[linearIdx].first == nullptr)
{
patchCoverageToReturn.textureTransformPairs[linearIdx].first =
tileProvider->getTemporaryTexture();
tileProvider->getDefaultTexture();
patchCoverageToReturn.textureTransformPairs[linearIdx].second =
getUvTransformationPatchToTile(patch, tileIndex);
}
+47 -8
View File
@@ -55,17 +55,17 @@ namespace openspace {
{
// Set a temporary texture
std::string fileName = "textures/earth_bluemarble.jpg";
_tempTexture = std::move(ghoul::io::TextureReader::ref().loadTexture(absPath(fileName)));
_defaultTexture = std::move(ghoul::io::TextureReader::ref().loadTexture(absPath(fileName)));
if (_tempTexture) {
if (_defaultTexture) {
LDEBUG("Loaded texture from '" << fileName << "'");
_tempTexture->uploadTexture();
_defaultTexture->uploadTexture();
// Textures of planets looks much smoother with AnisotropicMipMap rather than linear
// TODO: AnisotropicMipMap crashes on ATI cards ---abock
//_testTexture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap);
_tempTexture->setFilter(ghoul::opengl::Texture::FilterMode::Linear);
_tempTexture->setWrapping(ghoul::opengl::Texture::WrappingMode::ClampToBorder);
_defaultTexture->setFilter(ghoul::opengl::Texture::FilterMode::Linear);
_defaultTexture->setWrapping(ghoul::opengl::Texture::WrappingMode::ClampToBorder);
}
@@ -105,7 +105,44 @@ namespace openspace {
}
}
std::shared_ptr<Texture> TileProvider::getTile(GeodeticTileIndex tileIndex) {
Tile TileProvider::getMostHiResTile(GeodeticTileIndex tileIndex) {
std::shared_ptr<Texture> tex = nullptr;
glm::vec2 uvOffset(0, 0);
glm::vec2 uvScale(1, 1);
while (true) {
tex = getOrStartFetchingTile(tileIndex);
if (tex != nullptr) {
break;
}
if (!tileIndex.hasParent()) {
tex = getDefaultTexture();
break;
}
// If we have a parent, calculate the UV offset and scale from the tileIndex
else {
uvScale *= 0.5;
uvOffset *= 0.5;
if (tileIndex.isEastChild()) {
uvOffset.x += 0.5;
}
// In OpenGL, positive y direction is up
if (tileIndex.isNorthChild()) {
uvOffset.y += 0.5;
}
tileIndex = tileIndex.parent();
}
}
return { tex, uvOffset, uvScale };
}
std::shared_ptr<Texture> TileProvider::getOrStartFetchingTile(GeodeticTileIndex tileIndex) {
HashKey hashkey = tileIndex.hashKey();
@@ -125,8 +162,10 @@ namespace openspace {
}
}
std::shared_ptr<Texture> TileProvider::getTemporaryTexture() {
return _tempTexture;
std::shared_ptr<Texture> TileProvider::getDefaultTexture() {
return _defaultTexture;
}
std::shared_ptr<UninitializedTextureTile> TileProvider::getUninitializedTextureTile(
+19 -8
View File
@@ -44,23 +44,34 @@
//////////////////////////////////////////////////////////////////////////////////////////
namespace openspace {
using namespace ghoul::opengl;
struct Tile {
std::shared_ptr<Texture> texture;
glm::vec2 uvOffset;
glm::vec2 uvScale;
};
/**
Provides tiles through GDAL datasets which can be defined with xml files
for example for wms.
*/
class TileProvider {
public:
TileProvider(
const std::string& fileName,
int tileCacheSize,
int minimumPixelsize);
TileProvider(const std::string& fileName, int tileCacheSize, int minimumPixelSize);
~TileProvider();
std::shared_ptr<Texture> getTile(GeodeticTileIndex tileIndex);
std::shared_ptr<Texture> getTemporaryTexture();
Tile getMostHiResTile(GeodeticTileIndex tileIndex);
std::shared_ptr<Texture> getOrStartFetchingTile(GeodeticTileIndex tileIndex);
std::shared_ptr<Texture> getDefaultTexture();
void prerender();
@@ -98,7 +109,7 @@ namespace openspace {
ConcurrentJobManager<UninitializedTextureTile> _tileLoadManager;
std::shared_ptr<Texture> _tempTexture;
std::shared_ptr<Texture> _defaultTexture;
int _minimumPixelSize;
};
@@ -108,9 +108,6 @@ namespace openspace {
const GeodeticTileIndex& tileIndex)
{
using namespace glm;
GeodeticPatch newPatch = patch;
// TODO : Model transform should be fetched as a matrix directly.
@@ -121,25 +118,24 @@ namespace openspace {
// activate shader
_programObjectGlobalRendering->activate();
// Get the textures that should be used for rendering
std::shared_ptr<ghoul::opengl::Texture> tile00;
// For now just pick the first one from height maps
auto heightMapProviders = _tileProviderManager->heightMapProviders();
auto tileProviderHeight = heightMapProviders.begin()->second;
tile00 = tileProviderHeight->getTile(tileIndex);
if (tile00 == nullptr) {
tile00 = tileProviderHeight->getTemporaryTexture();
}
// Get the textures that should be used for rendering
Tile heightTile = tileProviderHeight->getMostHiResTile(tileIndex);
// Bind and use the texture
ghoul::opengl::TextureUnit texUnitHeight;
texUnitHeight.activate();
tile00->bind();
heightTile.texture->bind();
_programObjectGlobalRendering->setUniform("textureSamplerHeight", texUnitHeight);
_programObjectGlobalRendering->setUniform("heightSamplingScale", heightTile.uvScale);
_programObjectGlobalRendering->setUniform("heightSamplingOffset", heightTile.uvOffset);
@@ -147,28 +143,23 @@ namespace openspace {
// Pick the first color texture
auto colorTextureProviders = _tileProviderManager->colorTextureProviders();
auto tileProviderColor = colorTextureProviders.begin()->second;
tile00 = tileProviderColor->getTile(tileIndex);
Tile colorTile = tileProviderColor->getMostHiResTile(tileIndex);
if (tile00 == nullptr) {
tile00 = tileProviderColor->getTemporaryTexture();
}
// Now we use the same shader as for clipmap rendering so this uv transform is needed
glm::mat3 uvTransformColor = glm::mat3(1);
// Bind and use the texture
ghoul::opengl::TextureUnit texUnitColor;
texUnitColor.activate();
tile00->bind();
colorTile.texture->bind();
_programObjectGlobalRendering->setUniform("textureSamplerColor", texUnitColor);
_programObjectGlobalRendering->setUniform("colorSamplingScale", colorTile.uvScale);
_programObjectGlobalRendering->setUniform("colorSamplingOffset", colorTile.uvOffset);
Geodetic2 swCorner = newPatch.southWestCorner();
Geodetic2 swCorner = patch.southWestCorner();
auto patchSize = patch.size();
_programObjectGlobalRendering->setUniform("modelViewProjectionTransform", modelViewProjectionTransform);
_programObjectGlobalRendering->setUniform("minLatLon", vec2(swCorner.toLonLatVec2()));
_programObjectGlobalRendering->setUniform("lonLatScalingFactor", vec2(newPatch.size().toLonLatVec2()));
_programObjectGlobalRendering->setUniform("lonLatScalingFactor", vec2(patchSize.toLonLatVec2()));
_programObjectGlobalRendering->setUniform("radiiSquared", vec3(ellipsoid.radiiSquared()));
glEnable(GL_DEPTH_TEST);
@@ -24,6 +24,8 @@
// Colortexture coverage
uniform sampler2D textureSamplerColor;
uniform vec2 colorSamplingScale;
uniform vec2 colorSamplingOffset;
in vec4 vs_position;
in vec3 fs_position;
@@ -46,8 +48,15 @@ vec4 borderOverlay(vec2 uv, vec3 borderColor, float borderSize){
Fragment getFragment() {
Fragment frag;
frag.color = texture(textureSamplerColor, fs_uv);
frag.color = 1*frag.color + borderOverlay(fs_uv, vec3(0.5, 0.5, 0.5), 0.01);
vec2 samplePos = colorSamplingScale*fs_uv + colorSamplingOffset;
frag.color = texture(textureSamplerColor, samplePos);
// Sample position overlay
//frag.color = frag.color * 0.9 + 0.2*vec4(samplePos, 0, 1);
// Border overlay
frag.color = frag.color + borderOverlay(fs_uv, vec3(0.5, 0.5, 0.5), 0.02);
frag.depth = vs_position.w;
return frag;
@@ -31,6 +31,8 @@ uniform vec2 minLatLon;
uniform vec2 lonLatScalingFactor;
uniform sampler2D textureSamplerHeight;
uniform vec2 heightSamplingScale;
uniform vec2 heightSamplingOffset;
layout(location = 1) in vec2 in_UV;
@@ -53,7 +55,8 @@ void main()
fs_uv = in_UV;
PositionNormalPair pair = globalInterpolation();
float sampledHeight = texture(textureSamplerHeight, in_UV).r;
vec2 samplePos = heightSamplingScale*in_UV + heightSamplingOffset;
float sampledHeight = texture(textureSamplerHeight, samplePos).r;
pair.position += pair.normal * sampledHeight * 1e1;
vec4 position = modelViewProjectionTransform * vec4(pair.position, 1);