mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-05-04 09:59:44 -05:00
Testing simple global heightmapping using color textures.
This commit is contained in:
@@ -7,8 +7,23 @@ return {
|
||||
Type = "RenderableGlobe",
|
||||
Radii = {6378137.0, 6378137.0, 6356752.314245}, -- Earth's radii
|
||||
Textures = {
|
||||
Color = "textures/earth_bluemarble.jpg",
|
||||
}
|
||||
ColorTextures = {
|
||||
{
|
||||
Name = "BlueMarble",
|
||||
FilePath = "textures/earth_bluemarble.jpg",
|
||||
},
|
||||
{
|
||||
Name = "MODIS TERRA tileset",
|
||||
FilePath = "map_service_configs/TERRA_CR_B143_2016-04-12.wms",
|
||||
},
|
||||
},
|
||||
HightMaps = {
|
||||
{
|
||||
Name = "Terrain tileset",
|
||||
FilePath = "map_service_configs/TERRAIN.wms",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
GuiName = "/Solar/Planets/DebugGlobe"
|
||||
},
|
||||
|
||||
@@ -84,7 +84,7 @@ namespace openspace {
|
||||
// Covers all positive longitudes
|
||||
std::unique_ptr<ChunkNode> _rightRoot;
|
||||
|
||||
// Frustrum culler
|
||||
// Frustum culler
|
||||
std::shared_ptr<FrustumCuller> _frustumCuller;
|
||||
|
||||
// the patch used for actual rendering
|
||||
|
||||
@@ -50,9 +50,9 @@ namespace openspace {
|
||||
, _ellipsoid(ellipsoid)
|
||||
{
|
||||
// init Renderer
|
||||
auto outerPatchRenderer = new ClipMapPatchRenderer(shared_ptr<OuterClipMapGrid>(new OuterClipMapGrid(32)));
|
||||
auto outerPatchRenderer = new ClipMapPatchRenderer(shared_ptr<OuterClipMapGrid>(new OuterClipMapGrid(256)));
|
||||
_outerPatchRenderer.reset(outerPatchRenderer);
|
||||
auto innerPatchRenderer = new ClipMapPatchRenderer(shared_ptr<InnerClipMapGrid>(new InnerClipMapGrid(32)));
|
||||
auto innerPatchRenderer = new ClipMapPatchRenderer(shared_ptr<InnerClipMapGrid>(new InnerClipMapGrid(256)));
|
||||
_innerPatchRenderer.reset(innerPatchRenderer);
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,6 @@ namespace {
|
||||
|
||||
// Keys for the dictionary
|
||||
const std::string keyRadii = "Radii";
|
||||
const std::string keyHej = "hej";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
@@ -39,144 +39,144 @@
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
namespace {
|
||||
const std::string _loggerCat = "TextureTileSet";
|
||||
const std::string _loggerCat = "TextureTileSet";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
TextureTileSet::TextureTileSet(
|
||||
Geodetic2 sizeLevel0,
|
||||
Geodetic2 offsetLevel0,
|
||||
int depth)
|
||||
: _sizeLevel0(sizeLevel0)
|
||||
, _offsetLevel0(offsetLevel0)
|
||||
, _depth(depth)
|
||||
{
|
||||
|
||||
TextureTileSet::TextureTileSet(
|
||||
Geodetic2 sizeLevel0,
|
||||
Geodetic2 offsetLevel0,
|
||||
int depth)
|
||||
: _sizeLevel0(sizeLevel0)
|
||||
, _offsetLevel0(offsetLevel0)
|
||||
, _depth(depth)
|
||||
{
|
||||
|
||||
/*
|
||||
// Read using GDAL
|
||||
|
||||
// Read using GDAL
|
||||
std::string testFile = absPath("textures/earth_bluemarble.jpg");
|
||||
|
||||
std::string testFile = absPath("textures/earth_bluemarble.jpg");
|
||||
|
||||
GDALDataset *poDataset;
|
||||
GDALAllRegister();
|
||||
poDataset = (GDALDataset *)GDALOpen(testFile.c_str(), GA_ReadOnly);
|
||||
ghoul_assert(poDataset != NULL, "Unable to read dataset" << testFile);
|
||||
GdalDataConverter conv;
|
||||
|
||||
|
||||
GDALDataset *poDataset;
|
||||
GDALAllRegister();
|
||||
poDataset = (GDALDataset *)GDALOpen(testFile.c_str(), GA_ReadOnly);
|
||||
ghoul_assert(poDataset != NULL, "Unable to read dataset" << testFile);
|
||||
GdalDataConverter conv;
|
||||
TileIndex ti;
|
||||
ti.x = 0;
|
||||
ti.y = 0;
|
||||
ti.level = 0;
|
||||
_testTexture = conv.convertToOpenGLTexture(poDataset, ti, GL_UNSIGNED_BYTE);
|
||||
|
||||
TileIndex ti;
|
||||
ti.x = 0;
|
||||
ti.y = 0;
|
||||
ti.level = 0;
|
||||
_testTexture = conv.convertToOpenGLTexture(poDataset, ti, GL_UNSIGNED_BYTE);
|
||||
_testTexture->uploadTexture();
|
||||
_testTexture->setFilter(ghoul::opengl::Texture::FilterMode::Linear);
|
||||
*/
|
||||
|
||||
|
||||
// Set e texture to test
|
||||
std::string fileName = "textures/earth_bluemarble.jpg";
|
||||
//std::string fileName = "../../../build/tiles/tile5_8_12.png";
|
||||
//std::string fileName = "tile5_8_12.png";
|
||||
_testTexture = std::move(ghoul::io::TextureReader::ref().loadTexture(absPath(fileName)));
|
||||
|
||||
if (_testTexture) {
|
||||
LDEBUG("Loaded texture from '" << "textures/earth_bluemarble.jpg" << "'");
|
||||
_testTexture->uploadTexture();
|
||||
|
||||
_testTexture->uploadTexture();
|
||||
_testTexture->setFilter(ghoul::opengl::Texture::FilterMode::Linear);
|
||||
|
||||
/*
|
||||
|
||||
// Set e texture to test
|
||||
std::string fileName = "textures/earth_bluemarble.jpg";
|
||||
//std::string fileName = "../../../build/tiles/tile5_8_12.png";
|
||||
//std::string fileName = "tile5_8_12.png";
|
||||
_testTexture = std::move(ghoul::io::TextureReader::ref().loadTexture(absPath(fileName)));
|
||||
|
||||
if (_testTexture) {
|
||||
LDEBUG("Loaded texture from '" << "textures/earth_bluemarble.jpg" << "'");
|
||||
_testTexture->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);
|
||||
_testTexture->setFilter(ghoul::opengl::Texture::FilterMode::Linear);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 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);
|
||||
_testTexture->setFilter(ghoul::opengl::Texture::FilterMode::Linear);
|
||||
}
|
||||
*/
|
||||
}
|
||||
TextureTileSet::~TextureTileSet(){
|
||||
|
||||
TextureTileSet::~TextureTileSet(){
|
||||
}
|
||||
|
||||
}
|
||||
TileIndex TextureTileSet::getTileIndex(GeodeticPatch patch) {
|
||||
// Calculate the level of the index depanding on the size of the incoming patch.
|
||||
// The level is as big as possible (as far down as possible) but it can't be
|
||||
// too big since at maximum four tiles should be used to cover a patch
|
||||
int level = log2(static_cast<int>(glm::max(
|
||||
_sizeLevel0.lat / (patch.size().lat),
|
||||
_sizeLevel0.lon / (patch.size().lon))));
|
||||
|
||||
// If the depth is not big enough, the level must be clamped.
|
||||
level = glm::min(level, _depth);
|
||||
|
||||
// Calculate the index in x y where the tile should be positioned
|
||||
Vec2 tileSize = _sizeLevel0.toLonLatVec2() / pow(2, level);
|
||||
Vec2 nw = patch.northWestCorner().toLonLatVec2();
|
||||
Vec2 offset = _offsetLevel0.toLonLatVec2();
|
||||
glm::ivec2 tileIndexXY = (nw - offset) / tileSize;
|
||||
|
||||
TileIndex TextureTileSet::getTileIndex(GeodeticPatch patch) {
|
||||
// Calculate the level of the index depanding on the size of the incoming patch.
|
||||
// The level is as big as possible (as far down as possible) but it can't be
|
||||
// too big since at maximum four tiles should be used to cover a patch
|
||||
int level = log2(static_cast<int>(glm::max(
|
||||
_sizeLevel0.lat / (patch.size().lat),
|
||||
_sizeLevel0.lon / (patch.size().lon))));
|
||||
|
||||
// If the depth is not big enough, the level must be clamped.
|
||||
level = glm::min(level, _depth);
|
||||
|
||||
// Calculate the index in x y where the tile should be positioned
|
||||
Vec2 tileSize = _sizeLevel0.toLonLatVec2() / pow(2, level);
|
||||
Vec2 nw = patch.northWestCorner().toLonLatVec2();
|
||||
Vec2 offset = _offsetLevel0.toLonLatVec2();
|
||||
glm::ivec2 tileIndexXY = (nw - offset) / tileSize;
|
||||
// Flip y since indices increase from top to bottom
|
||||
tileIndexXY.y *= -1;
|
||||
|
||||
// Flip y since indices increase from top to bottom
|
||||
tileIndexXY.y *= -1;
|
||||
// Create the tileindex
|
||||
TileIndex tileIndex = { tileIndexXY.x, tileIndexXY.y, level };
|
||||
return tileIndex;
|
||||
}
|
||||
|
||||
// Create the tileindex
|
||||
TileIndex tileIndex = { tileIndexXY.x, tileIndexXY.y, level };
|
||||
return tileIndex;
|
||||
}
|
||||
std::shared_ptr<Texture> TextureTileSet::getTile(GeodeticPatch patch) {
|
||||
return getTile(getTileIndex(patch));
|
||||
}
|
||||
|
||||
std::shared_ptr<Texture> TextureTileSet::getTile(GeodeticPatch patch) {
|
||||
return getTile(getTileIndex(patch));
|
||||
}
|
||||
std::shared_ptr<Texture> TextureTileSet::getTile(const TileIndex& tileIndex) {
|
||||
return _testTexture;
|
||||
}
|
||||
|
||||
std::shared_ptr<Texture> TextureTileSet::getTile(const TileIndex& tileIndex) {
|
||||
return _testTexture;
|
||||
}
|
||||
GeodeticPatch TextureTileSet::getTilePositionAndScale(
|
||||
const TileIndex& tileIndex) {
|
||||
Geodetic2 tileSize = Geodetic2(
|
||||
_sizeLevel0.lat / pow(2, tileIndex.level),
|
||||
_sizeLevel0.lon / pow(2, tileIndex.level));
|
||||
Geodetic2 northWest = Geodetic2(
|
||||
_offsetLevel0.lat + tileIndex.y * tileSize.lat,
|
||||
_offsetLevel0.lon + tileIndex.x * tileSize.lon);
|
||||
|
||||
return GeodeticPatch(
|
||||
Geodetic2(northWest.lat - tileSize.lat / 2, northWest.lon + tileSize.lon / 2),
|
||||
Geodetic2(tileSize.lat / 2, tileSize.lon / 2));
|
||||
}
|
||||
|
||||
GeodeticPatch TextureTileSet::getTilePositionAndScale(
|
||||
const TileIndex& tileIndex) {
|
||||
Geodetic2 tileSize = Geodetic2(
|
||||
_sizeLevel0.lat / pow(2, tileIndex.level),
|
||||
_sizeLevel0.lon / pow(2, tileIndex.level));
|
||||
Geodetic2 northWest = Geodetic2(
|
||||
_offsetLevel0.lat + tileIndex.y * tileSize.lat,
|
||||
_offsetLevel0.lon + tileIndex.x * tileSize.lon);
|
||||
|
||||
return GeodeticPatch(
|
||||
Geodetic2(northWest.lat - tileSize.lat / 2, northWest.lon + tileSize.lon / 2),
|
||||
Geodetic2(tileSize.lat / 2, tileSize.lon / 2));
|
||||
}
|
||||
glm::mat3 TextureTileSet::getUvTransformationPatchToTile(
|
||||
GeodeticPatch patch,
|
||||
const TileIndex& tileIndex)
|
||||
{
|
||||
GeodeticPatch tile = getTilePositionAndScale(tileIndex);
|
||||
return getUvTransformationPatchToTile(patch, tile);
|
||||
}
|
||||
|
||||
glm::mat3 TextureTileSet::getUvTransformationPatchToTile(
|
||||
GeodeticPatch patch,
|
||||
const TileIndex& tileIndex)
|
||||
{
|
||||
GeodeticPatch tile = getTilePositionAndScale(tileIndex);
|
||||
return getUvTransformationPatchToTile(patch, tile);
|
||||
}
|
||||
glm::mat3 TextureTileSet::getUvTransformationPatchToTile(
|
||||
GeodeticPatch patch,
|
||||
GeodeticPatch tile)
|
||||
{
|
||||
Vec2 posDiff =
|
||||
patch.southWestCorner().toLonLatVec2() -
|
||||
tile.southWestCorner().toLonLatVec2();
|
||||
|
||||
glm::mat3 TextureTileSet::getUvTransformationPatchToTile(
|
||||
GeodeticPatch patch,
|
||||
GeodeticPatch tile)
|
||||
{
|
||||
Vec2 posDiff =
|
||||
patch.southWestCorner().toLonLatVec2() -
|
||||
tile.southWestCorner().toLonLatVec2();
|
||||
glm::mat3 invTileScale = glm::mat3(
|
||||
{ 1 / (tile.halfSize().lon * 2), 0, 0,
|
||||
0, 1 / (tile.halfSize().lat * 2), 0,
|
||||
0, 0, 1 });
|
||||
|
||||
glm::mat3 invTileScale = glm::mat3(
|
||||
{ 1 / (tile.halfSize().lon * 2), 0, 0,
|
||||
0, 1 / (tile.halfSize().lat * 2), 0,
|
||||
0, 0, 1 });
|
||||
glm::mat3 globalTranslation = glm::mat3(
|
||||
{ 1, 0, 0,
|
||||
0, 1, 0,
|
||||
posDiff.x, posDiff.y, 1 });
|
||||
|
||||
glm::mat3 globalTranslation = glm::mat3(
|
||||
{ 1, 0, 0,
|
||||
0, 1, 0,
|
||||
posDiff.x, posDiff.y, 1 });
|
||||
glm::mat3 patchScale = glm::mat3(
|
||||
{ (patch.halfSize().lon * 2), 0, 0,
|
||||
0, (patch.halfSize().lat * 2), 0,
|
||||
0, 0, 1 });
|
||||
|
||||
glm::mat3 patchScale = glm::mat3(
|
||||
{ (patch.halfSize().lon * 2), 0, 0,
|
||||
0, (patch.halfSize().lat * 2), 0,
|
||||
0, 0, 1 });
|
||||
|
||||
return invTileScale * globalTranslation * patchScale;
|
||||
}
|
||||
return invTileScale * globalTranslation * patchScale;
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -31,13 +31,25 @@ uniform vec2 minLatLon;
|
||||
uniform vec2 lonLatScalingFactor;
|
||||
uniform ivec2 contraction; // [-1, 1]
|
||||
|
||||
uniform mat3 uvTransformPatchToTile;
|
||||
|
||||
uniform int segmentsPerPatch;
|
||||
|
||||
uniform sampler2D textureSampler;
|
||||
|
||||
layout(location = 1) in vec2 in_uv;
|
||||
|
||||
out vec4 vs_position;
|
||||
out vec2 vs_uv;
|
||||
out vec3 fs_position;
|
||||
out vec2 fs_uv;
|
||||
|
||||
#include "PowerScaling/powerScaling_vs.hglsl"
|
||||
|
||||
struct PositionNormalPair {
|
||||
vec3 position;
|
||||
vec3 normal;
|
||||
};
|
||||
|
||||
vec3 geodeticSurfaceNormal(float latitude, float longitude)
|
||||
{
|
||||
float cosLat = cos(latitude);
|
||||
@@ -47,7 +59,7 @@ vec3 geodeticSurfaceNormal(float latitude, float longitude)
|
||||
sin(latitude));
|
||||
}
|
||||
|
||||
vec3 geodetic3ToCartesian(
|
||||
PositionNormalPair geodetic3ToCartesian(
|
||||
float latitude,
|
||||
float longitude,
|
||||
float height,
|
||||
@@ -57,10 +69,13 @@ vec3 geodetic3ToCartesian(
|
||||
vec3 k = radiiSquared * normal;
|
||||
float gamma = sqrt(dot(k, normal));
|
||||
vec3 rSurface = k / gamma;
|
||||
return rSurface + height * normal;
|
||||
PositionNormalPair toReturn;
|
||||
toReturn.position = rSurface + height * normal;
|
||||
toReturn.normal = normal;
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
vec3 geodetic2ToCartesian(float latitude, float longitude, vec3 radiiSquared)
|
||||
PositionNormalPair geodetic2ToCartesian(float latitude, float longitude, vec3 radiiSquared)
|
||||
{
|
||||
// Position on surface : height = 0
|
||||
return geodetic3ToCartesian(latitude, longitude, 0, radiiSquared);
|
||||
@@ -73,26 +88,32 @@ vec3 latLonToCartesian(float latitude, float longitude, float radius) {
|
||||
sin(latitude));
|
||||
}
|
||||
|
||||
vec3 globalInterpolation(vec2 uv) {
|
||||
PositionNormalPair globalInterpolation(vec2 uv) {
|
||||
vec2 lonLatInput;
|
||||
lonLatInput.y = minLatLon.y + lonLatScalingFactor.y * uv.y; // Lat
|
||||
lonLatInput.x = minLatLon.x + lonLatScalingFactor.x * uv.x; // Lon
|
||||
vec3 positionModelSpace = geodetic2ToCartesian(lonLatInput.y, lonLatInput.x, radiiSquared);// latLonToCartesian(lonLatInput.y, lonLatInput.x, globeRadius);
|
||||
return positionModelSpace;
|
||||
return geodetic2ToCartesian(lonLatInput.y, lonLatInput.x, radiiSquared);;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vs_uv = in_uv;
|
||||
fs_uv = in_uv;
|
||||
|
||||
vec2 scaledContraction = contraction / 32.0f;
|
||||
vs_uv += scaledContraction;
|
||||
vs_uv = clamp(vs_uv, 0, 1);
|
||||
vs_uv -= scaledContraction;
|
||||
// Contract
|
||||
vec2 scaledContraction = contraction / float(segmentsPerPatch);
|
||||
fs_uv += scaledContraction;
|
||||
fs_uv = clamp(fs_uv, 0, 1);
|
||||
fs_uv -= scaledContraction;
|
||||
|
||||
vec3 p = globalInterpolation(vs_uv);
|
||||
PositionNormalPair pair = globalInterpolation(fs_uv);
|
||||
|
||||
vec4 position = modelViewProjectionTransform * vec4(p, 1);
|
||||
vs_position = z_normalization(position);
|
||||
gl_Position = vs_position;
|
||||
vec4 textureColor = texture(textureSampler, vec2(uvTransformPatchToTile * vec3(fs_uv.s, fs_uv.t, 1)));
|
||||
|
||||
pair.position += pair.normal * textureColor.r * 3e4;
|
||||
|
||||
vec4 position = modelViewProjectionTransform * vec4(pair.position, 1);
|
||||
fs_position = pair.position;
|
||||
|
||||
gl_Position = z_normalization(position);
|
||||
vs_position = gl_Position;
|
||||
}
|
||||
@@ -33,7 +33,7 @@ uniform vec2 lonLatScalingFactor;
|
||||
layout(location = 1) in vec2 in_UV;
|
||||
|
||||
out vec4 vs_position;
|
||||
out vec2 vs_uv;
|
||||
out vec2 fs_uv;
|
||||
|
||||
#include "PowerScaling/powerScaling_vs.hglsl"
|
||||
|
||||
@@ -83,7 +83,7 @@ vec3 globalInterpolation() {
|
||||
|
||||
void main()
|
||||
{
|
||||
vs_uv = in_UV;
|
||||
fs_uv = in_UV;
|
||||
vec3 p = globalInterpolation();
|
||||
|
||||
vec4 position = modelViewProjectionTransform * vec4(p, 1);
|
||||
|
||||
@@ -41,7 +41,8 @@ uniform mat3 uvTransformPatchToTile;
|
||||
uniform int segmentsPerPatch;
|
||||
|
||||
in vec4 vs_position;
|
||||
in vec2 vs_uv;
|
||||
in vec3 fs_position;
|
||||
in vec2 fs_uv;
|
||||
|
||||
|
||||
#include "PowerScaling/powerScaling_fs.hglsl"
|
||||
@@ -50,13 +51,13 @@ in vec2 vs_uv;
|
||||
Fragment getFragment() {
|
||||
Fragment frag;
|
||||
|
||||
frag.color = texture(textureSampler, vec2(uvTransformPatchToTile * vec3(vs_uv.s, vs_uv.t, 1)));
|
||||
//frag.color = frag.color * 0.5 + 0.999*texture(textureSampler, vs_uv);
|
||||
frag.color = texture(textureSampler, vec2(uvTransformPatchToTile * vec3(fs_uv.s, fs_uv.t, 1)));
|
||||
//frag.color = frag.color * 0.5 + 0.999*texture(textureSampler, fs_uv);
|
||||
|
||||
vec4 uvColor = vec4(fract(vs_uv * segmentsPerPatch), 0.4,1);
|
||||
vec4 uvColor = vec4(fract(fs_uv * segmentsPerPatch), 0.4,1);
|
||||
frag.color = frag.color.a < 0.1 ? uvColor * 0.5 : frag.color;
|
||||
|
||||
frag.depth = pscDepth(vs_position);
|
||||
frag.depth = vs_position.w;
|
||||
|
||||
return frag;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user