diff --git a/modules/globebrowsing/CMakeLists.txt b/modules/globebrowsing/CMakeLists.txt index 4995b25560..6587c2547a 100644 --- a/modules/globebrowsing/CMakeLists.txt +++ b/modules/globebrowsing/CMakeLists.txt @@ -56,6 +56,7 @@ set(HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/other/concurrentjobmanager.h ${CMAKE_CURRENT_SOURCE_DIR}/other/concurrentqueue.h ${CMAKE_CURRENT_SOURCE_DIR}/other/tileprovidermanager.h + ${CMAKE_CURRENT_SOURCE_DIR}/other/layeredtextureshaderprovider.h ) @@ -69,7 +70,6 @@ set(SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/globes/chunkindex.cpp ${CMAKE_CURRENT_SOURCE_DIR}/globes/chunk.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/meshes/trianglesoup.cpp ${CMAKE_CURRENT_SOURCE_DIR}/meshes/grid.cpp ${CMAKE_CURRENT_SOURCE_DIR}/meshes/basicgrid.cpp @@ -90,6 +90,7 @@ set(SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/other/lrucache.inl ${CMAKE_CURRENT_SOURCE_DIR}/other/concurrentjobmanager.inl ${CMAKE_CURRENT_SOURCE_DIR}/other/tileprovidermanager.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/other/layeredtextureshaderprovider.cpp ) source_group("Source Files" FILES ${SOURCE_FILES}) diff --git a/modules/globebrowsing/other/layeredtextureshaderprovider.cpp b/modules/globebrowsing/other/layeredtextureshaderprovider.cpp new file mode 100644 index 0000000000..07d8e88d7c --- /dev/null +++ b/modules/globebrowsing/other/layeredtextureshaderprovider.cpp @@ -0,0 +1,132 @@ +/***************************************************************************************** +* * +* OpenSpace * +* * +* Copyright (c) 2014-2016 * +* * +* 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 + +#include +#include + +#include "ghoul\misc\dictionary.h" + +#include + +namespace { + const std::string _loggerCat = "LayeredTextureShaderProvider"; +} + +namespace openspace { + + bool LayeredTextureInfo::operator==(const LayeredTextureInfo& other) const + { + return numLayers == other.numLayers && keyNumLayers == other.keyNumLayers; + } + + bool LayeredTexturePreprocessingData::operator==( + const LayeredTexturePreprocessingData& other) const + { + + if (layeredTextureInfo.size() != other.layeredTextureInfo.size()) + { + return false; + } + else + { + bool equal = true; + for (size_t i = 0; i < layeredTextureInfo.size(); i++) + { + equal = equal && (layeredTextureInfo[i] == other.layeredTextureInfo[i]); + } + return equal; + } + } + + LayeredTextureShaderProvider::LayeredTextureShaderProvider( + const std::string& shaderName, + const std::string& vsPath, + const std::string& fsPath) + : _shaderName(shaderName) + , _vsPath(vsPath) + , _fsPath(fsPath) + { + + } + + LayeredTextureShaderProvider::~LayeredTextureShaderProvider() + { + if (_programObject) { + RenderEngine& renderEngine = OsEng.renderEngine(); + renderEngine.removeRenderProgram(_programObject); + _programObject = nullptr; + } + } + + ProgramObject* LayeredTextureShaderProvider::getUpdatedShaderProgram( + LayeredTexturePreprocessingData preprocessingData) + { + if (!(preprocessingData == _preprocessingData) || _programObject == nullptr) + { // No need to recompile shader. Shader is up to date and can be returned. + recompileShaderProgram(preprocessingData); + } + return _programObject.get(); + } + + void LayeredTextureShaderProvider::recompileShaderProgram( + LayeredTexturePreprocessingData preprocessingData) + { + _preprocessingData = preprocessingData; + ghoul::Dictionary shaderDictionary; + + // Different texture types can be height maps or color texture for example + // These are used differently within the shaders. + auto textureTypes = _preprocessingData.layeredTextureInfo; + for (size_t i = 0; i < textureTypes.size(); i++) + { + shaderDictionary.setValue( + textureTypes[i].keyNumLayers, textureTypes[i].numLayers); + } + + _programObject = OsEng.renderEngine().buildRenderProgram( + _shaderName, + _vsPath, + _fsPath); + + /* + try { + _programObject = ProgramObject::Build( + _shaderName, + _vsPath, + _fsPath, + shaderDictionary); + } + catch (ghoul::RuntimeError& error) { + + LERROR(error.message); + } + */ + ghoul_assert(_programObject != nullptr, "Failed to initialize programObject!"); + using IgnoreError = ProgramObject::IgnoreError; + _programObject->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes); + } + +} // namespace openspace diff --git a/modules/globebrowsing/other/layeredtextureshaderprovider.h b/modules/globebrowsing/other/layeredtextureshaderprovider.h new file mode 100644 index 0000000000..ccea9d5f94 --- /dev/null +++ b/modules/globebrowsing/other/layeredtextureshaderprovider.h @@ -0,0 +1,80 @@ +/***************************************************************************************** +* * +* OpenSpace * +* * +* Copyright (c) 2014-2016 * +* * +* 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. * +****************************************************************************************/ + +#ifndef __LAYERED_TEXTURE_SHADER_PROVIDER__ +#define __LAYERED_TEXTURE_SHADER_PROVIDER__ + +#include +#include +#include "ghoul/opengl/programobject.h" + +////////////////////////////////////////////////////////////////////////////////////////// +// LAYERED TEXTURE SHADER PROVIDER // +////////////////////////////////////////////////////////////////////////////////////////// + +namespace openspace { + + using namespace ghoul::opengl; + + struct LayeredTextureInfo + { + std::string keyNumLayers; + int numLayers; + + bool operator==(const LayeredTextureInfo& other) const; + }; + + struct LayeredTexturePreprocessingData + { + std::vector layeredTextureInfo; + + bool operator==(const LayeredTexturePreprocessingData& other) const; + }; + + class LayeredTextureShaderProvider + { + public: + LayeredTextureShaderProvider( + const std::string& shaderName, + const std::string& vsPath, + const std::string& fsPath); + ~LayeredTextureShaderProvider(); + + ProgramObject* getUpdatedShaderProgram( + LayeredTexturePreprocessingData preprocessingData); + + private: + void recompileShaderProgram(LayeredTexturePreprocessingData preprocessingData); + + std::unique_ptr _programObject; + LayeredTexturePreprocessingData _preprocessingData; + + const std::string _shaderName; + const std::string _vsPath; + const std::string _fsPath; + }; + +} // namespace openspace + +#endif // __LAYERED_TEXTURE_SHADER_PROVIDER__ \ No newline at end of file diff --git a/modules/globebrowsing/rendering/patchrenderer.cpp b/modules/globebrowsing/rendering/patchrenderer.cpp index 6e9fbb7770..a84f4cab92 100644 --- a/modules/globebrowsing/rendering/patchrenderer.cpp +++ b/modules/globebrowsing/rendering/patchrenderer.cpp @@ -36,7 +36,8 @@ #include #include - +// STL includes +#include #define _USE_MATH_DEFINES #include @@ -62,11 +63,7 @@ namespace openspace { } PatchRenderer::~PatchRenderer() { - if (_programObjectGlobalRendering) { - RenderEngine& renderEngine = OsEng.renderEngine(); - renderEngine.removeRenderProgram(_programObjectGlobalRendering); - _programObjectGlobalRendering = nullptr; - } + } void PatchRenderer::update() { @@ -91,6 +88,19 @@ namespace openspace { : PatchRenderer(tileProviderManager) , _grid(grid) { + _globalRenderingShaderProvider = unique_ptr + (new LayeredTextureShaderProvider( + "GlobalChunkedLodPatch", + "${MODULE_GLOBEBROWSING}/shaders/globalchunkedlodpatch_vs.glsl", + "${MODULE_GLOBEBROWSING}/shaders/globalchunkedlodpatch_fs.glsl")); + + _localRenderingShaderProvider = unique_ptr + (new LayeredTextureShaderProvider( + "LocalChunkedLodPatch", + "${MODULE_GLOBEBROWSING}/shaders/localchunkedlodpatch_vs.glsl", + "${MODULE_GLOBEBROWSING}/shaders/localchunkedlodpatch_fs.glsl")); + + /* _programObjectGlobalRendering = OsEng.renderEngine().buildRenderProgram( "GlobalChunkedLodPatch", "${MODULE_GLOBEBROWSING}/shaders/globalchunkedlodpatch_vs.glsl", @@ -102,10 +112,11 @@ namespace openspace { "${MODULE_GLOBEBROWSING}/shaders/localchunkedlodpatch_vs.glsl", "${MODULE_GLOBEBROWSING}/shaders/localchunkedlodpatch_fs.glsl"); ghoul_assert(_programObjectLocalRendering != nullptr, "Failed to initialize programObject!"); - using IgnoreError = ghoul::opengl::ProgramObject::IgnoreError; _programObjectGlobalRendering->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes); _programObjectLocalRendering->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes); + */ + } void ChunkRenderer::renderChunk( @@ -126,21 +137,144 @@ namespace openspace { const Ellipsoid& ellipsoid, const RenderData& data) { + using namespace glm; + // All providers of tiles + auto heightMapProviders = _tileProviderManager->heightMapProviders(); + auto colorTextureProviders = _tileProviderManager->colorTextureProviders(); + + int numHeightMapProviders = heightMapProviders.size(); + int numColorTextureProviders = colorTextureProviders.size(); + + // Create information for the shader provider + LayeredTextureInfo layeredTextureInfoHeight; + LayeredTextureInfo layeredTextureInfoColor; + layeredTextureInfoHeight.keyNumLayers = "numLayersHeight"; + layeredTextureInfoHeight.numLayers = numHeightMapProviders; + layeredTextureInfoColor.keyNumLayers = "numLayersColor"; + layeredTextureInfoColor.numLayers = numColorTextureProviders; + + LayeredTexturePreprocessingData layeredTexturePreprocessingData; + layeredTexturePreprocessingData.layeredTextureInfo.push_back( + layeredTextureInfoHeight); + layeredTexturePreprocessingData.layeredTextureInfo.push_back( + layeredTextureInfoColor); + + // Now the shader program can be accessed + ProgramObject* programObject = + _globalRenderingShaderProvider->getUpdatedShaderProgram( + layeredTexturePreprocessingData); + + // Activate the shader program + programObject->activate(); + + ghoul::opengl::TextureUnit texUnitHeight; + ghoul::opengl::TextureUnit texUnitColor; + + + // Go through all the height map providers + int i = 0; + for (auto it = heightMapProviders.begin(); it != heightMapProviders.end(); it++) + { + auto tileProvider = it->second; + // Get the texture that should be used for rendering + Tile tile = tileProvider->getMostHiResTile(chunk.index()); + TileDepthTransform depthTransform = tileProvider->depthTransform(); + + // The texture needs a unit to sample from + texUnitHeight.activate(); + tile.texture->bind(); + + std::string indexedTileKey = "heightTiles[" + std::to_string(i) + "]"; + // Send uniforms for the tile to the shader + programObject->setUniform(indexedTileKey + ".textureSampler", texUnitHeight); + + programObject->setUniform( + indexedTileKey + ".uvTransform.uvScale", + tile.uvTransform.uvScale); + programObject->setUniform( + indexedTileKey + ".uvTransform.uvOffset", + tile.uvTransform.uvOffset); + + programObject->setUniform( + indexedTileKey + ".depthTransform.depthScale", + depthTransform.depthScale); + programObject->setUniform( + indexedTileKey + ".depthTransform.depthOffset", + depthTransform.depthOffset); + + i++; + } + + // Go through all the color texture providers + i = 0; + for (auto it = colorTextureProviders.begin(); it != colorTextureProviders.end(); it++) + { + auto tileProvider = it->second; + // Get the texture that should be used for rendering + Tile tile = tileProvider->getMostHiResTile(chunk.index()); + + // The texture needs a unit to sample from + texUnitColor.activate(); + tile.texture->bind(); + + std::string indexedTileKey = "colorTiles[" + std::to_string(i) + "]"; + // Send uniforms for the tile to the shader + programObject->setUniform(indexedTileKey + ".textureSampler", texUnitColor); + + programObject->setUniform( + indexedTileKey + ".uvTransform.uvScale", + tile.uvTransform.uvScale); + programObject->setUniform( + indexedTileKey + ".uvTransform.uvOffset", + tile.uvTransform.uvOffset); + + i++; + } + + // Calculate other uniform variables needed for rendering + Geodetic2 swCorner = chunk.surfacePatch().southWestCorner(); + auto patchSize = chunk.surfacePatch().size(); + // TODO : Model transform should be fetched as a matrix directly. mat4 modelTransform = translate(mat4(1), data.position.vec3()); mat4 viewTransform = data.camera.combinedViewMatrix(); mat4 modelViewProjectionTransform = data.camera.projectionMatrix() * viewTransform * modelTransform; + // Upload the uniform variables + programObject->setUniform("modelViewProjectionTransform", modelViewProjectionTransform); + programObject->setUniform("minLatLon", vec2(swCorner.toLonLatVec2())); + programObject->setUniform("lonLatScalingFactor", vec2(patchSize.toLonLatVec2())); + programObject->setUniform("radiiSquared", vec3(ellipsoid.radiiSquared())); + + // OpenGL rendering settings + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + + // render + _grid->geometry().drawUsingActiveProgram(); + + // disable shader + programObject->deactivate(); + + + + + + + + + /* // activate shader _programObjectGlobalRendering->activate(); // For now just pick the first one from height maps - auto heightMapProviders = _tileProviderManager->heightMapProviders(); - auto tileProviderHeight = heightMapProviders.begin()->second; + //auto heightMapProviders = _tileProviderManager->heightMapProviders(); + //auto tileProviderHeight = heightMapProviders.begin()->second; // Get the textures that should be used for rendering Tile heightTile = tileProviderHeight->getMostHiResTile(chunk.index()); @@ -190,6 +324,7 @@ namespace openspace { // disable shader _programObjectGlobalRendering->deactivate(); + */ } @@ -198,6 +333,167 @@ namespace openspace { const Ellipsoid& ellipsoid, const RenderData& data) { + + using namespace glm; + + // All providers of tiles + auto heightMapProviders = _tileProviderManager->heightMapProviders(); + auto colorTextureProviders = _tileProviderManager->colorTextureProviders(); + + int numHeightMapProviders = heightMapProviders.size(); + int numColorTextureProviders = colorTextureProviders.size(); + + // Create information for the shader provider + LayeredTextureInfo layeredTextureInfoHeight; + LayeredTextureInfo layeredTextureInfoColor; + layeredTextureInfoHeight.keyNumLayers = "numLayersHeight"; + layeredTextureInfoHeight.numLayers = numHeightMapProviders; + layeredTextureInfoColor.keyNumLayers = "numLayersColor"; + layeredTextureInfoColor.numLayers = numColorTextureProviders; + + LayeredTexturePreprocessingData layeredTexturePreprocessingData; + layeredTexturePreprocessingData.layeredTextureInfo.push_back( + layeredTextureInfoHeight); + layeredTexturePreprocessingData.layeredTextureInfo.push_back( + layeredTextureInfoColor); + + // Now the shader program can be accessed + ProgramObject* programObject = + _localRenderingShaderProvider->getUpdatedShaderProgram( + layeredTexturePreprocessingData); + + // Activate the shader program + programObject->activate(); + + ghoul::opengl::TextureUnit texUnitHeight; + ghoul::opengl::TextureUnit texUnitColor; + + // Go through all the height map providers + int i = 0; + for (auto it = heightMapProviders.begin(); it != heightMapProviders.end(); it++) + { + auto tileProvider = it->second; + // Get the texture that should be used for rendering + Tile tile = tileProvider->getMostHiResTile(chunk.index()); + TileDepthTransform depthTransform = tileProvider->depthTransform(); + + // The texture needs a unit to sample from + texUnitHeight.activate(); + tile.texture->bind(); + + std::string indexedTileKey = "heightTiles[" + std::to_string(i) + "]"; + // Send uniforms for the tile to the shader + programObject->setUniform(indexedTileKey + ".textureSampler", texUnitHeight); + + programObject->setUniform( + indexedTileKey + ".uvTransform.uvScale", + tile.uvTransform.uvScale); + programObject->setUniform( + indexedTileKey + ".uvTransform.uvOffset", + tile.uvTransform.uvOffset); + + programObject->setUniform( + indexedTileKey + ".depthTransform.depthScale", + depthTransform.depthScale); + programObject->setUniform( + indexedTileKey + ".depthTransform.depthOffset", + depthTransform.depthOffset); + + i++; + } + + // Go through all the color texture providers + i = 0; + for (auto it = colorTextureProviders.begin(); it != colorTextureProviders.end(); it++) + { + auto tileProvider = it->second; + // Get the texture that should be used for rendering + Tile tile = tileProvider->getMostHiResTile(chunk.index()); + + // The texture needs a unit to sample from + texUnitColor.activate(); + tile.texture->bind(); + + std::string indexedTileKey = "colorTiles[" + std::to_string(i) + "]"; + // Send uniforms for the tile to the shader + programObject->setUniform(indexedTileKey + ".textureSampler", texUnitColor); + + programObject->setUniform( + indexedTileKey + ".uvTransform.uvScale", + tile.uvTransform.uvScale); + programObject->setUniform( + indexedTileKey + ".uvTransform.uvOffset", + tile.uvTransform.uvOffset); + + i++; + } + + + + + + + + + // Calculate other uniform variables needed for rendering + + // TODO : Model transform should be fetched as a matrix directly. + mat4 modelTransform = translate(mat4(1), data.position.vec3()); + mat4 viewTransform = data.camera.combinedViewMatrix(); + mat4 modelViewTransform = viewTransform * modelTransform; + + Geodetic2 sw = chunk.surfacePatch().southWestCorner(); + Geodetic2 se = chunk.surfacePatch().southEastCorner(); + Geodetic2 nw = chunk.surfacePatch().northWestCorner(); + Geodetic2 ne = chunk.surfacePatch().northEastCorner(); + + // Get model space positions of the four control points + Vec3 patchSwModelSpace = ellipsoid.geodetic2ToCartesian(sw); + Vec3 patchSeModelSpace = ellipsoid.geodetic2ToCartesian(se); + Vec3 patchNwModelSpace = ellipsoid.geodetic2ToCartesian(nw); + Vec3 patchNeModelSpace = ellipsoid.geodetic2ToCartesian(ne); + + // Transform all control points to camera space + Vec3 patchSwCameraSpace = Vec3(dmat4(modelViewTransform) * glm::dvec4(patchSwModelSpace, 1)); + Vec3 patchSeCameraSpace = Vec3(dmat4(modelViewTransform) * glm::dvec4(patchSeModelSpace, 1)); + Vec3 patchNwCameraSpace = Vec3(dmat4(modelViewTransform) * glm::dvec4(patchNwModelSpace, 1)); + Vec3 patchNeCameraSpace = Vec3(dmat4(modelViewTransform) * glm::dvec4(patchNeModelSpace, 1)); + + // Send control points to shader + programObject->setUniform("p00", vec3(patchSwCameraSpace)); + programObject->setUniform("p10", vec3(patchSeCameraSpace)); + programObject->setUniform("p01", vec3(patchNwCameraSpace)); + programObject->setUniform("p11", vec3(patchNeCameraSpace)); + + vec3 patchNormalCameraSpace = normalize( + cross(patchSeCameraSpace - patchSwCameraSpace, + patchNwCameraSpace - patchSwCameraSpace)); + + programObject->setUniform( + "patchNormalCameraSpace", + patchNormalCameraSpace); + + programObject->setUniform( + "projectionTransform", + data.camera.projectionMatrix()); + + // OpenGL rendering settings + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + + // render + _grid->geometry().drawUsingActiveProgram(); + + // disable shader + programObject->deactivate(); + + + + + + + /* using namespace glm; // TODO : Model transform should be fetched as a matrix directly. @@ -287,6 +583,7 @@ namespace openspace { // disable shader _programObjectLocalRendering->deactivate(); + */ } ////////////////////////////////////////////////////////////////////////////////////// @@ -319,6 +616,15 @@ namespace openspace { _programObjectLocalRendering->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes); } + ClipMapPatchRenderer::~ClipMapPatchRenderer() + { + if (_programObjectGlobalRendering) { + RenderEngine& renderEngine = OsEng.renderEngine(); + renderEngine.removeRenderProgram(_programObjectGlobalRendering); + _programObjectGlobalRendering = nullptr; + } + } + void ClipMapPatchRenderer::renderPatch( const Geodetic2& patchSize, const RenderData& data, diff --git a/modules/globebrowsing/rendering/patchrenderer.h b/modules/globebrowsing/rendering/patchrenderer.h index f3ee419ff8..a48039b57e 100644 --- a/modules/globebrowsing/rendering/patchrenderer.h +++ b/modules/globebrowsing/rendering/patchrenderer.h @@ -39,10 +39,9 @@ #include #include #include +#include #include - - namespace ghoul { namespace opengl { class ProgramObject; @@ -52,7 +51,6 @@ namespace opengl { namespace openspace { - class LonLatPatch; class TriangleSoup; using std::shared_ptr; @@ -68,8 +66,6 @@ namespace openspace { void update(); protected: - unique_ptr _programObjectGlobalRendering; - unique_ptr _programObjectLocalRendering; std::shared_ptr _tileProviderManager; }; @@ -96,7 +92,10 @@ namespace openspace { const Chunk& chunk, const Ellipsoid& ellipsoid, const RenderData& data); + shared_ptr _grid; + unique_ptr _globalRenderingShaderProvider; + unique_ptr _localRenderingShaderProvider; }; @@ -109,6 +108,8 @@ namespace openspace { shared_ptr grid, shared_ptr tileProviderManager); + ~ClipMapPatchRenderer(); + void renderPatch( const Geodetic2& patchSize, const RenderData& data, @@ -124,6 +125,9 @@ namespace openspace { const RenderData& data, const Ellipsoid& ellipsoid); + unique_ptr _programObjectGlobalRendering; + unique_ptr _programObjectLocalRendering; + PatchCoverageProvider _patchCoverageProvider; shared_ptr _grid; }; diff --git a/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl b/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl index 488cc35fa3..ce6166c2dc 100644 --- a/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl +++ b/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl @@ -26,18 +26,35 @@ #include "PowerScaling/powerScaling_fs.hglsl" #include "fragment.glsl" -uniform TextureTile colorTile; +#define NUMLAYERS_COLORTEXTURE 1 +#define NUMLAYERS_HEIGHTMAP 1 + +uniform TextureTile colorTiles[NUMLAYERS_COLORTEXTURE]; in vec4 fs_position; in vec2 fs_uv; +vec4 blendOver(vec4 oldColor, vec4 newColor) +{ + vec4 toReturn; + toReturn.rgb = + (newColor.rgb * newColor.a + oldColor.rgb * oldColor.a * (1 - newColor.a)) / + (newColor.a + oldColor.a * (1 - newColor.a)); + toReturn.a = newColor.a + oldColor.a * (1 - newColor.a); + return toReturn; +} + Fragment getFragment() { Fragment frag; - vec2 samplePos = - colorTile.uvTransform.uvScale * fs_uv + - colorTile.uvTransform.uvOffset; - frag.color = texture(colorTile.textureSampler, samplePos); + for (int i = 0; i < NUMLAYERS_COLORTEXTURE; ++i) + { + vec2 samplePos = + colorTiles[i].uvTransform.uvScale * fs_uv + + colorTiles[i].uvTransform.uvOffset; + vec4 colorSample = texture(colorTiles[i].textureSampler, samplePos); + frag.color = blendOver(frag.color, colorSample); + } //frag.color.rgb *= 10; diff --git a/modules/globebrowsing/shaders/globalchunkedlodpatch_vs.glsl b/modules/globebrowsing/shaders/globalchunkedlodpatch_vs.glsl index bf4f36ea2e..efc89bca55 100644 --- a/modules/globebrowsing/shaders/globalchunkedlodpatch_vs.glsl +++ b/modules/globebrowsing/shaders/globalchunkedlodpatch_vs.glsl @@ -28,13 +28,16 @@ #include <${MODULE_GLOBEBROWSING}/shaders/ellipsoid.hglsl> #include <${MODULE_GLOBEBROWSING}/shaders/texturetile.hglsl> +#define NUMLAYERS_COLORTEXTURE 1 +#define NUMLAYERS_HEIGHTMAP 1 + uniform mat4 modelViewProjectionTransform; uniform vec3 radiiSquared; uniform vec2 minLatLon; uniform vec2 lonLatScalingFactor; -uniform TextureTile heightTile; +uniform TextureTile heightTiles[NUMLAYERS_HEIGHTMAP]; layout(location = 1) in vec2 in_uv; @@ -53,22 +56,28 @@ void main() { PositionNormalPair pair = globalInterpolation(); - vec2 samplePos = - heightTile.uvTransform.uvScale * in_uv + - heightTile.uvTransform.uvOffset; + float height = 0; + for (int i = 0; i < NUMLAYERS_HEIGHTMAP; ++i) + { + vec2 samplePos = + heightTiles[i].uvTransform.uvScale * in_uv + + heightTiles[i].uvTransform.uvOffset; - float sampledHeight = texture(heightTile.textureSampler, samplePos).r; + float sampledValue = texture(heightTiles[i].textureSampler, samplePos).r; + + // TODO : Some kind of blending here. Now it just writes over + height = (sampledValue * + heightTiles[i].depthTransform.depthScale + + heightTiles[i].depthTransform.depthOffset); + } - pair.position += - pair.normal * - (sampledHeight * - heightTile.depthTransform.depthScale + - heightTile.depthTransform.depthOffset); + // Add the height in the direction of the normal + pair.position += pair.normal * height; - vec4 position = modelViewProjectionTransform * vec4(pair.position, 1); + vec4 positionClippingSpace = modelViewProjectionTransform * vec4(pair.position, 1); // Write output fs_uv = in_uv; - fs_position = z_normalization(position); + fs_position = z_normalization(positionClippingSpace); gl_Position = fs_position; } \ No newline at end of file diff --git a/modules/globebrowsing/shaders/localchunkedlodpatch_fs.glsl b/modules/globebrowsing/shaders/localchunkedlodpatch_fs.glsl index 8f935d9225..43e3c94595 100644 --- a/modules/globebrowsing/shaders/localchunkedlodpatch_fs.glsl +++ b/modules/globebrowsing/shaders/localchunkedlodpatch_fs.glsl @@ -26,18 +26,40 @@ #include "PowerScaling/powerScaling_fs.hglsl" #include "fragment.glsl" -uniform TextureTile colorTile; +#define NUMLAYERS_COLORTEXTURE 1 +#define NUMLAYERS_HEIGHTMAP 1 + +uniform TextureTile colorTiles[NUMLAYERS_COLORTEXTURE]; in vec4 fs_position; in vec2 fs_uv; +vec4 blendOver(vec4 oldColor, vec4 newColor) +{ + vec4 toReturn; + toReturn.rgb = + (newColor.rgb * newColor.a + oldColor.rgb * oldColor.a * (1 - newColor.a)) / + (newColor.a + oldColor.a * (1 - newColor.a)); + toReturn.a = newColor.a + oldColor.a * (1 - newColor.a); + return toReturn; +} + Fragment getFragment() { Fragment frag; - vec2 samplePos = - colorTile.uvTransform.uvScale * fs_uv + - colorTile.uvTransform.uvOffset; - frag.color = texture(colorTile.textureSampler, samplePos); + for (int i = 0; i < NUMLAYERS_COLORTEXTURE; ++i) + { + vec2 samplePos = + colorTiles[i].uvTransform.uvScale * fs_uv + + colorTiles[i].uvTransform.uvOffset; + vec4 colorSample = texture(colorTiles[i].textureSampler, samplePos); + frag.color = blendOver(frag.color, colorSample); + } + + //vec2 samplePos = + // colorTile.uvTransform.uvScale * fs_uv + + // colorTile.uvTransform.uvOffset; + //frag.color = texture(colorTile.textureSampler, samplePos); //frag.color.rgb *= 10; diff --git a/modules/globebrowsing/shaders/localchunkedlodpatch_vs.glsl b/modules/globebrowsing/shaders/localchunkedlodpatch_vs.glsl index 152acaa92b..6688a5be6d 100644 --- a/modules/globebrowsing/shaders/localchunkedlodpatch_vs.glsl +++ b/modules/globebrowsing/shaders/localchunkedlodpatch_vs.glsl @@ -29,6 +29,9 @@ #include <${MODULE_GLOBEBROWSING}/shaders/ellipsoid.hglsl> #include <${MODULE_GLOBEBROWSING}/shaders/texturetile.hglsl> +#define NUMLAYERS_COLORTEXTURE 1 +#define NUMLAYERS_HEIGHTMAP 1 + uniform mat4 projectionTransform; // Input points in camera space @@ -38,7 +41,7 @@ uniform vec3 p01; uniform vec3 p11; uniform vec3 patchNormalCameraSpace; -uniform TextureTile heightTile; +uniform TextureTile heightTiles[NUMLAYERS_HEIGHTMAP]; layout(location = 1) in vec2 in_uv; @@ -58,18 +61,23 @@ void main() // Position in cameraspace vec3 p = bilinearInterpolation(in_uv); - // Transform uv coordinates to texture space - vec2 samplePos = - heightTile.uvTransform.uvScale * in_uv + - heightTile.uvTransform.uvOffset; + float height = 0; + for (int i = 0; i < NUMLAYERS_HEIGHTMAP; ++i) + { + vec2 samplePos = + heightTiles[i].uvTransform.uvScale * in_uv + + heightTiles[i].uvTransform.uvOffset; - float sampledHeight = texture(heightTile.textureSampler, samplePos).r; + float sampledValue = texture(heightTiles[i].textureSampler, samplePos).r; + + // TODO : Some kind of blending here. Now it just writes over + height = (sampledValue * + heightTiles[i].depthTransform.depthScale + + heightTiles[i].depthTransform.depthOffset); + } // Translate the point along normal - p += patchNormalCameraSpace * - (sampledHeight * - heightTile.depthTransform.depthScale + - heightTile.depthTransform.depthOffset); + p += patchNormalCameraSpace * height; vec4 positionClippingSpace = projectionTransform * vec4(p, 1); diff --git a/modules/globebrowsing/shaders/multipletexturestest_fs.glsl b/modules/globebrowsing/shaders/multipletexturestest_fs.glsl new file mode 100644 index 0000000000..4cadf80de0 --- /dev/null +++ b/modules/globebrowsing/shaders/multipletexturestest_fs.glsl @@ -0,0 +1,71 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * 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 <${MODULE_GLOBEBROWSING}/shaders/texturetile.hglsl> +#include "PowerScaling/powerScaling_fs.hglsl" +#include "fragment.glsl" + +#define NUMLAYERS_COLORTEXTURE #{numLayersColor} +#define NUMLAYERS_HEIGHTMAP #{numLayersHeight} + +uniform TextureTile colorTiles[NUMLAYERS_COLORTEXTURE]; + +in vec4 fs_position; +in vec2 fs_uv; + +vec4 blendOver(vec4 oldColor, vec4 newColor) +{ + vec4 toReturn; + toReturn.rgb = + (newColor.rgb * newColor.a + oldColor.rgb * oldColor.a * (1 - newColor.a)) / + (newColor.a + oldColor.a * (1 - newColor.a)); + toReturn.a = newColor.a + oldColor.a * (1 - newColor.a); + return toReturn; +} + +Fragment getFragment() { + Fragment frag; + + for (int i = 0; i < NUMLAYERS_COLORTEXTURE; ++i) + { + vec2 samplePos = + colorTile.uvTransform.uvScale * fs_uv + + colorTile.uvTransform.uvOffset; + vec4 colorSample = texture(colorTile.textureSampler, samplePos); + frag.color = blendOver(frag.color, colorSample); + } + + //frag.color.rgb *= 10; + + // Sample position overlay + //frag.color = frag.color * 0.9 + 0.2*vec4(samplePos, 0, 1); + + // Border overlay + //frag.color = frag.color + patchBorderOverlay(fs_uv, vec3(0.5, 0.5, 0.5), 0.02); + + frag.depth = fs_position.w; + + return frag; +} + diff --git a/modules/globebrowsing/shaders/multipletexturestest_vs.glsl b/modules/globebrowsing/shaders/multipletexturestest_vs.glsl new file mode 100644 index 0000000000..81fe0721c1 --- /dev/null +++ b/modules/globebrowsing/shaders/multipletexturestest_vs.glsl @@ -0,0 +1,83 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * 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. * + ****************************************************************************************/ + +#version __CONTEXT__ + +#include "PowerScaling/powerScaling_vs.hglsl" +#include <${MODULE_GLOBEBROWSING}/shaders/ellipsoid.hglsl> +#include <${MODULE_GLOBEBROWSING}/shaders/texturetile.hglsl> + +#define NUMLAYERS_COLORTEXTURE #{numLayersColor} +#define NUMLAYERS_HEIGHTMAP #{numLayersHeight} + +uniform mat4 modelViewProjectionTransform; +uniform vec3 radiiSquared; + +uniform vec2 minLatLon; +uniform vec2 lonLatScalingFactor; + +uniform TextureTile heightTiles[NUMLAYERS_HEIGHTMAP]; + +layout(location = 1) in vec2 in_uv; + +out vec2 fs_uv; +out vec4 fs_position; + +PositionNormalPair globalInterpolation() { + vec2 lonLatInput; + lonLatInput.y = minLatLon.y + lonLatScalingFactor.y * in_uv.y; // Lat + lonLatInput.x = minLatLon.x + lonLatScalingFactor.x * in_uv.x; // Lon + PositionNormalPair positionPairModelSpace = geodetic2ToCartesian(lonLatInput.y, lonLatInput.x, radiiSquared); + return positionPairModelSpace; +} + +void main() +{ + PositionNormalPair pair = globalInterpolation(); + + float height = 0; + for (int i = 0; i < NUMLAYERS_HEIGHTMAP; ++i) + { + vec2 samplePos = + heightTiles[i].uvTransform.uvScale * in_uv + + heightTiles[i].uvTransform.uvOffset; + + float sampledValue = texture(heightTiles[i].textureSampler, samplePos).r; + + // TODO : Some kind of blending here. Now it just writes over + height = (sampledValue * + heightTiles[i].depthTransform.depthScale + + heightTiles[i].depthTransform.depthOffset); + } + + // Add the height in the direction of the normal + pair.position += pair.normal * height; + + vec4 position = modelViewProjectionTransform * vec4(pair.position, 1); + + // Write output + fs_uv = in_uv; + fs_position = z_normalization(position); + gl_Position = fs_position; +} \ No newline at end of file