mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-04-23 20:50:59 -05:00
TileProvider serves tiles with highest available resolution and a corresponding translation and scaling, given a tileIndex
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user