mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-03-13 17:09:05 -05:00
The data type to be read by GDAL can be changed explicitly.
This commit is contained in:
@@ -41,7 +41,7 @@ namespace openspace {
|
||||
|
||||
|
||||
AsyncTileDataProvider::AsyncTileDataProvider(const std::string& filename, int minNumPixels, ThreadPool& pool)
|
||||
: _textureDataProvider(std::shared_ptr<TileDataset>(new TileDataset(filename, minNumPixels)))
|
||||
: _textureDataProvider(std::shared_ptr<TileDataset>(new TileDataset(filename, minNumPixels, 0)))
|
||||
, _concurrentJobManager(pool)
|
||||
{
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace openspace {
|
||||
// INIT THIS TO FALSE AFTER REMOVED FROM TILEPROVIDER
|
||||
bool TileDataset::GdalHasBeenInitialized = false;
|
||||
|
||||
TileDataset::TileDataset(const std::string& fileName, int minimumPixelSize)
|
||||
TileDataset::TileDataset(const std::string& fileName, int minimumPixelSize, GLuint dataType)
|
||||
: _minimumPixelSize(minimumPixelSize)
|
||||
{
|
||||
|
||||
@@ -53,6 +53,7 @@ namespace openspace {
|
||||
|
||||
_dataset = (GDALDataset *)GDALOpen(absPath(fileName).c_str(), GA_ReadOnly);
|
||||
ghoul_assert(_dataset != nullptr, "Failed to load dataset: " << fileName);
|
||||
_dataLayout = DataLayout(_dataset, dataType);
|
||||
|
||||
_depthTransform = calculateTileDepthTransform();
|
||||
_tileLevelDifference = calculateTileLevelDifference(_dataset, minimumPixelSize);
|
||||
@@ -72,10 +73,10 @@ namespace openspace {
|
||||
|
||||
TileDepthTransform TileDataset::calculateTileDepthTransform() {
|
||||
GDALRasterBand* firstBand = _dataset->GetRasterBand(1);
|
||||
GDALDataType gdalType = firstBand->GetRasterDataType();
|
||||
|
||||
double maximumValue = (gdalType == GDT_Float32 || gdalType == GDT_Float64) ?
|
||||
1.0 : firstBand->GetMaximum();
|
||||
// Floating point types does not have a fix maximum or minimum value and
|
||||
// can not be normalized when sampling a texture. Hence no rescaling is needed.
|
||||
double maximumValue = (_dataLayout.gdalType == GDT_Float32 || _dataLayout.gdalType == GDT_Float64) ?
|
||||
1.0 : getMaximumValue(_dataLayout.gdalType);
|
||||
|
||||
TileDepthTransform transform;
|
||||
transform.depthOffset = firstBand->GetOffset();
|
||||
@@ -96,8 +97,9 @@ namespace openspace {
|
||||
std::shared_ptr<TileIOResult> TileDataset::readTileData(ChunkIndex chunkIndex)
|
||||
{
|
||||
GdalDataRegion region(_dataset, chunkIndex, _tileLevelDifference);
|
||||
DataLayout dataLayout(_dataset, region);
|
||||
char* imageData = new char[dataLayout.totalNumBytes];
|
||||
size_t bytesPerLine = _dataLayout.bytesPerPixel * region.numPixels.x;
|
||||
size_t totalNumBytes = bytesPerLine * region.numPixels.y;
|
||||
char* imageData = new char[totalNumBytes];
|
||||
|
||||
CPLErr worstError = CPLErr::CE_None;
|
||||
|
||||
@@ -105,7 +107,7 @@ namespace openspace {
|
||||
for (size_t i = 0; i < region.numRasters; i++) {
|
||||
GDALRasterBand* rasterBand = _dataset->GetRasterBand(i + 1)->GetOverview(region.overview);
|
||||
|
||||
char* dataDestination = imageData + (i * dataLayout.bytesPerDatum);
|
||||
char* dataDestination = imageData + (i * _dataLayout.bytesPerDatum);
|
||||
|
||||
CPLErr err = rasterBand->RasterIO(
|
||||
GF_Read,
|
||||
@@ -116,16 +118,16 @@ namespace openspace {
|
||||
dataDestination, // Where to put data
|
||||
region.numPixels.x, // width to write x in destination
|
||||
region.numPixels.y, // width to write y in destination
|
||||
dataLayout.gdalType, // Type
|
||||
dataLayout.bytesPerPixel, // Pixel spacing
|
||||
dataLayout.bytesPerLine); // Line spacing
|
||||
_dataLayout.gdalType, // Type
|
||||
_dataLayout.bytesPerPixel, // Pixel spacing
|
||||
bytesPerLine); // Line spacing
|
||||
|
||||
// CE_None = 0, CE_Debug = 1, CE_Warning = 2, CE_Failure = 3, CE_Fatal = 4
|
||||
worstError = std::max(worstError, err);
|
||||
}
|
||||
|
||||
std::shared_ptr<RawTileData> tileData = nullptr;
|
||||
tileData = createRawTileData(region, dataLayout, imageData);
|
||||
tileData = createRawTileData(region, _dataLayout, imageData);
|
||||
|
||||
std::shared_ptr<TileIOResult> result(new TileIOResult);
|
||||
result->error = worstError;
|
||||
@@ -138,15 +140,17 @@ namespace openspace {
|
||||
std::shared_ptr<RawTileData> TileDataset::createRawTileData(const GdalDataRegion& region,
|
||||
const DataLayout& dataLayout, const char* imageData)
|
||||
{
|
||||
|
||||
size_t bytesPerLine = dataLayout.bytesPerPixel * region.numPixels.x;
|
||||
size_t totalNumBytes = bytesPerLine * region.numPixels.y;
|
||||
|
||||
//if(cplError == CPLErr::CE_Fatal)
|
||||
|
||||
// GDAL reads image data top to bottom. We want the opposite.
|
||||
char* imageDataYflipped = new char[dataLayout.totalNumBytes];
|
||||
char* imageDataYflipped = new char[totalNumBytes];
|
||||
for (size_t y = 0; y < region.numPixels.y; y++) {
|
||||
for (size_t x = 0; x < dataLayout.bytesPerLine; x++) {
|
||||
imageDataYflipped[x + y * dataLayout.bytesPerLine] =
|
||||
imageData[x + (region.numPixels.y - 1 - y) * dataLayout.bytesPerLine];
|
||||
for (size_t x = 0; x < bytesPerLine; x++) {
|
||||
imageDataYflipped[x + y * bytesPerLine] =
|
||||
imageData[x + (region.numPixels.y - 1 - y) * bytesPerLine];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,11 +182,25 @@ namespace openspace {
|
||||
case GDT_Float32: return sizeof(GLfloat);
|
||||
case GDT_Float64: return sizeof(GLdouble);
|
||||
default:
|
||||
//LERROR("Unknown data type");
|
||||
LERROR("Unknown data type");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
size_t TileDataset::getMaximumValue(GDALDataType gdalType) {
|
||||
switch (gdalType) {
|
||||
case GDT_Byte: return 2 << 7;
|
||||
case GDT_UInt16: return 2 << 15;
|
||||
case GDT_Int16: return 2 << 14;
|
||||
case GDT_UInt32: return 2 << 31;
|
||||
case GDT_Int32: return 2 << 30;
|
||||
default:
|
||||
LERROR("Unknown data type");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
glm::uvec2 TileDataset::geodeticToPixel(GDALDataset* dataSet, const Geodetic2& geo) {
|
||||
double padfTransform[6];
|
||||
@@ -238,7 +256,7 @@ namespace openspace {
|
||||
case GDT_Int32: format.glFormat = GL_R32I; break;
|
||||
case GDT_Float32: format.glFormat = GL_R32F; break;
|
||||
//case GDT_Float64: format.glFormat = GL_RED; break; // No representation of 64 bit float?
|
||||
default: ;//LERROR("GDAL data type unknown to OpenGL: " << gdalType);
|
||||
default: LERROR("GDAL data type unknown to OpenGL: " << gdalType);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
@@ -251,7 +269,7 @@ namespace openspace {
|
||||
case GDT_Int32: format.glFormat = GL_RG32I; break;
|
||||
case GDT_Float32: format.glFormat = GL_RG32F; break;
|
||||
case GDT_Float64: format.glFormat = GL_RED; break; // No representation of 64 bit float?
|
||||
default: ;//LERROR("GDAL data type unknown to OpenGL: " << gdalType);
|
||||
default: LERROR("GDAL data type unknown to OpenGL: " << gdalType);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
@@ -264,7 +282,7 @@ namespace openspace {
|
||||
case GDT_Int32: format.glFormat = GL_RGB32I; break;
|
||||
case GDT_Float32: format.glFormat = GL_RGB32F; break;
|
||||
// case GDT_Float64: format.glFormat = GL_RED; break;// No representation of 64 bit float?
|
||||
default: ;//LERROR("GDAL data type unknown to OpenGL: " << gdalType);
|
||||
default: LERROR("GDAL data type unknown to OpenGL: " << gdalType);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
@@ -277,11 +295,11 @@ namespace openspace {
|
||||
case GDT_Int32: format.glFormat = GL_RGBA32I; break;
|
||||
case GDT_Float32: format.glFormat = GL_RGBA32F; break;
|
||||
case GDT_Float64: format.glFormat = GL_RED; break; // No representation of 64 bit float?
|
||||
default: ;//LERROR("GDAL data type unknown to OpenGL: " << gdalType);
|
||||
default: LERROR("GDAL data type unknown to OpenGL: " << gdalType);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
//LERROR("Unknown number of channels for OpenGL texture: " << rasterCount);
|
||||
LERROR("Unknown number of channels for OpenGL texture: " << rasterCount);
|
||||
break;
|
||||
}
|
||||
return format;
|
||||
@@ -302,11 +320,26 @@ namespace openspace {
|
||||
case GDT_Float32: return GL_FLOAT;
|
||||
case GDT_Float64: return GL_DOUBLE;
|
||||
default:
|
||||
//LERROR("GDAL data type unknown to OpenGL: " << gdalType);
|
||||
LERROR("GDAL data type unknown to OpenGL: " << gdalType);
|
||||
return GL_UNSIGNED_BYTE;
|
||||
}
|
||||
}
|
||||
|
||||
GDALDataType TileDataset::getGdalDataType(GLuint glType) {
|
||||
switch (glType) {
|
||||
case GL_UNSIGNED_BYTE: return GDT_Byte;
|
||||
case GL_UNSIGNED_SHORT: return GDT_UInt16;
|
||||
case GL_SHORT: return GDT_Int16;
|
||||
case GL_UNSIGNED_INT: return GDT_UInt32;
|
||||
case GL_INT: return GDT_Int32;
|
||||
case GL_FLOAT: return GDT_Float32;
|
||||
case GL_DOUBLE: return GDT_Float64;
|
||||
default:
|
||||
LERROR("OpenGL data type unknown to GDAL: " << gdalType);
|
||||
return GDT_Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TileDataset::GdalDataRegion::GdalDataRegion(GDALDataset * dataSet,
|
||||
const ChunkIndex& chunkIndex, int tileLevelDifference)
|
||||
@@ -351,14 +384,14 @@ namespace openspace {
|
||||
numPixels = pixelEnd - pixelStart;
|
||||
}
|
||||
|
||||
TileDataset::DataLayout::DataLayout() {
|
||||
}
|
||||
|
||||
TileDataset::DataLayout::DataLayout(GDALDataset* dataSet, const GdalDataRegion& region) {
|
||||
TileDataset::DataLayout::DataLayout(GDALDataset* dataSet, GLuint glType) {
|
||||
// Assume all raster bands have the same data type
|
||||
gdalType = dataSet->GetRasterBand(1)->GetRasterDataType();
|
||||
gdalType = glType != 0 ? getGdalDataType(glType) : dataSet->GetRasterBand(1)->GetRasterDataType();
|
||||
bytesPerDatum = numberOfBytes(gdalType);
|
||||
bytesPerPixel = bytesPerDatum * region.numRasters;
|
||||
bytesPerLine = bytesPerPixel * region.numPixels.x;
|
||||
totalNumBytes = bytesPerLine * region.numPixels.y;
|
||||
bytesPerPixel = bytesPerDatum * dataSet->GetRasterCount();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ namespace openspace {
|
||||
class TileDataset {
|
||||
public:
|
||||
|
||||
TileDataset(const std::string& fileName, int minimumPixelSize);
|
||||
TileDataset(const std::string& fileName, int minimumPixelSize, GLuint dataType);
|
||||
~TileDataset();
|
||||
|
||||
|
||||
@@ -126,13 +126,12 @@ namespace openspace {
|
||||
};
|
||||
|
||||
struct DataLayout {
|
||||
DataLayout(GDALDataset* dataSet, const GdalDataRegion& region);
|
||||
DataLayout();
|
||||
DataLayout(GDALDataset* dataSet, GLuint glType);
|
||||
|
||||
GDALDataType gdalType;
|
||||
size_t bytesPerDatum;
|
||||
size_t bytesPerPixel;
|
||||
size_t bytesPerLine;
|
||||
size_t totalNumBytes;
|
||||
};
|
||||
|
||||
|
||||
@@ -153,10 +152,14 @@ namespace openspace {
|
||||
|
||||
static GLuint getOpenGLDataType(GDALDataType gdalType);
|
||||
|
||||
static GDALDataType getGdalDataType(GLuint glType);
|
||||
|
||||
static RawTileData::TextureFormat getTextureFormat(int rasterCount, GDALDataType gdalType);
|
||||
|
||||
static size_t numberOfBytes(GDALDataType gdalType);
|
||||
|
||||
static size_t getMaximumValue(GDALDataType gdalType);
|
||||
|
||||
static std::shared_ptr<RawTileData> createRawTileData(const GdalDataRegion& region,
|
||||
const DataLayout& dataLayout, const char* imageData);
|
||||
|
||||
@@ -173,6 +176,7 @@ namespace openspace {
|
||||
TileDepthTransform _depthTransform;
|
||||
|
||||
GDALDataset* _dataset;
|
||||
DataLayout _dataLayout;
|
||||
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user