mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-07 20:21:24 -06:00
Added shadow and ring components to Globebrowsing and shaders for shadows.
This commit is contained in:
@@ -9,9 +9,9 @@ asset.onInitialize(function ()
|
||||
|
||||
openspace.globebrowsing.goToGeo("Earth", 58.5877, 16.1924, 20000000)
|
||||
|
||||
openspace.markInterestingNodes({ "Earth", "Mars", "Moon", "Sun" })
|
||||
openspace.markInterestingNodes({ "Saturn", "Mars", "Moon", "Sun", "Saturn" })
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function ()
|
||||
openspace.removeInterestingNodes({ "Earth", "Mars", "Moon", "Sun" })
|
||||
openspace.removeInterestingNodes({ "Earth", "Mars", "Moon", "Sun", "Saturn" })
|
||||
end)
|
||||
|
||||
@@ -34,6 +34,15 @@ local Saturn = {
|
||||
Enabled = true
|
||||
}
|
||||
}
|
||||
},
|
||||
Rings = {
|
||||
Texture = textures .. "/saturn_rings.png",
|
||||
Size = 140445000,
|
||||
Offset = { 74500 / 140445.100671159, 1.0 }, -- min / max extend
|
||||
Shadows = {
|
||||
Enabled = true,
|
||||
DistanceFraction = 50.0
|
||||
}
|
||||
}
|
||||
},
|
||||
Tag = { "planet_solarSystem", "planet_giants" },
|
||||
@@ -42,21 +51,22 @@ local Saturn = {
|
||||
}
|
||||
}
|
||||
|
||||
local SaturnRings = {
|
||||
Identifier = "SaturnRings",
|
||||
Parent = Saturn.Identifier,
|
||||
Renderable = {
|
||||
Type = "RenderableRings",
|
||||
Texture = textures .. "/saturn_rings.png",
|
||||
Size = 140445000,
|
||||
Offset = { 74500 / 140445.100671159, 1.0 } -- min / max extend
|
||||
},
|
||||
GUI = {
|
||||
Name = "Saturn Rings",
|
||||
Path = "/Solar System/Planets/Saturn"
|
||||
}
|
||||
}
|
||||
-- local SaturnRings = {
|
||||
-- Identifier = "SaturnRings",
|
||||
-- Parent = Saturn.Identifier,
|
||||
-- Renderable = {
|
||||
-- Type = "RenderableRings",
|
||||
-- Texture = textures .. "/saturn_rings.png",
|
||||
-- Size = 140445000,
|
||||
-- Offset = { 74500 / 140445.100671159, 1.0 } -- min / max extend
|
||||
-- },
|
||||
-- GUI = {
|
||||
-- Name = "Saturn Rings",
|
||||
-- Path = "/Solar System/Planets/Saturn"
|
||||
-- }
|
||||
-- }
|
||||
|
||||
|
||||
|
||||
assetHelper.registerSceneGraphNodesAndExport(asset, { Saturn, SaturnRings })
|
||||
--assetHelper.registerSceneGraphNodesAndExport(asset, { Saturn, SaturnRings })
|
||||
assetHelper.registerSceneGraphNodesAndExport(asset, { Saturn })
|
||||
|
||||
@@ -51,6 +51,8 @@ set(HEADER_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/rawtile.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/rawtiledatareader.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/renderableglobe.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/ringscomponent.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/shadowcomponent.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/skirtedgrid.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/tileindex.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/tileloadjob.h
|
||||
@@ -80,6 +82,8 @@ set(SOURCE_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/rawtile.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/rawtiledatareader.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/renderableglobe.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/ringscomponent.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/shadowcomponent.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/skirtedgrid.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/tileindex.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/tileloadjob.cpp
|
||||
@@ -94,6 +98,10 @@ set(SHADER_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/globalrenderer_vs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/localrenderer_vs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/renderer_fs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/rings_vs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/rings_fs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/rings_geom_vs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/rings_geom_fs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/texturetilemapping.hglsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/tile.hglsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/tileheight.hglsl
|
||||
|
||||
129
modules/globebrowsing/shaders/rings_fs.glsl
Normal file
129
modules/globebrowsing/shaders/rings_fs.glsl
Normal file
@@ -0,0 +1,129 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2018 *
|
||||
* *
|
||||
* 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 "PowerScaling/powerScaling_fs.hglsl"
|
||||
#include "fragment.glsl"
|
||||
|
||||
in vec2 vs_st;
|
||||
in float vs_screenSpaceDepth;
|
||||
in vec4 vs_positionViewSpace;
|
||||
in flat vec4 shadowCoords;
|
||||
|
||||
uniform sampler2D shadowPositionTexture;
|
||||
|
||||
uniform sampler2DShadow shadowMap;
|
||||
uniform sampler1D texture1;
|
||||
uniform vec2 textureOffset;
|
||||
uniform float transparency;
|
||||
|
||||
uniform bool hasSunPosition;
|
||||
uniform vec3 sunPosition;
|
||||
uniform float _nightFactor;
|
||||
|
||||
// temp
|
||||
in vec4 fragPosInLightSpace;
|
||||
|
||||
Fragment getFragment() {
|
||||
// Moving the origin to the center
|
||||
vec2 st = (vs_st - vec2(0.5)) * 2.0;
|
||||
|
||||
// The length of the texture coordinates vector is our distance from the center
|
||||
float radius = length(st);
|
||||
|
||||
// We only want to consider ring-like objects so we need to discard everything else
|
||||
if (radius > 1.0)
|
||||
discard;
|
||||
|
||||
// Remapping the texture coordinates
|
||||
// Radius \in [0,1], texCoord \in [textureOffset.x, textureOffset.y]
|
||||
// textureOffset.x -> 0
|
||||
// textureOffset.y -> 1
|
||||
float texCoord = (radius - textureOffset.x) / (textureOffset.y - textureOffset.x);
|
||||
if (texCoord < 0.f || texCoord > 1.f) {
|
||||
discard;
|
||||
}
|
||||
|
||||
vec4 diffuse = texture(texture1, texCoord);
|
||||
float colorValue = length(diffuse.rgb);
|
||||
// times 3 as length of vec3(1.0, 1.0, 1.0) will return 3 and we want
|
||||
// to normalize the transparency value to [0,1]
|
||||
if (colorValue < 3.0 * transparency) {
|
||||
diffuse.a = pow(colorValue / (3.0 * transparency), 1);
|
||||
}
|
||||
|
||||
// shadow == 1.0 means it is not in shadow
|
||||
float shadow = 1.0;
|
||||
if ( shadowCoords.z >= 0 ) {
|
||||
shadow = textureProj(shadowMap, shadowCoords);
|
||||
}
|
||||
|
||||
// shadow = 1.0;
|
||||
// vec4 depthInTexture = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
// //if (shadowCoords.z >= 0) {
|
||||
// if (true) {
|
||||
// vec4 byHandCoords = shadowCoords / shadowCoords.w;
|
||||
// // Distance of the current pixel from the light source
|
||||
// depthInTexture = texture(shadowPositionTexture, byHandCoords.xy);
|
||||
// //depthInTexture = texture(shadowPositionTexture, vec2(0.5, 0.5));
|
||||
// // if (depthInTexture.x < byHandCoords.z) {
|
||||
// // shadow = 0.0;
|
||||
// // }
|
||||
// if (length(fragPosInLightSpace) > depthInTexture.x) {
|
||||
// shadow = 0.2;
|
||||
// }
|
||||
// //shadow = length(fragPosInLightSpace);
|
||||
// }
|
||||
|
||||
// The normal for the one plane depends on whether we are dealing
|
||||
// with a front facing or back facing fragment
|
||||
vec3 normal;
|
||||
// The plane is oriented on the xz plane
|
||||
// WARNING: This might not be the case for Uranus
|
||||
if (gl_FrontFacing) {
|
||||
normal = vec3(-1.0, 0.0, 0.0);
|
||||
}
|
||||
else {
|
||||
normal = vec3(1.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
// Reduce the color of the fragment by the user factor
|
||||
// if we are facing away from the Sun
|
||||
if (dot(sunPosition, normal) < 0) {
|
||||
diffuse.xyz *= _nightFactor;
|
||||
}
|
||||
|
||||
Fragment frag;
|
||||
//frag.color = depthInTexture;
|
||||
frag.color = (0.55 * diffuse * shadow) + diffuse * 0.45;
|
||||
//frag.color = vec4(shadow * vec3(1.0, 1.0, 1.0), 1.0);
|
||||
//frag.depth = vs_position.w;
|
||||
frag.depth = vs_screenSpaceDepth;
|
||||
if (diffuse.a < 1.0)
|
||||
frag.gPosition = vec4(1e30, 1e30, 1e30, 1.0);
|
||||
else
|
||||
frag.gPosition = vs_positionViewSpace;
|
||||
frag.gNormal = vec4(normal, 1.0);
|
||||
|
||||
return frag;
|
||||
}
|
||||
75
modules/globebrowsing/shaders/rings_geom_fs.glsl
Normal file
75
modules/globebrowsing/shaders/rings_geom_fs.glsl
Normal file
@@ -0,0 +1,75 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2018 *
|
||||
* *
|
||||
* 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 "PowerScaling/powerScaling_fs.hglsl"
|
||||
#include "fragment.glsl"
|
||||
|
||||
layout (location = 3) out vec4 renderedPosition;
|
||||
|
||||
in vec2 vs_st;
|
||||
in float vs_screenSpaceDepth;
|
||||
in vec4 vs_positionViewSpace;
|
||||
|
||||
uniform vec2 textureOffset;
|
||||
|
||||
Fragment getFragment() {
|
||||
// Moving the origin to the center
|
||||
vec2 st = (vs_st - vec2(0.5)) * 2.0;
|
||||
|
||||
// The length of the texture coordinates vector is our distance from the center
|
||||
float radius = length(st);
|
||||
|
||||
// We only want to consider ring-like objects so we need to discard everything else
|
||||
if (radius > 1.0)
|
||||
discard;
|
||||
|
||||
// Remapping the texture coordinates
|
||||
// Radius \in [0,1], texCoord \in [textureOffset.x, textureOffset.y]
|
||||
// textureOffset.x -> 0
|
||||
// textureOffset.y -> 1
|
||||
float texCoord = (radius - textureOffset.x) / (textureOffset.y - textureOffset.x);
|
||||
if (texCoord < 0.f || texCoord > 1.f) {
|
||||
discard;
|
||||
}
|
||||
|
||||
// The normal for the one plane depends on whether we are dealing
|
||||
// with a front facing or back facing fragment
|
||||
//vec3 normal;
|
||||
// The plane is oriented on the xz plane
|
||||
// WARNING: This might not be the case for Uranus
|
||||
// if (gl_FrontFacing) {
|
||||
// normal = vec3(-1.0, 0.0, 0.0);
|
||||
// }
|
||||
// else {
|
||||
// normal = vec3(1.0, 0.0, 0.0);
|
||||
// }
|
||||
|
||||
Fragment frag;
|
||||
frag.color = vec4(1.0);;
|
||||
frag.depth = vs_screenSpaceDepth;
|
||||
renderedPosition = vec4(vec3(length(vs_positionViewSpace.xyz)), 1.0);//vec4(vs_positionViewSpace.xyz, 1.0);
|
||||
//renderedPosition = vec4(vec3(vs_screenSpaceDepth.w)/10.0, 1.0);
|
||||
|
||||
return frag;
|
||||
}
|
||||
51
modules/globebrowsing/shaders/rings_geom_vs.glsl
Normal file
51
modules/globebrowsing/shaders/rings_geom_vs.glsl
Normal file
@@ -0,0 +1,51 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2018 *
|
||||
* *
|
||||
* 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/powerScalingMath.hglsl"
|
||||
|
||||
layout(location = 0) in vec2 in_position;
|
||||
layout(location = 1) in vec2 in_st;
|
||||
|
||||
out vec2 vs_st;
|
||||
out float vs_screenSpaceDepth;
|
||||
out vec4 vs_positionViewSpace;
|
||||
|
||||
uniform dmat4 modelViewMatrix;
|
||||
uniform dmat4 projectionMatrix;
|
||||
|
||||
void main() {
|
||||
vs_st = in_st;
|
||||
|
||||
dvec4 positionViewSpace = modelViewMatrix * dvec4(in_position, 0.0, 1.0);
|
||||
vec4 positionClipSpace = vec4(projectionMatrix * positionViewSpace);
|
||||
vec4 positionClipSpaceZNorm = z_normalization(positionClipSpace);
|
||||
|
||||
vs_screenSpaceDepth = positionClipSpaceZNorm.w;
|
||||
vs_positionViewSpace = vec4(positionViewSpace);
|
||||
|
||||
//gl_Position = positionClipSpaceZNorm;
|
||||
gl_Position = positionClipSpace;
|
||||
}
|
||||
67
modules/globebrowsing/shaders/rings_vs.glsl
Normal file
67
modules/globebrowsing/shaders/rings_vs.glsl
Normal file
@@ -0,0 +1,67 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2018 *
|
||||
* *
|
||||
* 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"
|
||||
|
||||
layout(location = 0) in vec2 in_position;
|
||||
layout(location = 1) in vec2 in_st;
|
||||
|
||||
out vec2 vs_st;
|
||||
out float vs_screenSpaceDepth;
|
||||
out vec4 vs_positionViewSpace;
|
||||
out vec4 shadowCoords;
|
||||
|
||||
// temp
|
||||
out vec4 fragPosInLightSpace;
|
||||
uniform dmat4 objectToLightSpaceMatrix;
|
||||
|
||||
uniform dmat4 modelViewMatrix;
|
||||
uniform dmat4 projectionMatrix;
|
||||
|
||||
// ShadowMatrix is the matrix defined by:
|
||||
// textureCoordsMatrix * projectionMatrix * combinedViewMatrix * modelMatrix
|
||||
// where textureCoordsMatrix is just a scale and bias computation: [-1,1] to [0,1]
|
||||
uniform dmat4 shadowMatrix;
|
||||
|
||||
|
||||
void main() {
|
||||
vs_st = in_st;
|
||||
|
||||
dvec4 positionViewSpace = modelViewMatrix * dvec4(in_position, 0.0, 1.0);
|
||||
vec4 positionClipSpace = vec4(projectionMatrix * positionViewSpace);
|
||||
vec4 positionClipSpaceZNorm = z_normalization(positionClipSpace);
|
||||
|
||||
shadowCoords = vec4(shadowMatrix * dvec4(in_position, 0.0, 1.0));
|
||||
// temp
|
||||
fragPosInLightSpace = vec4(objectToLightSpaceMatrix *
|
||||
dvec4(in_position.xy, 0.0, 1.0));
|
||||
|
||||
vs_screenSpaceDepth = positionClipSpaceZNorm.w;
|
||||
vs_positionViewSpace = vec4(positionViewSpace);
|
||||
|
||||
//gl_Position = positionClipSpaceZNorm;
|
||||
gl_Position = positionClipSpace;
|
||||
}
|
||||
@@ -505,6 +505,8 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
|
||||
, _grid(DefaultSkirtedGridSegments, DefaultSkirtedGridSegments)
|
||||
, _leftRoot(Chunk(LeftHemisphereIndex))
|
||||
, _rightRoot(Chunk(RightHemisphereIndex))
|
||||
, _ringsComponent(dictionary)
|
||||
, _shadowComponent(dictionary)
|
||||
{
|
||||
_generalProperties.currentLodScaleFactor.setReadOnly(true);
|
||||
|
||||
@@ -656,6 +658,20 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
|
||||
_labelsDictionary = dictionary.value<ghoul::Dictionary>(KeyLabels);
|
||||
}
|
||||
|
||||
// Components
|
||||
if (dictionary.hasKey("Rings")) {
|
||||
_ringsComponent.initialize();
|
||||
addPropertySubOwner(_ringsComponent);
|
||||
_hasRings = true;
|
||||
|
||||
ghoul::Dictionary ringsDic;
|
||||
dictionary.getValue("Rings", ringsDic);
|
||||
if (ringsDic.hasKey("Shadows")) {
|
||||
_shadowComponent.initialize();
|
||||
addPropertySubOwner(_shadowComponent);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef OPENSPACE_MODULE_GLOBEBROWSING_INSTRUMENTATION
|
||||
_module = global::moduleEngine.module<GlobeBrowsingModule>();
|
||||
#endif // OPENSPACE_MODULE_GLOBEBROWSING_INSTRUMENTATION
|
||||
@@ -670,6 +686,11 @@ void RenderableGlobe::initializeGL() {
|
||||
_layerManager.update();
|
||||
|
||||
_grid.initializeGL();
|
||||
|
||||
_ringsComponent.initializeGL();
|
||||
|
||||
_shadowComponent.initializeGL();
|
||||
|
||||
// Recompile the shaders directly so that it is not done the first time the render
|
||||
// function is called.
|
||||
recompileShaders();
|
||||
@@ -691,6 +712,10 @@ void RenderableGlobe::deinitializeGL() {
|
||||
}
|
||||
|
||||
_grid.deinitializeGL();
|
||||
|
||||
_ringsComponent.deinitializeGL();
|
||||
|
||||
_shadowComponent.deinitializeGL();
|
||||
}
|
||||
|
||||
bool RenderableGlobe::isReady() const {
|
||||
@@ -713,8 +738,49 @@ void RenderableGlobe::render(const RenderData& data, RendererTasks& rendererTask
|
||||
|
||||
if (distanceToCamera < distance) {
|
||||
try {
|
||||
renderChunks(data, rendererTask);
|
||||
_globeLabelsComponent.draw(data);
|
||||
// Before Shadows
|
||||
//renderChunks(data, rendererTask);
|
||||
//_globeLabelsComponent.draw(data);
|
||||
|
||||
|
||||
if (_hasRings && _ringsComponent.isEnabled()) {
|
||||
if (_shadowComponent.isEnabled()) {
|
||||
|
||||
glDisablei(GL_BLEND, 3);
|
||||
//glEnablei(GL_DEPTH_TEST, 3);
|
||||
_shadowComponent.begin(data);
|
||||
|
||||
//_ringsComponent.draw(data, RingsComponent::GeometryOnly);
|
||||
//RenderData tmpRD = data;
|
||||
//tmpRD.modelTransform.rotation = tmpRD.modelTransform.rotation * glm::dmat3(glm::rotate(glm::dmat4(1), 90.0, glm::dvec3(1.0, 0.0, 0.0)));
|
||||
//_ringsComponent.draw(tmpRD, RingsComponent::GeometryOnly);
|
||||
renderChunks(data, rendererTask, true);
|
||||
|
||||
_shadowComponent.end(data);
|
||||
glEnablei(GL_BLEND, 3);
|
||||
|
||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(2.5f, 10.0f);
|
||||
|
||||
_ringsComponent.draw(
|
||||
data,
|
||||
RingsComponent::GeometryAndShading,
|
||||
_shadowComponent.shadowMapData()
|
||||
);
|
||||
renderChunks(data, rendererTask);
|
||||
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
}
|
||||
else {
|
||||
renderChunks(data, rendererTask);
|
||||
_ringsComponent.draw(data, RingsComponent::GeometryAndShading);
|
||||
}
|
||||
}
|
||||
else {
|
||||
renderChunks(data, rendererTask);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
catch (const ghoul::opengl::TextureUnit::TextureUnitError&) {
|
||||
std::string layer = _lastChangedLayer ? _lastChangedLayer->guiName() : "";
|
||||
@@ -852,7 +918,8 @@ const glm::dmat4& RenderableGlobe::modelTransform() const {
|
||||
// Rendering code
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void RenderableGlobe::renderChunks(const RenderData& data, RendererTasks&) {
|
||||
void RenderableGlobe::renderChunks(const RenderData& data, RendererTasks&,
|
||||
const bool renderGeomOnly) {
|
||||
if (_shadersNeedRecompilation) {
|
||||
recompileShaders();
|
||||
}
|
||||
@@ -1086,7 +1153,7 @@ void RenderableGlobe::renderChunks(const RenderData& data, RendererTasks&) {
|
||||
// Render all chunks that want to be rendered globally
|
||||
_globalRenderer.program->activate();
|
||||
for (int i = 0; i < std::min(globalCount, ChunkBufferSize); ++i) {
|
||||
renderChunkGlobally(*global[i], data);
|
||||
renderChunkGlobally(*global[i], data, renderGeomOnly);
|
||||
}
|
||||
_globalRenderer.program->deactivate();
|
||||
|
||||
@@ -1094,7 +1161,7 @@ void RenderableGlobe::renderChunks(const RenderData& data, RendererTasks&) {
|
||||
// Render all chunks that need to be rendered locally
|
||||
_localRenderer.program->activate();
|
||||
for (int i = 0; i < std::min(localCount, ChunkBufferSize); ++i) {
|
||||
renderChunkLocally(*local[i], data);
|
||||
renderChunkLocally(*local[i], data, renderGeomOnly);
|
||||
}
|
||||
_localRenderer.program->deactivate();
|
||||
|
||||
@@ -1151,7 +1218,8 @@ void RenderableGlobe::renderChunks(const RenderData& data, RendererTasks&) {
|
||||
}
|
||||
}
|
||||
|
||||
void RenderableGlobe::renderChunkGlobally(const Chunk& chunk, const RenderData& data) {
|
||||
void RenderableGlobe::renderChunkGlobally(const Chunk& chunk, const RenderData& data,
|
||||
const bool renderGeomOnly) {
|
||||
//PerfMeasure("globally");
|
||||
const TileIndex& tileIndex = chunk.tileIndex;
|
||||
ghoul::opengl::ProgramObject& program = *_globalRenderer.program;
|
||||
@@ -1199,16 +1267,21 @@ void RenderableGlobe::renderChunkGlobally(const Chunk& chunk, const RenderData&
|
||||
}
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(GL_BACK);
|
||||
|
||||
if (!renderGeomOnly) {
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(GL_BACK);
|
||||
}
|
||||
|
||||
_grid.drawUsingActiveProgram();
|
||||
|
||||
for (GPULayerGroup& l : _globalRenderer.gpuLayerGroups) {
|
||||
l.deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
void RenderableGlobe::renderChunkLocally(const Chunk& chunk, const RenderData& data) {
|
||||
void RenderableGlobe::renderChunkLocally(const Chunk& chunk, const RenderData& data,
|
||||
const bool renderGeomOnly) {
|
||||
//PerfMeasure("locally");
|
||||
const TileIndex& tileIndex = chunk.tileIndex;
|
||||
ghoul::opengl::ProgramObject& program = *_localRenderer.program;
|
||||
@@ -1301,9 +1374,11 @@ void RenderableGlobe::renderChunkLocally(const Chunk& chunk, const RenderData& d
|
||||
}
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(GL_BACK);
|
||||
|
||||
if (!renderGeomOnly) {
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(GL_BACK);
|
||||
}
|
||||
|
||||
_grid.drawUsingActiveProgram();
|
||||
|
||||
for (GPULayerGroup& l : _localRenderer.gpuLayerGroups) {
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
#include <modules/globebrowsing/src/globelabelscomponent.h>
|
||||
#include <modules/globebrowsing/src/gpulayergroup.h>
|
||||
#include <modules/globebrowsing/src/layermanager.h>
|
||||
#include <modules/globebrowsing/src/ringscomponent.h>
|
||||
#include <modules/globebrowsing/src/shadowcomponent.h>
|
||||
#include <modules/globebrowsing/src/skirtedgrid.h>
|
||||
#include <modules/globebrowsing/src/tileindex.h>
|
||||
#include <openspace/properties/scalar/floatproperty.h>
|
||||
@@ -181,7 +183,8 @@ private:
|
||||
*/
|
||||
float getHeight(const glm::dvec3& position) const;
|
||||
|
||||
void renderChunks(const RenderData& data, RendererTasks& rendererTask);
|
||||
void renderChunks(const RenderData& data, RendererTasks& rendererTask,
|
||||
const bool renderGeomOnly = false);
|
||||
|
||||
/**
|
||||
* Chunks can be rendered either globally or locally. Global rendering is performed
|
||||
@@ -191,7 +194,8 @@ private:
|
||||
* point precision by doing this which means that the camera too close to a global
|
||||
* tile will lead to jagging. We only render global chunks for lower chunk levels.
|
||||
*/
|
||||
void renderChunkGlobally(const Chunk& chunk, const RenderData& data);
|
||||
void renderChunkGlobally(const Chunk& chunk, const RenderData& data,
|
||||
const bool renderGeomOnly = false);
|
||||
|
||||
/**
|
||||
* Local rendering of chunks are done using linear interpolation in camera space.
|
||||
@@ -204,7 +208,8 @@ private:
|
||||
* levels) the better the approximation becomes. This is why we only render local
|
||||
* chunks for higher chunk levels.
|
||||
*/
|
||||
void renderChunkLocally(const Chunk& chunk, const RenderData& data);
|
||||
void renderChunkLocally(const Chunk& chunk, const RenderData& data,
|
||||
const bool renderGeomOnly = false);
|
||||
|
||||
void debugRenderChunk(const Chunk& chunk, const glm::dmat4& mvp,
|
||||
bool renderBounds, bool renderAABB) const;
|
||||
@@ -275,6 +280,11 @@ private:
|
||||
size_t _iterationsOfUnavailableData = 0;
|
||||
Layer* _lastChangedLayer = nullptr;
|
||||
|
||||
// Components
|
||||
RingsComponent _ringsComponent;
|
||||
ShadowComponent _shadowComponent;
|
||||
bool _hasRings = false;
|
||||
|
||||
// Labels
|
||||
GlobeLabelsComponent _globeLabelsComponent;
|
||||
ghoul::Dictionary _labelsDictionary;
|
||||
|
||||
445
modules/globebrowsing/src/ringscomponent.cpp
Normal file
445
modules/globebrowsing/src/ringscomponent.cpp
Normal file
@@ -0,0 +1,445 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2018 *
|
||||
* *
|
||||
* 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 <modules/globebrowsing/src/ringscomponent.h>
|
||||
#include <modules/globebrowsing/globebrowsingmodule.h>
|
||||
#include <modules/globebrowsing/src/renderableglobe.h>
|
||||
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
|
||||
#include <ghoul/filesystem/cachemanager.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/misc/dictionary.h>
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
#include <ghoul/io/texture/texturereader.h>
|
||||
#include <ghoul/opengl/texture.h>
|
||||
#include <ghoul/opengl/textureunit.h>
|
||||
|
||||
#include <ghoul/font/fontmanager.h>
|
||||
#include <ghoul/font/fontrenderer.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <cstdlib>
|
||||
#include <locale>
|
||||
|
||||
namespace {
|
||||
constexpr const std::array<const char*, 7> UniformNames = {
|
||||
"modelViewMatrix", "projectionMatrix", "textureOffset",
|
||||
"transparency", "_nightFactor", "sunPosition", "texture1"
|
||||
};
|
||||
|
||||
constexpr const std::array<const char*, 3> GeomUniformNames = {
|
||||
"modelViewMatrix", "projectionMatrix", "textureOffset"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo TextureInfo = {
|
||||
"Texture",
|
||||
"Texture",
|
||||
"This value is the path to a texture on disk that contains a one-dimensional "
|
||||
"texture which is used for these rings."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo SizeInfo = {
|
||||
"Size",
|
||||
"Size",
|
||||
"This value specifies the radius of the rings in meter."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo OffsetInfo = {
|
||||
"Offset",
|
||||
"Offset",
|
||||
"This value is used to limit the width of the rings.Each of the two values is a "
|
||||
"value between 0 and 1, where 0 is the center of the ring and 1 is the maximum "
|
||||
"extent at the radius. If this value is, for example {0.5, 1.0}, the ring is "
|
||||
"only shown between radius/2 and radius. It defaults to {0.0, 1.0}."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo NightFactorInfo = {
|
||||
"NightFactor",
|
||||
"Night Factor",
|
||||
"This value is a multiplicative factor that is applied to the side of the rings "
|
||||
"that is facing away from the Sun. If this value is equal to '1', no darkening "
|
||||
"of the night side occurs."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo TransparencyInfo = {
|
||||
"Transparency",
|
||||
"Transparency",
|
||||
"This value determines the transparency of part of the rings depending on the "
|
||||
"color values. For this value v, the transparency is equal to length(color) / v."
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation RingsComponent::Documentation() {
|
||||
using namespace documentation;
|
||||
return {
|
||||
"Rings Component",
|
||||
"globebrowsing_rings_component",
|
||||
{
|
||||
{
|
||||
TextureInfo.identifier,
|
||||
new StringVerifier,
|
||||
Optional::Yes,
|
||||
TextureInfo.description
|
||||
},
|
||||
{
|
||||
SizeInfo.identifier,
|
||||
new DoubleVerifier,
|
||||
Optional::Yes,
|
||||
SizeInfo.description
|
||||
},
|
||||
{
|
||||
OffsetInfo.identifier,
|
||||
new DoubleVector2Verifier,
|
||||
Optional::Yes,
|
||||
OffsetInfo.description
|
||||
},
|
||||
{
|
||||
NightFactorInfo.identifier,
|
||||
new DoubleVerifier,
|
||||
Optional::Yes,
|
||||
NightFactorInfo.description
|
||||
},
|
||||
{
|
||||
TransparencyInfo.identifier,
|
||||
new DoubleVerifier,
|
||||
Optional::Yes,
|
||||
TransparencyInfo.description
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
RingsComponent::RingsComponent(const ghoul::Dictionary& dictionary)
|
||||
: properties::PropertyOwner({ "Rings" })
|
||||
, _texturePath(TextureInfo)
|
||||
, _size(SizeInfo, 1.f, 0.f, 1e25f)
|
||||
, _offset(OffsetInfo, glm::vec2(0.f, 1.f), glm::vec2(0.f), glm::vec2(1.f))
|
||||
, _nightFactor(NightFactorInfo, 0.33f, 0.f, 1.f)
|
||||
, _transparency(TransparencyInfo, 0.15f, 0.f, 1.f)
|
||||
, _enabled({ "Enabled", "Enabled", "Enable/Disable Rings" }, true)
|
||||
, _ringsDictionary(dictionary)
|
||||
{
|
||||
using ghoul::filesystem::File;
|
||||
|
||||
if (dictionary.hasKey("Rings")) {
|
||||
dictionary.getValue("Rings", _ringsDictionary);
|
||||
}
|
||||
|
||||
documentation::testSpecificationAndThrow(
|
||||
Documentation(),
|
||||
_ringsDictionary,
|
||||
"RingsComponent"
|
||||
);
|
||||
}
|
||||
|
||||
void RingsComponent::initialize()
|
||||
{
|
||||
using ghoul::filesystem::File;
|
||||
|
||||
addProperty(_enabled);
|
||||
|
||||
_size = static_cast<float>(_ringsDictionary.value<double>(SizeInfo.identifier));
|
||||
//setBoundingSphere(_size);
|
||||
_size.onChange([&]() { _planeIsDirty = true; });
|
||||
addProperty(_size);
|
||||
|
||||
_texturePath = absPath(_ringsDictionary.value<std::string>(TextureInfo.identifier));
|
||||
_textureFile = std::make_unique<File>(_texturePath);
|
||||
|
||||
if (_ringsDictionary.hasKeyAndValue<glm::vec2>(OffsetInfo.identifier)) {
|
||||
_offset = _ringsDictionary.value<glm::vec2>(OffsetInfo.identifier);
|
||||
}
|
||||
addProperty(_offset);
|
||||
|
||||
_texturePath.onChange([&]() { loadTexture(); });
|
||||
addProperty(_texturePath);
|
||||
|
||||
_textureFile->setCallback([&](const File&) { _textureIsDirty = true; });
|
||||
|
||||
if (_ringsDictionary.hasKeyAndValue<double>(NightFactorInfo.identifier)) {
|
||||
_nightFactor = static_cast<float>(
|
||||
_ringsDictionary.value<double>(NightFactorInfo.identifier)
|
||||
);
|
||||
}
|
||||
addProperty(_nightFactor);
|
||||
|
||||
if (_ringsDictionary.hasKeyAndValue<double>(TransparencyInfo.identifier)) {
|
||||
_transparency = static_cast<float>(
|
||||
_ringsDictionary.value<double>(TransparencyInfo.identifier)
|
||||
);
|
||||
}
|
||||
addProperty(_transparency);
|
||||
}
|
||||
|
||||
bool RingsComponent::isReady() const {
|
||||
return (_shader || _geometryOnlyShader) && _texture;
|
||||
}
|
||||
|
||||
void RingsComponent::initializeGL() {
|
||||
_shader = global::renderEngine.buildRenderProgram(
|
||||
"RingsProgram",
|
||||
absPath("${MODULE_GLOBEBROWSING}/shaders/rings_vs.glsl"),
|
||||
absPath("${MODULE_GLOBEBROWSING}/shaders/rings_fs.glsl")
|
||||
);
|
||||
|
||||
_geometryOnlyShader = global::renderEngine.buildRenderProgram(
|
||||
"RingsGeomOnlyProgram",
|
||||
absPath("${MODULE_GLOBEBROWSING}/shaders/rings_geom_vs.glsl"),
|
||||
absPath("${MODULE_GLOBEBROWSING}/shaders/rings_geom_fs.glsl")
|
||||
);
|
||||
|
||||
ghoul::opengl::updateUniformLocations(*_shader, _uniformCache, UniformNames);
|
||||
ghoul::opengl::updateUniformLocations(
|
||||
*_geometryOnlyShader,
|
||||
_geomUniformCache,
|
||||
GeomUniformNames
|
||||
);
|
||||
|
||||
glGenVertexArrays(1, &_quad);
|
||||
glGenBuffers(1, &_vertexPositionBuffer);
|
||||
|
||||
createPlane();
|
||||
loadTexture();
|
||||
}
|
||||
|
||||
void RingsComponent::deinitializeGL() {
|
||||
glDeleteVertexArrays(1, &_quad);
|
||||
_quad = 0;
|
||||
|
||||
glDeleteBuffers(1, &_vertexPositionBuffer);
|
||||
_vertexPositionBuffer = 0;
|
||||
|
||||
_textureFile = nullptr;
|
||||
_texture = nullptr;
|
||||
|
||||
global::renderEngine.removeRenderProgram(_shader.get());
|
||||
_shader = nullptr;
|
||||
|
||||
global::renderEngine.removeRenderProgram(_geometryOnlyShader.get());
|
||||
_geometryOnlyShader = nullptr;
|
||||
}
|
||||
|
||||
void RingsComponent::draw(
|
||||
const RenderData& data,
|
||||
const RingsComponent::RenderPass renderPass,
|
||||
const ShadowComponent::ShadowMapData& shadowData
|
||||
) {
|
||||
|
||||
if (renderPass == GeometryAndShading) {
|
||||
_shader->activate();
|
||||
}
|
||||
else if (renderPass == GeometryOnly) {
|
||||
_geometryOnlyShader->activate();
|
||||
}
|
||||
|
||||
const glm::dmat4 modelTransform =
|
||||
glm::translate(glm::dmat4(1.0), data.modelTransform.translation) *
|
||||
glm::dmat4(data.modelTransform.rotation) *
|
||||
glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale));
|
||||
|
||||
const glm::dmat4 modelViewTransform = data.camera.combinedViewMatrix() * modelTransform;
|
||||
const glm::dmat4 projectionMatrix = glm::dmat4(data.camera.projectionMatrix());
|
||||
|
||||
ghoul::opengl::TextureUnit unit;
|
||||
if (renderPass == GeometryAndShading) {
|
||||
_shader->setUniform(_uniformCache.modelViewMatrix, modelViewTransform);
|
||||
_shader->setUniform(_uniformCache.projectionMatrix, projectionMatrix);
|
||||
_shader->setUniform(_uniformCache.textureOffset, _offset);
|
||||
_shader->setUniform(_uniformCache.transparency, _transparency);
|
||||
_shader->setUniform(_uniformCache.nightFactor, _nightFactor);
|
||||
_shader->setUniform(_uniformCache.sunPosition, _sunPosition);
|
||||
|
||||
unit.activate();
|
||||
_texture->bind();
|
||||
_shader->setUniform(_uniformCache.texture, unit);
|
||||
|
||||
// Adding the model transformation to the final shadow matrix so we have a
|
||||
// complete transformation from the model coordinates to the clip space of
|
||||
// the light position.
|
||||
_shader->setUniform("shadowMatrix", shadowData.shadowMatrix * modelTransform);
|
||||
|
||||
ghoul::opengl::TextureUnit shadowMapUnit;
|
||||
shadowMapUnit.activate();
|
||||
glBindTexture(GL_TEXTURE_2D, shadowData.shadowDepthTexture);
|
||||
|
||||
_shader->setUniform("shadowMap", shadowMapUnit);
|
||||
|
||||
// DEBUGGING
|
||||
ghoul::opengl::TextureUnit shadowTextureUnit;
|
||||
shadowTextureUnit.activate();
|
||||
glBindTexture(GL_TEXTURE_2D, shadowData.positionInLightSpaceTexture);
|
||||
_shader->setUniform("shadowPositionTexture", shadowTextureUnit);
|
||||
_shader->setUniform("objectToLightSpaceMatrix",
|
||||
shadowData.worldToLightSpaceMatrix * modelTransform);
|
||||
|
||||
}
|
||||
else if (renderPass == GeometryOnly) {
|
||||
_geometryOnlyShader->setUniform(
|
||||
_geomUniformCache.modelViewMatrix,
|
||||
modelViewTransform
|
||||
);
|
||||
_geometryOnlyShader->setUniform(
|
||||
_geomUniformCache.projectionMatrix,
|
||||
projectionMatrix
|
||||
);
|
||||
_geometryOnlyShader->setUniform(
|
||||
_geomUniformCache.textureOffset,
|
||||
_offset
|
||||
);
|
||||
}
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
glBindVertexArray(_quad);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
|
||||
glEnable(GL_CULL_FACE);
|
||||
|
||||
if (renderPass == GeometryAndShading) {
|
||||
_shader->deactivate();
|
||||
}
|
||||
else if (renderPass == GeometryOnly) {
|
||||
_geometryOnlyShader->deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
void RingsComponent::update(const UpdateData& data) {
|
||||
if (_shader->isDirty()) {
|
||||
_shader->rebuildFromFile();
|
||||
ghoul::opengl::updateUniformLocations(*_shader, _uniformCache, UniformNames);
|
||||
}
|
||||
|
||||
if (_geometryOnlyShader->isDirty()) {
|
||||
_geometryOnlyShader->rebuildFromFile();
|
||||
ghoul::opengl::updateUniformLocations(
|
||||
*_geometryOnlyShader,
|
||||
_geomUniformCache,
|
||||
GeomUniformNames
|
||||
);
|
||||
}
|
||||
|
||||
if (_planeIsDirty) {
|
||||
createPlane();
|
||||
_planeIsDirty = false;
|
||||
}
|
||||
|
||||
if (_textureIsDirty) {
|
||||
loadTexture();
|
||||
_textureIsDirty = false;
|
||||
}
|
||||
|
||||
_sunPosition = glm::normalize(
|
||||
global::renderEngine.scene()->sceneGraphNode("Sun")->worldPosition() -
|
||||
data.modelTransform.translation
|
||||
);
|
||||
}
|
||||
|
||||
void RingsComponent::loadTexture() {
|
||||
if (!_texturePath.value().empty()) {
|
||||
using namespace ghoul::io;
|
||||
using namespace ghoul::opengl;
|
||||
std::unique_ptr<Texture> texture = TextureReader::ref().loadTexture(
|
||||
absPath(_texturePath)
|
||||
);
|
||||
|
||||
if (texture) {
|
||||
LDEBUGC(
|
||||
"RingsComponent",
|
||||
fmt::format("Loaded texture from '{}'", absPath(_texturePath))
|
||||
);
|
||||
_texture = std::move(texture);
|
||||
|
||||
_texture->uploadTexture();
|
||||
_texture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap);
|
||||
|
||||
_textureFile = std::make_unique<ghoul::filesystem::File>(_texturePath);
|
||||
_textureFile->setCallback(
|
||||
[&](const ghoul::filesystem::File&) { _textureIsDirty = true; }
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RingsComponent::createPlane() {
|
||||
const GLfloat size = _size;
|
||||
|
||||
struct VertexData {
|
||||
GLfloat x;
|
||||
GLfloat y;
|
||||
GLfloat s;
|
||||
GLfloat t;
|
||||
};
|
||||
|
||||
VertexData data[] = {
|
||||
{ -size, -size, 0.f, 0.f },
|
||||
{ size, size, 1.f, 1.f },
|
||||
{ -size, size, 0.f, 1.f },
|
||||
{ -size, -size, 0.f, 0.f },
|
||||
{ size, -size, 1.f, 0.f },
|
||||
{ size, size, 1.f, 1.f },
|
||||
};
|
||||
|
||||
glBindVertexArray(_quad);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vertexPositionBuffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(
|
||||
0,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
sizeof(VertexData),
|
||||
nullptr
|
||||
);
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(
|
||||
1,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
sizeof(VertexData),
|
||||
reinterpret_cast<void*>(offsetof(VertexData, s)) // NOLINT
|
||||
);
|
||||
}
|
||||
|
||||
bool RingsComponent::isEnabled() const {
|
||||
return _enabled;
|
||||
}
|
||||
} // namespace openspace
|
||||
115
modules/globebrowsing/src/ringscomponent.h
Normal file
115
modules/globebrowsing/src/ringscomponent.h
Normal file
@@ -0,0 +1,115 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2018 *
|
||||
* *
|
||||
* 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 __OPENSPACE_MODULE_GLOBEBROWSING___RINGSCOMPONENT___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___RINGSCOMPONENT___H__
|
||||
|
||||
#include <openspace/properties/propertyowner.h>
|
||||
|
||||
#include <modules/globebrowsing/src/shadowcomponent.h>
|
||||
|
||||
#include <openspace/properties/scalar/boolproperty.h>
|
||||
#include <openspace/properties/scalar/floatproperty.h>
|
||||
#include <openspace/properties/scalar/intproperty.h>
|
||||
#include <openspace/properties/vector/vec2property.h>
|
||||
#include <openspace/properties/vector/vec4property.h>
|
||||
#include <openspace/properties/stringproperty.h>
|
||||
|
||||
#include <ghoul/glm.h>
|
||||
#include <ghoul/opengl/texture.h>
|
||||
#include <ghoul/opengl/uniformcache.h>
|
||||
|
||||
namespace ghoul {
|
||||
class Dictionary;
|
||||
}
|
||||
|
||||
namespace ghoul::filesystem { class File; }
|
||||
|
||||
namespace ghoul::opengl {
|
||||
class ProgramObject;
|
||||
} // namespace ghoul::opengl
|
||||
|
||||
namespace openspace {
|
||||
struct RenderData;
|
||||
struct UpdateData;
|
||||
|
||||
namespace documentation { struct Documentation; }
|
||||
|
||||
class RingsComponent : public properties::PropertyOwner {
|
||||
public:
|
||||
enum RenderPass {
|
||||
GeometryOnly,
|
||||
GeometryAndShading
|
||||
};
|
||||
public:
|
||||
RingsComponent(const ghoul::Dictionary& dictionary);
|
||||
|
||||
void initialize();
|
||||
void initializeGL();
|
||||
void deinitializeGL();
|
||||
|
||||
bool isReady() const;
|
||||
|
||||
void draw(
|
||||
const RenderData& data,
|
||||
const RingsComponent::RenderPass renderPass,
|
||||
const ShadowComponent::ShadowMapData& shadowData = {}
|
||||
);
|
||||
void update(const UpdateData& data);
|
||||
|
||||
static documentation::Documentation Documentation();
|
||||
|
||||
bool isEnabled() const;
|
||||
|
||||
private:
|
||||
void loadTexture();
|
||||
void createPlane();
|
||||
|
||||
properties::StringProperty _texturePath;
|
||||
properties::FloatProperty _size;
|
||||
properties::Vec2Property _offset;
|
||||
properties::FloatProperty _nightFactor;
|
||||
properties::FloatProperty _transparency;
|
||||
properties::BoolProperty _enabled;
|
||||
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _shader;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _geometryOnlyShader;
|
||||
UniformCache(modelViewMatrix, projectionMatrix, textureOffset,
|
||||
transparency, nightFactor, sunPosition, texture) _uniformCache;
|
||||
UniformCache(modelViewMatrix, projectionMatrix, textureOffset) _geomUniformCache;
|
||||
std::unique_ptr<ghoul::opengl::Texture> _texture;
|
||||
std::unique_ptr<ghoul::filesystem::File> _textureFile;
|
||||
|
||||
ghoul::Dictionary _ringsDictionary;
|
||||
bool _textureIsDirty = false;
|
||||
GLuint _quad = 0;
|
||||
GLuint _vertexPositionBuffer = 0;
|
||||
bool _planeIsDirty = false;
|
||||
|
||||
glm::vec3 _sunPosition;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___RINGSCOMPONENT___H__
|
||||
708
modules/globebrowsing/src/shadowcomponent.cpp
Normal file
708
modules/globebrowsing/src/shadowcomponent.cpp
Normal file
@@ -0,0 +1,708 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2018 *
|
||||
* *
|
||||
* 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 <modules/globebrowsing/src/shadowcomponent.h>
|
||||
#include <modules/globebrowsing/globebrowsingmodule.h>
|
||||
#include <modules/globebrowsing/src/renderableglobe.h>
|
||||
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/interaction/orbitalnavigator.h>
|
||||
#include <openspace/interaction/keyframenavigator.h>
|
||||
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
|
||||
#include <openspace/util/camera.h>
|
||||
|
||||
#include <ghoul/filesystem/cachemanager.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/misc/dictionary.h>
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
#include <ghoul/io/texture/texturereader.h>
|
||||
#include <ghoul/opengl/texture.h>
|
||||
#include <ghoul/opengl/textureunit.h>
|
||||
|
||||
#include <ghoul/font/fontmanager.h>
|
||||
#include <ghoul/font/fontrenderer.h>
|
||||
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
#include <fstream>
|
||||
#include <cstdlib>
|
||||
#include <locale>
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "ShadowComponent";
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo SaveDepthTextureInfo = {
|
||||
"SaveDepthTextureInfo",
|
||||
"Save Depth Texture",
|
||||
"Debug"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo DistanceFractionInfo = {
|
||||
"DistanceFraction",
|
||||
"Distance Fraction",
|
||||
"Distance fraction of original distance from light source to the globe to be "
|
||||
"considered as the new light source distance."
|
||||
};
|
||||
|
||||
void checkFrameBufferState(const std::string& codePosition)
|
||||
{
|
||||
if (glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
||||
LERROR("Framework not built. " + codePosition);
|
||||
GLenum fbErr = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
switch (fbErr) {
|
||||
case GL_FRAMEBUFFER_UNDEFINED:
|
||||
LERROR("Indefined framebuffer.");
|
||||
break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
|
||||
LERROR("Incomplete, missing attachement.");
|
||||
break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
|
||||
LERROR("Framebuffer doesn't have at least one image attached to it.");
|
||||
break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
|
||||
LERROR(
|
||||
"Returned if the value of GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is "
|
||||
"GL_NONE for any color attachment point(s) named by GL_DRAW_BUFFERi."
|
||||
);
|
||||
break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
|
||||
LERROR(
|
||||
"Returned if GL_READ_BUFFER is not GL_NONE and the value of "
|
||||
"GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is GL_NONE for the color "
|
||||
"attachment point named by GL_READ_BUFFER.");
|
||||
break;
|
||||
case GL_FRAMEBUFFER_UNSUPPORTED:
|
||||
LERROR(
|
||||
"Returned if the combination of internal formats of the attached "
|
||||
"images violates an implementation - dependent set of restrictions."
|
||||
);
|
||||
break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
|
||||
LERROR(
|
||||
"Returned if the value of GL_RENDERBUFFE_r_samples is not the same "
|
||||
"for all attached renderbuffers; if the value of GL_TEXTURE_SAMPLES "
|
||||
"is the not same for all attached textures; or , if the attached "
|
||||
"images are a mix of renderbuffers and textures, the value of "
|
||||
"GL_RENDERBUFFE_r_samples does not match the value of "
|
||||
"GL_TEXTURE_SAMPLES."
|
||||
);
|
||||
LERROR(
|
||||
"Returned if the value of GL_TEXTURE_FIXED_SAMPLE_LOCATIONS is not "
|
||||
"the same for all attached textures; or , if the attached images are "
|
||||
"a mix of renderbuffers and textures, the value of "
|
||||
"GL_TEXTURE_FIXED_SAMPLE_LOCATIONS is not GL_TRUE for all attached "
|
||||
"textures."
|
||||
);
|
||||
break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:
|
||||
LERROR(
|
||||
"Returned if any framebuffer attachment is layered, and any "
|
||||
"populated attachment is not layered, or if all populated color "
|
||||
"attachments are not from textures of the same target."
|
||||
);
|
||||
break;
|
||||
default:
|
||||
LDEBUG("No error found checking framebuffer: " + codePosition);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation ShadowComponent::Documentation() {
|
||||
using namespace documentation;
|
||||
return {
|
||||
"ShadowsRing Component",
|
||||
"globebrowsing_shadows_component",
|
||||
{
|
||||
{
|
||||
DistanceFractionInfo.identifier,
|
||||
new DoubleVerifier,
|
||||
Optional::Yes,
|
||||
DistanceFractionInfo.description
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
ShadowComponent::ShadowComponent(const ghoul::Dictionary& dictionary)
|
||||
: properties::PropertyOwner({ "Shadows" })
|
||||
, _saveDepthTexture(SaveDepthTextureInfo)
|
||||
, _distanceFraction(DistanceFractionInfo, 30, 1, 100000)
|
||||
, _enabled({ "Enabled", "Enabled", "Enable/Disable Shadows" }, true)
|
||||
, _shadowMapDictionary(dictionary)
|
||||
, _shadowDepthTextureHeight(1024)
|
||||
, _shadowDepthTextureWidth(1024)
|
||||
, _shadowDepthTexture(-1)
|
||||
, _positionInLightSpaceTexture(-1)
|
||||
, _shadowFBO(-1)
|
||||
, _firstPassSubroutine(-1)
|
||||
, _secondPassSubroutine(1)
|
||||
, _defaultFBO(-1)
|
||||
, _sunPosition(0.0)
|
||||
, _shadowMatrix(1.0)
|
||||
, _executeDepthTextureSave(false)
|
||||
{
|
||||
using ghoul::filesystem::File;
|
||||
|
||||
if (dictionary.hasKey("Rings")) {
|
||||
ghoul::Dictionary ringsDic;
|
||||
dictionary.getValue("Rings", ringsDic);
|
||||
if (ringsDic.hasKey("Shadows")) {
|
||||
ringsDic.getValue("Shadows", _shadowMapDictionary);
|
||||
}
|
||||
}
|
||||
|
||||
documentation::testSpecificationAndThrow(
|
||||
Documentation(),
|
||||
_shadowMapDictionary,
|
||||
"ShadowComponent"
|
||||
);
|
||||
|
||||
if (_shadowMapDictionary.hasKey(DistanceFractionInfo.identifier)) {
|
||||
_distanceFraction = static_cast<int>(
|
||||
_shadowMapDictionary.value<float>(DistanceFractionInfo.identifier)
|
||||
);
|
||||
}
|
||||
|
||||
_saveDepthTexture.onChange([&]() {
|
||||
_executeDepthTextureSave = true;
|
||||
});
|
||||
|
||||
addProperty(_enabled);
|
||||
addProperty(_saveDepthTexture);
|
||||
addProperty(_distanceFraction);
|
||||
}
|
||||
|
||||
void ShadowComponent::initialize()
|
||||
{
|
||||
using ghoul::filesystem::File;
|
||||
}
|
||||
|
||||
bool ShadowComponent::isReady() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void ShadowComponent::initializeGL() {
|
||||
createDepthTexture();
|
||||
createShadowFBO();
|
||||
}
|
||||
|
||||
void ShadowComponent::deinitializeGL() {
|
||||
glDeleteTextures(1, &_shadowDepthTexture);
|
||||
glDeleteTextures(1, &_positionInLightSpaceTexture);
|
||||
glDeleteFramebuffers(1, &_shadowFBO);
|
||||
checkGLError("ShadowComponent::deinitializeGL() -- Deleted Textures and Framebuffer");
|
||||
}
|
||||
|
||||
void ShadowComponent::begin(const RenderData& data) {
|
||||
// ===========================================
|
||||
// Builds light's ModelViewProjectionMatrix:
|
||||
// ===========================================
|
||||
|
||||
glm::dvec3 diffVector = glm::dvec3(_sunPosition) - data.modelTransform.translation;
|
||||
double originalLightDistance = glm::length(diffVector);
|
||||
glm::dvec3 lightDirection = glm::normalize(diffVector);
|
||||
|
||||
// Percentage of the original light source distance (to avoid artifacts)
|
||||
double multiplier = originalLightDistance *
|
||||
(static_cast<double>(_distanceFraction)/1.0E5);
|
||||
|
||||
// New light source position
|
||||
glm::dvec3 lightPosition = data.modelTransform.translation +
|
||||
(lightDirection * multiplier);
|
||||
|
||||
// Saving current Camera parameters
|
||||
_cameraPos = data.camera.positionVec3();
|
||||
// JCC: We have aim and ancor nodes and position now. Need to fix this.
|
||||
//_cameraFocus = data.camera.focusPositionVec3();
|
||||
_cameraRotation = data.camera.rotationQuaternion();
|
||||
|
||||
//=============== Automatically Created Camera Matrix ===================
|
||||
//=======================================================================
|
||||
//glm::dmat4 lightViewMatrix = glm::lookAt(
|
||||
// //lightPosition,
|
||||
// glm::dvec3(0.0),
|
||||
// //glm::dvec3(_sunPosition), // position
|
||||
// glm::dvec3(data.modelTransform.translation), // focus
|
||||
// data.camera.lookUpVectorWorldSpace() // up
|
||||
// //glm::dvec3(0.0, 1.0, 0.0)
|
||||
//);
|
||||
|
||||
//camera->setPositionVec3(lightPosition);
|
||||
//camera->setFocusPositionVec3(data.modelTransform.translation);
|
||||
//camera->setRotation(glm::dquat(glm::inverse(lightViewMatrix)));
|
||||
|
||||
//=======================================================================
|
||||
//=======================================================================
|
||||
|
||||
|
||||
//=============== Manually Created Camera Matrix ===================
|
||||
//==================================================================
|
||||
// camera Z
|
||||
glm::dvec3 cameraZ = lightDirection;
|
||||
|
||||
// camera X
|
||||
glm::dvec3 upVector = glm::dvec3(0.0, -1.0, 0.0);
|
||||
glm::dvec3 cameraX = glm::normalize(glm::cross(upVector, cameraZ));
|
||||
|
||||
// camera Y
|
||||
glm::dvec3 cameraY = glm::cross(cameraZ, cameraX);
|
||||
|
||||
// init 4x4 matrix
|
||||
glm::dmat4 cameraRotationMatrix(1.0);
|
||||
|
||||
double* matrix = glm::value_ptr(cameraRotationMatrix);
|
||||
matrix[0] = cameraX.x;
|
||||
matrix[4] = cameraX.y;
|
||||
matrix[8] = cameraX.z;
|
||||
matrix[1] = cameraY.x;
|
||||
matrix[5] = cameraY.y;
|
||||
matrix[9] = cameraY.z;
|
||||
matrix[2] = cameraZ.x;
|
||||
matrix[6] = cameraZ.y;
|
||||
matrix[10] = cameraZ.z;
|
||||
|
||||
// set translation part
|
||||
// We aren't setting the position here because it is set in
|
||||
// the camera->setPosition()
|
||||
//matrix[12] = -glm::dot(cameraX, lightPosition);
|
||||
//matrix[13] = -glm::dot(cameraY, lightPosition);
|
||||
//matrix[14] = -glm::dot(cameraZ, lightPosition);
|
||||
|
||||
/*Scene* scene = camera->parent()->scene();
|
||||
global::navigationHandler.setFocusNode(data.);
|
||||
*/
|
||||
|
||||
Camera camera(data.camera);
|
||||
camera.setPositionVec3(lightPosition);
|
||||
// JCC: We have aim and ancor nodes and position now. Need to fix this.
|
||||
//camera.setFocusPositionVec3(data.modelTransform.translation);
|
||||
camera.setRotation(glm::dquat(glm::inverse(cameraRotationMatrix)));
|
||||
|
||||
//=======================================================================
|
||||
//=======================================================================
|
||||
|
||||
|
||||
//============= Light Matrix by Camera Matrices Composition =============
|
||||
//=======================================================================
|
||||
glm::dmat4 lightProjectionMatrix = glm::dmat4(camera.projectionMatrix());
|
||||
//glm::dmat4 lightProjectionMatrix = glm::ortho(-1000.0, 1000.0, -1000.0, 1000.0, 0.0010, 1000.0);
|
||||
//glm::dmat4 lightProjectionMatrix = glm::frustum(-1.0, 1.0, -1.0, 1.0, 1.0, 1000000.0);
|
||||
|
||||
// The model transformation missing in the final shadow matrix is add when rendering each
|
||||
// object (using its transformations provided by the RenderData structure)
|
||||
_shadowData.shadowMatrix =
|
||||
_toTextureCoordsMatrix *
|
||||
lightProjectionMatrix *
|
||||
camera.combinedViewMatrix();
|
||||
|
||||
// temp
|
||||
_shadowData.worldToLightSpaceMatrix = glm::dmat4(camera.combinedViewMatrix());
|
||||
|
||||
checkGLError("begin() -- Saving Current GL State");
|
||||
// Saves current state
|
||||
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &_defaultFBO);
|
||||
glGetIntegerv(GL_VIEWPORT, _mViewport);
|
||||
_faceCulling = glIsEnabled(GL_CULL_FACE);
|
||||
glGetIntegerv(GL_CULL_FACE_MODE, &_faceToCull);
|
||||
_polygonOffSet = glIsEnabled(GL_POLYGON_OFFSET_FILL);
|
||||
glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &_polygonOffSetFactor);
|
||||
glGetFloatv(GL_POLYGON_OFFSET_UNITS, &_polygonOffSetUnits);
|
||||
glGetFloatv(GL_COLOR_CLEAR_VALUE, _colorClearValue);
|
||||
glGetFloatv(GL_DEPTH_CLEAR_VALUE, &_depthClearValue);
|
||||
_depthIsEnabled = glIsEnabled(GL_DEPTH_TEST);
|
||||
glGetIntegerv(GL_DEPTH_FUNC, &_depthFunction);
|
||||
_blendIsEnabled = glIsEnabled(GL_BLEND);
|
||||
|
||||
|
||||
checkGLError("begin() -- before binding FBO");
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, _shadowFBO);
|
||||
checkGLError("begin() -- after binding FBO");
|
||||
glViewport(0, 0, _shadowDepthTextureWidth, _shadowDepthTextureHeight);
|
||||
checkGLError("begin() -- set new viewport");
|
||||
glClearDepth(1.0f);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
checkGLError("begin() -- after cleanning Depth buffer");
|
||||
|
||||
|
||||
/*glEnable(GL_CULL_FACE);
|
||||
checkGLError("begin() -- enabled cull face");
|
||||
glCullFace(GL_FRONT);
|
||||
checkGLError("begin() -- set cullface to front");*/
|
||||
/*glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
checkGLError("begin() -- enabled polygon offset fill");
|
||||
glPolygonOffset(2.5f, 10.0f);
|
||||
checkGLError("begin() -- set values for polygon offset");*/
|
||||
|
||||
checkGLError("begin() finished");
|
||||
|
||||
}
|
||||
|
||||
void ShadowComponent::end(const RenderData& data) {
|
||||
checkGLError("end() -- Flushing");
|
||||
//glFlush();
|
||||
if (_executeDepthTextureSave) {
|
||||
saveDepthBuffer();
|
||||
_executeDepthTextureSave = false;
|
||||
}
|
||||
|
||||
// Restores Camera Parameters
|
||||
Camera camera = data.camera;
|
||||
camera.setPositionVec3(_cameraPos);
|
||||
// JCC: We have aim and ancor nodes and position now. Need to fix this.
|
||||
//camera.setFocusPositionVec3(_cameraFocus);
|
||||
camera.setRotation(_cameraRotation);
|
||||
|
||||
// Restores system state
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, _defaultFBO);
|
||||
checkGLError("end() -- Rebinding default FBO");
|
||||
glViewport(
|
||||
_mViewport[0],
|
||||
_mViewport[1],
|
||||
_mViewport[2],
|
||||
_mViewport[3]
|
||||
);
|
||||
|
||||
if (_faceCulling) {
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(_faceToCull);
|
||||
}
|
||||
else {
|
||||
glDisable(GL_CULL_FACE);
|
||||
}
|
||||
|
||||
if (_depthIsEnabled) {
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
else {
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
glDepthFunc(_depthFunction);
|
||||
|
||||
if (_polygonOffSet) {
|
||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(_polygonOffSetFactor, _polygonOffSetUnits);
|
||||
}
|
||||
else {
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
}
|
||||
|
||||
glClearColor(
|
||||
_colorClearValue[0],
|
||||
_colorClearValue[1],
|
||||
_colorClearValue[2],
|
||||
_colorClearValue[3]
|
||||
);
|
||||
glClearDepth(_depthClearValue);
|
||||
|
||||
if (_blendIsEnabled) {
|
||||
glEnable(GL_BLEND);
|
||||
}
|
||||
|
||||
checkGLError("end() finished");
|
||||
}
|
||||
|
||||
void ShadowComponent::update(const UpdateData& /*data*/) {
|
||||
_sunPosition = global::renderEngine.scene()->sceneGraphNode("Sun")->worldPosition();
|
||||
}
|
||||
|
||||
void ShadowComponent::createDepthTexture() {
|
||||
checkGLError("createDepthTexture() -- Starting configuration");
|
||||
glGenTextures(1, &_shadowDepthTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, _shadowDepthTexture);
|
||||
glTexStorage2D(
|
||||
GL_TEXTURE_2D,
|
||||
1,
|
||||
GL_DEPTH_COMPONENT32F,
|
||||
_shadowDepthTextureWidth,
|
||||
_shadowDepthTextureHeight
|
||||
);
|
||||
|
||||
/*glTexImage2D(
|
||||
GL_TEXTURE_2D,
|
||||
0,
|
||||
GL_DEPTH_COMPONENT32F,
|
||||
_shadowDepthTextureWidth,
|
||||
_shadowDepthTextureHeight,
|
||||
0,
|
||||
GL_DEPTH_COMPONENT,
|
||||
GL_FLOAT,
|
||||
0
|
||||
);*/
|
||||
checkGLError("createDepthTexture() -- Depth testure created");
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, shadowBorder);
|
||||
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
|
||||
checkGLError("createdDepthTexture");
|
||||
|
||||
glGenTextures(1, &_positionInLightSpaceTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, _positionInLightSpaceTexture);
|
||||
//glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D,
|
||||
0,
|
||||
GL_RGB32F,
|
||||
_shadowDepthTextureWidth,
|
||||
_shadowDepthTextureHeight,
|
||||
0,
|
||||
GL_RGBA,
|
||||
GL_FLOAT,
|
||||
nullptr
|
||||
);
|
||||
checkGLError("createDepthTexture() -- Position/Distance buffer created");
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
checkGLError("createdPositionTexture");
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
_shadowData.shadowDepthTexture = _shadowDepthTexture;
|
||||
_shadowData.positionInLightSpaceTexture = _positionInLightSpaceTexture;
|
||||
}
|
||||
|
||||
void ShadowComponent::createShadowFBO() {
|
||||
// Saves current FBO first
|
||||
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &_defaultFBO);
|
||||
|
||||
/*GLint _mViewport[4];
|
||||
glGetIntegerv(GL_VIEWPORT, _mViewport);*/
|
||||
|
||||
glGenFramebuffers(1, &_shadowFBO);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, _shadowFBO);
|
||||
glFramebufferTexture2D(
|
||||
GL_FRAMEBUFFER,
|
||||
GL_DEPTH_ATTACHMENT,
|
||||
GL_TEXTURE_2D,
|
||||
_shadowDepthTexture,
|
||||
0
|
||||
);
|
||||
|
||||
glFramebufferTexture(
|
||||
GL_FRAMEBUFFER,
|
||||
GL_COLOR_ATTACHMENT3,
|
||||
_positionInLightSpaceTexture,
|
||||
0
|
||||
);
|
||||
checkGLError("createShadowFBO() -- Created Shadow Framebuffer");
|
||||
//GLenum drawBuffers[] = { GL_NONE };
|
||||
GLenum drawBuffers[] = { GL_NONE, GL_NONE, GL_NONE, GL_COLOR_ATTACHMENT3 };
|
||||
glDrawBuffers(4, drawBuffers);
|
||||
|
||||
checkFrameBufferState("createShadowFBO()");
|
||||
|
||||
// Restores system state
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, _defaultFBO);
|
||||
/*glViewport(
|
||||
_mViewport[0],
|
||||
_mViewport[1],
|
||||
_mViewport[2],
|
||||
_mViewport[3]
|
||||
);*/
|
||||
checkGLError("createShadowFBO() -- createdShadowFBO");
|
||||
}
|
||||
|
||||
void ShadowComponent::saveDepthBuffer() {
|
||||
int size = _shadowDepthTextureWidth * _shadowDepthTextureHeight;
|
||||
GLubyte * buffer = new GLubyte[size];
|
||||
|
||||
glReadPixels(
|
||||
0,
|
||||
0,
|
||||
_shadowDepthTextureWidth,
|
||||
_shadowDepthTextureHeight,
|
||||
GL_DEPTH_COMPONENT,
|
||||
GL_UNSIGNED_BYTE,
|
||||
buffer
|
||||
);
|
||||
|
||||
checkGLError("readDepthBuffer To buffer");
|
||||
std::fstream ppmFile;
|
||||
|
||||
ppmFile.open("depthBufferShadowMapping.ppm", std::fstream::out);
|
||||
if (ppmFile.is_open()) {
|
||||
|
||||
ppmFile << "P3" << std::endl;
|
||||
ppmFile << _shadowDepthTextureWidth << " " << _shadowDepthTextureHeight
|
||||
<< std::endl;
|
||||
ppmFile << "255" << std::endl;
|
||||
|
||||
std::cout << "\n\nSaving depth texture to file depthBufferShadowMapping.ppm\n\n";
|
||||
int k = 0;
|
||||
for (int i = 0; i < _shadowDepthTextureWidth; i++) {
|
||||
for (int j = 0; j < _shadowDepthTextureHeight; j++, k++) {
|
||||
unsigned int val = static_cast<unsigned int>(buffer[k]);
|
||||
ppmFile << val << " " << val << " " << val << " ";
|
||||
}
|
||||
ppmFile << std::endl;
|
||||
}
|
||||
|
||||
ppmFile.close();
|
||||
|
||||
std::cout << "Texture saved to file depthBufferShadowMapping.ppm\n\n";
|
||||
}
|
||||
|
||||
delete[] buffer;
|
||||
|
||||
GLfloat * bBuffer = new GLfloat[size * 4];
|
||||
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT3);
|
||||
glReadPixels(
|
||||
0,
|
||||
0,
|
||||
_shadowDepthTextureWidth,
|
||||
_shadowDepthTextureHeight,
|
||||
GL_RGBA,
|
||||
GL_FLOAT,
|
||||
bBuffer
|
||||
);
|
||||
|
||||
checkGLError("readPositionBuffer To buffer");
|
||||
ppmFile.clear();
|
||||
|
||||
ppmFile.open("positionBufferShadowMapping.ppm", std::fstream::out);
|
||||
if (ppmFile.is_open()) {
|
||||
|
||||
ppmFile << "P3" << std::endl;
|
||||
ppmFile << _shadowDepthTextureWidth << " " << _shadowDepthTextureHeight
|
||||
<< std::endl;
|
||||
ppmFile << "255" << std::endl;
|
||||
|
||||
std::cout << "\n\nSaving texture position to positionBufferShadowMapping.ppm\n\n";
|
||||
|
||||
float biggestValue = 0.f;
|
||||
|
||||
int k = 0;
|
||||
for (int i = 0; i < _shadowDepthTextureWidth; i++) {
|
||||
for (int j = 0; j < _shadowDepthTextureHeight; j++) {
|
||||
biggestValue = bBuffer[k] > biggestValue ?
|
||||
bBuffer[k] : biggestValue;
|
||||
k += 4;
|
||||
}
|
||||
}
|
||||
|
||||
biggestValue /= 255.f;
|
||||
|
||||
k = 0;
|
||||
for (int i = 0; i < _shadowDepthTextureWidth; i++) {
|
||||
for (int j = 0; j < _shadowDepthTextureHeight; j++) {
|
||||
ppmFile << static_cast<unsigned int>(bBuffer[k] / biggestValue) << " "
|
||||
<< static_cast<unsigned int>(bBuffer[k + 1] / biggestValue) << " "
|
||||
<< static_cast<unsigned int>(bBuffer[k + 2] / biggestValue) << " ";
|
||||
k += 4;
|
||||
}
|
||||
ppmFile << std::endl;
|
||||
}
|
||||
|
||||
ppmFile.close();
|
||||
|
||||
std::cout << "Texture saved to file positionBufferShadowMapping.ppm\n\n";
|
||||
}
|
||||
|
||||
delete[] bBuffer;
|
||||
}
|
||||
|
||||
void ShadowComponent::checkGLError(const std::string & where) const {
|
||||
const GLenum error = glGetError();
|
||||
switch (error) {
|
||||
case GL_NO_ERROR:
|
||||
break;
|
||||
case GL_INVALID_ENUM:
|
||||
LERRORC(
|
||||
"OpenGL Invalid State",
|
||||
fmt::format("Function {}: GL_INVALID_ENUM", where)
|
||||
);
|
||||
break;
|
||||
case GL_INVALID_VALUE:
|
||||
LERRORC(
|
||||
"OpenGL Invalid State",
|
||||
fmt::format("Function {}: GL_INVALID_VALUE", where)
|
||||
);
|
||||
break;
|
||||
case GL_INVALID_OPERATION:
|
||||
LERRORC(
|
||||
"OpenGL Invalid State",
|
||||
fmt::format(
|
||||
"Function {}: GL_INVALID_OPERATION", where
|
||||
));
|
||||
break;
|
||||
case GL_INVALID_FRAMEBUFFER_OPERATION:
|
||||
LERRORC(
|
||||
"OpenGL Invalid State",
|
||||
fmt::format(
|
||||
"Function {}: GL_INVALID_FRAMEBUFFER_OPERATION",
|
||||
where
|
||||
)
|
||||
);
|
||||
break;
|
||||
case GL_OUT_OF_MEMORY:
|
||||
LERRORC(
|
||||
"OpenGL Invalid State",
|
||||
fmt::format("Function {}: GL_OUT_OF_MEMORY", where)
|
||||
);
|
||||
break;
|
||||
default:
|
||||
LERRORC(
|
||||
"OpenGL Invalid State",
|
||||
fmt::format("Unknown error code: {0:x}", static_cast<int>(error))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
bool ShadowComponent::isEnabled() const {
|
||||
return _enabled;
|
||||
}
|
||||
|
||||
ShadowComponent::ShadowMapData ShadowComponent::shadowMapData() const {
|
||||
return _shadowData;
|
||||
}
|
||||
} // namespace openspace
|
||||
160
modules/globebrowsing/src/shadowcomponent.h
Normal file
160
modules/globebrowsing/src/shadowcomponent.h
Normal file
@@ -0,0 +1,160 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2018 *
|
||||
* *
|
||||
* 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 __OPENSPACE_MODULE_GLOBEBROWSING___SHADOWCOMPONENT___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___SHADOWCOMPONENT___H__
|
||||
|
||||
#include <openspace/properties/propertyowner.h>
|
||||
|
||||
#include <openspace/properties/scalar/boolproperty.h>
|
||||
#include <openspace/properties/scalar/floatproperty.h>
|
||||
#include <openspace/properties/scalar/intproperty.h>
|
||||
#include <openspace/properties/vector/vec2property.h>
|
||||
#include <openspace/properties/vector/vec4property.h>
|
||||
#include <openspace/properties/stringproperty.h>
|
||||
#include <openspace/properties/triggerproperty.h>
|
||||
|
||||
#include <ghoul/glm.h>
|
||||
#include <ghoul/opengl/texture.h>
|
||||
#include <ghoul/opengl/uniformcache.h>
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
namespace ghoul {
|
||||
class Dictionary;
|
||||
}
|
||||
|
||||
namespace ghoul::filesystem { class File; }
|
||||
|
||||
namespace ghoul::opengl {
|
||||
class ProgramObject;
|
||||
} // namespace ghoul::opengl
|
||||
|
||||
namespace openspace {
|
||||
struct RenderData;
|
||||
struct UpdateData;
|
||||
|
||||
namespace documentation { struct Documentation; }
|
||||
|
||||
static const GLfloat shadowBorder[] = { 1.f, 1.f, 1.f, 1.f };
|
||||
|
||||
class ShadowComponent : public properties::PropertyOwner {
|
||||
public:
|
||||
struct ShadowMapData {
|
||||
glm::dmat4 shadowMatrix;
|
||||
// temp
|
||||
glm::dmat4 worldToLightSpaceMatrix;
|
||||
GLuint shadowDepthTexture;
|
||||
GLuint positionInLightSpaceTexture;
|
||||
};
|
||||
public:
|
||||
ShadowComponent(const ghoul::Dictionary& dictionary);
|
||||
|
||||
void initialize();
|
||||
void initializeGL();
|
||||
void deinitializeGL();
|
||||
//bool deinitialize();
|
||||
|
||||
bool isReady() const;
|
||||
|
||||
void begin(const RenderData& data);
|
||||
void end(const RenderData& data);
|
||||
void update(const UpdateData& data);
|
||||
|
||||
static documentation::Documentation Documentation();
|
||||
|
||||
bool isEnabled() const;
|
||||
|
||||
ShadowComponent::ShadowMapData shadowMapData() const;
|
||||
|
||||
private:
|
||||
void createDepthTexture();
|
||||
void createShadowFBO();
|
||||
|
||||
// Debug
|
||||
void saveDepthBuffer();
|
||||
void checkGLError(const std::string & where) const;
|
||||
|
||||
private:
|
||||
|
||||
ShadowMapData _shadowData;
|
||||
|
||||
// Texture coords in [0, 1], while clip coords in [-1, 1]
|
||||
const glm::dmat4 _toTextureCoordsMatrix = glm::dmat4(
|
||||
glm::dvec4(0.5, 0.0, 0.0, 0.0),
|
||||
glm::dvec4(0.0, 0.5, 0.0, 0.0),
|
||||
glm::dvec4(0.0, 0.0, 0.5, 0.0),
|
||||
glm::dvec4(0.5, 0.5, 0.5, 1.0)
|
||||
);
|
||||
|
||||
// DEBUG
|
||||
properties::TriggerProperty _saveDepthTexture;
|
||||
properties::IntProperty _distanceFraction;
|
||||
properties::BoolProperty _enabled;
|
||||
|
||||
ghoul::Dictionary _shadowMapDictionary;
|
||||
|
||||
int _shadowDepthTextureHeight;
|
||||
int _shadowDepthTextureWidth;
|
||||
|
||||
GLuint _shadowDepthTexture;
|
||||
GLuint _positionInLightSpaceTexture;
|
||||
GLuint _shadowFBO;
|
||||
GLuint _firstPassSubroutine;
|
||||
GLuint _secondPassSubroutine;
|
||||
GLint _defaultFBO;
|
||||
GLint _mViewport[4];
|
||||
|
||||
GLboolean _faceCulling;
|
||||
GLboolean _polygonOffSet;
|
||||
GLboolean _depthIsEnabled;
|
||||
GLboolean _blendIsEnabled = false;
|
||||
|
||||
GLenum _faceToCull;
|
||||
GLenum _depthFunction;
|
||||
|
||||
GLfloat _polygonOffSetFactor;
|
||||
GLfloat _polygonOffSetUnits;
|
||||
GLfloat _colorClearValue[4];
|
||||
GLfloat _depthClearValue;
|
||||
|
||||
glm::vec3 _sunPosition;
|
||||
|
||||
glm::dmat4 _shadowMatrix;
|
||||
|
||||
glm::dvec3 _cameraPos;
|
||||
glm::dvec3 _cameraFocus;
|
||||
glm::dquat _cameraRotation;
|
||||
|
||||
std::stringstream _serializedCamera;
|
||||
|
||||
// DEBUG
|
||||
bool _executeDepthTextureSave;
|
||||
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___SHADOWCOMPONENT___H__
|
||||
Reference in New Issue
Block a user