diff --git a/modules/globebrowsing/rendering/patchrenderer.cpp b/modules/globebrowsing/rendering/patchrenderer.cpp index 2184ab1398..1e5df03114 100644 --- a/modules/globebrowsing/rendering/patchrenderer.cpp +++ b/modules/globebrowsing/rendering/patchrenderer.cpp @@ -92,20 +92,39 @@ namespace openspace { , _grid(grid) { _programObjectGlobalRendering = OsEng.renderEngine().buildRenderProgram( - "GlobalChunkedLodPatch", + "GlobalClipMapPatch", "${MODULE_GLOBEBROWSING}/shaders/globalchunkedlodpatch_vs.glsl", "${MODULE_GLOBEBROWSING}/shaders/globalchunkedlodpatch_fs.glsl"); ghoul_assert(_programObjectGlobalRendering != nullptr, "Failed to initialize programObject!"); + _programObjectLocalRendering = OsEng.renderEngine().buildRenderProgram( + "LocalClipMapPatch", + "${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(const Chunk& chunk, const Ellipsoid& ellipsoid, + void ChunkRenderer::renderChunk( + const Chunk& chunk, + const Ellipsoid& ellipsoid, const RenderData& data) - + { + if (chunk.index().level < 10) { + renderChunkGlobally(chunk, ellipsoid, data); + } + else { + renderChunkLocally(chunk, ellipsoid, data); + } + } + + void ChunkRenderer::renderChunkGlobally( + const Chunk& chunk, + const Ellipsoid& ellipsoid, + const RenderData& data) { using namespace glm; @@ -172,6 +191,96 @@ namespace openspace { } + void ChunkRenderer::renderChunkLocally( + const Chunk& chunk, + const Ellipsoid& ellipsoid, + const RenderData& data) + { + using namespace glm; + + // 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; + + // activate shader + _programObjectLocalRendering->activate(); + + + // For now just pick the first one from height maps + auto heightMapProviders = _tileProviderManager->heightMapProviders(); + auto tileProviderHeight = heightMapProviders.begin()->second; + + // Get the textures that should be used for rendering + Tile heightTile = tileProviderHeight->getMostHiResTile(chunk.index()); + + // Bind and use the texture + ghoul::opengl::TextureUnit texUnitHeight; + texUnitHeight.activate(); + heightTile.texture->bind(); + _programObjectLocalRendering->setUniform("textureSamplerHeight", texUnitHeight); + _programObjectLocalRendering->setUniform("heightSamplingScale", heightTile.transform.uvScale); + _programObjectLocalRendering->setUniform("heightSamplingOffset", heightTile.transform.uvOffset); + + // Pick the first color texture + auto colorTextureProviders = _tileProviderManager->colorTextureProviders(); + auto tileProviderColor = colorTextureProviders.begin()->second; + Tile colorTile = tileProviderColor->getMostHiResTile(chunk.index()); + + + // Bind and use the texture + ghoul::opengl::TextureUnit texUnitColor; + texUnitColor.activate(); + colorTile.texture->bind(); + _programObjectLocalRendering->setUniform("textureSamplerColor", texUnitColor); + _programObjectLocalRendering->setUniform("colorSamplingScale", colorTile.transform.uvScale); + _programObjectLocalRendering->setUniform("colorSamplingOffset", colorTile.transform.uvOffset); + + + 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 + _programObjectLocalRendering->setUniform("p00", vec3(patchSwCameraSpace)); + _programObjectLocalRendering->setUniform("p10", vec3(patchSeCameraSpace)); + _programObjectLocalRendering->setUniform("p01", vec3(patchNwCameraSpace)); + _programObjectLocalRendering->setUniform("p11", vec3(patchNeCameraSpace)); + + vec3 patchNormalCameraSpace = normalize( + cross(patchSeCameraSpace - patchSwCameraSpace, + patchNwCameraSpace - patchSwCameraSpace)); + _programObjectLocalRendering->setUniform( + "patchNormalCameraSpace", + patchNormalCameraSpace); + + _programObjectLocalRendering->setUniform( + "projectionTransform", + data.camera.projectionMatrix()); + + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + + // render + _grid->geometry().drawUsingActiveProgram(); + + // disable shader + _programObjectLocalRendering->deactivate(); + } ////////////////////////////////////////////////////////////////////////////////////// // CLIPMAP PATCH RENDERER // diff --git a/modules/globebrowsing/rendering/patchrenderer.h b/modules/globebrowsing/rendering/patchrenderer.h index cea4d048c2..f3ee419ff8 100644 --- a/modules/globebrowsing/rendering/patchrenderer.h +++ b/modules/globebrowsing/rendering/patchrenderer.h @@ -83,10 +83,19 @@ namespace openspace { ChunkRenderer(shared_ptr grid, shared_ptr tileProviderManager); - - void ChunkRenderer::renderChunk(const Chunk& chunk, const Ellipsoid& ellipsoid, const RenderData& data); - + void ChunkRenderer::renderChunk( + const Chunk& chunk, + const Ellipsoid& ellipsoid, + const RenderData& data); private: + void ChunkRenderer::renderChunkGlobally( + const Chunk& chunk, + const Ellipsoid& ellipsoid, + const RenderData& data); + void ChunkRenderer::renderChunkLocally( + const Chunk& chunk, + const Ellipsoid& ellipsoid, + const RenderData& data); shared_ptr _grid; }; diff --git a/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl b/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl index 8652a9a144..414ff6135a 100644 --- a/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl +++ b/modules/globebrowsing/shaders/globalchunkedlodpatch_fs.glsl @@ -55,7 +55,7 @@ Fragment getFragment() { //frag.color = frag.color * 0.9 + 0.2*vec4(samplePos, 0, 1); // Border overlay - frag.color = frag.color + borderOverlay(fs_uv, vec3(0.5, 0.5, 0.5), 0.02); + //frag.color = frag.color + borderOverlay(fs_uv, vec3(0.5, 0.5, 0.5), 0.02); frag.depth = vs_position.w; diff --git a/modules/globebrowsing/shaders/localchunkedlodpatch_fs.glsl b/modules/globebrowsing/shaders/localchunkedlodpatch_fs.glsl new file mode 100644 index 0000000000..54fccc6a16 --- /dev/null +++ b/modules/globebrowsing/shaders/localchunkedlodpatch_fs.glsl @@ -0,0 +1,60 @@ +/***************************************************************************************** + * * + * 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. * + ****************************************************************************************/ + +// Colortexture coverage +uniform sampler2D textureSamplerColor; +uniform vec2 colorSamplingScale; +uniform vec2 colorSamplingOffset; + +in vec4 fs_position; +in vec2 fs_uv; + +#include "PowerScaling/powerScaling_fs.hglsl" +#include "fragment.glsl" + +vec4 borderOverlay(vec2 uv, vec3 borderColor, float borderSize){ + vec2 uvOffset = uv - vec2(0.5); + float thres = 0.5 - borderSize/2; + bool isBorder = abs(uvOffset.x) > thres || abs(uvOffset.y) > thres; + vec3 color = isBorder ? borderColor : vec3(0); + return vec4(color, 0); +} + +Fragment getFragment() { + Fragment frag; + + vec2 samplePos = colorSamplingScale * fs_uv + colorSamplingOffset; + frag.color = texture(textureSamplerColor, samplePos);// + vec4(0.5,0,0,0); + + // Sample position overlay + //frag.color = frag.color * 0.9 + 0.2*vec4(samplePos, 0, 1); + + // Border overlay + //frag.color = frag.color + borderOverlay(fs_uv, vec3(0.5, 0.5, 0.5), 0.02); + + frag.depth = fs_position.w; + + return frag; +} + diff --git a/modules/globebrowsing/shaders/localchunkedlodpatch_vs.glsl b/modules/globebrowsing/shaders/localchunkedlodpatch_vs.glsl new file mode 100644 index 0000000000..c1ba33dfc0 --- /dev/null +++ b/modules/globebrowsing/shaders/localchunkedlodpatch_vs.glsl @@ -0,0 +1,77 @@ +/***************************************************************************************** + * * + * 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__ + +uniform mat4 projectionTransform; + +// Input points in camera space +uniform vec3 p00; +uniform vec3 p10; +uniform vec3 p01; +uniform vec3 p11; + +uniform vec3 patchNormalCameraSpace; + +uniform sampler2D textureSamplerHeight; +uniform vec2 heightSamplingScale; +uniform vec2 heightSamplingOffset; + +layout(location = 1) in vec2 in_uv; + +out vec2 fs_uv; +out vec4 fs_position; + +#include "PowerScaling/powerScaling_vs.hglsl" +#include <${MODULE_GLOBEBROWSING}/shaders/ellipsoid.hglsl> + +vec3 bilinearInterpolation(vec2 uv) { + // Bilinear interpolation + vec3 p0 = (1 - uv.x) * p00 + uv.x * p10; + vec3 p1 = (1 - uv.x) * p01 + uv.x * p11; + vec3 p = (1 - uv.y) * p0 + uv.y * p1; + return p; +} + +void main() +{ + fs_uv = in_uv; + + // Position in cameraspace + vec3 p = bilinearInterpolation(fs_uv); + + // Transform uv coordinates to texture space + vec2 samplePos = heightSamplingScale * in_uv + heightSamplingOffset; + + float sampledHeight = texture(textureSamplerHeight, samplePos).r; + + // Translate the point along normal + p += patchNormalCameraSpace * sampledHeight * pow(2,15); + + vec4 positionClippingSpace = projectionTransform * vec4(p, 1); + + gl_Position = z_normalization(positionClippingSpace); + fs_position = gl_Position; +} \ No newline at end of file