/***************************************************************************************** * * * OpenSpace * * * * Copyright (c) 2014-2019 * * * * Permission is hereby granted, free of charge, to any person obtaining a copy of this * * software and associated documentation files (the "Software"), to deal in the Software * * without restriction, including without limitation the rights to use, copy, modify, * * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * * permit persons to whom the Software is furnished to do so, subject to the following * * conditions: * * * * The above copyright notice and this permission notice shall be included in all copies * * or substantial portions of the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ #include namespace { const glm::ivec2 TilePixelStartOffset = glm::ivec2(-2); const glm::ivec2 TilePixelSizeDifference = glm::ivec2(4); size_t numberOfRasters(ghoul::opengl::Texture::Format format) { switch (format) { case ghoul::opengl::Texture::Format::Red: return 1; case ghoul::opengl::Texture::Format::RG: return 2; case ghoul::opengl::Texture::Format::RGB: case ghoul::opengl::Texture::Format::BGR: return 3; case ghoul::opengl::Texture::Format::RGBA: case ghoul::opengl::Texture::Format::BGRA: return 4; default: { ghoul_assert(false, "Unknown format"); throw ghoul::MissingCaseException(); } } } size_t numberOfBytes(GLenum glType) { switch (glType) { case GL_UNSIGNED_BYTE: return sizeof(GLubyte); case GL_BYTE: return sizeof(GLbyte); case GL_UNSIGNED_SHORT: return sizeof(GLushort); case GL_SHORT: return sizeof(GLshort); case GL_UNSIGNED_INT: return sizeof(GLuint); case GL_INT: return sizeof(GLint); case GL_HALF_FLOAT: return sizeof(GLhalf); case GL_FLOAT: return sizeof(GLfloat); case GL_DOUBLE: return sizeof(GLdouble); default: ghoul_assert(false, "Unknown data type"); throw ghoul::MissingCaseException(); } } unsigned int uniqueIdForTextureFormat(ghoul::opengl::Texture::Format textureFormat) { switch (textureFormat) { case ghoul::opengl::Texture::Format::Red: return 0; case ghoul::opengl::Texture::Format::RG: return 1; case ghoul::opengl::Texture::Format::RGB: return 2; case ghoul::opengl::Texture::Format::BGR: return 3; case ghoul::opengl::Texture::Format::RGBA: return 4; case ghoul::opengl::Texture::Format::BGRA: return 5; case ghoul::opengl::Texture::Format::DepthComponent: return 6; default: throw ghoul::MissingCaseException(); } } openspace::globebrowsing::TileTextureInitData::HashKey calculateHashKey( const glm::ivec3& dimensions, const ghoul::opengl::Texture::Format& format, const GLenum& glType) { ghoul_assert(dimensions.x > 0, "Incorrect dimension"); ghoul_assert(dimensions.y > 0, "Incorrect dimension"); ghoul_assert(dimensions.x <= 1024, "Incorrect dimension"); ghoul_assert(dimensions.y <= 1024, "Incorrect dimension"); ghoul_assert(dimensions.z == 1, "Incorrect dimension"); unsigned int formatId = uniqueIdForTextureFormat(format); ghoul_assert(formatId < 256, "Incorrect format"); openspace::globebrowsing::TileTextureInitData::HashKey res = 0ULL; res |= dimensions.x; res |= dimensions.y << 10; res |= static_cast>(glType) << (10 + 16); res |= formatId << (10 + 16 + 4); return res; } } // namespace namespace openspace::globebrowsing { TileTextureInitData tileTextureInitData(layergroupid::GroupID id, bool shouldPadTiles, size_t preferredTileSize) { switch (id) { case layergroupid::GroupID::HeightLayers: { const size_t tileSize = preferredTileSize ? preferredTileSize : 64; return TileTextureInitData( tileSize, tileSize, GL_FLOAT, ghoul::opengl::Texture::Format::Red, TileTextureInitData::PadTiles(shouldPadTiles), TileTextureInitData::ShouldAllocateDataOnCPU::Yes ); } case layergroupid::GroupID::ColorLayers: { const size_t tileSize = preferredTileSize ? preferredTileSize : 512; return TileTextureInitData( tileSize, tileSize, GL_UNSIGNED_BYTE, ghoul::opengl::Texture::Format::BGRA, TileTextureInitData::PadTiles(shouldPadTiles) ); } case layergroupid::GroupID::Overlays: { const size_t tileSize = preferredTileSize ? preferredTileSize : 512; return TileTextureInitData( tileSize, tileSize, GL_UNSIGNED_BYTE, ghoul::opengl::Texture::Format::BGRA, TileTextureInitData::PadTiles(shouldPadTiles) ); } case layergroupid::GroupID::NightLayers: { const size_t tileSize = preferredTileSize ? preferredTileSize : 512; return TileTextureInitData( tileSize, tileSize, GL_UNSIGNED_BYTE, ghoul::opengl::Texture::Format::BGRA, TileTextureInitData::PadTiles(shouldPadTiles) ); } case layergroupid::GroupID::WaterMasks: { const size_t tileSize = preferredTileSize ? preferredTileSize : 512; return TileTextureInitData( tileSize, tileSize, GL_UNSIGNED_BYTE, ghoul::opengl::Texture::Format::BGRA, TileTextureInitData::PadTiles(shouldPadTiles) ); } default: { throw ghoul::MissingCaseException(); } } } TileTextureInitData::TileTextureInitData(size_t width, size_t height, GLenum type, ghoul::opengl::Texture::Format textureFormat, PadTiles pad, ShouldAllocateDataOnCPU allocCpu) : dimensions(width, height, 1) , tilePixelStartOffset(pad ? TilePixelStartOffset : glm::ivec2(0)) , tilePixelSizeDifference(pad ? TilePixelSizeDifference : glm::ivec2(0)) , glType(type) , ghoulTextureFormat(textureFormat) , nRasters(numberOfRasters(ghoulTextureFormat)) , bytesPerDatum(numberOfBytes(glType)) , bytesPerPixel(nRasters * bytesPerDatum) , bytesPerLine(bytesPerPixel * width) , totalNumBytes(bytesPerLine * height) , shouldAllocateDataOnCPU(allocCpu) , padTiles(pad) , hashKey(calculateHashKey(dimensions, ghoulTextureFormat, glType)) {} TileTextureInitData TileTextureInitData::operator=(const TileTextureInitData& rhs) { if (this == &rhs) { return TileTextureInitData(*this); } return TileTextureInitData(rhs); } TileTextureInitData TileTextureInitData::operator=(TileTextureInitData&& rhs) { if (this == &rhs) { return TileTextureInitData(*this); } return TileTextureInitData(rhs); } } // namespace openspace::globebrowsing