mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-07 20:21:24 -06:00
Generalize gdaldataconverter so it can handle any data type.
This commit is contained in:
@@ -2,14 +2,7 @@
|
||||
<Service name="TiledWMS">
|
||||
<ServerUrl>http://map1.vis.earthdata.nasa.gov/twms-geo/twms.cgi?</ServerUrl>
|
||||
<TiledGroupName>MODIS TERRA tileset</TiledGroupName>
|
||||
<Change key="${time}">2016-04-27</Change>
|
||||
<Change key="${time}">2016-04-12</Change>
|
||||
</Service>
|
||||
<DataWindow>
|
||||
<UpperLeftX>-180.0</UpperLeftX>
|
||||
<UpperLeftY>90.0</UpperLeftY>
|
||||
<LowerRightX>180.0</LowerRightX>
|
||||
<LowerRightY>-90.0</LowerRightY>
|
||||
<YOrigin>bottom</YOrigin>
|
||||
</DataWindow>
|
||||
<MaxConnections>20</MaxConnections>
|
||||
</GDAL_WMS>
|
||||
|
||||
@@ -82,7 +82,7 @@ set(SOURCE_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/texturetileset.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/patchcoverageprovider.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/tileprovider.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/gdaldataconverter.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/gdaldataconverter.inl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/lrucache.inl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/concurrentjobmanager.inl
|
||||
|
||||
|
||||
@@ -49,7 +49,8 @@ namespace openspace {
|
||||
: _clipMapPyramid(Geodetic2(M_PI / 2, M_PI / 2))
|
||||
, _ellipsoid(ellipsoid)
|
||||
{
|
||||
_tileProvider = shared_ptr<TileProvider>(new TileProvider("map_service_configs/TERRAIN.wms", 100));
|
||||
_tileProvider = shared_ptr<TileProvider>(new TileProvider(
|
||||
"map_service_configs/TERRAIN.wms", 100));
|
||||
// init Renderer
|
||||
auto outerPatchRenderer = new ClipMapPatchRenderer(
|
||||
shared_ptr<OuterClipMapGrid>(new OuterClipMapGrid(512)),
|
||||
|
||||
@@ -36,24 +36,11 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
namespace openspace {
|
||||
using namespace ghoul::opengl;
|
||||
|
||||
// forward declaration
|
||||
class GeodeticTileIndex;
|
||||
//class Geodetic2;
|
||||
|
||||
class GdalDataConverter
|
||||
{
|
||||
public:
|
||||
GdalDataConverter();
|
||||
~GdalDataConverter();
|
||||
|
||||
std::shared_ptr<Texture> convertToOpenGLTexture(
|
||||
GDALDataset* dataSet,
|
||||
const GeodeticTileIndex& tileIndex,
|
||||
int GLType);
|
||||
struct UninitializedTextureTile {
|
||||
|
||||
struct TextureFormat
|
||||
{
|
||||
@@ -61,17 +48,49 @@ namespace openspace {
|
||||
GLuint glFormat;
|
||||
};
|
||||
|
||||
struct TextureDataType
|
||||
UninitializedTextureTile(
|
||||
void* data,
|
||||
glm::uvec3 dims,
|
||||
TextureFormat format,
|
||||
GLuint glType,
|
||||
const GeodeticTileIndex& ti)
|
||||
: imageData(data)
|
||||
, dimensions(dims)
|
||||
, texFormat(format)
|
||||
, glType(glType)
|
||||
, tileIndex(ti)
|
||||
{
|
||||
Texture::Format ghoulFormat;
|
||||
GLuint glFormat;
|
||||
};
|
||||
|
||||
TextureFormat getTextureFormatFromRasterCount(int rasterCount);
|
||||
}
|
||||
|
||||
void* imageData;
|
||||
glm::uvec3 dimensions;
|
||||
TextureFormat texFormat;
|
||||
GLuint glType;
|
||||
const GeodeticTileIndex tileIndex;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class GdalDataConverter
|
||||
{
|
||||
public:
|
||||
|
||||
GdalDataConverter();
|
||||
~GdalDataConverter();
|
||||
|
||||
std::shared_ptr<UninitializedTextureTile> getUninitializedTextureTile(
|
||||
GDALDataset * dataSet,
|
||||
const GeodeticTileIndex & tileIndex);
|
||||
|
||||
UninitializedTextureTile::TextureFormat getTextureFormatFromRasterCount(
|
||||
int rasterCount);
|
||||
GLuint getGlDataTypeFromGdalDataType(GDALDataType gdalType);
|
||||
|
||||
glm::uvec2 geodeticToPixel(GDALDataset* dataSet, const Geodetic2& geo);
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#include <modules/globebrowsing/other/gdaldataconverter.inl>
|
||||
|
||||
#endif // __GDALDATACONVERTER_H__
|
||||
@@ -27,92 +27,106 @@
|
||||
#include <modules/globebrowsing/other/tileprovider.h>
|
||||
#include <modules/globebrowsing/geodetics/angle.h>
|
||||
|
||||
namespace {
|
||||
const std::string _loggerCat = "GdalDataConverter";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
GdalDataConverter::GdalDataConverter()
|
||||
template<class T>
|
||||
GdalDataConverter<T>::GdalDataConverter()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
GdalDataConverter::~GdalDataConverter()
|
||||
template<class T>
|
||||
GdalDataConverter<T>::~GdalDataConverter()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::shared_ptr<Texture> GdalDataConverter::convertToOpenGLTexture(
|
||||
template<class T>
|
||||
std::shared_ptr<UninitializedTextureTile> GdalDataConverter<T>::getUninitializedTextureTile(
|
||||
GDALDataset* dataSet,
|
||||
const GeodeticTileIndex& tileIndex,
|
||||
int GLType)
|
||||
{
|
||||
const GeodeticTileIndex& tileIndex) {
|
||||
int nRasters = dataSet->GetRasterCount();
|
||||
|
||||
ghoul_assert(nRasters > 0, "Bad dataset. Contains no rasterband.");
|
||||
|
||||
GDALRasterBand* firstBand = dataSet->GetRasterBand(1);
|
||||
// Assume all raster bands have the same data type
|
||||
GDALDataType gdalType = firstBand->GetRasterDataType();
|
||||
|
||||
// Level = overviewCount - overview
|
||||
int overviewCount = firstBand->GetOverviewCount();
|
||||
int overview = overviewCount - tileIndex.level - 1;
|
||||
int numOverviews = firstBand->GetOverviewCount();
|
||||
|
||||
// The output texture will have this size
|
||||
int xSizelevel0 = firstBand->GetOverview(overviewCount - 1)->GetXSize();
|
||||
int ySizelevel0 = firstBand->GetOverview(overviewCount - 1)->GetYSize();
|
||||
int xSize0 = firstBand->GetXSize();
|
||||
int ySize0 = firstBand->GetYSize();
|
||||
|
||||
GeodeticPatch patch = GeodeticPatch(tileIndex);
|
||||
glm::uvec2 pixelStart0 = geodeticToPixel(dataSet, patch.northWestCorner());
|
||||
glm::uvec2 pixelEnd0 = geodeticToPixel(dataSet, patch.southEastCorner());
|
||||
glm::uvec2 numberOfPixels0 = pixelEnd0 - pixelStart0;
|
||||
|
||||
|
||||
int minNumPixels0 = glm::min(numberOfPixels0.x, numberOfPixels0.y);
|
||||
|
||||
int minNumPixelsRequired = 512;
|
||||
int ov = log2(minNumPixels0) - log2(minNumPixelsRequired + 1);
|
||||
|
||||
// The data that the texture should read
|
||||
GLubyte* imageData = new GLubyte[xSizelevel0 * ySizelevel0 * nRasters];
|
||||
ov = glm::clamp(ov, 0, numOverviews - 1);
|
||||
|
||||
glm::uvec2 pixelStart(pixelStart0.x >> (ov + 1), pixelStart0.y >> (ov + 1));
|
||||
glm::uvec2 numberOfPixels(numberOfPixels0.x >> (ov + 1), numberOfPixels0.y >> (ov + 1));
|
||||
|
||||
// GDAL reads image data top to bottom
|
||||
T* imageData = new T[numberOfPixels.x * numberOfPixels.y * nRasters];
|
||||
|
||||
// Read the data (each rasterband is a separate channel)
|
||||
for (size_t i = 0; i < nRasters; i++)
|
||||
{
|
||||
GDALRasterBand* rasterBand = dataSet->GetRasterBand(i + 1)->GetOverview(overview);
|
||||
|
||||
int xBeginRead = tileIndex.x * pow(2, tileIndex.level) * xSizelevel0;
|
||||
int yBeginRead = tileIndex.y * pow(2, tileIndex.level) * ySizelevel0;
|
||||
for (size_t i = 0; i < nRasters; i++) {
|
||||
GDALRasterBand* rasterBand = dataSet->GetRasterBand(i + 1)->GetOverview(ov);
|
||||
|
||||
int xSize = rasterBand->GetXSize();
|
||||
int ySize = rasterBand->GetYSize();
|
||||
|
||||
rasterBand->RasterIO(
|
||||
GF_Read,
|
||||
xBeginRead, // Begin read x
|
||||
yBeginRead, // Begin read y
|
||||
xSizelevel0, // width to read x
|
||||
ySizelevel0, // width to read y
|
||||
imageData + i, // Where to put data
|
||||
xSizelevel0, // width to read x in destination
|
||||
ySizelevel0, // width to read y in destination
|
||||
GDT_Byte, // Type
|
||||
sizeof(GLubyte) * nRasters, // Pixel spacing
|
||||
0); // Line spacing
|
||||
pixelStart.x, // Begin read x
|
||||
pixelStart.y, // Begin read y
|
||||
numberOfPixels.x, // width to read x
|
||||
numberOfPixels.y, // width to read y
|
||||
imageData + i, // Where to put data
|
||||
numberOfPixels.x, // width to write x in destination
|
||||
numberOfPixels.y, // width to write y in destination
|
||||
gdalType, // Type
|
||||
sizeof(T) * nRasters, // Pixel spacing
|
||||
0); // Line spacing
|
||||
}
|
||||
|
||||
GdalDataConverter::TextureFormat textrureFormat =
|
||||
// GDAL reads image data top to bottom. We want the opposite.
|
||||
T* imageDataYflipped = new T[numberOfPixels.x * numberOfPixels.y * nRasters];
|
||||
for (size_t y = 0; y < numberOfPixels.y; y++) {
|
||||
for (size_t x = 0; x < numberOfPixels.x; x++) {
|
||||
imageDataYflipped[x + y * numberOfPixels.x] =
|
||||
imageData[x + (numberOfPixels.y - y) * numberOfPixels.x];
|
||||
}
|
||||
}
|
||||
|
||||
delete[] imageData;
|
||||
|
||||
glm::uvec3 dims(numberOfPixels.x, numberOfPixels.y, 1);
|
||||
UninitializedTextureTile::TextureFormat textrureFormat =
|
||||
getTextureFormatFromRasterCount(nRasters);
|
||||
|
||||
|
||||
Texture* tex = new Texture(
|
||||
static_cast<void*>(imageData),
|
||||
glm::uvec3(xSizelevel0, ySizelevel0, 1),
|
||||
textrureFormat.ghoulFormat,
|
||||
textrureFormat.glFormat,
|
||||
GL_UNSIGNED_BYTE,
|
||||
Texture::FilterMode::Linear,
|
||||
Texture::WrappingMode::Repeat);
|
||||
|
||||
// The texture should take ownership of the data
|
||||
std::shared_ptr<Texture> texture = std::shared_ptr<Texture>(tex);
|
||||
|
||||
|
||||
// Do not free imageData since the texture now has ownership of it
|
||||
return texture;
|
||||
GLuint glType = getGlDataTypeFromGdalDataType(gdalType);
|
||||
UninitializedTextureTile* uninitedTexPtr = new UninitializedTextureTile(
|
||||
imageDataYflipped,
|
||||
dims,
|
||||
textrureFormat,
|
||||
glType,
|
||||
tileIndex);
|
||||
std::shared_ptr<UninitializedTextureTile> uninitedTex =
|
||||
std::shared_ptr<UninitializedTextureTile>(uninitedTexPtr);
|
||||
return uninitedTex;
|
||||
}
|
||||
|
||||
|
||||
|
||||
glm::uvec2 GdalDataConverter::geodeticToPixel(GDALDataset* dataSet, const Geodetic2& geo) {
|
||||
template<class T>
|
||||
glm::uvec2 GdalDataConverter<T>::geodeticToPixel(GDALDataset* dataSet, const Geodetic2& geo) {
|
||||
double padfTransform[6];
|
||||
CPLErr err = dataSet->GetGeoTransform(padfTransform);
|
||||
|
||||
@@ -140,19 +154,17 @@ namespace openspace {
|
||||
double L = (-a[0]*b[1] + a[1]*b[0] - a[1]*Y + b[1]*X) / divisor;
|
||||
// ref: https://www.wolframalpha.com/input/?i=X+%3D+a0+%2B+a1P+%2B+a2L,+Y+%3D+b0+%2B+b1P+%2B+b2L,+solve+for+P+and+L
|
||||
|
||||
|
||||
double Xp = a[0] + P*a[1] + L*a[2];
|
||||
double Yp = b[0] + P*b[1] + L*b[2];
|
||||
|
||||
return glm::uvec2(P, L);
|
||||
}
|
||||
|
||||
|
||||
|
||||
GdalDataConverter::TextureFormat GdalDataConverter::getTextureFormatFromRasterCount(
|
||||
template<class T>
|
||||
UninitializedTextureTile::TextureFormat GdalDataConverter<T>::getTextureFormatFromRasterCount(
|
||||
int rasterCount)
|
||||
{
|
||||
TextureFormat format;
|
||||
UninitializedTextureTile::TextureFormat format;
|
||||
|
||||
switch (rasterCount)
|
||||
{
|
||||
@@ -173,10 +185,42 @@ namespace openspace {
|
||||
format.glFormat = GL_RGBA;
|
||||
break;
|
||||
default:
|
||||
|
||||
LERROR("Too many channels for OpenGL.");
|
||||
break;
|
||||
}
|
||||
return format;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
GLuint GdalDataConverter<T>::getGlDataTypeFromGdalDataType(GDALDataType gdalType)
|
||||
{
|
||||
switch (gdalType)
|
||||
{
|
||||
case GDT_Byte:
|
||||
return GL_BYTE;
|
||||
break;
|
||||
case GDT_UInt16:
|
||||
return GL_UNSIGNED_SHORT;
|
||||
break;
|
||||
case GDT_Int16:
|
||||
return GL_SHORT;
|
||||
break;
|
||||
case GDT_UInt32:
|
||||
return GL_UNSIGNED_INT;
|
||||
break;
|
||||
case GDT_Int32:
|
||||
return GL_INT;
|
||||
break;
|
||||
case GDT_Float32:
|
||||
return GL_FLOAT;
|
||||
break;
|
||||
case GDT_Float64:
|
||||
return GL_DOUBLE;
|
||||
break;
|
||||
default:
|
||||
LERROR("GDAL data type unknown to OpenGL: " << gdalType);
|
||||
return GL_UNSIGNED_BYTE;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
@@ -52,7 +52,7 @@ namespace openspace {
|
||||
, _offsetLevel0(offsetLevel0)
|
||||
, _depth(depth)
|
||||
{
|
||||
|
||||
/*
|
||||
|
||||
|
||||
// Read using GDAL
|
||||
@@ -76,7 +76,7 @@ namespace openspace {
|
||||
_testTexture->uploadTexture();
|
||||
_testTexture->setFilter(ghoul::opengl::Texture::FilterMode::Linear);
|
||||
|
||||
|
||||
*/
|
||||
/*
|
||||
// Set e texture to test
|
||||
std::string fileName = "textures/earth_bluemarble.jpg";
|
||||
|
||||
@@ -51,7 +51,9 @@ namespace openspace {
|
||||
{
|
||||
int downloadApplicationVersion = 1;
|
||||
if (!DownloadManager::isInitialized()) {
|
||||
DownloadManager::initialize("../tmp_openspace_downloads/", downloadApplicationVersion);
|
||||
DownloadManager::initialize(
|
||||
"../tmp_openspace_downloads/",
|
||||
downloadApplicationVersion);
|
||||
}
|
||||
|
||||
if (!hasInitializedGDAL) {
|
||||
@@ -64,25 +66,23 @@ namespace openspace {
|
||||
//auto desc = _gdalDataSet->GetDescription();
|
||||
|
||||
ghoul_assert(_gdalDataSet != nullptr, "Failed to load dataset: " << filePath);
|
||||
|
||||
}
|
||||
|
||||
TileProvider::~TileProvider(){
|
||||
delete _gdalDataSet;
|
||||
}
|
||||
|
||||
|
||||
void TileProvider::prerender() {
|
||||
while (_tileLoadManager.numFinishedJobs() > 0) {
|
||||
auto finishedJob = _tileLoadManager.popFinishedJob();
|
||||
std::shared_ptr<UninitializedTextureTile> uninitedTex = finishedJob->product();
|
||||
std::shared_ptr<UninitializedTextureTile> uninitedTex =
|
||||
finishedJob->product();
|
||||
HashKey key = uninitedTex->tileIndex.hashKey();
|
||||
std::shared_ptr<Texture> texture = initializeTexture(uninitedTex);
|
||||
_tileCache.put(key, texture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<Texture> TileProvider::getTile(const GeodeticTileIndex& tileIndex) {
|
||||
HashKey hashkey = tileIndex.hashKey();
|
||||
|
||||
@@ -102,101 +102,60 @@ namespace openspace {
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<UninitializedTextureTile> TileProvider::getUninitializedTextureTile(
|
||||
const GeodeticTileIndex& tileIndex) {
|
||||
|
||||
// We assume here that all rasterbands have the same data type
|
||||
GDALDataType gdalType = _gdalDataSet->GetRasterBand(1)->GetRasterDataType();
|
||||
|
||||
|
||||
|
||||
|
||||
std::shared_ptr<UninitializedTextureTile> TileProvider::getUninitializedTextureTile(const GeodeticTileIndex& tileIndex) {
|
||||
int nRasters = _gdalDataSet->GetRasterCount();
|
||||
|
||||
ghoul_assert(nRasters > 0, "Bad dataset. Contains no rasterband.");
|
||||
|
||||
GDALRasterBand* firstBand = _gdalDataSet->GetRasterBand(1);
|
||||
|
||||
// Level = overviewCount - overview
|
||||
int numOverviews = firstBand->GetOverviewCount();
|
||||
|
||||
|
||||
int xSize0 = firstBand->GetXSize();
|
||||
int ySize0 = firstBand->GetYSize();
|
||||
|
||||
GeodeticPatch patch = GeodeticPatch(tileIndex);
|
||||
glm::uvec2 pixelStart0 = _converter.geodeticToPixel(_gdalDataSet, patch.northWestCorner());
|
||||
glm::uvec2 pixelEnd0 = _converter.geodeticToPixel(_gdalDataSet, patch.southEastCorner());
|
||||
glm::uvec2 numberOfPixels0 = pixelEnd0 - pixelStart0;
|
||||
|
||||
|
||||
int minNumPixels0 = glm::min(numberOfPixels0.x, numberOfPixels0.y);
|
||||
|
||||
int minNumPixelsRequired = 512;
|
||||
int ov = log2(minNumPixels0) - log2(minNumPixelsRequired);
|
||||
|
||||
ov = glm::clamp(ov, 0, numOverviews - 1);
|
||||
|
||||
glm::uvec2 pixelStart(pixelStart0.x >> (ov + 1), pixelStart0.y >> (ov + 1));
|
||||
glm::uvec2 numberOfPixels(numberOfPixels0.x >> (ov + 1), numberOfPixels0.y >> (ov + 1));
|
||||
|
||||
|
||||
|
||||
// GDAL reads image data top to bottom
|
||||
GLubyte* imageData = new GLubyte[numberOfPixels.x * numberOfPixels.y * nRasters];
|
||||
|
||||
// Read the data (each rasterband is a separate channel)
|
||||
for (size_t i = 0; i < nRasters; i++) {
|
||||
GDALRasterBand* rasterBand = _gdalDataSet->GetRasterBand(i + 1)->GetOverview(ov);
|
||||
|
||||
int xSize = rasterBand->GetXSize();
|
||||
int ySize = rasterBand->GetYSize();
|
||||
|
||||
rasterBand->RasterIO(
|
||||
GF_Read,
|
||||
pixelStart.x, // Begin read x
|
||||
pixelStart.y, // Begin read y
|
||||
numberOfPixels.x, // width to read x
|
||||
numberOfPixels.y, // width to read y
|
||||
imageData + i, // Where to put data
|
||||
numberOfPixels.x, // width to write x in destination
|
||||
numberOfPixels.y, // width to write y in destination
|
||||
GDT_Byte, // Type
|
||||
sizeof(GLubyte) * nRasters, // Pixel spacing
|
||||
0); // Line spacing
|
||||
switch (gdalType)
|
||||
{
|
||||
case GDT_Byte:
|
||||
return _uByteConverter.getUninitializedTextureTile(_gdalDataSet, tileIndex);
|
||||
break;
|
||||
case GDT_UInt16:
|
||||
return _uShortConverter.getUninitializedTextureTile(_gdalDataSet, tileIndex);
|
||||
break;
|
||||
case GDT_Int16:
|
||||
return _shortConverter.getUninitializedTextureTile(_gdalDataSet, tileIndex);
|
||||
break;
|
||||
case GDT_UInt32:
|
||||
return _uIntConverter.getUninitializedTextureTile(_gdalDataSet, tileIndex);
|
||||
break;
|
||||
case GDT_Int32:
|
||||
return _intConverter.getUninitializedTextureTile(_gdalDataSet, tileIndex);
|
||||
break;
|
||||
case GDT_Float32:
|
||||
return _floatConverter.getUninitializedTextureTile(_gdalDataSet, tileIndex);
|
||||
break;
|
||||
case GDT_Float64:
|
||||
return _doubleConverter.getUninitializedTextureTile(_gdalDataSet, tileIndex);
|
||||
break;
|
||||
default:
|
||||
LERROR("GDAL data type unknown to OpenGL: " << gdalType);
|
||||
}
|
||||
|
||||
// GDAL reads image data top to bottom. We want the opposite.
|
||||
GLubyte* imageDataYflipped = new GLubyte[numberOfPixels.x * numberOfPixels.y * nRasters];
|
||||
for (size_t y = 0; y < numberOfPixels.y; y++) {
|
||||
for (size_t x = 0; x < numberOfPixels.x; x++) {
|
||||
imageDataYflipped[x + y * numberOfPixels.x] = imageData[x + (numberOfPixels.y - y) * numberOfPixels.x];
|
||||
}
|
||||
}
|
||||
|
||||
delete[] imageData;
|
||||
|
||||
glm::uvec3 dims(numberOfPixels.x, numberOfPixels.y, 1);
|
||||
GdalDataConverter::TextureFormat textrureFormat = _converter.getTextureFormatFromRasterCount(nRasters);
|
||||
UninitializedTextureTile* uninitedTexPtr = new UninitializedTextureTile(imageDataYflipped, dims, textrureFormat, tileIndex);
|
||||
std::shared_ptr<UninitializedTextureTile> uninitedTex = std::shared_ptr<UninitializedTextureTile>(uninitedTexPtr);
|
||||
return uninitedTex;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<Texture> TileProvider::initializeTexture(std::shared_ptr<UninitializedTextureTile> uninitedTexture) {
|
||||
std::shared_ptr<Texture> TileProvider::initializeTexture(
|
||||
std::shared_ptr<UninitializedTextureTile> uninitedTexture) {
|
||||
Texture* tex = new Texture(
|
||||
static_cast<void*>(uninitedTexture->imageData),
|
||||
uninitedTexture->imageData,
|
||||
uninitedTexture->dimensions,
|
||||
uninitedTexture->texFormat.ghoulFormat,
|
||||
uninitedTexture->texFormat.glFormat,
|
||||
GL_UNSIGNED_BYTE,
|
||||
uninitedTexture->glType,
|
||||
Texture::FilterMode::Linear,
|
||||
Texture::WrappingMode::Repeat);
|
||||
Texture::WrappingMode::ClampToBorder);
|
||||
|
||||
// The texture should take ownership of the data
|
||||
std::shared_ptr<Texture> texture = std::shared_ptr<Texture>(tex);
|
||||
|
||||
texture->uploadTexture();
|
||||
/*
|
||||
texture->setWrapping(ghoul::opengl::Texture::WrappingMode::ClampToBorder);
|
||||
texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear);
|
||||
|
||||
*/
|
||||
return texture;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,39 +39,18 @@
|
||||
#include <modules/globebrowsing/other/concurrentjobmanager.h>
|
||||
#include <modules/globebrowsing/other/gdaldataconverter.h>
|
||||
|
||||
|
||||
namespace openspace {
|
||||
|
||||
|
||||
struct UninitializedTextureTile {
|
||||
UninitializedTextureTile(GLubyte* data, glm::uvec3 dims,
|
||||
GdalDataConverter::TextureFormat format, const GeodeticTileIndex& ti)
|
||||
: imageData(data)
|
||||
, dimensions(dims)
|
||||
, texFormat(format)
|
||||
, tileIndex(ti){
|
||||
|
||||
}
|
||||
|
||||
|
||||
GLubyte * imageData;
|
||||
glm::uvec3 dimensions;
|
||||
GdalDataConverter::TextureFormat texFormat;
|
||||
const GeodeticTileIndex tileIndex;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// TILE PROVIDER //
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace openspace {
|
||||
|
||||
|
||||
|
||||
using namespace ghoul::opengl;
|
||||
|
||||
/**
|
||||
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);
|
||||
@@ -81,26 +60,39 @@ namespace openspace {
|
||||
|
||||
void prerender();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
friend class TextureTileLoadJob;
|
||||
|
||||
std::shared_ptr<UninitializedTextureTile> getUninitializedTextureTile(const GeodeticTileIndex& tileIndex);
|
||||
std::shared_ptr<Texture> initializeTexture(std::shared_ptr<UninitializedTextureTile> uninitedTexture);
|
||||
|
||||
/**
|
||||
Fetches all the needeed texture data from the GDAL dataset.
|
||||
*/
|
||||
std::shared_ptr<UninitializedTextureTile> getUninitializedTextureTile(
|
||||
const GeodeticTileIndex& tileIndex);
|
||||
|
||||
/**
|
||||
Creates an OpenGL texture and pushes the data to the GPU.
|
||||
*/
|
||||
std::shared_ptr<Texture> initializeTexture(
|
||||
std::shared_ptr<UninitializedTextureTile> uninitedTexture);
|
||||
|
||||
LRUCache<HashKey, std::shared_ptr<Texture>> _tileCache;
|
||||
|
||||
|
||||
const std::string _filePath;
|
||||
|
||||
static bool hasInitializedGDAL;
|
||||
GDALDataset* _gdalDataSet;
|
||||
GdalDataConverter _converter;
|
||||
|
||||
// Converters are needed for all different data types since they are templated.
|
||||
GdalDataConverter<GLbyte> _uByteConverter;
|
||||
GdalDataConverter<GLushort> _uShortConverter;
|
||||
GdalDataConverter<GLshort> _shortConverter;
|
||||
GdalDataConverter<GLuint> _uIntConverter;
|
||||
GdalDataConverter<GLint> _intConverter;
|
||||
GdalDataConverter<GLfloat> _floatConverter;
|
||||
GdalDataConverter<GLdouble> _doubleConverter;
|
||||
|
||||
ConcurrentJobManager<UninitializedTextureTile> _tileLoadManager;
|
||||
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -114,18 +114,21 @@ void main()
|
||||
PositionNormalPair pair = globalInterpolation(fs_uv);
|
||||
|
||||
|
||||
vec4 textureColor = vec4(0);
|
||||
float sampledHeight00, sampledHeight10, sampledHeight01, sampledHeight11;
|
||||
|
||||
|
||||
vec2 uv00 = vec2(uvTransformPatchToTile00 * vec3(fs_uv.s, fs_uv.t, 1));
|
||||
textureColor += texture(textureSampler00, uv00);
|
||||
sampledHeight00 = texture(textureSampler00, uv00).r;
|
||||
vec2 uv10 = vec2(uvTransformPatchToTile10 * vec3(fs_uv.s, fs_uv.t, 1));
|
||||
textureColor += texture(textureSampler10, uv10);
|
||||
sampledHeight10 = texture(textureSampler10, uv10).r;
|
||||
vec2 uv01 = vec2(uvTransformPatchToTile01 * vec3(fs_uv.s, fs_uv.t, 1));
|
||||
textureColor += texture(textureSampler01, uv01);
|
||||
sampledHeight01 = texture(textureSampler01, uv01).r;
|
||||
vec2 uv11 = vec2(uvTransformPatchToTile11 * vec3(fs_uv.s, fs_uv.t, 1));
|
||||
textureColor += texture(textureSampler11, uv11);
|
||||
sampledHeight11 = texture(textureSampler11, uv11).r;
|
||||
|
||||
pair.position += pair.normal * textureColor.r * 1e4;
|
||||
float sampledHeight = max(sampledHeight00, max(sampledHeight10, max(sampledHeight01, sampledHeight11)));
|
||||
|
||||
pair.position += pair.normal * sampledHeight * 1e5;
|
||||
|
||||
vec4 position = modelViewProjectionTransform * vec4(pair.position, 1);
|
||||
fs_position = pair.position;
|
||||
|
||||
@@ -58,18 +58,22 @@ Fragment getFragment() {
|
||||
Fragment frag;
|
||||
|
||||
frag.color = vec4(0);
|
||||
|
||||
vec4 color00, color10, color01, color11;
|
||||
|
||||
vec2 uv00 = vec2(uvTransformPatchToTile00 * vec3(fs_uv.s, fs_uv.t, 1));
|
||||
frag.color += texture(textureSampler00, uv00);
|
||||
color00 = texture(textureSampler00, uv00);
|
||||
|
||||
vec2 uv10 = vec2(uvTransformPatchToTile10 * vec3(fs_uv.s, fs_uv.t, 1));
|
||||
frag.color += texture(textureSampler10, uv10);
|
||||
color10 += texture(textureSampler10, uv10);
|
||||
|
||||
vec2 uv01 = vec2(uvTransformPatchToTile01 * vec3(fs_uv.s, fs_uv.t, 1));
|
||||
frag.color += texture(textureSampler01, uv01);
|
||||
color01 += texture(textureSampler01, uv01);
|
||||
|
||||
vec2 uv11 = vec2(uvTransformPatchToTile11 * vec3(fs_uv.s, fs_uv.t, 1));
|
||||
frag.color += texture(textureSampler11, uv11);
|
||||
color11 += texture(textureSampler11, uv11);
|
||||
|
||||
frag.color = max(color00, max(color10, max(color01, color11))) * 10;
|
||||
|
||||
//frag.color = frag.color * 0.5 + 0.999*texture(textureSampler, fs_uv);
|
||||
//frag.color /= 4;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user