mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-07 04:00:37 -06:00
Feature/globebrowsing speedup (#735)
* Removal of ChunkRenderer, ChunkedLodGlobe, ChunkCuller, chunklevel evaluator, culling classes, layershadermanager, GpuLayer, GPUData, ChunkNode, Grid, BasicGrid, Chunk files, Angle, AABB classes, PointGlobe, Ellipsoid, TileSelector, tiledatatype, iodescription, simplerawtilerreader, rawtilereader * Less dynamic allocation for SkirtedGrid, LayerManager, RenderableGlobe, TextureUnit * Clean up memory management in RawTiles * Code simplification * Optimize shader uniform setting * Introduce UniformCache * Callback simplification * Turn ChunkNode into a struct * Use a MemoryPool to organize all ChunkNodes rather than use unique_ptr and the necessary memory allocation * Collect draw calls * Consolidate fragment shaders between local and global renderer * Shader cleanup and optimization * Update CMake to not include included shaders * Integrate traversal function into the looping * Replace std::queue with std::vector * Merge TextureContainer into MemoryAwareTileCache * Lazy computation of chunk bounding boxes * Memory management of LayerGroup * Remove class hierarchy from tileproviders (temporaltileprovider not working yet) * Remove PBO classes * Chunk status stored in Chunk * Don't create a copy of the ChunkTilePile * Enable culling by projected area on default * Have raw tile reader return a Tile instead of a shared_ptr to a tile * Start making GDAL mandatory * Increase the default lod scale factor to 15
This commit is contained in:
@@ -137,7 +137,7 @@ public:
|
||||
|
||||
void setRenderable(std::unique_ptr<Renderable> renderable);
|
||||
const Renderable* renderable() const;
|
||||
//Renderable* renderable();
|
||||
Renderable* renderable();
|
||||
|
||||
const std::string& guiPath() const;
|
||||
bool hasGuiHintHidden() const;
|
||||
|
||||
@@ -1,107 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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_CORE___GPUDATA___H__
|
||||
#define __OPENSPACE_CORE___GPUDATA___H__
|
||||
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
#include <ghoul/opengl/texture.h>
|
||||
#include <ghoul/opengl/textureunit.h>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
// @TODO: This class should disappear as it doesn't server much of a purpose and only
|
||||
// complicates local reasoning
|
||||
|
||||
namespace openspace {
|
||||
|
||||
/**
|
||||
* Manages a GPU representation of the templated data type T.
|
||||
* This class provides a simple interface setting the value of
|
||||
* the binded GLSL variable.
|
||||
*/
|
||||
template<typename T>
|
||||
class GPUData {
|
||||
public:
|
||||
/**
|
||||
* Updates the uniform location of the uniform variable named <name>
|
||||
* in the provided shader program.
|
||||
*/
|
||||
void bind(ghoul::opengl::ProgramObject* program, const std::string& name) {
|
||||
_uniformLocation = program->uniformLocation(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of T to its corresponding GPU value.
|
||||
* OBS! Users must ensure bind has been called before using this method
|
||||
*/
|
||||
void setValue(ghoul::opengl::ProgramObject* program, T val) {
|
||||
program->setUniform(_uniformLocation, val);
|
||||
}
|
||||
|
||||
protected:
|
||||
GLint _uniformLocation = -1;
|
||||
};
|
||||
|
||||
/**
|
||||
* Manages a Texture on the GPU.
|
||||
* This class provides a simple interface binding texture to the
|
||||
* named uniform.
|
||||
*/
|
||||
class GPUTexture {
|
||||
public:
|
||||
/**
|
||||
* Updates the uniform location of the uniform variable named <name>
|
||||
* in the provided shader program.
|
||||
*/
|
||||
void bind(ghoul::opengl::ProgramObject* program, const std::string& name) {
|
||||
_uniformLocation = program->uniformLocation(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets and assignes a texture unit within the provided shader
|
||||
* program.
|
||||
* OBS! Users must ensure bind has been called before using this method.
|
||||
*/
|
||||
void setValue(ghoul::opengl::ProgramObject* program, ghoul::opengl::Texture* texture){
|
||||
_texUnit = std::make_unique<ghoul::opengl::TextureUnit>();
|
||||
_texUnit->activate();
|
||||
if (texture) {
|
||||
texture->bind();
|
||||
}
|
||||
program->setUniform(_uniformLocation, *_texUnit);
|
||||
}
|
||||
|
||||
void deactivate() {
|
||||
_texUnit = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<ghoul::opengl::TextureUnit> _texUnit;
|
||||
GLint _uniformLocation = -1;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_CORE___GPUDATA___H__
|
||||
@@ -37,7 +37,7 @@ struct Job {
|
||||
virtual ~Job() = default;
|
||||
|
||||
virtual void execute() = 0;
|
||||
virtual std::shared_ptr<P> product() = 0;
|
||||
virtual P product() = 0;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -55,9 +55,9 @@
|
||||
namespace {
|
||||
static const char* _loggerCat = "RenderableAtmosphere";
|
||||
|
||||
const char* keyShadowGroup = "ShadowGroup";
|
||||
const char* keyShadowSource = "Source";
|
||||
const char* keyShadowCaster = "Caster";
|
||||
const char* KeyShadowGroup = "ShadowGroup";
|
||||
const char* KeyShadowSource = "Source";
|
||||
const char* KeyShadowCaster = "Caster";
|
||||
|
||||
const char* keyAtmosphere = "Atmosphere";
|
||||
const char* keyAtmosphereRadius = "AtmosphereRadius";
|
||||
@@ -293,18 +293,18 @@ RenderableAtmosphere::RenderableAtmosphere(const ghoul::Dictionary& dictionary)
|
||||
//======== Reads Shadow (Eclipses) Entries in mod file ===========
|
||||
//================================================================
|
||||
ghoul::Dictionary shadowDictionary;
|
||||
bool success = dictionary.getValue(keyShadowGroup, shadowDictionary);
|
||||
bool success = dictionary.getValue(KeyShadowGroup, shadowDictionary);
|
||||
bool disableShadows = false;
|
||||
if (success) {
|
||||
std::vector<std::pair<std::string, double>> sourceArray;
|
||||
unsigned int sourceCounter = 1;
|
||||
while (success) {
|
||||
std::string sourceName;
|
||||
success = shadowDictionary.getValue(keyShadowSource +
|
||||
success = shadowDictionary.getValue(KeyShadowSource +
|
||||
std::to_string(sourceCounter) + ".Name", sourceName);
|
||||
if (success) {
|
||||
double sourceRadius;
|
||||
success = shadowDictionary.getValue(keyShadowSource +
|
||||
success = shadowDictionary.getValue(KeyShadowSource +
|
||||
std::to_string(sourceCounter) + ".Radius", sourceRadius);
|
||||
if (success) {
|
||||
sourceArray.emplace_back(sourceName, sourceRadius);
|
||||
@@ -329,11 +329,11 @@ RenderableAtmosphere::RenderableAtmosphere(const ghoul::Dictionary& dictionary)
|
||||
unsigned int casterCounter = 1;
|
||||
while (success) {
|
||||
std::string casterName;
|
||||
success = shadowDictionary.getValue(keyShadowCaster +
|
||||
success = shadowDictionary.getValue(KeyShadowCaster +
|
||||
std::to_string(casterCounter) + ".Name", casterName);
|
||||
if (success) {
|
||||
double casterRadius;
|
||||
success = shadowDictionary.getValue(keyShadowCaster +
|
||||
success = shadowDictionary.getValue(KeyShadowCaster +
|
||||
std::to_string(casterCounter) + ".Radius", casterRadius);
|
||||
if (success) {
|
||||
casterArray.emplace_back(casterName, casterRadius);
|
||||
|
||||
@@ -227,21 +227,6 @@ void DebugRenderer::renderCameraFrustum(const RenderData& data, const Camera& ot
|
||||
glEnable(GL_CULL_FACE);
|
||||
}
|
||||
|
||||
#ifdef OPENSPACE_MODULE_GLOBEBROWSING_ENABLED
|
||||
void DebugRenderer::renderAABB2(const globebrowsing::AABB2& screenSpaceAABB,
|
||||
const glm::vec4& rgba) const
|
||||
{
|
||||
Vertices vertices = {
|
||||
glm::vec4(screenSpaceAABB.min.x, screenSpaceAABB.min.y, 1, 1),
|
||||
glm::vec4(screenSpaceAABB.min.x, screenSpaceAABB.max.y, 1, 1),
|
||||
glm::vec4(screenSpaceAABB.max.x, screenSpaceAABB.min.y, 1, 1),
|
||||
glm::vec4(screenSpaceAABB.max.x, screenSpaceAABB.max.y, 1, 1)
|
||||
};
|
||||
|
||||
renderVertices(vertices, GL_LINES, rgba);
|
||||
}
|
||||
#endif // OPENSPACE_MODULE_GLOBEBROWSING_ENABLED
|
||||
|
||||
#ifdef OPENSPACE_MODULE_GLOBEBROWSING_ENABLED
|
||||
const DebugRenderer::Vertices DebugRenderer::verticesFor(
|
||||
const globebrowsing::AABB3& screenSpaceAABB) const
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include <openspace/util/updatestructures.h>
|
||||
|
||||
#ifdef OPENSPACE_MODULE_GLOBEBROWSING_ENABLED
|
||||
#include <modules/globebrowsing/geometry/aabb.h>
|
||||
#include <modules/globebrowsing/src/basictypes.h>
|
||||
#endif // OPENSPACE_MODULE_GLOBEBROWSING_ENABLED
|
||||
|
||||
#include <ghoul/glm.h>
|
||||
@@ -132,15 +132,6 @@ public:
|
||||
void renderCameraFrustum(const RenderData& data, const Camera& otherCamera,
|
||||
const glm::vec4& rgba = { 1.f, 1.f, 1.f, 0.3f }) const;
|
||||
|
||||
#ifdef OPENSPACE_MODULE_GLOBEBROWSING_ENABLED
|
||||
/**
|
||||
* Renders a screen space AABB2 to the screen with the provided color
|
||||
*/
|
||||
void renderAABB2(const globebrowsing::AABB2& screenSpaceAABB,
|
||||
const glm::vec4& rgba = { 1.f, 1.f, 1.f, 0.3f }) const;
|
||||
#endif // OPENSPACE_MODULE_GLOBEBROWSING_ENABLED
|
||||
|
||||
|
||||
#ifdef OPENSPACE_MODULE_GLOBEBROWSING_ENABLED
|
||||
/**
|
||||
* Takes a AABB3 in screen space and returns vertices representing the corner points
|
||||
|
||||
@@ -26,201 +26,76 @@ include(${OPENSPACE_CMAKE_EXT_DIR}/module_definition.cmake)
|
||||
|
||||
set(HEADER_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/globebrowsingmodule.h
|
||||
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/cache/lrucache.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/cache/lrucache.inl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/cache/memoryawaretilecache.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/cache/texturecontainer.h
|
||||
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/chunk/chunk.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/chunk/chunknode.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/chunk/chunklevelevaluator/chunklevelevaluator.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/chunk/chunklevelevaluator/availabletiledataevaluator.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/chunk/chunklevelevaluator/distanceevaluator.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/chunk/chunklevelevaluator/projectedareaevaluator.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/chunk/culling/chunkculler.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/chunk/culling/frustumculler.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/chunk/culling/horizonculler.h
|
||||
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/dashboard/dashboarditemglobelocation.h
|
||||
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/geometry/aabb.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/geometry/angle.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/geometry/angle.inl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/geometry/ellipsoid.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/geometry/geodetic2.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/geometry/geodetic3.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/geometry/geodeticpatch.h
|
||||
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/globes/chunkedlodglobe.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/globes/pointglobe.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/globes/renderableglobe.h
|
||||
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/meshes/basicgrid.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/meshes/grid.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/meshes/skirtedgrid.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/meshes/trianglesoup.h
|
||||
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/prioritizingconcurrentjobmanager.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/prioritizingconcurrentjobmanager.inl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/pixelbuffer.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/pixelbuffercontainer.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/pixelbuffercontainer.inl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/statscollector.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/templatedstatscollector.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/templatedstatscollector.inl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/timequantizer.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/lruthreadpool.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/lruthreadpool.inl
|
||||
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/chunkrenderer.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/layershadermanager.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/gpu/gpuchunktile.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/gpu/gpuchunktilepile.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/gpu/gpuheightlayer.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/gpu/gpulayer.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/gpu/gpulayeradjustment.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/gpu/gpulayergroup.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/gpu/gpulayermanager.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/gpu/gpulayerrendersettings.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/gpu/gputiledepthtransform.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/gpu/gputileuvtransform.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/layer/layer.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/layer/layeradjustment.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/layer/layergroup.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/layer/layergroupid.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/layer/layermanager.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/layer/layerrendersettings.h
|
||||
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/asynctiledataprovider.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/chunktile.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/pixelregion.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/rawtile.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/textureformat.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/tile.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/tiledepthtransform.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileindex.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/tilemetadata.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileselector.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileuvtransform.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileloadjob.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/defaulttileprovider.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/singleimageprovider.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/sizereferencetileprovider.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/temporaltileprovider.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/texttileprovider.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/tileindextileprovider.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/tileprovider.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/tileproviderbyindex.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/tileproviderbylevel.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/tiletextureinitdata.h
|
||||
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/rawtiledatareader/rawtiledatareader.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/rawtiledatareader/gdalrawtiledatareader.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/rawtiledatareader/simplerawtiledatareader.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/rawtiledatareader/gdalwrapper.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/rawtiledatareader/iodescription.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/rawtiledatareader/tiledatatype.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/asynctiledataprovider.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/basictypes.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/dashboarditemglobelocation.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/ellipsoid.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/gdalwrapper.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/geodeticpatch.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/gpulayergroup.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/layer.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/layeradjustment.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/layergroup.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/layergroupid.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/layermanager.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/layerrendersettings.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/lrucache.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/lrucache.inl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/lruthreadpool.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/lruthreadpool.inl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/memoryawaretilecache.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/prioritizingconcurrentjobmanager.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/prioritizingconcurrentjobmanager.inl
|
||||
${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/skirtedgrid.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/tileindex.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/tileloadjob.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/tileprovider.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/tiletextureinitdata.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/timequantizer.h
|
||||
)
|
||||
|
||||
set(SOURCE_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/globebrowsingmodule.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/globebrowsingmodule_lua.inl
|
||||
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/cache/memoryawaretilecache.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/cache/texturecontainer.cpp
|
||||
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/chunk/chunk.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/chunk/chunknode.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/chunk/chunklevelevaluator/availabletiledataevaluator.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/chunk/chunklevelevaluator/distanceevaluator.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/chunk/chunklevelevaluator/projectedareaevaluator.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/chunk/culling/frustumculler.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/chunk/culling/horizonculler.cpp
|
||||
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/dashboard/dashboarditemglobelocation.cpp
|
||||
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/geometry/aabb.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/geometry/ellipsoid.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/geometry/geodetic2.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/geometry/geodeticpatch.cpp
|
||||
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/globes/chunkedlodglobe.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/globes/pointglobe.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/globes/renderableglobe.cpp
|
||||
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/meshes/basicgrid.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/meshes/grid.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/meshes/skirtedgrid.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/meshes/trianglesoup.cpp
|
||||
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/pixelbuffer.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/statscollector.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/other/timequantizer.cpp
|
||||
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/chunkrenderer.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/layershadermanager.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/gpu/gpuchunktile.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/gpu/gpuchunktilepile.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/gpu/gpuheightlayer.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/gpu/gpulayer.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/gpu/gpulayeradjustment.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/gpu/gpulayergroup.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/gpu/gpulayermanager.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/gpu/gpulayerrendersettings.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/gpu/gputiledepthtransform.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/gpu/gputileuvtransform.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/layer/layer.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/layer/layeradjustment.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/layer/layergroup.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/layer/layergroupid.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/layer/layermanager.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rendering/layer/layerrendersettings.cpp
|
||||
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/asynctiledataprovider.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/pixelregion.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/rawtile.cpp
|
||||
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/tile.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileindex.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/tilemetadata.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileselector.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileloadjob.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/defaulttileprovider.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/singleimageprovider.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/sizereferencetileprovider.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/temporaltileprovider.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/texttileprovider.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/tileindextileprovider.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/tileprovider.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/tileproviderbyindex.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/tileproviderbylevel.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/tiletextureinitdata.cpp
|
||||
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/rawtiledatareader/rawtiledatareader.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/rawtiledatareader/gdalrawtiledatareader.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/rawtiledatareader/simplerawtiledatareader.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/rawtiledatareader/gdalwrapper.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/rawtiledatareader/iodescription.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/rawtiledatareader/tiledatatype.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/asynctiledataprovider.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/dashboarditemglobelocation.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/ellipsoid.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/gdalwrapper.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/geodeticpatch.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/gpulayergroup.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/layer.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/layeradjustment.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/layergroup.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/layergroupid.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/layermanager.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/layerrendersettings.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/memoryawaretilecache.cpp
|
||||
${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/skirtedgrid.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/tileindex.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/tileloadjob.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/tileprovider.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/tiletextureinitdata.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/timequantizer.cpp
|
||||
)
|
||||
source_group("Source Files" FILES ${SOURCE_FILES})
|
||||
|
||||
set(SHADER_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/blending.hglsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/ellipsoid.hglsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/globalchunkedlodpatch_vs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/globalchunkedlodpatch_fs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/localchunkedlodpatch_vs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/localchunkedlodpatch_fs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/pointglobe_vs.glsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/pointglobe_fs.glsl
|
||||
${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/texturetilemapping.hglsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/tile.hglsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/tilefragment.hglsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/tileheight.hglsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/tilevertexskirt.hglsl
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shaders/globeshading.hglsl
|
||||
)
|
||||
|
||||
source_group("Shader Files" FILES ${SHADER_FILES})
|
||||
@@ -232,36 +107,31 @@ create_new_module(
|
||||
${HEADER_FILES} ${SOURCE_FILES} ${SHADER_FILES}
|
||||
)
|
||||
|
||||
option(OPENSPACE_MODULE_GLOBEBROWSING_USE_GDAL "Use GDAL" ON)
|
||||
|
||||
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/gdal_data DESTINATION modules/globebrowsing)
|
||||
|
||||
if (OPENSPACE_MODULE_GLOBEBROWSING_USE_GDAL)
|
||||
if (WIN32)
|
||||
target_include_directories(
|
||||
openspace-module-globebrowsing
|
||||
SYSTEM PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ext/gdal/include
|
||||
)
|
||||
if (WIN32)
|
||||
target_include_directories(
|
||||
openspace-module-globebrowsing
|
||||
SYSTEM PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ext/gdal/include
|
||||
)
|
||||
|
||||
target_link_libraries(
|
||||
openspace-module-globebrowsing
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ext/gdal/lib/gdal_i.lib
|
||||
)
|
||||
register_external_libraries("${CMAKE_CURRENT_SOURCE_DIR}/ext/gdal/lib/gdal202.dll")
|
||||
else (WIN32)
|
||||
find_package(GDAL REQUIRED)
|
||||
target_link_libraries(
|
||||
openspace-module-globebrowsing
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ext/gdal/lib/gdal_i.lib
|
||||
)
|
||||
register_external_libraries("${CMAKE_CURRENT_SOURCE_DIR}/ext/gdal/lib/gdal202.dll")
|
||||
else (WIN32)
|
||||
find_package(GDAL REQUIRED)
|
||||
|
||||
target_include_directories(
|
||||
openspace-module-globebrowsing
|
||||
SYSTEM PUBLIC
|
||||
${GDAL_INCLUDE_DIR}
|
||||
)
|
||||
target_include_directories(
|
||||
openspace-module-globebrowsing
|
||||
SYSTEM PUBLIC
|
||||
${GDAL_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
target_link_libraries(openspace-module-globebrowsing ${GDAL_LIBRARY})
|
||||
target_link_libraries(openspace-module-globebrowsing ${GDAL_LIBRARY})
|
||||
|
||||
mark_as_advanced(GDAL_CONFIG GDAL_INCLUDE_DIR GDAL_LIBRARY)
|
||||
mark_as_advanced(GDAL_CONFIG GDAL_INCLUDE_DIR GDAL_LIBRARY)
|
||||
|
||||
endif () # WIN32
|
||||
target_compile_definitions(openspace-module-globebrowsing PUBLIC GLOBEBROWSING_USE_GDAL)
|
||||
endif () # OPENSPACE_MODULE_GLOBEBROWSING_USE_GDAL
|
||||
endif () # WIN32
|
||||
|
||||
83
modules/globebrowsing/cache/texturecontainer.cpp
vendored
83
modules/globebrowsing/cache/texturecontainer.cpp
vendored
@@ -1,83 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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/cache/texturecontainer.h>
|
||||
|
||||
namespace openspace::globebrowsing::cache {
|
||||
|
||||
TextureContainer::TextureContainer(TileTextureInitData initData, size_t numTextures)
|
||||
: _initData(std::move(initData))
|
||||
, _numTextures(numTextures)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void TextureContainer::reset() {
|
||||
_textures.clear();
|
||||
_freeTexture = 0;
|
||||
for (size_t i = 0; i < _numTextures; ++i) {
|
||||
using namespace ghoul::opengl;
|
||||
std::unique_ptr<Texture> tex = std::make_unique<Texture>(
|
||||
_initData.dimensions(),
|
||||
_initData.ghoulTextureFormat(),
|
||||
_initData.glTextureFormat(),
|
||||
_initData.glType(),
|
||||
Texture::FilterMode::Linear,
|
||||
Texture::WrappingMode::ClampToEdge,
|
||||
Texture::AllocateData(_initData.shouldAllocateDataOnCPU())
|
||||
);
|
||||
|
||||
tex->setDataOwnership(Texture::TakeOwnership::Yes);
|
||||
tex->uploadTexture();
|
||||
tex->setFilter(Texture::FilterMode::AnisotropicMipMap);
|
||||
|
||||
_textures.push_back(std::move(tex));
|
||||
}
|
||||
}
|
||||
|
||||
void TextureContainer::reset(size_t numTextures) {
|
||||
_numTextures = numTextures;
|
||||
reset();
|
||||
}
|
||||
|
||||
ghoul::opengl::Texture* TextureContainer::getTextureIfFree() {
|
||||
if (_freeTexture < _textures.size()) {
|
||||
ghoul::opengl::Texture* texture = _textures[_freeTexture].get();
|
||||
_freeTexture++;
|
||||
return texture;
|
||||
}
|
||||
else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
const TileTextureInitData& TextureContainer::tileTextureInitData() const {
|
||||
return _initData;
|
||||
}
|
||||
|
||||
size_t TextureContainer::size() const {
|
||||
return _textures.size();
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing::cache
|
||||
76
modules/globebrowsing/cache/texturecontainer.h
vendored
76
modules/globebrowsing/cache/texturecontainer.h
vendored
@@ -1,76 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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___TEXTURE_CONTAINER___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___TEXTURE_CONTAINER___H__
|
||||
|
||||
#include <modules/globebrowsing/tile/tiletextureinitdata.h>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace openspace::globebrowsing::cache {
|
||||
|
||||
/**
|
||||
* Owner of texture data used for tiles. Instead of dynamically allocating textures one
|
||||
* by one, they are created once and reused.
|
||||
*/
|
||||
class TextureContainer {
|
||||
public:
|
||||
/**
|
||||
* \param initData is the description of the texture type.
|
||||
* \param numTextures is the number of textures to allocate.
|
||||
*/
|
||||
TextureContainer(TileTextureInitData initData, size_t numTextures);
|
||||
|
||||
~TextureContainer() = default;
|
||||
|
||||
void reset();
|
||||
void reset(size_t numTextures);
|
||||
|
||||
/**
|
||||
* \return A pointer to a texture if there is one texture never used before. If there
|
||||
* are no textures left, nullptr is returned. TextureContainer still owns the
|
||||
* texture so no delete should be called on the raw pointer.
|
||||
*/
|
||||
ghoul::opengl::Texture* getTextureIfFree();
|
||||
|
||||
const TileTextureInitData& tileTextureInitData() const;
|
||||
|
||||
/**
|
||||
* \returns the number of textures in this TextureContainer
|
||||
*/
|
||||
size_t size() const;
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<ghoul::opengl::Texture>> _textures;
|
||||
|
||||
const TileTextureInitData _initData;
|
||||
size_t _freeTexture = 0;
|
||||
size_t _numTextures;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing::cache
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___TEXTURE_CONTAINER___H__
|
||||
@@ -1,227 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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/chunk/chunk.h>
|
||||
|
||||
#include <modules/globebrowsing/geometry/geodetic3.h>
|
||||
#include <modules/globebrowsing/globes/renderableglobe.h>
|
||||
#include <modules/globebrowsing/globes/chunkedlodglobe.h>
|
||||
#include <modules/globebrowsing/rendering/layer/layergroup.h>
|
||||
#include <modules/globebrowsing/rendering/layer/layermanager.h>
|
||||
#include <modules/globebrowsing/tile/chunktile.h>
|
||||
#include <modules/globebrowsing/tile/tileselector.h>
|
||||
#include <modules/globebrowsing/tile/tilemetadata.h>
|
||||
#include <modules/globebrowsing/rendering/layer/layerrendersettings.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
Chunk::Chunk(const RenderableGlobe& owner, const TileIndex& tileIndex, bool initVisible)
|
||||
: _owner(owner)
|
||||
, _tileIndex(tileIndex)
|
||||
, _isVisible(initVisible)
|
||||
, _surfacePatch(tileIndex)
|
||||
{}
|
||||
|
||||
const GeodeticPatch& Chunk::surfacePatch() const {
|
||||
return _surfacePatch;
|
||||
}
|
||||
|
||||
const RenderableGlobe& Chunk::owner() const {
|
||||
return _owner;
|
||||
}
|
||||
|
||||
const TileIndex Chunk::tileIndex() const {
|
||||
return _tileIndex;
|
||||
}
|
||||
|
||||
bool Chunk::isVisible() const {
|
||||
return _isVisible;
|
||||
}
|
||||
|
||||
Chunk::Status Chunk::update(const RenderData& data) {
|
||||
const std::shared_ptr<const Camera>& savedCamera = _owner.savedCamera();
|
||||
const Camera& camRef = savedCamera ? *savedCamera : data.camera;
|
||||
|
||||
RenderData myRenderData = {
|
||||
camRef,
|
||||
data.position,
|
||||
data.time,
|
||||
data.doPerformanceMeasurement,
|
||||
data.renderBinMask,
|
||||
data.modelTransform
|
||||
};
|
||||
|
||||
_isVisible = true;
|
||||
if (_owner.chunkedLodGlobe()->testIfCullable(*this, myRenderData)) {
|
||||
_isVisible = false;
|
||||
return Status::WantMerge;
|
||||
}
|
||||
|
||||
const int desiredLevel = _owner.chunkedLodGlobe()->desiredLevel(
|
||||
*this,
|
||||
myRenderData
|
||||
);
|
||||
|
||||
if (desiredLevel < _tileIndex.level) {
|
||||
return Status::WantMerge;
|
||||
}
|
||||
else if (_tileIndex.level < desiredLevel) {
|
||||
return Status::WantSplit;
|
||||
}
|
||||
else {
|
||||
return Status::DoNothing;
|
||||
}
|
||||
}
|
||||
|
||||
Chunk::BoundingHeights Chunk::boundingHeights() const {
|
||||
using ChunkTileSettingsPair = std::pair<ChunkTile, const LayerRenderSettings*>;
|
||||
|
||||
BoundingHeights boundingHeights { 0.f, 0.f, false };
|
||||
|
||||
// In the future, this should be abstracted away and more easily queryable.
|
||||
// One must also handle how to sample pick one out of multiplte heightmaps
|
||||
std::shared_ptr<LayerManager> lm = owner().chunkedLodGlobe()->layerManager();
|
||||
|
||||
// The raster of a height map is the first one. We assume that the height map is
|
||||
// a single raster image. If it is not we will just use the first raster
|
||||
// (that is channel 0).
|
||||
const size_t HeightChannel = 0;
|
||||
const LayerGroup& heightmaps = lm->layerGroup(layergroupid::GroupID::HeightLayers);
|
||||
std::vector<ChunkTileSettingsPair> chunkTileSettingPairs =
|
||||
tileselector::getTilesAndSettingsUnsorted(heightmaps, _tileIndex);
|
||||
|
||||
bool lastHadMissingData = true;
|
||||
for (const ChunkTileSettingsPair& chunkTileSettingsPair : chunkTileSettingPairs) {
|
||||
const ChunkTile& chunkTile = chunkTileSettingsPair.first;
|
||||
const LayerRenderSettings* settings = chunkTileSettingsPair.second;
|
||||
const bool goodTile = (chunkTile.tile.status() == Tile::Status::OK);
|
||||
const bool hasTileMetaData = (chunkTile.tile.metaData() != nullptr);
|
||||
|
||||
if (goodTile && hasTileMetaData) {
|
||||
TileMetaData* tileMetaData = chunkTile.tile.metaData();
|
||||
|
||||
const float minValue = settings->performLayerSettings(
|
||||
tileMetaData->minValues[HeightChannel]
|
||||
);
|
||||
const float maxValue = settings->performLayerSettings(
|
||||
tileMetaData->maxValues[HeightChannel]
|
||||
);
|
||||
|
||||
if (!boundingHeights.available) {
|
||||
if (tileMetaData->hasMissingData[HeightChannel]) {
|
||||
boundingHeights.min = std::min(DefaultHeight, minValue);
|
||||
boundingHeights.max = std::max(DefaultHeight, maxValue);
|
||||
}
|
||||
else {
|
||||
boundingHeights.min = minValue;
|
||||
boundingHeights.max = maxValue;
|
||||
}
|
||||
boundingHeights.available = true;
|
||||
}
|
||||
else {
|
||||
boundingHeights.min = std::min(boundingHeights.min, minValue);
|
||||
boundingHeights.max = std::max(boundingHeights.max, maxValue);
|
||||
}
|
||||
lastHadMissingData = tileMetaData->hasMissingData[HeightChannel];
|
||||
}
|
||||
|
||||
// Allow for early termination
|
||||
if (!lastHadMissingData) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return boundingHeights;
|
||||
}
|
||||
|
||||
std::vector<glm::dvec4> Chunk::boundingPolyhedronCorners() const {
|
||||
const Ellipsoid& ellipsoid = owner().ellipsoid();
|
||||
const GeodeticPatch& patch = surfacePatch();
|
||||
|
||||
const BoundingHeights& boundingHeight = boundingHeights();
|
||||
|
||||
// assume worst case
|
||||
const double patchCenterRadius = ellipsoid.maximumRadius();
|
||||
|
||||
const double maxCenterRadius = patchCenterRadius + boundingHeight.max;
|
||||
Geodetic2 halfSize = patch.halfSize();
|
||||
|
||||
// As the patch is curved, the maximum height offsets at the corners must be long
|
||||
// enough to cover large enough to cover a boundingHeight.max at the center of the
|
||||
// patch.
|
||||
// Approximating scaleToCoverCenter by assuming the latitude and longitude angles
|
||||
// of "halfSize" are equal to the angles they create from the center of the
|
||||
// globe to the patch corners. This is true for the longitude direction when
|
||||
// the ellipsoid can be approximated as a sphere and for the latitude for patches
|
||||
// close to the equator. Close to the pole this will lead to a bigger than needed
|
||||
// value for scaleToCoverCenter. However, this is a simple calculation and a good
|
||||
// Approximation.
|
||||
const double y1 = tan(halfSize.lat);
|
||||
const double y2 = tan(halfSize.lon);
|
||||
const double scaleToCoverCenter = sqrt(1 + pow(y1, 2) + pow(y2, 2));
|
||||
|
||||
const double maxCornerHeight = maxCenterRadius * scaleToCoverCenter -
|
||||
patchCenterRadius;
|
||||
|
||||
const bool chunkIsNorthOfEquator = patch.isNorthern();
|
||||
|
||||
// The minimum height offset, however, we can simply
|
||||
const double minCornerHeight = boundingHeight.min;
|
||||
std::vector<glm::dvec4> corners(8);
|
||||
|
||||
const double latCloseToEquator = patch.edgeLatitudeNearestEquator();
|
||||
const Geodetic3 p1Geodetic = {
|
||||
{ latCloseToEquator, patch.minLon() },
|
||||
maxCornerHeight
|
||||
};
|
||||
const Geodetic3 p2Geodetic = {
|
||||
{ latCloseToEquator, patch.maxLon() },
|
||||
maxCornerHeight
|
||||
};
|
||||
|
||||
const glm::vec3 p1 = ellipsoid.cartesianPosition(p1Geodetic);
|
||||
const glm::vec3 p2 = ellipsoid.cartesianPosition(p2Geodetic);
|
||||
const glm::vec3 p = 0.5f * (p1 + p2);
|
||||
const Geodetic2 pGeodetic = ellipsoid.cartesianToGeodetic2(p);
|
||||
const double latDiff = latCloseToEquator - pGeodetic.lat;
|
||||
|
||||
for (size_t i = 0; i < 8; ++i) {
|
||||
const Quad q = static_cast<Quad>(i % 4);
|
||||
const double cornerHeight = i < 4 ? minCornerHeight : maxCornerHeight;
|
||||
Geodetic3 cornerGeodetic = { patch.corner(q), cornerHeight };
|
||||
|
||||
const bool cornerIsNorthern = !((i / 2) % 2);
|
||||
const bool cornerCloseToEquator = chunkIsNorthOfEquator ^ cornerIsNorthern;
|
||||
if (cornerCloseToEquator) {
|
||||
cornerGeodetic.geodetic2.lat += latDiff;
|
||||
}
|
||||
|
||||
corners[i] = glm::dvec4(ellipsoid.cartesianPosition(cornerGeodetic), 1);
|
||||
}
|
||||
|
||||
return corners;
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -1,103 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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___CHUNK___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___CHUNK___H__
|
||||
|
||||
#include <modules/globebrowsing/geometry/geodeticpatch.h>
|
||||
#include <modules/globebrowsing/tile/tileindex.h>
|
||||
#include <ghoul/glm.h>
|
||||
#include <vector>
|
||||
|
||||
namespace openspace { struct RenderData; }
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
class RenderableGlobe;
|
||||
struct TileIndex;
|
||||
|
||||
class Chunk {
|
||||
public:
|
||||
constexpr static float DefaultHeight = 0.f;
|
||||
|
||||
struct BoundingHeights {
|
||||
float min;
|
||||
float max;
|
||||
bool available;
|
||||
};
|
||||
|
||||
enum class Status {
|
||||
DoNothing,
|
||||
WantMerge,
|
||||
WantSplit
|
||||
};
|
||||
|
||||
Chunk(const RenderableGlobe& owner, const TileIndex& tileIndex,
|
||||
bool initVisible = true);
|
||||
|
||||
/**
|
||||
* Updates the Chunk internally and returns the Status of the Chunk.
|
||||
*
|
||||
* Tests if the Chunk is cullable and gets the desired level of the Chunk. If the
|
||||
* Chunk is cullable it will be set to invisible and return Status::WANT_MERGE.
|
||||
* If the desired level is smaller than the current level of the chunk it will
|
||||
* return Status::WANT_MERGE, if it is larger it will return Status::WANT_SPLIT,
|
||||
* otherwise Status::DO_NOTHING.
|
||||
*
|
||||
* \return The Status of the chunk.
|
||||
*/
|
||||
Status update(const RenderData& data);
|
||||
|
||||
/**
|
||||
* Returns a convex polyhedron of eight vertices tightly bounding the volume of
|
||||
* the Chunk.
|
||||
*/
|
||||
std::vector<glm::dvec4> boundingPolyhedronCorners() const;
|
||||
|
||||
const GeodeticPatch& surfacePatch() const;
|
||||
const RenderableGlobe& owner() const;
|
||||
const TileIndex tileIndex() const;
|
||||
bool isVisible() const;
|
||||
|
||||
/**
|
||||
* Returns BoundingHeights that fits the Chunk as tightly as possible.
|
||||
*
|
||||
* If the Chunk uses more than one HightLayer, the BoundingHeights will be set
|
||||
* to cover all HeightLayers. If the Chunk has a higher level than its highest
|
||||
* resolution HightLayer Tile, it will base its BoundingHeights on that Tile.
|
||||
* This means that high level Chunks can have BoundingHeights that are not
|
||||
* tightly fitting.
|
||||
*/
|
||||
BoundingHeights boundingHeights() const;
|
||||
|
||||
private:
|
||||
const RenderableGlobe& _owner;
|
||||
const TileIndex _tileIndex;
|
||||
bool _isVisible;
|
||||
const GeodeticPatch _surfacePatch;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___CHUNK___H__
|
||||
@@ -1,57 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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/chunk/chunklevelevaluator/availabletiledataevaluator.h>
|
||||
|
||||
#include <modules/globebrowsing/chunk/chunk.h>
|
||||
#include <modules/globebrowsing/globes/chunkedlodglobe.h>
|
||||
#include <modules/globebrowsing/globes/renderableglobe.h>
|
||||
#include <modules/globebrowsing/rendering/layer/layer.h>
|
||||
#include <modules/globebrowsing/rendering/layer/layergroup.h>
|
||||
#include <modules/globebrowsing/rendering/layer/layermanager.h>
|
||||
#include <modules/globebrowsing/tile/tile.h>
|
||||
|
||||
namespace openspace::globebrowsing::chunklevelevaluator {
|
||||
|
||||
int AvailableTileData::desiredLevel(const Chunk& chunk, const RenderData&) const {
|
||||
std::shared_ptr<LayerManager> layerManager =
|
||||
chunk.owner().chunkedLodGlobe()->layerManager();
|
||||
|
||||
const int currLevel = chunk.tileIndex().level;
|
||||
|
||||
for (size_t i = 0; i < layergroupid::NUM_LAYER_GROUPS; ++i) {
|
||||
for (const std::shared_ptr<Layer>& layer :
|
||||
layerManager->layerGroup(i).activeLayers())
|
||||
{
|
||||
Tile::Status status = layer->tileStatus(chunk.tileIndex());
|
||||
if (status == Tile::Status::OK) {
|
||||
return UnknownDesiredLevel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return currLevel - 1;
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing::chunklevelevaluator
|
||||
@@ -1,45 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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___AVAILABLETILEDATAEVALUATOR___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___AVAILABLETILEDATAEVALUATOR___H__
|
||||
|
||||
#include <modules/globebrowsing/chunk/chunklevelevaluator/chunklevelevaluator.h>
|
||||
|
||||
namespace openspace::globebrowsing::chunklevelevaluator {
|
||||
|
||||
/**
|
||||
* If this chunk has available tile data for any LayerGroup on any of its active
|
||||
* Layers it will return an UNKNOWN_DESIRED_LEVEL. If no data is available it will
|
||||
* evaluate to a level that is <code>current level -1</code>.
|
||||
*/
|
||||
class AvailableTileData : public Evaluator {
|
||||
public:
|
||||
virtual ~AvailableTileData() override = default;
|
||||
int desiredLevel(const Chunk& chunk, const RenderData& data) const override;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing::chunklevelevaluator
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___AVAILABLETILEDATAEVALUATOR___H__
|
||||
@@ -1,49 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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___CHUNKLEVELEVALUATOR___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___CHUNKLEVELEVALUATOR___H__
|
||||
|
||||
namespace openspace { struct RenderData; }
|
||||
|
||||
namespace openspace::globebrowsing { class Chunk; }
|
||||
|
||||
namespace openspace::globebrowsing::chunklevelevaluator {
|
||||
|
||||
/**
|
||||
* Abstract class defining an interface for accessing a desired level of a Chunk.
|
||||
* The desired level can be used in the process of determining whether a Chunk should
|
||||
* want to split, merge or do nothing.
|
||||
*/
|
||||
class Evaluator {
|
||||
public:
|
||||
virtual ~Evaluator() = default;
|
||||
constexpr static const int UnknownDesiredLevel = -1;
|
||||
|
||||
virtual int desiredLevel(const Chunk& chunk, const RenderData& data) const = 0;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing::chunklevelevaluator
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___CHUNKLEVELEVALUATOR___H__
|
||||
@@ -1,70 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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/chunk/chunklevelevaluator/distanceevaluator.h>
|
||||
|
||||
#include <modules/globebrowsing/chunk/chunk.h>
|
||||
#include <modules/globebrowsing/globes/chunkedlodglobe.h>
|
||||
#include <modules/globebrowsing/globes/renderableglobe.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
|
||||
namespace openspace::globebrowsing::chunklevelevaluator {
|
||||
|
||||
int Distance::desiredLevel(const Chunk& chunk, const RenderData& data) const {
|
||||
// Calculations are done in the reference frame of the globe
|
||||
// (model space). Hence, the camera position needs to be transformed
|
||||
// with the inverse model matrix
|
||||
const glm::dmat4 inverseModelTransform = chunk.owner().inverseModelTransform();
|
||||
const RenderableGlobe& globe = chunk.owner();
|
||||
const Ellipsoid& ellipsoid = globe.ellipsoid();
|
||||
|
||||
const glm::dvec3 cameraPosition = glm::dvec3(inverseModelTransform *
|
||||
glm::dvec4(data.camera.positionVec3(), 1.0));
|
||||
|
||||
const Geodetic2 pointOnPatch = chunk.surfacePatch().closestPoint(
|
||||
ellipsoid.cartesianToGeodetic2(cameraPosition)
|
||||
);
|
||||
const glm::dvec3 patchNormal = ellipsoid.geodeticSurfaceNormal(pointOnPatch);
|
||||
glm::dvec3 patchPosition = ellipsoid.cartesianSurfacePosition(pointOnPatch);
|
||||
|
||||
const Chunk::BoundingHeights heights = chunk.boundingHeights();
|
||||
const double heightToChunk = heights.min;
|
||||
|
||||
// Offset position according to height
|
||||
patchPosition += patchNormal * heightToChunk;
|
||||
|
||||
const glm::dvec3 cameraToChunk = patchPosition - cameraPosition;
|
||||
|
||||
// Calculate desired level based on distance
|
||||
const double distanceToPatch = glm::length(cameraToChunk);
|
||||
const double distance = distanceToPatch;
|
||||
|
||||
const double scaleFactor = globe.generalProperties().lodScaleFactor *
|
||||
ellipsoid.minimumRadius();
|
||||
const double projectedScaleFactor = scaleFactor / distance;
|
||||
const int desiredLevel = static_cast<int>(ceil(log2(projectedScaleFactor)));
|
||||
return desiredLevel;
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing::chunklevelevaluator
|
||||
@@ -1,44 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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___DISTANCEEVALUATOR___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___DISTANCEEVALUATOR___H__
|
||||
|
||||
#include <modules/globebrowsing/chunk/chunklevelevaluator/chunklevelevaluator.h>
|
||||
|
||||
namespace openspace::globebrowsing::chunklevelevaluator {
|
||||
|
||||
/**
|
||||
* Evaluate the Chunk level depending on the distance from the Camera to the Chunk.
|
||||
* This evaluation method aims to keep the screen size (horizontal length and not
|
||||
* area) of all chunks constant.
|
||||
*/
|
||||
class Distance : public Evaluator {
|
||||
public:
|
||||
int desiredLevel(const Chunk& chunk, const RenderData& data) const override;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing::chunklevelevaluator
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___DISTANCEEVALUATOR___H__
|
||||
@@ -1,129 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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/chunk/chunklevelevaluator/projectedareaevaluator.h>
|
||||
|
||||
#include <modules/globebrowsing/chunk/chunk.h>
|
||||
#include <modules/globebrowsing/geometry/geodetic3.h>
|
||||
#include <modules/globebrowsing/globes/chunkedlodglobe.h>
|
||||
#include <modules/globebrowsing/globes/renderableglobe.h>
|
||||
#include <modules/globebrowsing/rendering/layer/layermanager.h>
|
||||
#include <modules/globebrowsing/tile/tileprovider/tileprovider.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
|
||||
namespace openspace::globebrowsing::chunklevelevaluator {
|
||||
|
||||
int ProjectedArea::desiredLevel(const Chunk& chunk, const RenderData& data) const {
|
||||
// Calculations are done in the reference frame of the globe
|
||||
// (model space). Hence, the camera position needs to be transformed
|
||||
// with the inverse model matrix
|
||||
const glm::dmat4 inverseModelTransform = chunk.owner().inverseModelTransform();
|
||||
|
||||
const RenderableGlobe& globe = chunk.owner();
|
||||
const Ellipsoid& ellipsoid = globe.ellipsoid();
|
||||
const glm::dvec4 cameraPositionModelSpace = glm::dvec4(data.camera.positionVec3(), 1);
|
||||
const glm::dvec3 cameraPosition = glm::dvec3(
|
||||
inverseModelTransform * cameraPositionModelSpace
|
||||
);
|
||||
const glm::dvec3 cameraToEllipsoidCenter = -cameraPosition;
|
||||
|
||||
const Geodetic2 cameraGeodeticPos = ellipsoid.cartesianToGeodetic2(cameraPosition);
|
||||
|
||||
// Approach:
|
||||
// The projected area of the chunk will be calculated based on a small area that
|
||||
// is close to the camera, and the scaled up to represent the full area.
|
||||
// The advantage of doing this is that it will better handle the cases where the
|
||||
// full patch is very curved (e.g. stretches from latitude 0 to 90 deg).
|
||||
|
||||
const Geodetic2 center = chunk.surfacePatch().center();
|
||||
const Geodetic2 closestCorner = chunk.surfacePatch().closestCorner(cameraGeodeticPos);
|
||||
|
||||
// Camera
|
||||
// |
|
||||
// V
|
||||
//
|
||||
// oo
|
||||
// [ ]<
|
||||
// *geodetic space*
|
||||
//
|
||||
// closestCorner
|
||||
// +-----------------+ <-- north east corner
|
||||
// | |
|
||||
// | center |
|
||||
// | |
|
||||
// +-----------------+ <-- south east corner
|
||||
|
||||
const Chunk::BoundingHeights heights = chunk.boundingHeights();
|
||||
const Geodetic3 c = { center, heights.min };
|
||||
const Geodetic3 c1 = { Geodetic2(center.lat, closestCorner.lon), heights.min };
|
||||
const Geodetic3 c2 = { Geodetic2(closestCorner.lat, center.lon), heights.min };
|
||||
|
||||
// Camera
|
||||
// |
|
||||
// V
|
||||
//
|
||||
// oo
|
||||
// [ ]<
|
||||
// *geodetic space*
|
||||
//
|
||||
// +--------c2-------+ <-- north east corner
|
||||
// | |
|
||||
// c1 c |
|
||||
// | |
|
||||
// +-----------------+ <-- south east corner
|
||||
|
||||
|
||||
// Go from geodetic to cartesian space and project onto unit sphere
|
||||
const glm::dvec3 A = glm::normalize(
|
||||
cameraToEllipsoidCenter + ellipsoid.cartesianPosition(c)
|
||||
);
|
||||
const glm::dvec3 B = glm::normalize(
|
||||
cameraToEllipsoidCenter + ellipsoid.cartesianPosition(c1)
|
||||
);
|
||||
const glm::dvec3 C = glm::normalize(
|
||||
cameraToEllipsoidCenter + ellipsoid.cartesianPosition(c2)
|
||||
);
|
||||
|
||||
// Camera *cartesian space*
|
||||
// | +--------+---+
|
||||
// V __--'' __--'' /
|
||||
// C-------A--------- +
|
||||
// oo / / /
|
||||
//[ ]< +-------B----------+
|
||||
//
|
||||
|
||||
// If the geodetic patch is small (i.e. has small width), that means the patch in
|
||||
// cartesian space will be almost flat, and in turn, the triangle ABC will roughly
|
||||
// correspond to 1/8 of the full area
|
||||
const glm::dvec3 AB = B - A;
|
||||
const glm::dvec3 AC = C - A;
|
||||
const double areaABC = 0.5 * glm::length(glm::cross(AC, AB));
|
||||
const double projectedChunkAreaApprox = 8 * areaABC;
|
||||
|
||||
const double scaledArea = globe.generalProperties().lodScaleFactor *
|
||||
projectedChunkAreaApprox;
|
||||
return chunk.tileIndex().level + static_cast<int>(round(scaledArea - 1));
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing::chunklevelevaluator
|
||||
@@ -1,46 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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___PROJECTEDAREAEVALUATOR___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___PROJECTEDAREAEVALUATOR___H__
|
||||
|
||||
#include <modules/globebrowsing/chunk/chunklevelevaluator/chunklevelevaluator.h>
|
||||
|
||||
namespace openspace::globebrowsing::chunklevelevaluator {
|
||||
|
||||
/**
|
||||
* Evaluate the chunk level using the area of the non-heightmapped Chunk projected
|
||||
* on a sphere with the center in the position of the camera. A Chunk near the
|
||||
* horizon will have a small projected area and hence a lower desired level. This
|
||||
* evaluation is more forgiving than EvaluateChunkLevelByDistance, meaning it results
|
||||
* in lower desired levels.
|
||||
*/
|
||||
class ProjectedArea : public Evaluator {
|
||||
public:
|
||||
virtual int desiredLevel(const Chunk& chunk, const RenderData& data) const override;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing::chunklevelevaluator
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___PROJECTEDAREAEVALUATOR___H__
|
||||
@@ -1,187 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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/chunk/chunknode.h>
|
||||
|
||||
#include <ghoul/misc/assert.h>
|
||||
#include <stack>
|
||||
#include <queue>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
ChunkNode::ChunkNode(Chunk chunk, ChunkNode* parent)
|
||||
: _parent(parent)
|
||||
, _children({ {nullptr, nullptr, nullptr, nullptr} })
|
||||
, _chunk(std::move(chunk))
|
||||
{}
|
||||
|
||||
bool ChunkNode::isRoot() const {
|
||||
return _parent == nullptr;
|
||||
}
|
||||
|
||||
bool ChunkNode::isLeaf() const {
|
||||
return _children[0] == nullptr;
|
||||
}
|
||||
|
||||
bool ChunkNode::updateChunkTree(const RenderData& data) {
|
||||
if (isLeaf()) {
|
||||
Chunk::Status status = _chunk.update(data);
|
||||
if (status == Chunk::Status::WantSplit) {
|
||||
split();
|
||||
}
|
||||
return status == Chunk::Status::WantMerge;
|
||||
}
|
||||
else {
|
||||
char requestedMergeMask = 0;
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
if (_children[i]->updateChunkTree(data)) {
|
||||
requestedMergeMask |= (1 << i);
|
||||
}
|
||||
}
|
||||
|
||||
const bool allChildrenWantsMerge = requestedMergeMask == 0xf;
|
||||
const bool thisChunkWantsSplit = _chunk.update(data) == Chunk::Status::WantSplit;
|
||||
|
||||
if (allChildrenWantsMerge && !thisChunkWantsSplit) {
|
||||
merge();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void ChunkNode::depthFirst(const std::function<void(const ChunkNode&)>& f) const {
|
||||
f(*this);
|
||||
if (!isLeaf()) {
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
_children[i]->depthFirst(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ChunkNode::breadthFirst(const std::function<void(const ChunkNode&)>& f) const {
|
||||
std::queue<const ChunkNode*> Q;
|
||||
|
||||
// Loop through nodes in breadths first order
|
||||
Q.push(this);
|
||||
while (!Q.empty()) {
|
||||
const ChunkNode* node = Q.front();
|
||||
Q.pop();
|
||||
|
||||
f(*node);
|
||||
|
||||
// Add children to queue, if any
|
||||
if (!node->isLeaf()) {
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
Q.push(node->_children[i].get());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ChunkNode::reverseBreadthFirst(const std::function<void(const ChunkNode&)>& f) const
|
||||
{
|
||||
std::stack<const ChunkNode*> S;
|
||||
std::queue<const ChunkNode*> Q;
|
||||
|
||||
// Loop through nodes in breadths first order
|
||||
Q.push(this);
|
||||
while (!Q.empty()) {
|
||||
const ChunkNode* node = Q.front();
|
||||
Q.pop();
|
||||
|
||||
// Add node to future stack
|
||||
S.push(node);
|
||||
|
||||
// Add children to queue, if any
|
||||
if (!node->isLeaf()) {
|
||||
for (const auto& c : node->_children) {
|
||||
Q.push(c.get());
|
||||
}
|
||||
//for (int i = 0; i < 4; ++i) {
|
||||
// Q.push(node->_children[i].get());
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
// Loop through all nodes in stack, this will be reversed breadth first
|
||||
while (!S.empty()) {
|
||||
f(*S.top());
|
||||
S.pop();
|
||||
}
|
||||
}
|
||||
|
||||
const ChunkNode& ChunkNode::find(const Geodetic2& location) const {
|
||||
const ChunkNode* node = this;
|
||||
|
||||
while (!node->isLeaf()) {
|
||||
const Geodetic2 center = node->_chunk.surfacePatch().center();
|
||||
int index = 0;
|
||||
if (center.lon < location.lon) {
|
||||
++index;
|
||||
}
|
||||
if (location.lat < center.lat) {
|
||||
++index;
|
||||
++index;
|
||||
}
|
||||
node = &(node->child(static_cast<Quad>(index)));
|
||||
}
|
||||
return *node;
|
||||
}
|
||||
|
||||
const ChunkNode& ChunkNode::child(const Quad& quad) const {
|
||||
return *_children[quad];
|
||||
}
|
||||
|
||||
void ChunkNode::split(int depth) {
|
||||
if (depth > 0 && isLeaf()) {
|
||||
for (size_t i = 0; i < _children.size(); ++i) {
|
||||
Chunk chunk(_chunk.owner(), _chunk.tileIndex().child(static_cast<Quad>(i)));
|
||||
_children[i] = std::make_unique<ChunkNode>(chunk, this);
|
||||
}
|
||||
}
|
||||
|
||||
if (depth - 1 > 0) {
|
||||
for (const std::unique_ptr<ChunkNode>& child : _children) {
|
||||
child->split(depth - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ChunkNode::merge() {
|
||||
for (std::unique_ptr<ChunkNode>& child : _children) {
|
||||
if (child) {
|
||||
child->merge();
|
||||
}
|
||||
child = nullptr;
|
||||
}
|
||||
|
||||
ghoul_assert(isLeaf(), "ChunkNode must be leaf after merge");
|
||||
}
|
||||
|
||||
const Chunk& ChunkNode::chunk() const {
|
||||
return _chunk;
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -1,84 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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___CHUNKNODE___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___CHUNKNODE___H__
|
||||
|
||||
#include <modules/globebrowsing/chunk/chunk.h>
|
||||
|
||||
#include <array>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
class ChunkedLodGlobe;
|
||||
|
||||
class ChunkNode {
|
||||
public:
|
||||
ChunkNode(Chunk chunk, ChunkNode* parent = nullptr);
|
||||
|
||||
/**
|
||||
* Recursively split the ChunkNode.
|
||||
*
|
||||
* \param depth defines how deep the recursion should go. If depth == 1 (default),
|
||||
* the ChunkNode will only split once.
|
||||
*/
|
||||
void split(int depth = 1);
|
||||
|
||||
/**
|
||||
* Deletes all children of the ChunkNode recursively.
|
||||
*/
|
||||
void merge();
|
||||
|
||||
bool isRoot() const;
|
||||
bool isLeaf() const;
|
||||
|
||||
void depthFirst(const std::function<void(const ChunkNode&)>& f) const;
|
||||
void breadthFirst(const std::function<void(const ChunkNode&)>& f) const;
|
||||
void reverseBreadthFirst(const std::function<void(const ChunkNode&)>& f) const;
|
||||
|
||||
const ChunkNode& find(const Geodetic2& location) const;
|
||||
const ChunkNode& child(const Quad& quad) const;
|
||||
const Chunk& chunk() const;
|
||||
|
||||
/**
|
||||
* Updates all children recursively. If this ChunkNode wants to split it will,
|
||||
* otherwise check if the children wants to merge. If all children wants to merge
|
||||
* and the Status of this Chunk is not Status::WANT_SPLIT it will merge.
|
||||
*
|
||||
* \returns true if the ChunkNode can merge and false if it can not merge.
|
||||
*/
|
||||
bool updateChunkTree(const RenderData& data);
|
||||
|
||||
private:
|
||||
ChunkNode* _parent;
|
||||
std::array<std::unique_ptr<ChunkNode>, 4> _children;
|
||||
|
||||
Chunk _chunk;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___CHUNKNODE___H__
|
||||
@@ -1,47 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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___CHUNKCULLER___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___CHUNKCULLER___H__
|
||||
|
||||
namespace openspace { struct RenderData; }
|
||||
|
||||
namespace openspace::globebrowsing { class Chunk; }
|
||||
|
||||
namespace openspace::globebrowsing::culling {
|
||||
|
||||
class ChunkCuller {
|
||||
public:
|
||||
virtual ~ChunkCuller() = default;
|
||||
/**
|
||||
* Determine if the Chunk is cullable. That is return true if removing the
|
||||
* Chunk 'culling it' will not have any result on the final rendering. Culling
|
||||
* it will make the rendering faster.
|
||||
*/
|
||||
virtual bool isCullable(const Chunk& chunk, const RenderData& renderData) = 0;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing::culling
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___CHUNKCULLER___H__
|
||||
@@ -1,61 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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/chunk/culling/frustumculler.h>
|
||||
|
||||
#include <modules/globebrowsing/chunk/chunk.h>
|
||||
#include <modules/globebrowsing/globes/renderableglobe.h>
|
||||
|
||||
#include <openspace/util/updatestructures.h>
|
||||
|
||||
namespace openspace::globebrowsing::culling {
|
||||
|
||||
FrustumCuller::FrustumCuller(AABB3 viewFrustum)
|
||||
: _viewFrustum(std::move(viewFrustum))
|
||||
{}
|
||||
|
||||
bool FrustumCuller::isCullable(const Chunk& chunk, const RenderData& renderData) {
|
||||
// Calculate the MVP matrix
|
||||
const glm::dmat4 modelTransform = chunk.owner().modelTransform();
|
||||
const glm::dmat4 viewTransform = glm::dmat4(renderData.camera.combinedViewMatrix());
|
||||
const glm::dmat4 modelViewProjectionTransform = glm::dmat4(
|
||||
renderData.camera.sgctInternal.projectionMatrix()
|
||||
) * viewTransform * modelTransform;
|
||||
|
||||
const std::vector<glm::dvec4>& corners = chunk.boundingPolyhedronCorners();
|
||||
|
||||
// Create a bounding box that fits the patch corners
|
||||
AABB3 bounds; // in screen space
|
||||
for (size_t i = 0; i < 8; ++i) {
|
||||
const glm::dvec4 cornerClippingSpace = modelViewProjectionTransform * corners[i];
|
||||
const glm::dvec3 ndc = glm::dvec3(
|
||||
(1.f / glm::abs(cornerClippingSpace.w)) * cornerClippingSpace
|
||||
);
|
||||
bounds.expand(ndc);
|
||||
}
|
||||
|
||||
return !(_viewFrustum.intersects(bounds));
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing::culling
|
||||
@@ -1,59 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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___FRUSTUMCULLER___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___FRUSTUMCULLER___H__
|
||||
|
||||
#include <modules/globebrowsing/chunk/culling/chunkculler.h>
|
||||
|
||||
#include <modules/globebrowsing/geometry/aabb.h>
|
||||
|
||||
namespace openspace::globebrowsing::culling {
|
||||
|
||||
/**
|
||||
* Culls all chunks that are completely outside the view frustum.
|
||||
*
|
||||
* The frustum culling uses a 2D axis aligned bounding box for the Chunk in
|
||||
* screen space. This is calculated from a bounding polyhedron bounding the
|
||||
* Chunk. Hence the culling will not be 'perfect' but fast and good enough for
|
||||
* culling chunks outside the frustum with some margin.
|
||||
*/
|
||||
class FrustumCuller : public ChunkCuller {
|
||||
public:
|
||||
virtual ~FrustumCuller() override = default;
|
||||
/**
|
||||
* \param viewFrustum is the view space in normalized device coordinates space.
|
||||
* Hence it is an axis aligned bounding box and not a real frustum.
|
||||
*/
|
||||
FrustumCuller(AABB3 viewFrustum);
|
||||
|
||||
bool isCullable(const Chunk& chunk, const RenderData& renderData) override;
|
||||
|
||||
private:
|
||||
const AABB3 _viewFrustum;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing::culling
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___FRUSTUMCULLER___H__
|
||||
@@ -1,108 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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/chunk/culling/horizonculler.h>
|
||||
|
||||
#include <modules/globebrowsing/chunk/chunk.h>
|
||||
#include <modules/globebrowsing/globes/renderableglobe.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
#include <array>
|
||||
|
||||
namespace openspace::globebrowsing::culling {
|
||||
|
||||
bool HorizonCuller::isCullable(const Chunk& chunk, const RenderData& renderData) {
|
||||
// Calculations are done in the reference frame of the globe. Hence, the camera
|
||||
// position needs to be transformed with the inverse model matrix
|
||||
const glm::dmat4 inverseModelTransform = chunk.owner().inverseModelTransform();
|
||||
|
||||
const Ellipsoid& ellipsoid = chunk.owner().ellipsoid();
|
||||
const GeodeticPatch& patch = chunk.surfacePatch();
|
||||
const float maxHeight = chunk.boundingHeights().max;
|
||||
const glm::dvec3 globePos = glm::dvec3(0,0,0); // In model space it is 0
|
||||
const double minimumGlobeRadius = ellipsoid.minimumRadius();
|
||||
|
||||
const glm::dvec3 cameraPos = glm::dvec3(
|
||||
inverseModelTransform * glm::dvec4(renderData.camera.positionVec3(), 1)
|
||||
);
|
||||
|
||||
const glm::dvec3 globeToCamera = cameraPos;
|
||||
|
||||
const Geodetic2 cameraPositionOnGlobe = ellipsoid.cartesianToGeodetic2(globeToCamera);
|
||||
const Geodetic2 closestPatchPoint = patch.closestPoint(cameraPositionOnGlobe);
|
||||
glm::dvec3 objectPos = ellipsoid.cartesianSurfacePosition(closestPatchPoint);
|
||||
|
||||
// objectPosition is closest in latlon space but not guaranteed to be closest in
|
||||
// castesian coordinates. Therefore we compare it to the corners and pick the
|
||||
// real closest point,
|
||||
std::array<glm::dvec3, 4> corners = {
|
||||
ellipsoid.cartesianSurfacePosition(chunk.surfacePatch().corner(NORTH_WEST)),
|
||||
ellipsoid.cartesianSurfacePosition(chunk.surfacePatch().corner(NORTH_EAST)),
|
||||
ellipsoid.cartesianSurfacePosition(chunk.surfacePatch().corner(SOUTH_WEST)),
|
||||
ellipsoid.cartesianSurfacePosition(chunk.surfacePatch().corner(SOUTH_EAST))
|
||||
};
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
const double distance = glm::length(cameraPos - corners[i]);
|
||||
if (distance < glm::length(cameraPos - objectPos)) {
|
||||
objectPos = corners[i];
|
||||
}
|
||||
}
|
||||
|
||||
return isCullable(cameraPos, globePos, objectPos, maxHeight, minimumGlobeRadius);
|
||||
}
|
||||
|
||||
bool HorizonCuller::isCullable(const glm::dvec3& cameraPosition,
|
||||
const glm::dvec3& globePosition,
|
||||
const glm::dvec3& objectPosition,
|
||||
double objectBoundingSphereRadius,
|
||||
double minimumGlobeRadius)
|
||||
{
|
||||
const double objectP = pow(length(objectPosition - globePosition), 2);
|
||||
const double horizonP = pow(minimumGlobeRadius - objectBoundingSphereRadius, 2);
|
||||
if (objectP < horizonP) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const double cameraP = pow(length(cameraPosition - globePosition), 2);
|
||||
const double minR = pow(minimumGlobeRadius, 2);
|
||||
if (cameraP < minR) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const double minimumAllowedDistanceToObjectFromHorizon = sqrt(objectP - horizonP);
|
||||
const double distanceToHorizon = sqrt(cameraP - minR);
|
||||
|
||||
// Minimum allowed for the object to be occluded
|
||||
const double minimumAllowedDistanceToObjectSquared =
|
||||
pow(distanceToHorizon + minimumAllowedDistanceToObjectFromHorizon, 2) +
|
||||
pow(objectBoundingSphereRadius, 2);
|
||||
|
||||
const double distanceToObjectSquared = pow(
|
||||
length(objectPosition - cameraPosition),
|
||||
2
|
||||
);
|
||||
return distanceToObjectSquared > minimumAllowedDistanceToObjectSquared;
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing::culling
|
||||
@@ -1,53 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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___HORIZONCULLER___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___HORIZONCULLER___H__
|
||||
|
||||
#include <modules/globebrowsing/chunk/culling/chunkculler.h>
|
||||
|
||||
#include <ghoul/glm.h>
|
||||
|
||||
namespace openspace::globebrowsing::culling {
|
||||
|
||||
/**
|
||||
* In this implementation of the horizon culling, the closer the ellipsoid is to a
|
||||
* sphere, the better this will make the culling. Using the minimum radius to
|
||||
* be safe. This means that if the ellipsoid has high difference between radii,
|
||||
* splitting might accur even though it may not be needed.
|
||||
*/
|
||||
class HorizonCuller : public ChunkCuller {
|
||||
public:
|
||||
virtual ~HorizonCuller() override = default;
|
||||
bool isCullable(const Chunk& chunk, const RenderData& renderData) override;
|
||||
|
||||
private:
|
||||
bool isCullable(const glm::dvec3& cameraPosition, const glm::dvec3& globePosition,
|
||||
const glm::dvec3& objectPosition, double objectBoundingSphereRadius,
|
||||
double minimumGlobeRadius);
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing::culling
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___HORIZONCULLER___H__
|
||||
@@ -1,169 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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/geometry/aabb.h>
|
||||
|
||||
#include <limits>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
AABB1::AABB1(float minValue, float maxValue)
|
||||
: min(minValue)
|
||||
, max(maxValue)
|
||||
{}
|
||||
|
||||
void AABB1::expand(float p) {
|
||||
min = glm::min(min, p);
|
||||
max = glm::max(max, p);
|
||||
}
|
||||
|
||||
float AABB1::center() const {
|
||||
return 0.5f * (min + max);
|
||||
}
|
||||
|
||||
float AABB1::size() const {
|
||||
return max - min;
|
||||
}
|
||||
|
||||
bool AABB1::contains(float p) const {
|
||||
return (min <= p) && (p <= max);
|
||||
}
|
||||
|
||||
bool AABB1::contains(const AABB1& o) const {
|
||||
return (min <= o.min) && (o.max <= max);
|
||||
}
|
||||
|
||||
bool AABB1::intersects(const AABB1& o) const {
|
||||
return (min <= o.max) && (o.min <= max);
|
||||
}
|
||||
|
||||
AABB1::AABBSpatialRelation AABB1::relationTo(const AABB1& o) const {
|
||||
if (intersects(o)) {
|
||||
if (contains(o)) {
|
||||
return AABB1::AABBSpatialRelation::Containing;
|
||||
}
|
||||
if (o.contains(*this)) {
|
||||
return AABB1::AABBSpatialRelation::Contained;
|
||||
}
|
||||
return AABB1::AABBSpatialRelation::Intersecting;
|
||||
}
|
||||
return AABB1::AABBSpatialRelation::None;
|
||||
}
|
||||
|
||||
AABB2::AABB2(glm::vec2 minValue, glm::vec2 maxValue)
|
||||
: min(std::move(minValue))
|
||||
, max(std::move(maxValue))
|
||||
{}
|
||||
|
||||
void AABB2::expand(const glm::vec2& p) {
|
||||
min = glm::min(min, p);
|
||||
max = glm::max(max, p);
|
||||
}
|
||||
|
||||
glm::vec2 AABB2::center() const {
|
||||
return 0.5f * (min + max);
|
||||
}
|
||||
|
||||
glm::vec2 AABB2::size() const {
|
||||
return max - min;
|
||||
}
|
||||
|
||||
bool AABB2::contains(const glm::vec2& p) const {
|
||||
return (min.x <= p.x) && (p.x <= max.x)
|
||||
&& (min.y <= p.y) && (p.y <= max.y);
|
||||
}
|
||||
|
||||
bool AABB2::contains(const AABB2& o) const {
|
||||
return (min.x <= o.min.x) && (o.max.x <= max.x)
|
||||
&& (min.y <= o.min.y) && (o.max.y <= max.y);
|
||||
}
|
||||
|
||||
bool AABB2::intersects(const AABB2& o) const {
|
||||
return (min.x <= o.max.x) && (o.min.x <= max.x)
|
||||
&& (min.y <= o.max.y) && (o.min.y <= max.y);
|
||||
}
|
||||
|
||||
AABB2::AABBSpatialRelation AABB2::relationTo(const AABB2& o) const {
|
||||
if (intersects(o)) {
|
||||
if (contains(o)) {
|
||||
return AABB2::AABBSpatialRelation::Containing;
|
||||
}
|
||||
if (o.contains(*this)) {
|
||||
return AABB2::AABBSpatialRelation::Contained;
|
||||
}
|
||||
return AABB2::AABBSpatialRelation::Intersecting;
|
||||
}
|
||||
return AABB2::AABBSpatialRelation::None;
|
||||
}
|
||||
|
||||
AABB3::AABB3(glm::vec3 minValue, glm::vec3 maxValue)
|
||||
: min(std::move(minValue))
|
||||
, max(std::move(maxValue))
|
||||
{}
|
||||
|
||||
void AABB3::expand(glm::vec3 p) {
|
||||
min = glm::min(min, p);
|
||||
max = glm::max(max, p);
|
||||
}
|
||||
|
||||
glm::vec3 AABB3::center() const {
|
||||
return 0.5f * (min + max);
|
||||
}
|
||||
|
||||
glm::vec3 AABB3::size() const {
|
||||
return max - min;
|
||||
}
|
||||
|
||||
bool AABB3::contains(const glm::vec3& p) const {
|
||||
return (min.x <= p.x) && (p.x <= max.x)
|
||||
&& (min.y <= p.y) && (p.y <= max.y)
|
||||
&& (min.z <= p.z) && (p.z <= max.z);
|
||||
}
|
||||
|
||||
bool AABB3::contains(const AABB3& o) const {
|
||||
return (min.x <= o.min.x) && (o.max.x <= max.x)
|
||||
&& (min.y <= o.min.y) && (o.max.y <= max.y)
|
||||
&& (min.z <= o.min.z) && (o.max.z <= max.z);
|
||||
}
|
||||
|
||||
bool AABB3::intersects(const AABB3& o) const {
|
||||
return (min.x <= o.max.x) && (o.min.x <= max.x)
|
||||
&& (min.y <= o.max.y) && (o.min.y <= max.y)
|
||||
&& (min.z <= o.max.z) && (o.min.z <= max.z);
|
||||
}
|
||||
|
||||
AABB3::AABBSpatialRelation AABB3::relationTo(const AABB3& o) const {
|
||||
if (intersects(o)) {
|
||||
if (contains(o)) {
|
||||
return AABB3::AABBSpatialRelation::Containing;
|
||||
}
|
||||
if (o.contains(*this)) {
|
||||
return AABB3::AABBSpatialRelation::Contained;
|
||||
}
|
||||
return AABB3::AABBSpatialRelation::Intersecting;
|
||||
}
|
||||
return AABB3::AABBSpatialRelation::None;
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -1,103 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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___AABB___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___AABB___H__
|
||||
|
||||
#include <ghoul/glm.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
struct AABB1 {
|
||||
enum class AABBSpatialRelation {
|
||||
None,
|
||||
Intersecting,
|
||||
Contained,
|
||||
Containing
|
||||
};
|
||||
|
||||
AABB1(float minValue = std::numeric_limits<float>::max(),
|
||||
float maxValue = -std::numeric_limits<float>::max());
|
||||
|
||||
void expand(float p);
|
||||
float center() const;
|
||||
float size() const;
|
||||
bool contains(float p) const;
|
||||
bool contains(const AABB1& o) const;
|
||||
bool intersects(const AABB1& o) const;
|
||||
AABBSpatialRelation relationTo(const AABB1& o) const;
|
||||
|
||||
float min;
|
||||
float max;
|
||||
};
|
||||
|
||||
struct AABB2 {
|
||||
enum class AABBSpatialRelation {
|
||||
None,
|
||||
Intersecting,
|
||||
Contained,
|
||||
Containing
|
||||
};
|
||||
|
||||
AABB2(glm::vec2 minValue = glm::vec2(std::numeric_limits<float>::max()),
|
||||
glm::vec2 maxValue = glm::vec2(-std::numeric_limits<float>::max()));
|
||||
|
||||
void expand(const glm::vec2& p);
|
||||
glm::vec2 center() const;
|
||||
glm::vec2 size() const;
|
||||
bool contains(const glm::vec2& p) const;
|
||||
bool contains(const AABB2& o) const;
|
||||
bool intersects(const AABB2& o) const;
|
||||
AABBSpatialRelation relationTo(const AABB2& o) const;
|
||||
|
||||
glm::vec2 min;
|
||||
glm::vec2 max;
|
||||
};
|
||||
|
||||
struct AABB3 {
|
||||
enum class AABBSpatialRelation {
|
||||
None,
|
||||
Intersecting,
|
||||
Contained,
|
||||
Containing
|
||||
};
|
||||
|
||||
AABB3(glm::vec3 minValue = glm::vec3(std::numeric_limits<float>::max()),
|
||||
glm::vec3 maxValue = glm::vec3(-std::numeric_limits<float>::max()));
|
||||
|
||||
void expand(const glm::vec3 p);
|
||||
glm::vec3 center() const;
|
||||
glm::vec3 size() const;
|
||||
bool contains(const glm::vec3& p) const;
|
||||
bool contains(const AABB3& o) const;
|
||||
bool intersects(const AABB3& o) const;
|
||||
AABBSpatialRelation relationTo(const AABB3& o) const;
|
||||
|
||||
glm::vec3 min;
|
||||
glm::vec3 max;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___AABB___H__
|
||||
@@ -1,110 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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___ANGLE___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___ANGLE___H__
|
||||
|
||||
#include <ghoul/glm.h>
|
||||
#include <memory>
|
||||
//#include <math.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
template <typename T>
|
||||
class Angle {
|
||||
public:
|
||||
/** = 0 radians = 0 degrees = no revolution */
|
||||
static const Angle<T> ZERO;
|
||||
|
||||
/** = PI/2 radians = 90 degrees = quarter of a revolution */
|
||||
static const Angle<T> QUARTER;
|
||||
|
||||
/** = PI radians = 180 degrees = half a revolution */
|
||||
static const Angle<T> HALF;
|
||||
|
||||
/** = 2PI radians = 360 degrees = a full revolution */
|
||||
static const Angle<T> FULL;
|
||||
|
||||
static Angle<T> fromRadians(T radians);
|
||||
static Angle<T> fromDegrees(T degrees);
|
||||
|
||||
/** Copy constructor */
|
||||
Angle<T>(const Angle<T>& other);
|
||||
|
||||
public:
|
||||
inline T asRadians() const;
|
||||
inline T asDegrees() const;
|
||||
|
||||
Angle<T> operator+(const Angle<T>& rhs) const;
|
||||
Angle<T> operator-(const Angle<T>& rhs) const;
|
||||
Angle<T> operator*(T rhs) const;
|
||||
Angle<T> operator/(T rhs) const;
|
||||
|
||||
Angle<T> operator-() const;
|
||||
|
||||
void operator+=(const Angle<T>& rhs);
|
||||
void operator-=(const Angle<T>& rhs);
|
||||
void operator*=(T rhs);
|
||||
void operator/=(T rhs);
|
||||
|
||||
bool operator<(const Angle<T>& rhs) const;
|
||||
bool operator<=(const Angle<T>& rhs) const;
|
||||
bool operator>(const Angle<T>& rhs) const;
|
||||
bool operator>=(const Angle<T>& rhs) const;
|
||||
bool operator==(const Angle<T>& rhs) const;
|
||||
bool operator!=(const Angle<T>& rhs) const;
|
||||
|
||||
/**
|
||||
* Normalizes the angle to the interval [0, 2pi[
|
||||
*/
|
||||
Angle<T>& normalize();
|
||||
|
||||
/**
|
||||
* Normalizes the angle to the interval [center - pi, center + pi[
|
||||
*/
|
||||
Angle<T>& normalizeAround(const Angle<T>& center);
|
||||
|
||||
/**
|
||||
* Clamps the angle to the interval [min, max].
|
||||
* Default arguments are [0, 2pi].
|
||||
*/
|
||||
Angle<T>& clamp(const Angle<T>& min = ZERO, const Angle<T>& max = FULL);
|
||||
|
||||
Angle<T> abs() const;
|
||||
|
||||
private:
|
||||
/** Private constructor. Use factory methods to avoid unit confusion */
|
||||
Angle<T>(T rad);
|
||||
|
||||
T _radians;
|
||||
};
|
||||
|
||||
using dAngle = Angle<double>;
|
||||
using fAngle = Angle<float>;
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#include "angle.inl"
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___ANGLE___H__
|
||||
@@ -1,205 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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/geometry/angle.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// STATIC CONSTANTS //
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename T>
|
||||
const Angle<T> Angle<T>::ZERO = Angle<T>(T(0));
|
||||
|
||||
template <typename T>
|
||||
const Angle<T> Angle<T>::QUARTER = Angle<T>(glm::half_pi<T>());
|
||||
|
||||
template <typename T>
|
||||
const Angle<T> Angle<T>::HALF = Angle<T>(glm::pi<T>());
|
||||
|
||||
template <typename T>
|
||||
const Angle<T> Angle<T>::FULL = Angle<T>(glm::two_pi<T>());
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructors //
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename T>
|
||||
Angle<T>::Angle(const Angle<T>& other)
|
||||
: _radians(other._radians)
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
Angle<T>::Angle(T radians)
|
||||
: _radians(radians)
|
||||
{}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Factory Methods //
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename T>
|
||||
Angle<T> Angle<T>::fromRadians(T rads) {
|
||||
return Angle<T>(rads);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Angle<T> Angle<T>::fromDegrees(T degrees) {
|
||||
return Angle<T>(glm::radians(degrees));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Conversions //
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename T>
|
||||
T Angle<T>::asRadians() const {
|
||||
return _radians;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T Angle<T>::asDegrees() const {
|
||||
return glm::degrees(_radians);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Operators //
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename T>
|
||||
Angle<T> Angle<T>::operator+(const Angle<T>& rhs) const{
|
||||
return Angle<T>(_radians + rhs._radians);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Angle<T> Angle<T>::operator-(const Angle<T>& rhs) const{
|
||||
return Angle<T>(_radians - rhs._radians);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Angle<T> Angle<T>::operator*(T multiplier) const{
|
||||
return Angle<T>(_radians * multiplier);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Angle<T> Angle<T>::operator/(T divisor) const{
|
||||
return Angle<T>(_radians / divisor);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Angle<T> Angle<T>::operator-() const {
|
||||
return Angle<T>(-_radians);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Angle<T>::operator+=(const Angle<T>& rhs){
|
||||
_radians += rhs._radians;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Angle<T>::operator-=(const Angle<T>& rhs){
|
||||
_radians -= rhs._radians;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Angle<T>::operator*=(T multiplier){
|
||||
_radians *= multiplier;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Angle<T>::operator/=(T divisor){
|
||||
_radians /= divisor;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool Angle<T>::operator<(const Angle<T>& rhs) const{
|
||||
return _radians < rhs._radians;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool Angle<T>::operator<=(const Angle<T>& rhs) const{
|
||||
return _radians <= rhs._radians;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool Angle<T>::operator>(const Angle<T>& rhs) const{
|
||||
return _radians > rhs._radians;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool Angle<T>::operator>=(const Angle<T>& rhs) const{
|
||||
return _radians >= rhs._radians;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool Angle<T>::operator==(const Angle<T>& rhs) const{
|
||||
return _radians == rhs._radians;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool Angle<T>::operator!=(const Angle<T>& rhs) const{
|
||||
return _radians != rhs._radians;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Chainable Relative Mutators //
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename T>
|
||||
Angle<T>& Angle<T>::normalize() {
|
||||
// this will cause _radians to be in value range ]-2pi, 2pi[
|
||||
_radians = fmod(_radians, glm::two_pi<T>());
|
||||
|
||||
// ensure _radians are positive, ie in value range [0, 2pi[
|
||||
if (_radians < T(0)) {
|
||||
_radians += glm::two_pi<T>();
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Angle<T>& Angle<T>::normalizeAround(const Angle<T>& center) {
|
||||
_radians -= center._radians + glm::pi<T>();
|
||||
normalize();
|
||||
_radians += center._radians - glm::pi<T>();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Angle<T>& Angle<T>::clamp(const Angle<T>& min, const Angle<T>& max) {
|
||||
const T& minRad = min._radians;
|
||||
const T& maxRad = max._radians;
|
||||
|
||||
_radians = glm::clamp(_radians, minRad, maxRad);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Angle<T> Angle<T>::abs() const {
|
||||
return Angle<T>::fromRadians(glm::abs(_radians));
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -1,55 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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___GEODETIC2___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___GEODETIC2___H__
|
||||
|
||||
#include <ghoul/glm.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
struct Geodetic2 {
|
||||
Geodetic2(double latitude = 0.0, double longitude = 0.0);
|
||||
Geodetic2(const Geodetic2& src) = default;
|
||||
|
||||
//static Geodetic2 fromCartesian(const Vec3& v);
|
||||
//Vec3 asUnitCartesian() const;
|
||||
|
||||
glm::dvec2 toLonLatVec2() const;
|
||||
|
||||
bool operator==(const Geodetic2& other) const;
|
||||
bool operator!=(const Geodetic2& other) const { return !(*this == (other)); }
|
||||
|
||||
Geodetic2 operator+(const Geodetic2& other) const;
|
||||
Geodetic2 operator-(const Geodetic2& other) const;
|
||||
Geodetic2 operator*(double scalar) const;
|
||||
Geodetic2 operator/(double scalar) const;
|
||||
|
||||
double lat;
|
||||
double lon;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___GEODETIC2___H__
|
||||
@@ -1,39 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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___GEODETIC3___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___GEODETIC3___H__
|
||||
|
||||
#include <modules/globebrowsing/geometry/geodetic2.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
struct Geodetic3 {
|
||||
Geodetic2 geodetic2;
|
||||
double height;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___GEODETIC3___H__
|
||||
@@ -24,20 +24,12 @@
|
||||
|
||||
#include <modules/globebrowsing/globebrowsingmodule.h>
|
||||
|
||||
#include <modules/globebrowsing/cache/memoryawaretilecache.h>
|
||||
#include <modules/globebrowsing/dashboard/dashboarditemglobelocation.h>
|
||||
#include <modules/globebrowsing/geometry/geodetic3.h>
|
||||
#include <modules/globebrowsing/geometry/geodeticpatch.h>
|
||||
#include <modules/globebrowsing/tile/rawtiledatareader/gdalwrapper.h>
|
||||
#include <modules/globebrowsing/tile/tileprovider/defaulttileprovider.h>
|
||||
#include <modules/globebrowsing/tile/tileprovider/singleimageprovider.h>
|
||||
#include <modules/globebrowsing/tile/tileprovider/sizereferencetileprovider.h>
|
||||
#include <modules/globebrowsing/tile/tileprovider/temporaltileprovider.h>
|
||||
#include <modules/globebrowsing/tile/tileprovider/texttileprovider.h>
|
||||
#include <modules/globebrowsing/tile/tileprovider/tileindextileprovider.h>
|
||||
#include <modules/globebrowsing/tile/tileprovider/tileprovider.h>
|
||||
#include <modules/globebrowsing/tile/tileprovider/tileproviderbylevel.h>
|
||||
#include <modules/globebrowsing/tile/tileprovider/tileproviderbyindex.h>
|
||||
#include <modules/globebrowsing/src/basictypes.h>
|
||||
#include <modules/globebrowsing/src/dashboarditemglobelocation.h>
|
||||
#include <modules/globebrowsing/src/gdalwrapper.h>
|
||||
#include <modules/globebrowsing/src/geodeticpatch.h>
|
||||
#include <modules/globebrowsing/src/memoryawaretilecache.h>
|
||||
#include <modules/globebrowsing/src/tileprovider.h>
|
||||
#include <openspace/engine/globalscallbacks.h>
|
||||
#include <openspace/scripting/lualibrary.h>
|
||||
#include <openspace/util/factorymanager.h>
|
||||
@@ -48,7 +40,6 @@
|
||||
#include <ghoul/systemcapabilities/generalcapabilitiescomponent.h>
|
||||
#include <vector>
|
||||
|
||||
#ifdef GLOBEBROWSING_USE_GDAL
|
||||
#include <gdal.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
@@ -63,14 +54,11 @@
|
||||
#pragma warning (pop)
|
||||
#endif // _MSC_VER
|
||||
|
||||
#endif // GLOBEBROWSING_USE_GDAL
|
||||
|
||||
#include "globebrowsingmodule_lua.inl"
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "GlobeBrowsingModule";
|
||||
|
||||
#ifdef GLOBEBROWSING_USE_GDAL
|
||||
openspace::GlobeBrowsingModule::Capabilities
|
||||
parseSubDatasets(char** subDatasets, int nSubdatasets)
|
||||
{
|
||||
@@ -121,9 +109,6 @@ namespace {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // GLOBEBROWSING_USE_GDAL
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
@@ -138,14 +123,18 @@ void GlobeBrowsingModule::internalInitialize(const ghoul::Dictionary&) {
|
||||
_tileCache = std::make_unique<globebrowsing::cache::MemoryAwareTileCache>();
|
||||
addPropertySubOwner(*_tileCache);
|
||||
|
||||
#ifdef GLOBEBROWSING_USE_GDAL
|
||||
tileprovider::initializeDefaultTile();
|
||||
|
||||
// Convert from MB to Bytes
|
||||
GdalWrapper::create(
|
||||
16ULL * 1024ULL * 1024ULL, // 16 MB
|
||||
static_cast<size_t>(CpuCap.installedMainMemory() * 0.25 * 1024 * 1024)
|
||||
);
|
||||
addPropertySubOwner(GdalWrapper::ref());
|
||||
#endif // GLOBEBROWSING_USE_GDAL
|
||||
});
|
||||
|
||||
global::callback::deinitializeGL.push_back([]() {
|
||||
tileprovider::deinitializeDefaultTile();
|
||||
});
|
||||
|
||||
|
||||
@@ -153,9 +142,7 @@ void GlobeBrowsingModule::internalInitialize(const ghoul::Dictionary&) {
|
||||
global::callback::render.push_back([&]() { _tileCache->update(); });
|
||||
|
||||
// Deinitialize
|
||||
#ifdef GLOBEBROWSING_USE_GDAL
|
||||
global::callback::deinitialize.push_back([&]() { GdalWrapper::ref().destroy(); });
|
||||
#endif // GLOBEBROWSING_USE_GDAL
|
||||
|
||||
// Get factories
|
||||
auto fRenderable = FactoryManager::ref().factory<Renderable>();
|
||||
@@ -177,12 +164,10 @@ void GlobeBrowsingModule::internalInitialize(const ghoul::Dictionary&) {
|
||||
layergroupid::LAYER_TYPE_NAMES[static_cast<int>(
|
||||
layergroupid::TypeID::SingleImageTileLayer
|
||||
)]);
|
||||
#ifdef GLOBEBROWSING_USE_GDAL
|
||||
fTileProvider->registerClass<tileprovider::TemporalTileProvider>(
|
||||
layergroupid::LAYER_TYPE_NAMES[static_cast<int>(
|
||||
layergroupid::TypeID::TemporalTileLayer
|
||||
)]);
|
||||
#endif // GLOBEBROWSING_USE_GDAL
|
||||
fTileProvider->registerClass<tileprovider::TileIndexTileProvider>(
|
||||
layergroupid::LAYER_TYPE_NAMES[static_cast<int>(
|
||||
layergroupid::TypeID::TileIndexTileLayer
|
||||
@@ -273,7 +258,6 @@ scripting::LuaLibrary GlobeBrowsingModule::luaLibrary() const {
|
||||
"Get geographic coordinates of the camera poosition in latitude, "
|
||||
"longitude, and altitude"
|
||||
},
|
||||
#ifdef GLOBEBROWSING_USE_GDAL
|
||||
{
|
||||
"loadWMSCapabilities",
|
||||
&globebrowsing::luascriptfunctions::loadWMSCapabilities,
|
||||
@@ -304,7 +288,6 @@ scripting::LuaLibrary GlobeBrowsingModule::luaLibrary() const {
|
||||
"component of the returned table can be used in the 'FilePath' argument "
|
||||
"for a call to the 'addLayer' function to add the value to a globe."
|
||||
}
|
||||
#endif // GLOBEBROWSING_USE_GDAL
|
||||
};
|
||||
res.scripts = {
|
||||
absPath("${MODULE_GLOBEBROWSING}/scripts/layer_support.lua")
|
||||
@@ -321,9 +304,11 @@ void GlobeBrowsingModule::goToChunk(int x, int y, int level) {
|
||||
void GlobeBrowsingModule::goToGeo(double latitude, double longitude) {
|
||||
using namespace globebrowsing;
|
||||
Camera* cam = global::navigationHandler.camera();
|
||||
goToGeodetic2(*cam, Geodetic2(
|
||||
Angle<double>::fromDegrees(latitude).asRadians(),
|
||||
Angle<double>::fromDegrees(longitude).asRadians()), true);
|
||||
goToGeodetic2(
|
||||
*cam,
|
||||
Geodetic2{ glm::radians(latitude), glm::radians(longitude) },
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
void GlobeBrowsingModule::goToGeo(double latitude, double longitude,
|
||||
@@ -335,9 +320,7 @@ void GlobeBrowsingModule::goToGeo(double latitude, double longitude,
|
||||
goToGeodetic3(
|
||||
*cam,
|
||||
{
|
||||
Geodetic2(
|
||||
Angle<double>::fromDegrees(latitude).asRadians(),
|
||||
Angle<double>::fromDegrees(longitude).asRadians()),
|
||||
Geodetic2{ glm::radians(latitude), glm::radians(longitude) },
|
||||
altitude
|
||||
},
|
||||
true
|
||||
@@ -351,10 +334,7 @@ glm::vec3 GlobeBrowsingModule::cartesianCoordinatesFromGeo(
|
||||
using namespace globebrowsing;
|
||||
|
||||
const Geodetic3 pos = {
|
||||
{
|
||||
Angle<double>::fromDegrees(latitude).asRadians(),
|
||||
Angle<double>::fromDegrees(longitude).asRadians()
|
||||
},
|
||||
{ glm::radians(latitude), glm::radians(longitude) },
|
||||
altitude
|
||||
};
|
||||
|
||||
@@ -379,7 +359,7 @@ void GlobeBrowsingModule::goToChunk(Camera& camera, const globebrowsing::TileInd
|
||||
|
||||
// Camera position in model space
|
||||
const glm::dvec3 camPos = camera.positionVec3();
|
||||
const glm::dmat4 inverseModelTransform = globe->inverseModelTransform();
|
||||
const glm::dmat4 inverseModelTransform = glm::inverse(globe->modelTransform());
|
||||
const glm::dvec3 cameraPositionModelSpace = glm::dvec3(
|
||||
inverseModelTransform * glm::dvec4(camPos, 1)
|
||||
);
|
||||
@@ -389,7 +369,10 @@ void GlobeBrowsingModule::goToChunk(Camera& camera, const globebrowsing::TileInd
|
||||
Geodetic2 positionOnPatch = patch.size();
|
||||
positionOnPatch.lat *= uv.y;
|
||||
positionOnPatch.lon *= uv.x;
|
||||
const Geodetic2 pointPosition = corner + positionOnPatch;
|
||||
const Geodetic2 pointPosition = {
|
||||
corner.lat + positionOnPatch.lat,
|
||||
corner.lon + positionOnPatch.lon
|
||||
};
|
||||
|
||||
const glm::dvec3 positionOnEllipsoid = globe->ellipsoid().geodeticSurfaceProjection(
|
||||
cameraPositionModelSpace
|
||||
@@ -467,7 +450,7 @@ void GlobeBrowsingModule::resetCameraDirection(Camera& camera,
|
||||
geo2
|
||||
);
|
||||
const glm::dvec3 slightlyNorth = globe->ellipsoid().cartesianSurfacePosition(
|
||||
Geodetic2(geo2.lat + 0.001, geo2.lon)
|
||||
Geodetic2{ geo2.lat + 0.001, geo2.lon }
|
||||
);
|
||||
const glm::dvec3 lookUpModelSpace = glm::normalize(
|
||||
slightlyNorth - positionModelSpace
|
||||
@@ -534,8 +517,6 @@ std::string GlobeBrowsingModule::layerTypeNamesList() {
|
||||
return listLayerTypes;
|
||||
}
|
||||
|
||||
#ifdef GLOBEBROWSING_USE_GDAL
|
||||
|
||||
void GlobeBrowsingModule::loadWMSCapabilities(std::string name, std::string globe,
|
||||
std::string url)
|
||||
{
|
||||
@@ -624,6 +605,4 @@ bool GlobeBrowsingModule::hasUrlInfo(const std::string& globe) const {
|
||||
return _urlList.find(globe) != _urlList.end();
|
||||
}
|
||||
|
||||
#endif // GLOBEBROWSING_USE_GDAL
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -61,7 +61,6 @@ public:
|
||||
scripting::LuaLibrary luaLibrary() const override;
|
||||
const globebrowsing::RenderableGlobe* castFocusNodeRenderableToGlobe();
|
||||
|
||||
#ifdef GLOBEBROWSING_USE_GDAL
|
||||
struct Layer {
|
||||
std::string name;
|
||||
std::string url;
|
||||
@@ -82,7 +81,6 @@ public:
|
||||
bool hasUrlInfo(const std::string& globe) const;
|
||||
|
||||
void removeWMSServer(const std::string& name);
|
||||
#endif // GLOBEBROWSING_USE_GDAL
|
||||
|
||||
protected:
|
||||
void internalInitialize(const ghoul::Dictionary&) override;
|
||||
@@ -108,14 +106,12 @@ private:
|
||||
|
||||
std::unique_ptr<globebrowsing::cache::MemoryAwareTileCache> _tileCache;
|
||||
|
||||
#ifdef GLOBEBROWSING_USE_GDAL
|
||||
// name -> capabilities
|
||||
std::map<std::string, std::future<Capabilities>> _inFlightCapabilitiesMap;
|
||||
// name -> capabilities
|
||||
std::map<std::string, Capabilities> _capabilitiesMap;
|
||||
|
||||
std::multimap<std::string, UrlInfo> _urlList;
|
||||
#endif // GLOBEBROWSING_USE_GDAL
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -22,17 +22,15 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/globebrowsing/globes/renderableglobe.h>
|
||||
#include <modules/globebrowsing/src/renderableglobe.h>
|
||||
|
||||
#include <modules/globebrowsing/geometry/angle.h>
|
||||
#include <modules/globebrowsing/rendering/layer/layermanager.h>
|
||||
#include <modules/globebrowsing/rendering/layer/layer.h>
|
||||
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <modules/globebrowsing/src/layer.h>
|
||||
#include <modules/globebrowsing/src/layermanager.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/rendering/renderable.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/query/query.h>
|
||||
@@ -58,13 +56,15 @@ int addLayer(lua_State* L) {
|
||||
}
|
||||
|
||||
// Get the renderable globe
|
||||
const RenderableGlobe* globe = dynamic_cast<const RenderableGlobe*>(n->renderable());
|
||||
RenderableGlobe* globe = dynamic_cast<RenderableGlobe*>(n->renderable());
|
||||
if (!globe) {
|
||||
return ghoul::lua::luaError(L, "Renderable is not a globe: " + globeName);
|
||||
}
|
||||
|
||||
// Get the layer group
|
||||
layergroupid::GroupID groupID = layergroupid::getGroupIDFromName(layerGroupName);
|
||||
layergroupid::GroupID groupID = ghoul::from_string<layergroupid::GroupID>(
|
||||
layerGroupName
|
||||
);
|
||||
if (groupID == layergroupid::GroupID::Unknown) {
|
||||
return ghoul::lua::luaError(L, "Unknown layer group: " + layerGroupName);
|
||||
}
|
||||
@@ -81,7 +81,7 @@ int addLayer(lua_State* L) {
|
||||
}
|
||||
lua_settop(L, 0);
|
||||
|
||||
std::shared_ptr<Layer> layer = globe->layerManager()->addLayer(groupID, d);
|
||||
Layer* layer = globe->layerManager().addLayer(groupID, d);
|
||||
if (layer) {
|
||||
layer->initialize();
|
||||
}
|
||||
@@ -108,18 +108,20 @@ int deleteLayer(lua_State* L) {
|
||||
}
|
||||
|
||||
// Get the renderable globe
|
||||
const RenderableGlobe* globe = dynamic_cast<const RenderableGlobe*>(n->renderable());
|
||||
RenderableGlobe* globe = dynamic_cast<RenderableGlobe*>(n->renderable());
|
||||
if (!globe) {
|
||||
return ghoul::lua::luaError(L, "Renderable is not a globe: " + globeName);
|
||||
}
|
||||
|
||||
// Get the layer group
|
||||
layergroupid::GroupID groupID = layergroupid::getGroupIDFromName(layerGroupName);
|
||||
layergroupid::GroupID groupID = ghoul::from_string<layergroupid::GroupID>(
|
||||
layerGroupName
|
||||
);
|
||||
if (groupID == layergroupid::GroupID::Unknown) {
|
||||
return ghoul::lua::luaError(L, "Unknown layer group: " + layerGroupName);
|
||||
}
|
||||
|
||||
globe->layerManager()->deleteLayer(groupID, layerName);
|
||||
globe->layerManager().deleteLayer(groupID, layerName);
|
||||
|
||||
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
|
||||
return 0;
|
||||
@@ -219,18 +221,12 @@ int getGeoPositionForCamera(lua_State* L) {
|
||||
const double altitude = glm::length(cameraPositionModelSpace -
|
||||
posHandle.centerToReferenceSurface);
|
||||
|
||||
ghoul::lua::push(
|
||||
L,
|
||||
Angle<double>::fromRadians(geo2.lat).asDegrees(),
|
||||
Angle<double>::fromRadians(geo2.lon).asDegrees(),
|
||||
altitude
|
||||
);
|
||||
ghoul::lua::push(L, glm::degrees(geo2.lat), glm::degrees(geo2.lon), altitude);
|
||||
|
||||
ghoul_assert(lua_gettop(L) == 3, "Incorrect number of items left on stack");
|
||||
return 3;
|
||||
}
|
||||
|
||||
#ifdef GLOBEBROWSING_USE_GDAL
|
||||
int loadWMSCapabilities(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 3, "lua::loadWMSCapabilities");
|
||||
|
||||
@@ -294,6 +290,5 @@ int capabilities(lua_State* L) {
|
||||
ghoul_assert(lua_gettop(L) == 1, "Incorrect number of items left on stack");
|
||||
return 1;
|
||||
}
|
||||
#endif // GLOBEBROWSING_USE_GDAL
|
||||
|
||||
} // namespace openspace::globebrowsing::luascriptfunctions
|
||||
|
||||
@@ -1,397 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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/globes/chunkedlodglobe.h>
|
||||
|
||||
#include <modules/globebrowsing/chunk/chunk.h>
|
||||
#include <modules/globebrowsing/chunk/chunklevelevaluator/chunklevelevaluator.h>
|
||||
#include <modules/globebrowsing/chunk/chunklevelevaluator/availabletiledataevaluator.h>
|
||||
#include <modules/globebrowsing/chunk/chunklevelevaluator/distanceevaluator.h>
|
||||
#include <modules/globebrowsing/chunk/chunklevelevaluator/projectedareaevaluator.h>
|
||||
#include <modules/globebrowsing/chunk/chunknode.h>
|
||||
#include <modules/globebrowsing/chunk/culling/chunkculler.h>
|
||||
#include <modules/globebrowsing/chunk/culling/frustumculler.h>
|
||||
#include <modules/globebrowsing/chunk/culling/horizonculler.h>
|
||||
#include <modules/globebrowsing/globes/renderableglobe.h>
|
||||
#include <modules/globebrowsing/meshes/skirtedgrid.h>
|
||||
#include <modules/globebrowsing/tile/tileindex.h>
|
||||
#include <modules/globebrowsing/tile/tileprovider/tileprovider.h>
|
||||
#include <modules/globebrowsing/rendering/chunkrenderer.h>
|
||||
#include <modules/globebrowsing/rendering/layer/layer.h>
|
||||
#include <modules/globebrowsing/rendering/layer/layergroup.h>
|
||||
#include <modules/globebrowsing/rendering/layer/layermanager.h>
|
||||
#include <modules/debugging/rendering/debugrenderer.h>
|
||||
#include <openspace/util/time.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/opengl/texture.h>
|
||||
//#include <math.h>
|
||||
|
||||
namespace {
|
||||
const openspace::globebrowsing::GeodeticPatch Coverage =
|
||||
openspace::globebrowsing::GeodeticPatch(0, 0, 90, 180);
|
||||
|
||||
const openspace::globebrowsing::TileIndex LeftHemisphereIndex =
|
||||
openspace::globebrowsing::TileIndex(0, 0, 1);
|
||||
|
||||
const openspace::globebrowsing::TileIndex RightHemisphereIndex =
|
||||
openspace::globebrowsing::TileIndex(1, 0, 1);
|
||||
} // namespace
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
ChunkedLodGlobe::ChunkedLodGlobe(const RenderableGlobe& owner, size_t segmentsPerPatch,
|
||||
std::shared_ptr<LayerManager> layerManager,
|
||||
Ellipsoid& ellipsoid)
|
||||
: Renderable({ { "Identifier", owner.identifier() }, { "Name", owner.guiName() } })
|
||||
#ifdef DEBUG_GLOBEBROWSING_STATSRECORD
|
||||
, stats(StatsCollector(absPath("test_stats"), 1, StatsCollector::Enabled::No))
|
||||
#endif // DEBUG_GLOBEBROWSING_STATSRECORD
|
||||
, _owner(owner)
|
||||
, _leftRoot(std::make_unique<ChunkNode>(Chunk(owner, LeftHemisphereIndex)))
|
||||
, _rightRoot(std::make_unique<ChunkNode>(Chunk(owner, RightHemisphereIndex)))
|
||||
, _layerManager(layerManager)
|
||||
{
|
||||
std::shared_ptr<SkirtedGrid> geometry = std::make_shared<SkirtedGrid>(
|
||||
static_cast<unsigned int>(segmentsPerPatch),
|
||||
static_cast<unsigned int>(segmentsPerPatch),
|
||||
TriangleSoup::Positions::No,
|
||||
TriangleSoup::TextureCoordinates::Yes,
|
||||
TriangleSoup::Normals::No
|
||||
);
|
||||
|
||||
_chunkCullers.push_back(std::make_unique<culling::HorizonCuller>());
|
||||
_chunkCullers.push_back(std::make_unique<culling::FrustumCuller>(
|
||||
AABB3(
|
||||
glm::vec3(-1, -1, 0),
|
||||
glm::vec3(1, 1, 1e35)
|
||||
)
|
||||
));
|
||||
|
||||
_chunkEvaluatorByAvailableTiles =
|
||||
std::make_unique<chunklevelevaluator::AvailableTileData>();
|
||||
_chunkEvaluatorByProjectedArea =
|
||||
std::make_unique<chunklevelevaluator::ProjectedArea>();
|
||||
_chunkEvaluatorByDistance = std::make_unique<chunklevelevaluator::Distance>();
|
||||
|
||||
_renderer = std::make_unique<ChunkRenderer>(geometry, layerManager, ellipsoid);
|
||||
}
|
||||
|
||||
ChunkedLodGlobe::~ChunkedLodGlobe() {} // NOLINT
|
||||
|
||||
bool ChunkedLodGlobe::isReady() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::shared_ptr<LayerManager> ChunkedLodGlobe::layerManager() const {
|
||||
return _layerManager;
|
||||
}
|
||||
|
||||
bool ChunkedLodGlobe::testIfCullable(const Chunk& chunk,
|
||||
const RenderData& renderData) const
|
||||
{
|
||||
if (_owner.debugProperties().performHorizonCulling &&
|
||||
_chunkCullers[0]->isCullable(chunk, renderData)) {
|
||||
return true;
|
||||
}
|
||||
if (_owner.debugProperties().performFrustumCulling &&
|
||||
_chunkCullers[1]->isCullable(chunk, renderData)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const ChunkNode& ChunkedLodGlobe::findChunkNode(const Geodetic2& location) const {
|
||||
ghoul_assert(
|
||||
Coverage.contains(location),
|
||||
"Point must be in lat [-90, 90] and lon [-180, 180]"
|
||||
);
|
||||
|
||||
return location.lon < Coverage.center().lon ?
|
||||
_leftRoot->find(location) :
|
||||
_rightRoot->find(location);
|
||||
}
|
||||
|
||||
int ChunkedLodGlobe::desiredLevel(const Chunk& chunk,
|
||||
const RenderData& renderData) const
|
||||
{
|
||||
int desiredLevel = 0;
|
||||
if (_owner.debugProperties().levelByProjectedAreaElseDistance) {
|
||||
desiredLevel = _chunkEvaluatorByProjectedArea->desiredLevel(chunk, renderData);
|
||||
}
|
||||
else {
|
||||
desiredLevel = _chunkEvaluatorByDistance->desiredLevel(chunk, renderData);
|
||||
}
|
||||
|
||||
int levelByAvailableData = _chunkEvaluatorByAvailableTiles->desiredLevel(
|
||||
chunk,
|
||||
renderData
|
||||
);
|
||||
if (levelByAvailableData != chunklevelevaluator::Evaluator::UnknownDesiredLevel &&
|
||||
_owner.debugProperties().limitLevelByAvailableData)
|
||||
{
|
||||
desiredLevel = glm::min(desiredLevel, levelByAvailableData);
|
||||
}
|
||||
|
||||
desiredLevel = glm::clamp(desiredLevel, MinSplitDepth, MaxSplitDepth);
|
||||
return desiredLevel;
|
||||
}
|
||||
|
||||
float ChunkedLodGlobe::getHeight(const glm::dvec3& position) const {
|
||||
float height = 0;
|
||||
|
||||
// Get the uv coordinates to sample from
|
||||
const Geodetic2 geodeticPosition = _owner.ellipsoid().cartesianToGeodetic2(position);
|
||||
const int chunkLevel = findChunkNode(geodeticPosition).chunk().tileIndex().level;
|
||||
|
||||
const TileIndex tileIndex = TileIndex(geodeticPosition, chunkLevel);
|
||||
const GeodeticPatch patch = GeodeticPatch(tileIndex);
|
||||
|
||||
const Geodetic2 geoDiffPatch = patch.corner(Quad::NORTH_EAST) -
|
||||
patch.corner(Quad::SOUTH_WEST);
|
||||
|
||||
const Geodetic2 geoDiffPoint = geodeticPosition - patch.corner(Quad::SOUTH_WEST);
|
||||
const glm::vec2 patchUV = glm::vec2(
|
||||
geoDiffPoint.lon / geoDiffPatch.lon,
|
||||
geoDiffPoint.lat / geoDiffPatch.lat
|
||||
);
|
||||
|
||||
// Get the tile providers for the height maps
|
||||
const std::vector<std::shared_ptr<Layer>>& heightMapLayers =
|
||||
_layerManager->layerGroup(layergroupid::GroupID::HeightLayers).activeLayers();
|
||||
|
||||
for (const std::shared_ptr<Layer>& layer : heightMapLayers) {
|
||||
tileprovider::TileProvider* tileProvider = layer->tileProvider();
|
||||
if (!tileProvider) {
|
||||
continue;
|
||||
}
|
||||
// Transform the uv coordinates to the current tile texture
|
||||
const ChunkTile chunkTile = tileProvider->chunkTile(tileIndex);
|
||||
const Tile& tile = chunkTile.tile;
|
||||
const TileUvTransform& uvTransform = chunkTile.uvTransform;
|
||||
const TileDepthTransform& depthTransform = tileProvider->depthTransform();
|
||||
if (tile.status() != Tile::Status::OK) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ghoul::opengl::Texture* tileTexture = tile.texture();
|
||||
if (!tileTexture) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
glm::vec2 transformedUv = layer->TileUvToTextureSamplePosition(
|
||||
uvTransform,
|
||||
patchUV,
|
||||
glm::uvec2(tileTexture->dimensions())
|
||||
);
|
||||
|
||||
// Sample and do linear interpolation
|
||||
// (could possibly be moved as a function in ghoul texture)
|
||||
// Suggestion: a function in ghoul::opengl::Texture that takes uv coordinates
|
||||
// in range [0,1] and uses the set interpolation method and clamping.
|
||||
|
||||
const glm::uvec3 dimensions = tileTexture->dimensions();
|
||||
|
||||
const glm::vec2 samplePos = transformedUv * glm::vec2(dimensions);
|
||||
glm::uvec2 samplePos00 = samplePos;
|
||||
samplePos00 = glm::clamp(
|
||||
samplePos00,
|
||||
glm::uvec2(0, 0),
|
||||
glm::uvec2(dimensions) - glm::uvec2(1)
|
||||
);
|
||||
const glm::vec2 samplePosFract = samplePos - glm::vec2(samplePos00);
|
||||
|
||||
const glm::uvec2 samplePos10 = glm::min(
|
||||
samplePos00 + glm::uvec2(1, 0),
|
||||
glm::uvec2(dimensions) - glm::uvec2(1)
|
||||
);
|
||||
const glm::uvec2 samplePos01 = glm::min(
|
||||
samplePos00 + glm::uvec2(0, 1),
|
||||
glm::uvec2(dimensions) - glm::uvec2(1)
|
||||
);
|
||||
const glm::uvec2 samplePos11 = glm::min(
|
||||
samplePos00 + glm::uvec2(1, 1),
|
||||
glm::uvec2(dimensions) - glm::uvec2(1)
|
||||
);
|
||||
|
||||
const float sample00 = tileTexture->texelAsFloat(samplePos00).x;
|
||||
const float sample10 = tileTexture->texelAsFloat(samplePos10).x;
|
||||
const float sample01 = tileTexture->texelAsFloat(samplePos01).x;
|
||||
const float sample11 = tileTexture->texelAsFloat(samplePos11).x;
|
||||
|
||||
// In case the texture has NaN or no data values don't use this height map.
|
||||
const bool anySampleIsNaN =
|
||||
std::isnan(sample00) ||
|
||||
std::isnan(sample01) ||
|
||||
std::isnan(sample10) ||
|
||||
std::isnan(sample11);
|
||||
|
||||
const bool anySampleIsNoData =
|
||||
sample00 == tileProvider->noDataValueAsFloat() ||
|
||||
sample01 == tileProvider->noDataValueAsFloat() ||
|
||||
sample10 == tileProvider->noDataValueAsFloat() ||
|
||||
sample11 == tileProvider->noDataValueAsFloat();
|
||||
|
||||
if (anySampleIsNaN || anySampleIsNoData) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const float sample0 = sample00 * (1.f - samplePosFract.x) +
|
||||
sample10 * samplePosFract.x;
|
||||
const float sample1 = sample01 * (1.f - samplePosFract.x) +
|
||||
sample11 * samplePosFract.x;
|
||||
|
||||
const float sample = sample0 * (1.f - samplePosFract.y) +
|
||||
sample1 * samplePosFract.y;
|
||||
|
||||
// Same as is used in the shader. This is not a perfect solution but
|
||||
// if the sample is actually a no-data-value (min_float) the interpolated
|
||||
// value might not be. Therefore we have a cut-off. Assuming no data value
|
||||
// is smaller than -100000
|
||||
if (sample > -100000) {
|
||||
// Perform depth transform to get the value in meters
|
||||
height = depthTransform.depthOffset + depthTransform.depthScale * sample;
|
||||
// Make sure that the height value follows the layer settings.
|
||||
// For example if the multiplier is set to a value bigger than one,
|
||||
// the sampled height should be modified as well.
|
||||
height = layer->renderSettings().performLayerSettings(height);
|
||||
}
|
||||
}
|
||||
// Return the result
|
||||
return height;
|
||||
}
|
||||
|
||||
void ChunkedLodGlobe::notifyShaderRecompilation() {
|
||||
_shadersNeedRecompilation = true;
|
||||
}
|
||||
|
||||
void ChunkedLodGlobe::recompileShaders() {
|
||||
_renderer->recompileShaders(_owner);
|
||||
_shadersNeedRecompilation = false;
|
||||
}
|
||||
|
||||
void ChunkedLodGlobe::render(const RenderData& data, RendererTasks&) {
|
||||
#ifdef DEBUG_GLOBEBROWSING_STATSRECORD
|
||||
stats.startNewRecord();
|
||||
#endif // DEBUG_GLOBEBROWSING_STATSRECORD
|
||||
if (_shadersNeedRecompilation) {
|
||||
_renderer->recompileShaders(_owner);
|
||||
_shadersNeedRecompilation = false;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_GLOBEBROWSING_STATSRECORD
|
||||
auto duration = std::chrono::system_clock::now().time_since_epoch();
|
||||
auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
|
||||
stats.i["time"] = millis;
|
||||
#endif // DEBUG_GLOBEBROWSING_STATSRECORD
|
||||
|
||||
_leftRoot->updateChunkTree(data);
|
||||
_rightRoot->updateChunkTree(data);
|
||||
|
||||
// Calculate the MVP matrix
|
||||
const glm::dmat4 viewTransform = glm::dmat4(data.camera.combinedViewMatrix());
|
||||
const glm::dmat4 vp = glm::dmat4(data.camera.sgctInternal.projectionMatrix()) *
|
||||
viewTransform;
|
||||
const glm::dmat4 mvp = vp * _owner.modelTransform();
|
||||
|
||||
// Render function
|
||||
auto renderJob = [this, &data, &mvp](const ChunkNode& chunkNode) {
|
||||
#ifdef DEBUG_GLOBEBROWSING_STATSRECORD
|
||||
stats.i["chunks nodes"]++;
|
||||
#endif // DEBUG_GLOBEBROWSING_STATSRECORD
|
||||
const Chunk& chunk = chunkNode.chunk();
|
||||
if (chunkNode.isLeaf()) {
|
||||
#ifdef DEBUG_GLOBEBROWSING_STATSRECORD
|
||||
stats.i["leafs chunk nodes"]++;
|
||||
#endif // DEBUG_GLOBEBROWSING_STATSRECORD
|
||||
|
||||
if (chunk.isVisible()) {
|
||||
#ifdef DEBUG_GLOBEBROWSING_STATSRECORD
|
||||
stats.i["rendered chunks"]++;
|
||||
#endif // DEBUG_GLOBEBROWSING_STATSRECORD
|
||||
_renderer->renderChunk(chunkNode.chunk(), data);
|
||||
debugRenderChunk(chunk, mvp);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
_leftRoot->breadthFirst(renderJob);
|
||||
_rightRoot->breadthFirst(renderJob);
|
||||
|
||||
//_leftRoot->reverseBreadthFirst(renderJob);
|
||||
//_rightRoot->reverseBreadthFirst(renderJob);
|
||||
|
||||
#ifdef DEBUG_GLOBEBROWSING_STATSRECORD
|
||||
auto duration2 = std::chrono::system_clock::now().time_since_epoch();
|
||||
auto ms2 = std::chrono::duration_cast<std::chrono::milliseconds>(duration2).count();
|
||||
stats.i["chunk globe render time"] = ms2 - millis;
|
||||
#endif // DEBUG_GLOBEBROWSING_STATSRECORD
|
||||
}
|
||||
|
||||
void ChunkedLodGlobe::debugRenderChunk(const Chunk& chunk, const glm::dmat4& mvp) const {
|
||||
if (_owner.debugProperties().showChunkBounds ||
|
||||
_owner.debugProperties().showChunkAABB)
|
||||
{
|
||||
const std::vector<glm::dvec4>& modelSpaceCorners =
|
||||
chunk.boundingPolyhedronCorners();
|
||||
|
||||
std::vector<glm::vec4> clippingSpaceCorners(8);
|
||||
AABB3 screenSpaceBounds;
|
||||
|
||||
for (size_t i = 0; i < 8; ++i) {
|
||||
const glm::vec4& clippingSpaceCorner = mvp * modelSpaceCorners[i];
|
||||
clippingSpaceCorners[i] = clippingSpaceCorner;
|
||||
|
||||
glm::vec3 screenSpaceCorner =
|
||||
glm::vec3((1.f / clippingSpaceCorner.w) * clippingSpaceCorner);
|
||||
screenSpaceBounds.expand(std::move(screenSpaceCorner));
|
||||
}
|
||||
|
||||
const unsigned int colorBits = 1 + chunk.tileIndex().level % 6;
|
||||
const glm::vec4 color = glm::vec4(
|
||||
colorBits & 1,
|
||||
colorBits & 2,
|
||||
colorBits & 4,
|
||||
0.3f
|
||||
);
|
||||
|
||||
if (_owner.debugProperties().showChunkBounds) {
|
||||
DebugRenderer::ref().renderNiceBox(clippingSpaceCorners, color);
|
||||
}
|
||||
|
||||
if (_owner.debugProperties().showChunkAABB) {
|
||||
const std::vector<glm::vec4>& screenSpacePoints =
|
||||
DebugRenderer::ref().verticesFor(screenSpaceBounds);
|
||||
DebugRenderer::ref().renderNiceBox(screenSpacePoints, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ChunkedLodGlobe::update(const UpdateData& data) {
|
||||
setBoundingSphere(static_cast<float>(
|
||||
_owner.ellipsoid().maximumRadius() * data.modelTransform.scale
|
||||
));
|
||||
_renderer->update();
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -1,154 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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___CHUNKED_LOD_GLOBE___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___CHUNKED_LOD_GLOBE___H__
|
||||
|
||||
#include <openspace/rendering/renderable.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
//#define DEBUG_GLOBEBROWSING_STATSRECORD
|
||||
|
||||
#ifdef DEBUG_GLOBEBROWSING_STATSRECORD
|
||||
#include <modules/globebrowsing/other/statscollector.h>
|
||||
#endif // DEBUG_GLOBEBROWSING_STATSRECORD
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
namespace chunklevelevaluator { class Evaluator; }
|
||||
|
||||
namespace culling { class ChunkCuller; }
|
||||
|
||||
class Chunk;
|
||||
class ChunkNode;
|
||||
class ChunkRenderer;
|
||||
class Ellipsoid;
|
||||
struct Geodetic2;
|
||||
class LayerManager;
|
||||
class RenderableGlobe;
|
||||
|
||||
class ChunkedLodGlobe : public Renderable {
|
||||
public:
|
||||
ChunkedLodGlobe(const RenderableGlobe& owner, size_t segmentsPerPatch,
|
||||
std::shared_ptr<LayerManager> layerManager, Ellipsoid& ellipsoid);
|
||||
~ChunkedLodGlobe();
|
||||
|
||||
bool isReady() const override;
|
||||
|
||||
void render(const RenderData& data, RendererTasks& rendererTask) override;
|
||||
void update(const UpdateData& data) override;
|
||||
|
||||
/**
|
||||
* Traverse the chunk tree and find the highest level chunk node.
|
||||
*
|
||||
* \param location is given in geodetic coordinates and must be in the range
|
||||
* latitude [-90, 90] and longitude [-180, 180]. In other words, it must be a
|
||||
* position defined on the globe in georeferenced coordinates.
|
||||
*/
|
||||
const ChunkNode& findChunkNode(const Geodetic2& location) const;
|
||||
|
||||
/**
|
||||
* Test if a specific chunk can saf;ely be culled without affecting the rendered
|
||||
* image.
|
||||
*
|
||||
* Goes through all available <code>ChunkCuller</code>s and check if any of them
|
||||
* allows culling of the <code>Chunk</code>s in question.
|
||||
*/
|
||||
bool testIfCullable(const Chunk& chunk, const RenderData& renderData) const;
|
||||
|
||||
/**
|
||||
* Gets the desired level which can be used to determine if a chunk should split
|
||||
* or merge.
|
||||
*
|
||||
* Using <code>ChunkLevelEvaluator</code>s, the desired level can be higher or
|
||||
* lower than the current level of the <code>Chunks</code>s
|
||||
* <code>TileIndex</code>. If the desired level is higher than that of the
|
||||
* <code>Chunk</code>, it wants to split. If it is lower, it wants to merge with
|
||||
* its siblings.
|
||||
*/
|
||||
int desiredLevel(const Chunk& chunk, const RenderData& renderData) const;
|
||||
|
||||
/**
|
||||
* Calculates the height from the surface of the reference ellipsoid to the
|
||||
* heigh mapped surface.
|
||||
*
|
||||
* The height can be negative if the height map contains negative values.
|
||||
*
|
||||
* \param <code>position</code> is the position of a point that gets geodetically
|
||||
* projected on the reference ellipsoid. <code>position</code> must be in
|
||||
* cartesian model space.
|
||||
* \returns the height from the reference ellipsoid to the globe surface.
|
||||
*/
|
||||
float getHeight(const glm::dvec3& position) const;
|
||||
|
||||
/**
|
||||
* Notifies the renderer to recompile its shaders the next time the render function is
|
||||
* called. The actual shader recompilation takes place in the render function because
|
||||
* properties that the shader depends on need to be properly synced.
|
||||
*/
|
||||
void notifyShaderRecompilation();
|
||||
|
||||
/**
|
||||
* Directly recompile the shaders of the renderer.
|
||||
*/
|
||||
void recompileShaders();
|
||||
|
||||
constexpr static const int MinSplitDepth = 2;
|
||||
constexpr static const int MaxSplitDepth = 22;
|
||||
|
||||
std::shared_ptr<LayerManager> layerManager() const;
|
||||
|
||||
#ifdef DEBUG_GLOBEBROWSING_STATSRECORD
|
||||
StatsCollector stats;
|
||||
#endif // DEBUG_GLOBEBROWSING_STATSRECORD
|
||||
|
||||
private:
|
||||
void debugRenderChunk(const Chunk& chunk, const glm::dmat4& mvp) const;
|
||||
|
||||
const RenderableGlobe& _owner;
|
||||
|
||||
// Covers all negative longitudes
|
||||
std::unique_ptr<ChunkNode> _leftRoot;
|
||||
|
||||
// Covers all positive longitudes
|
||||
std::unique_ptr<ChunkNode> _rightRoot;
|
||||
|
||||
// the patch used for actual rendering
|
||||
std::unique_ptr<ChunkRenderer> _renderer;
|
||||
|
||||
std::vector<std::unique_ptr<culling::ChunkCuller>> _chunkCullers;
|
||||
|
||||
std::unique_ptr<chunklevelevaluator::Evaluator> _chunkEvaluatorByAvailableTiles;
|
||||
std::unique_ptr<chunklevelevaluator::Evaluator> _chunkEvaluatorByProjectedArea;
|
||||
std::unique_ptr<chunklevelevaluator::Evaluator> _chunkEvaluatorByDistance;
|
||||
|
||||
std::shared_ptr<LayerManager> _layerManager;
|
||||
|
||||
bool _shadersNeedRecompilation = true;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___CHUNKED_LOD_GLOBE___H__
|
||||
@@ -1,187 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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/globes/pointglobe.h>
|
||||
|
||||
#include <modules/globebrowsing/globes/renderableglobe.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
|
||||
namespace {
|
||||
constexpr const std::array<const char*, 3> UniformNames = {
|
||||
"lightIntensityClamped", "modelViewTransform", "projectionTransform"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo IntensityClampInfo = {
|
||||
"IntensityClamp",
|
||||
"Intensity clamp",
|
||||
""
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo LightIntensityInfo = {
|
||||
"LightIntensity",
|
||||
"Light intensity",
|
||||
"" // @TODO Missing documentation
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
PointGlobe::PointGlobe(const RenderableGlobe& owner)
|
||||
: Renderable({ { "Identifier", owner.identifier() }, { "Name", owner.guiName() } })
|
||||
, _owner(owner)
|
||||
, _intensityClamp(IntensityClampInfo, 1.f, 0.f, 1.f)
|
||||
, _lightIntensity(LightIntensityInfo, 1.f, 0.f, 50.f)
|
||||
{
|
||||
addProperty(_intensityClamp);
|
||||
addProperty(_lightIntensity);
|
||||
}
|
||||
|
||||
PointGlobe::~PointGlobe() {
|
||||
glDeleteBuffers(1, &_vertexBufferID);
|
||||
glDeleteVertexArrays(1, &_vaoID);
|
||||
}
|
||||
|
||||
void PointGlobe::initialize() {
|
||||
_programObject = global::renderEngine.buildRenderProgram(
|
||||
"PointGlobe",
|
||||
absPath("${MODULE_GLOBEBROWSING}/shaders/pointglobe_vs.glsl"),
|
||||
absPath("${MODULE_GLOBEBROWSING}/shaders/pointglobe_fs.glsl")
|
||||
);
|
||||
|
||||
ghoul::opengl::updateUniformLocations(*_programObject, _uniformCache, UniformNames);
|
||||
|
||||
glGenVertexArrays(1, &_vaoID);
|
||||
glGenBuffers(1, &_vertexBufferID);
|
||||
|
||||
glBindVertexArray(_vaoID);
|
||||
|
||||
std::array<float, 2 * 6> quadVertexData = {
|
||||
-1.f, -1.f,
|
||||
1.f, -1.f,
|
||||
-1.f, 1.f,
|
||||
-1.f, 1.f,
|
||||
1.f, -1.f,
|
||||
1.f, 1.f
|
||||
};
|
||||
|
||||
// Vertex buffer
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferID);
|
||||
glBufferData(
|
||||
GL_ARRAY_BUFFER,
|
||||
sizeof(float) * quadVertexData.size(),
|
||||
quadVertexData.data(),
|
||||
GL_STATIC_DRAW
|
||||
);
|
||||
|
||||
// Position at location 0
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), nullptr);
|
||||
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
void PointGlobe::deinitialize() {
|
||||
glDeleteVertexArrays(1, &_vaoID);
|
||||
glDeleteBuffers(1, &_vertexBufferID);
|
||||
}
|
||||
|
||||
bool PointGlobe::isReady() const {
|
||||
return (_vaoID != 0) && (_vertexBufferID != 0);
|
||||
}
|
||||
|
||||
void PointGlobe::render(const RenderData& data, RendererTasks&) {
|
||||
_programObject->activate();
|
||||
|
||||
// Calculate variables to be used as uniform variables in shader
|
||||
const glm::dvec3 bodyPosition = data.modelTransform.translation;
|
||||
|
||||
const glm::dmat4 rotationTransform = glm::lookAt(
|
||||
glm::dvec3(0.0f),
|
||||
data.camera.positionVec3() - bodyPosition,
|
||||
glm::normalize(glm::dvec3(1000000.0f) - bodyPosition)
|
||||
);
|
||||
|
||||
const glm::dvec3 camToBody = bodyPosition - data.camera.positionVec3();
|
||||
const float distanceToBody = static_cast<float>(glm::length(camToBody));
|
||||
|
||||
const float avgRadius = static_cast<float>(_owner.ellipsoid().averageRadius());
|
||||
const float lightIntensity = static_cast<float>(
|
||||
_lightIntensity.value() * data.modelTransform.scale * avgRadius / distanceToBody
|
||||
);
|
||||
const float lightIntensityClamped = glm::min(lightIntensity, _intensityClamp.value());
|
||||
//float lightOverflow = glm::max(lightIntensity - lightIntensityClamped, 0.0f);
|
||||
|
||||
const float billboardRadius = lightIntensityClamped * distanceToBody;
|
||||
const glm::dmat4 scaleTransform = glm::scale(
|
||||
glm::dmat4(1.0), glm::dvec3(billboardRadius)
|
||||
);
|
||||
|
||||
setBoundingSphere(billboardRadius);
|
||||
|
||||
// Model transform and view transform needs to be in double precision
|
||||
const glm::dmat4 modelTransform = glm::translate(glm::dmat4(1.0), bodyPosition) *
|
||||
glm::inverse(rotationTransform) *
|
||||
scaleTransform; // Scale
|
||||
const glm::dmat4 modelViewTransform = data.camera.combinedViewMatrix() *
|
||||
modelTransform;
|
||||
|
||||
|
||||
_programObject->setUniform(
|
||||
_uniformCache.lightIntensityClamped,
|
||||
lightIntensityClamped
|
||||
);
|
||||
//_program->setUniform("lightOverflow", lightOverflow);
|
||||
//_program->setUniform("directionToSunViewSpace", directionToSunViewSpace);
|
||||
_programObject->setUniform(
|
||||
_uniformCache.modelView,
|
||||
glm::mat4(modelViewTransform)
|
||||
);
|
||||
_programObject->setUniform(
|
||||
_uniformCache.projection,
|
||||
data.camera.sgctInternal.projectionMatrix()
|
||||
);
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
glBindVertexArray(_vaoID);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vertexBufferID);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
glBindVertexArray(0);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_CULL_FACE);
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
_programObject->deactivate();
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -1,65 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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___POINTGLOBE___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___POINTGLOBE___H__
|
||||
|
||||
#include <openspace/rendering/renderable.h>
|
||||
|
||||
#include <openspace/properties/scalar/floatproperty.h>
|
||||
#include <ghoul/opengl/ghoul_gl.h>
|
||||
#include <ghoul/opengl/uniformcache.h>
|
||||
|
||||
namespace ghoul::opengl { class ProgramObject; }
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
class RenderableGlobe;
|
||||
|
||||
class PointGlobe : public Renderable {
|
||||
public:
|
||||
PointGlobe(const RenderableGlobe& owner);
|
||||
virtual ~PointGlobe();
|
||||
|
||||
void initialize() override;
|
||||
void deinitialize() override;
|
||||
bool isReady() const override;
|
||||
|
||||
void render(const RenderData& data, RendererTasks& rendererTask) override;
|
||||
|
||||
private:
|
||||
const RenderableGlobe& _owner;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _programObject;
|
||||
UniformCache(lightIntensityClamped, modelView, projection) _uniformCache;
|
||||
|
||||
GLuint _vertexBufferID = 0;
|
||||
GLuint _vaoID = 0;
|
||||
|
||||
properties::FloatProperty _intensityClamp;
|
||||
properties::FloatProperty _lightIntensity;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___POINTGLOBE___H__
|
||||
@@ -1,534 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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/globes/renderableglobe.h>
|
||||
|
||||
#include <modules/debugging/rendering/debugrenderer.h>
|
||||
#include <modules/globebrowsing/globes/chunkedlodglobe.h>
|
||||
#include <modules/globebrowsing/globes/pointglobe.h>
|
||||
#include <modules/globebrowsing/rendering/layer/layermanager.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* keyFrame = "Frame";
|
||||
constexpr const char* keyRadii = "Radii";
|
||||
constexpr const char* keySegmentsPerPatch = "SegmentsPerPatch";
|
||||
constexpr const char* keyLayers = "Layers";
|
||||
constexpr const char* keyShadowGroup = "ShadowGroup";
|
||||
constexpr const char* keyShadowSource = "Source";
|
||||
constexpr const char* keyShadowCaster = "Caster";
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo SaveOrThrowInfo = {
|
||||
"SaveOrThrowCamera",
|
||||
"Save or throw camera",
|
||||
"" // @TODO Missing documentation
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo ShowChunkEdgeInfo = {
|
||||
"ShowChunkEdges",
|
||||
"Show chunk edges",
|
||||
"" // @TODO Missing documentation
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo ShowChunkBoundsInfo = {
|
||||
"ShowChunkBounds",
|
||||
"Show chunk bounds",
|
||||
"" // @TODO Missing documentation
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo ShowChunkAABBInfo = {
|
||||
"ShowChunkAABB",
|
||||
"Show chunk AABB",
|
||||
"" // @TODO Missing documentation
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo HeightResolutionInfo = {
|
||||
"ShowHeightResolution",
|
||||
"Show height resolution",
|
||||
"" // @TODO Missing documentation
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo HeightIntensityInfo = {
|
||||
"ShowHeightIntensities",
|
||||
"Show height intensities",
|
||||
"" // @TODO Missing documentation
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo FrustumCullingInfo = {
|
||||
"PerformFrustumCulling",
|
||||
"Perform frustum culling",
|
||||
"" // @TODO Missing documentation
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo HorizonCullingInfo = {
|
||||
"PerformHorizonCulling",
|
||||
"Perform horizon culling",
|
||||
"" // @TODO Missing documentation
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo LevelProjectedAreaInfo = {
|
||||
"LevelByProjectedAreaElseDistance",
|
||||
"Level by projected area (else distance)",
|
||||
"" // @TODO Missing documentation
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo ResetTileProviderInfo = {
|
||||
"ResetTileProviders",
|
||||
"Reset tile providers",
|
||||
"" // @TODO Missing documentation
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo CollectStatsInfo = {
|
||||
"CollectStats",
|
||||
"Collect stats",
|
||||
"" // @TODO Missing documentation
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo LimitLevelInfo = {
|
||||
"LimitLevelByAvailableData",
|
||||
"Limit level by available data",
|
||||
"" // @TODO Missing documentation
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo ModelSpaceRenderingInfo = {
|
||||
"ModelSpaceRenderingCutoffLevel",
|
||||
"Model Space Rendering Cutoff Level",
|
||||
"" // @TODO Missing documentation
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo PerformShadingInfo = {
|
||||
"PerformShading",
|
||||
"Perform shading",
|
||||
"" // @TODO Missing documentation
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo AtmosphereInfo = {
|
||||
"Atmosphere",
|
||||
"Atmosphere",
|
||||
"" // @TODO Missing documentation
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo AccurateNormalsInfo = {
|
||||
"UseAccurateNormals",
|
||||
"Use Accurate Normals",
|
||||
"" // @TODO Missing documentation
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo EclipseInfo = {
|
||||
"Eclipse",
|
||||
"Eclipse",
|
||||
"Enables/Disable Eclipse shadows"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo EclipseHardShadowsInfo = {
|
||||
"EclipseHardShadows",
|
||||
"Eclipse Hard Shadows",
|
||||
"Enables the rendering of eclipse shadows using hard shadows"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo LodScaleFactorInfo = {
|
||||
"LodScaleFactor",
|
||||
"Level of Detail Scale Factor",
|
||||
"" // @TODO Missing documentation
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo CameraMinHeightInfo = {
|
||||
"CameraMinHeight",
|
||||
"Camera Minimum Height",
|
||||
"" // @TODO Missing documentation
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo OrenNayarRoughnessInfo = {
|
||||
"OrenNayarRoughness",
|
||||
"orenNayarRoughness",
|
||||
"" // @TODO Missing documentation
|
||||
};
|
||||
} // namespace
|
||||
|
||||
using namespace openspace::properties;
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
|
||||
: Renderable(dictionary)
|
||||
, _debugProperties({
|
||||
BoolProperty(SaveOrThrowInfo, false),
|
||||
BoolProperty(ShowChunkEdgeInfo, false),
|
||||
BoolProperty(ShowChunkBoundsInfo, false),
|
||||
BoolProperty(ShowChunkAABBInfo, false),
|
||||
BoolProperty(HeightResolutionInfo, false),
|
||||
BoolProperty(HeightIntensityInfo, false),
|
||||
BoolProperty(FrustumCullingInfo, true),
|
||||
BoolProperty(HorizonCullingInfo, true),
|
||||
BoolProperty(LevelProjectedAreaInfo, false),
|
||||
BoolProperty(ResetTileProviderInfo, false),
|
||||
BoolProperty(CollectStatsInfo, false),
|
||||
BoolProperty(LimitLevelInfo, true),
|
||||
IntProperty(ModelSpaceRenderingInfo, 10, 1, 22)
|
||||
})
|
||||
, _generalProperties({
|
||||
BoolProperty(PerformShadingInfo, true),
|
||||
BoolProperty(AtmosphereInfo, false),
|
||||
BoolProperty(AccurateNormalsInfo, false),
|
||||
BoolProperty(EclipseInfo, false),
|
||||
BoolProperty(EclipseHardShadowsInfo, false),
|
||||
FloatProperty(LodScaleFactorInfo, 10.f, 1.f, 50.f),
|
||||
FloatProperty(CameraMinHeightInfo, 100.f, 0.f, 1000.f),
|
||||
FloatProperty(OrenNayarRoughnessInfo, 0.f, 0.f, 1.f)
|
||||
})
|
||||
, _debugPropertyOwner({ "Debug" })
|
||||
{
|
||||
setIdentifier("RenderableGlobe");
|
||||
|
||||
dictionary.getValue(keyFrame, _frame);
|
||||
|
||||
// Read the radii in to its own dictionary
|
||||
if (dictionary.hasKeyAndValue<glm::dvec3>(keyRadii)) {
|
||||
const glm::dvec3 radii = dictionary.value<glm::vec3>(keyRadii);
|
||||
_ellipsoid = Ellipsoid(radii);
|
||||
setBoundingSphere(static_cast<float>(_ellipsoid.maximumRadius()));
|
||||
}
|
||||
else if (dictionary.hasKeyAndValue<double>(keyRadii)) {
|
||||
const double radius = dictionary.value<double>(keyRadii);
|
||||
_ellipsoid = Ellipsoid({ radius, radius, radius });
|
||||
setBoundingSphere(static_cast<float>(_ellipsoid.maximumRadius()));
|
||||
}
|
||||
|
||||
// Ghoul can't read ints from lua dictionaries...
|
||||
double patchSegmentsd;
|
||||
dictionary.getValue(keySegmentsPerPatch, patchSegmentsd);
|
||||
int patchSegments = static_cast<int>(patchSegmentsd);
|
||||
|
||||
if (dictionary.hasValue<bool>("PerformShading")) {
|
||||
_generalProperties.performShading = dictionary.value<bool>("PerformShading");
|
||||
}
|
||||
|
||||
// Init layer manager
|
||||
ghoul::Dictionary layersDictionary;
|
||||
if (!dictionary.getValue(keyLayers, layersDictionary)) {
|
||||
throw ghoul::RuntimeError(std::string(keyLayers) + " must be specified");
|
||||
}
|
||||
|
||||
_layerManager = std::make_shared<LayerManager>(layersDictionary);
|
||||
|
||||
_chunkedLodGlobe = std::make_unique<ChunkedLodGlobe>(
|
||||
*this,
|
||||
patchSegments,
|
||||
_layerManager,
|
||||
_ellipsoid
|
||||
);
|
||||
//_pointGlobe = std::make_shared<PointGlobe>(*this);
|
||||
|
||||
//_distanceSwitch.addSwitchValue(_chunkedLodGlobe);
|
||||
//_distanceSwitch.addSwitchValue(_pointGlobe);
|
||||
|
||||
addProperty(_generalProperties.atmosphereEnabled);
|
||||
addProperty(_generalProperties.performShading);
|
||||
addProperty(_generalProperties.useAccurateNormals);
|
||||
addProperty(_generalProperties.eclipseShadowsEnabled);
|
||||
addProperty(_generalProperties.eclipseHardShadows);
|
||||
addProperty(_generalProperties.lodScaleFactor);
|
||||
addProperty(_generalProperties.cameraMinHeight);
|
||||
addProperty(_generalProperties.orenNayarRoughness);
|
||||
|
||||
_debugPropertyOwner.addProperty(_debugProperties.saveOrThrowCamera);
|
||||
_debugPropertyOwner.addProperty(_debugProperties.showChunkEdges);
|
||||
_debugPropertyOwner.addProperty(_debugProperties.showChunkBounds);
|
||||
_debugPropertyOwner.addProperty(_debugProperties.showChunkAABB);
|
||||
_debugPropertyOwner.addProperty(_debugProperties.showHeightResolution);
|
||||
_debugPropertyOwner.addProperty(_debugProperties.showHeightIntensities);
|
||||
_debugPropertyOwner.addProperty(_debugProperties.performFrustumCulling);
|
||||
_debugPropertyOwner.addProperty(_debugProperties.performHorizonCulling);
|
||||
_debugPropertyOwner.addProperty(
|
||||
_debugProperties.levelByProjectedAreaElseDistance
|
||||
);
|
||||
_debugPropertyOwner.addProperty(_debugProperties.resetTileProviders);
|
||||
_debugPropertyOwner.addProperty(_debugProperties.collectStats);
|
||||
_debugPropertyOwner.addProperty(_debugProperties.limitLevelByAvailableData);
|
||||
_debugPropertyOwner.addProperty(_debugProperties.modelSpaceRenderingCutoffLevel);
|
||||
|
||||
auto notifyShaderRecompilation = [&](){
|
||||
_chunkedLodGlobe->notifyShaderRecompilation();
|
||||
};
|
||||
_generalProperties.atmosphereEnabled.onChange(notifyShaderRecompilation);
|
||||
_generalProperties.useAccurateNormals.onChange(notifyShaderRecompilation);
|
||||
_generalProperties.eclipseShadowsEnabled.onChange(notifyShaderRecompilation);
|
||||
_generalProperties.eclipseHardShadows.onChange(notifyShaderRecompilation);
|
||||
_generalProperties.performShading.onChange(notifyShaderRecompilation);
|
||||
_debugProperties.showChunkEdges.onChange(notifyShaderRecompilation);
|
||||
_debugProperties.showHeightResolution.onChange(notifyShaderRecompilation);
|
||||
_debugProperties.showHeightIntensities.onChange(notifyShaderRecompilation);
|
||||
|
||||
_layerManager->onChange(notifyShaderRecompilation);
|
||||
|
||||
addPropertySubOwner(_debugPropertyOwner);
|
||||
addPropertySubOwner(_layerManager.get());
|
||||
//addPropertySubOwner(_pointGlobe.get());
|
||||
|
||||
//================================================================
|
||||
//======== Reads Shadow (Eclipses) Entries in mod file ===========
|
||||
//================================================================
|
||||
ghoul::Dictionary shadowDictionary;
|
||||
bool success = dictionary.getValue(keyShadowGroup, shadowDictionary);
|
||||
bool disableShadows = false;
|
||||
if (success) {
|
||||
std::vector<std::pair<std::string, double>> sourceArray;
|
||||
unsigned int sourceCounter = 1;
|
||||
while (success) {
|
||||
std::string sourceName;
|
||||
success = shadowDictionary.getValue(keyShadowSource +
|
||||
std::to_string(sourceCounter) + ".Name", sourceName);
|
||||
if (success) {
|
||||
double sourceRadius;
|
||||
success = shadowDictionary.getValue(keyShadowSource +
|
||||
std::to_string(sourceCounter) + ".Radius", sourceRadius);
|
||||
if (success) {
|
||||
sourceArray.emplace_back(sourceName, sourceRadius);
|
||||
}
|
||||
else {
|
||||
//LWARNING("No Radius value expecified for Shadow Source Name "
|
||||
// << sourceName << " from " << name
|
||||
// << " planet.\nDisabling shadows for this planet.");
|
||||
disableShadows = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
sourceCounter++;
|
||||
}
|
||||
|
||||
if (!disableShadows && !sourceArray.empty()) {
|
||||
success = true;
|
||||
std::vector<std::pair<std::string, double>> casterArray;
|
||||
unsigned int casterCounter = 1;
|
||||
while (success) {
|
||||
std::string casterName;
|
||||
success = shadowDictionary.getValue(keyShadowCaster +
|
||||
std::to_string(casterCounter) + ".Name", casterName);
|
||||
if (success) {
|
||||
double casterRadius;
|
||||
success = shadowDictionary.getValue(keyShadowCaster +
|
||||
std::to_string(casterCounter) + ".Radius", casterRadius);
|
||||
if (success) {
|
||||
casterArray.emplace_back(casterName, casterRadius);
|
||||
}
|
||||
else {
|
||||
//LWARNING("No Radius value expecified for Shadow Caster Name "
|
||||
// << casterName << " from " << name
|
||||
// << " planet.\nDisabling shadows for this planet.");
|
||||
disableShadows = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
casterCounter++;
|
||||
}
|
||||
|
||||
std::vector<Ellipsoid::ShadowConfiguration> shadowConfArray;
|
||||
if (!disableShadows && (!sourceArray.empty() && !casterArray.empty())) {
|
||||
for (const auto & source : sourceArray) {
|
||||
for (const auto & caster : casterArray) {
|
||||
Ellipsoid::ShadowConfiguration sc;
|
||||
sc.source = source;
|
||||
sc.caster = caster;
|
||||
shadowConfArray.push_back(sc);
|
||||
}
|
||||
}
|
||||
_ellipsoid.setShadowConfigurationArray(shadowConfArray);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderableGlobe::initializeGL() {
|
||||
_layerManager->initialize();
|
||||
|
||||
_layerManager->update();
|
||||
|
||||
_chunkedLodGlobe->initializeGL();
|
||||
|
||||
// Recompile the shaders directly so that it is not done the first time the render
|
||||
// function is called.
|
||||
_chunkedLodGlobe->recompileShaders();
|
||||
}
|
||||
|
||||
void RenderableGlobe::deinitializeGL() {
|
||||
_chunkedLodGlobe->deinitializeGL();
|
||||
|
||||
_layerManager->deinitialize();
|
||||
}
|
||||
|
||||
bool RenderableGlobe::isReady() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderableGlobe::render(const RenderData& data, RendererTasks& rendererTask) {
|
||||
bool statsEnabled = _debugProperties.collectStats;
|
||||
#ifdef DEBUG_GLOBEBROWSING_STATSRECORD
|
||||
_chunkedLodGlobe->stats.setEnabled(statsEnabled);
|
||||
#else // DEBUG_GLOBEBROWSING_STATSRECORD
|
||||
if (statsEnabled) {
|
||||
LWARNINGC(
|
||||
"RenderableGlobe",
|
||||
"Stats collection was enabled, but ChunkedLodGlobe compiled without support"
|
||||
);
|
||||
_debugProperties.collectStats = false;
|
||||
}
|
||||
#endif // DEBUG_GLOBEBROWSING_STATSRECORD
|
||||
|
||||
if (_enabled) {
|
||||
if (_debugProperties.saveOrThrowCamera.value()) {
|
||||
_debugProperties.saveOrThrowCamera.setValue(false);
|
||||
|
||||
if (savedCamera() == nullptr) { // save camera
|
||||
setSaveCamera(std::make_shared<Camera>(data.camera));
|
||||
}
|
||||
else { // throw camera
|
||||
setSaveCamera(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
const double distanceToCamera = distance(
|
||||
data.camera.positionVec3(),
|
||||
data.modelTransform.translation
|
||||
);
|
||||
|
||||
// This distance will be enough to render the globe as one pixel if the field of
|
||||
// view is 'fov' radians and the screen resolution is 'res' pixels.
|
||||
const double fov = 2 * glm::pi<double>() / 6; // 60 degrees
|
||||
const int res = 2880;
|
||||
|
||||
const double distance = res * _chunkedLodGlobe->boundingSphere() / tan(fov / 2);
|
||||
|
||||
if (distanceToCamera < distance) {
|
||||
_chunkedLodGlobe->render(data, rendererTask);
|
||||
}
|
||||
}
|
||||
if (_savedCamera != nullptr) {
|
||||
DebugRenderer::ref().renderCameraFrustum(data, *_savedCamera);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderableGlobe::update(const UpdateData& data) {
|
||||
_time = data.time.j2000Seconds();
|
||||
_chunkedLodGlobe->update(data);
|
||||
|
||||
glm::dmat4 translation =
|
||||
glm::translate(glm::dmat4(1.0), data.modelTransform.translation);
|
||||
glm::dmat4 rotation = glm::dmat4(data.modelTransform.rotation);
|
||||
glm::dmat4 scaling =
|
||||
glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale,
|
||||
data.modelTransform.scale, data.modelTransform.scale));
|
||||
|
||||
_cachedModelTransform = translation * rotation * scaling;
|
||||
_cachedInverseModelTransform = glm::inverse(_cachedModelTransform);
|
||||
|
||||
if (_debugProperties.resetTileProviders) {
|
||||
_layerManager->reset();
|
||||
_debugProperties.resetTileProviders = false;
|
||||
}
|
||||
_layerManager->update();
|
||||
_chunkedLodGlobe->update(data);
|
||||
}
|
||||
|
||||
glm::dvec3 RenderableGlobe::projectOnEllipsoid(glm::dvec3 position) {
|
||||
return _ellipsoid.geodeticSurfaceProjection(position);
|
||||
}
|
||||
|
||||
float RenderableGlobe::getHeight(glm::dvec3 position) const {
|
||||
if (_chunkedLodGlobe) {
|
||||
return _chunkedLodGlobe->getHeight(position);
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ChunkedLodGlobe* RenderableGlobe::chunkedLodGlobe() const{
|
||||
return _chunkedLodGlobe.get();
|
||||
}
|
||||
|
||||
LayerManager* RenderableGlobe::layerManager() const {
|
||||
return _layerManager.get();
|
||||
}
|
||||
|
||||
const Ellipsoid& RenderableGlobe::ellipsoid() const{
|
||||
return _ellipsoid;
|
||||
}
|
||||
|
||||
const glm::dmat4& RenderableGlobe::modelTransform() const{
|
||||
return _cachedModelTransform;
|
||||
}
|
||||
|
||||
const glm::dmat4& RenderableGlobe::inverseModelTransform() const{
|
||||
return _cachedInverseModelTransform;
|
||||
}
|
||||
|
||||
const RenderableGlobe::DebugProperties&
|
||||
RenderableGlobe::debugProperties() const{
|
||||
return _debugProperties;
|
||||
}
|
||||
|
||||
const RenderableGlobe::GeneralProperties&
|
||||
RenderableGlobe::generalProperties() const{
|
||||
return _generalProperties;
|
||||
}
|
||||
|
||||
const std::shared_ptr<const Camera> RenderableGlobe::savedCamera() const {
|
||||
return _savedCamera;
|
||||
}
|
||||
|
||||
SurfacePositionHandle RenderableGlobe::calculateSurfacePositionHandle(
|
||||
const glm::dvec3& targetModelSpace) const
|
||||
{
|
||||
glm::dvec3 centerToEllipsoidSurface =
|
||||
_ellipsoid.geodeticSurfaceProjection(targetModelSpace);
|
||||
glm::dvec3 ellipsoidSurfaceToTarget = targetModelSpace - centerToEllipsoidSurface;
|
||||
// ellipsoidSurfaceOutDirection will point towards the target, we want the outward
|
||||
// direction. Therefore it must be flipped in case the target is under the reference
|
||||
// ellipsoid so that it always points outwards
|
||||
glm::dvec3 ellipsoidSurfaceOutDirection = glm::normalize(ellipsoidSurfaceToTarget);
|
||||
if (glm::dot(ellipsoidSurfaceOutDirection, centerToEllipsoidSurface) < 0) {
|
||||
ellipsoidSurfaceOutDirection *= -1.0;
|
||||
}
|
||||
|
||||
double heightToSurface = getHeight(targetModelSpace);
|
||||
heightToSurface = glm::isnan(heightToSurface) ? 0.0 : heightToSurface;
|
||||
centerToEllipsoidSurface = glm::isnan(glm::length(centerToEllipsoidSurface)) ?
|
||||
(glm::dvec3(0.0, 1.0, 0.0) * static_cast<double>(boundingSphere())) :
|
||||
centerToEllipsoidSurface;
|
||||
ellipsoidSurfaceOutDirection = glm::isnan(glm::length(ellipsoidSurfaceOutDirection)) ?
|
||||
glm::dvec3(0.0, 1.0, 0.0) : ellipsoidSurfaceOutDirection;
|
||||
|
||||
return {
|
||||
centerToEllipsoidSurface,
|
||||
ellipsoidSurfaceOutDirection,
|
||||
heightToSurface
|
||||
};
|
||||
}
|
||||
|
||||
void RenderableGlobe::setSaveCamera(std::shared_ptr<Camera> camera) {
|
||||
_savedCamera = std::move(camera);
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -1,149 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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___RENDERABLEGLOBE___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___RENDERABLEGLOBE___H__
|
||||
|
||||
#include <openspace/rendering/renderable.h>
|
||||
|
||||
#include <modules/globebrowsing/geometry/ellipsoid.h>
|
||||
//#include <modules/globebrowsing/other/distanceswitch.h>
|
||||
|
||||
#include <openspace/properties/scalar/floatproperty.h>
|
||||
#include <openspace/properties/scalar/intproperty.h>
|
||||
#include <openspace/properties/scalar/boolproperty.h>
|
||||
|
||||
#ifdef OPENSPACE_MODULE_ATMOSPHERE_ENABLED
|
||||
namespace openspace {
|
||||
class AtmosphereDeferredcaster;
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
class ChunkedLodGlobe;
|
||||
class PointGlobe;
|
||||
class LayerManager;
|
||||
|
||||
/**
|
||||
* A RenderableGlobe is a globe modeled as an ellipsoid using a chunked LOD algorithm for
|
||||
* rendering.
|
||||
*/
|
||||
class RenderableGlobe : public Renderable {
|
||||
public:
|
||||
/**
|
||||
* These properties are specific for <code>ChunkedLodGlobe</code> and separated from
|
||||
* the general properties of <code>RenderableGlobe</code>.
|
||||
*/
|
||||
struct DebugProperties {
|
||||
properties::BoolProperty saveOrThrowCamera;
|
||||
properties::BoolProperty showChunkEdges;
|
||||
properties::BoolProperty showChunkBounds;
|
||||
properties::BoolProperty showChunkAABB;
|
||||
properties::BoolProperty showHeightResolution;
|
||||
properties::BoolProperty showHeightIntensities;
|
||||
properties::BoolProperty performFrustumCulling;
|
||||
properties::BoolProperty performHorizonCulling;
|
||||
properties::BoolProperty levelByProjectedAreaElseDistance;
|
||||
properties::BoolProperty resetTileProviders;
|
||||
properties::BoolProperty collectStats;
|
||||
properties::BoolProperty limitLevelByAvailableData;
|
||||
properties::IntProperty modelSpaceRenderingCutoffLevel;
|
||||
};
|
||||
|
||||
struct GeneralProperties {
|
||||
properties::BoolProperty performShading;
|
||||
properties::BoolProperty atmosphereEnabled;
|
||||
properties::BoolProperty useAccurateNormals;
|
||||
properties::BoolProperty eclipseShadowsEnabled;
|
||||
properties::BoolProperty eclipseHardShadows;
|
||||
properties::FloatProperty lodScaleFactor;
|
||||
properties::FloatProperty cameraMinHeight;
|
||||
properties::FloatProperty orenNayarRoughness;
|
||||
};
|
||||
|
||||
// Shadow structure
|
||||
struct ShadowRenderingStruct {
|
||||
double xu;
|
||||
double xp;
|
||||
double rs;
|
||||
double rc;
|
||||
glm::dvec3 sourceCasterVec;
|
||||
glm::dvec3 casterPositionVec;
|
||||
bool isShadowing;
|
||||
};
|
||||
|
||||
RenderableGlobe(const ghoul::Dictionary& dictionary);
|
||||
~RenderableGlobe() = default;
|
||||
|
||||
void initializeGL() override;
|
||||
void deinitializeGL() override;
|
||||
bool isReady() const override;
|
||||
|
||||
void render(const RenderData& data, RendererTasks& rendererTask) override;
|
||||
void update(const UpdateData& data) override;
|
||||
|
||||
// Getters that perform calculations
|
||||
glm::dvec3 projectOnEllipsoid(glm::dvec3 position);
|
||||
float getHeight(glm::dvec3 position) const;
|
||||
|
||||
// Getters
|
||||
ChunkedLodGlobe* chunkedLodGlobe() const;
|
||||
LayerManager* layerManager() const;
|
||||
const Ellipsoid& ellipsoid() const;
|
||||
const glm::dmat4& modelTransform() const;
|
||||
const glm::dmat4& inverseModelTransform() const;
|
||||
const DebugProperties& debugProperties() const;
|
||||
const GeneralProperties& generalProperties() const;
|
||||
const std::shared_ptr<const Camera> savedCamera() const;
|
||||
double interactionDepthBelowEllipsoid();
|
||||
|
||||
// Setters
|
||||
void setSaveCamera(std::shared_ptr<Camera> camera);
|
||||
|
||||
virtual SurfacePositionHandle calculateSurfacePositionHandle(
|
||||
const glm::dvec3& targetModelSpace) const override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<ChunkedLodGlobe> _chunkedLodGlobe;
|
||||
|
||||
Ellipsoid _ellipsoid;
|
||||
std::shared_ptr<LayerManager> _layerManager;
|
||||
std::shared_ptr<Camera> _savedCamera;
|
||||
|
||||
std::string _frame;
|
||||
double _time = 0.0;
|
||||
|
||||
glm::dmat4 _cachedModelTransform;
|
||||
glm::dmat4 _cachedInverseModelTransform;
|
||||
|
||||
// Properties
|
||||
DebugProperties _debugProperties;
|
||||
GeneralProperties _generalProperties;
|
||||
properties::PropertyOwner _debugPropertyOwner;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___RENDERABLEGLOBE___H__
|
||||
@@ -1,171 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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/meshes/basicgrid.h>
|
||||
|
||||
#include <ghoul/glm.h>
|
||||
#include <ghoul/misc/assert.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
BasicGrid::BasicGrid(unsigned int xSegments, unsigned int ySegments,
|
||||
TriangleSoup::Positions usePositions,
|
||||
TriangleSoup::TextureCoordinates useTextureCoordinates,
|
||||
TriangleSoup::Normals useNormals)
|
||||
: Grid(xSegments, ySegments)
|
||||
{
|
||||
_geometry = std::make_unique<TriangleSoup>(
|
||||
createElements(xSegments, ySegments),
|
||||
usePositions,
|
||||
useTextureCoordinates,
|
||||
useNormals
|
||||
);
|
||||
|
||||
if (usePositions) {
|
||||
_geometry->setVertexPositions(createPositions(_xSegments, _ySegments));
|
||||
}
|
||||
|
||||
if (useTextureCoordinates) {
|
||||
_geometry->setVertexTextureCoordinates(
|
||||
createTextureCoordinates(_xSegments, _ySegments)
|
||||
);
|
||||
}
|
||||
if (useNormals) {
|
||||
_geometry->setVertexNormals(createNormals(_xSegments, _ySegments));
|
||||
}
|
||||
}
|
||||
|
||||
int BasicGrid::xSegments() const {
|
||||
return _xSegments;
|
||||
}
|
||||
|
||||
int BasicGrid::ySegments() const {
|
||||
return _ySegments;
|
||||
}
|
||||
|
||||
void BasicGrid::validate([[maybe_unused]] int xSegments, [[maybe_unused]] int ySegments) {
|
||||
ghoul_assert(
|
||||
xSegments > 0 && ySegments > 0,
|
||||
std::string("Resolution must be at least 1x1. (") +
|
||||
std::to_string(xSegments) + ", " + std::to_string(ySegments) + ")"
|
||||
);
|
||||
}
|
||||
|
||||
inline size_t BasicGrid::numElements(int xSegments, int ySegments) {
|
||||
return 3 * 2 * xSegments * ySegments;
|
||||
}
|
||||
|
||||
inline size_t BasicGrid::numVertices(int xSegments, int ySegments) {
|
||||
return (xSegments + 1) * (ySegments + 1);
|
||||
}
|
||||
|
||||
std::vector<GLuint> BasicGrid::createElements(int xSegments, int ySegments) {
|
||||
validate(xSegments, ySegments);
|
||||
|
||||
std::vector<GLuint> elements;
|
||||
elements.reserve(numElements(xSegments, ySegments));
|
||||
for (int y = 0; y < ySegments; y++) {
|
||||
for (int x = 0; x < xSegments; x++) {
|
||||
|
||||
// x v01---v11 x ..
|
||||
// | / |
|
||||
// x v00---v10 x ..
|
||||
//
|
||||
// x x x x ..
|
||||
// : : : :
|
||||
|
||||
const GLuint v00 = (y + 0) * (xSegments + 1) + x + 0;
|
||||
const GLuint v10 = (y + 0) * (xSegments + 1) + x + 1;
|
||||
const GLuint v01 = (y + 1) * (xSegments + 1) + x + 0;
|
||||
const GLuint v11 = (y + 1) * (xSegments + 1) + x + 1;
|
||||
|
||||
// add upper triangle
|
||||
elements.push_back(v00);
|
||||
elements.push_back(v10);
|
||||
elements.push_back(v11);
|
||||
|
||||
// add lower triangle
|
||||
elements.push_back(v00);
|
||||
elements.push_back(v11);
|
||||
elements.push_back(v01);
|
||||
}
|
||||
}
|
||||
|
||||
return elements;
|
||||
}
|
||||
|
||||
std::vector<glm::vec4> BasicGrid::createPositions(int xSegments, int ySegments) {
|
||||
validate(xSegments, ySegments);
|
||||
std::vector<glm::vec4> positions;
|
||||
positions.reserve(numVertices(xSegments, ySegments));
|
||||
|
||||
// Copy from 2d texture coordinates and use as template to create positions
|
||||
std::vector<glm::vec2> templateTextureCoords = createTextureCoordinates(
|
||||
xSegments,
|
||||
ySegments
|
||||
);
|
||||
for (const glm::vec2& coords : templateTextureCoords) {
|
||||
positions.emplace_back(coords, 0.f, 1.f);
|
||||
}
|
||||
//for (unsigned int i = 0; i < templateTextureCoords.size(); i++) {
|
||||
// positions.push_back(glm::vec4(
|
||||
// templateTextureCoords[i],
|
||||
// 0.0f,
|
||||
// 1.0f
|
||||
// ));
|
||||
//}
|
||||
return positions;
|
||||
}
|
||||
|
||||
std::vector<glm::vec2> BasicGrid::createTextureCoordinates(int xSegments, int ySegments) {
|
||||
validate(xSegments, ySegments);
|
||||
std::vector<glm::vec2> textureCoordinates;
|
||||
textureCoordinates.reserve(numVertices(xSegments, ySegments));
|
||||
|
||||
for (int y = 0; y < ySegments + 1; y++) {
|
||||
for (int x = 0; x < xSegments + 1; x++) {
|
||||
textureCoordinates.emplace_back(
|
||||
static_cast<float>(x) / static_cast<float>(xSegments),
|
||||
static_cast<float>(y) / static_cast<float>(ySegments)
|
||||
);
|
||||
}
|
||||
}
|
||||
return textureCoordinates;
|
||||
}
|
||||
|
||||
std::vector<glm::vec3> BasicGrid::createNormals(int xSegments, int ySegments) {
|
||||
validate(xSegments, ySegments);
|
||||
std::vector<glm::vec3> normals;
|
||||
normals.reserve(numVertices(xSegments, ySegments));
|
||||
|
||||
for (int y = 0; y < ySegments + 1; y++) {
|
||||
for (int x = 0; x < xSegments + 1; x++) {
|
||||
normals.emplace_back(0.f, 0.f, 1.f);
|
||||
}
|
||||
}
|
||||
|
||||
return normals;
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -1,70 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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___BASICGRIDGEOMETRY___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___BASICGRIDGEOMETRY___H__
|
||||
|
||||
#include <modules/globebrowsing/meshes/grid.h>
|
||||
|
||||
#include <modules/globebrowsing/meshes/trianglesoup.h>
|
||||
#include <vector>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
class BasicGrid : public Grid {
|
||||
public:
|
||||
/**
|
||||
* \param xSegments is the number of grid cells in the x direction.
|
||||
* \param ySegments is the number of grid cells in the y direction.
|
||||
* \param usePositions determines whether or not to upload any vertex position data
|
||||
* to the GPU.
|
||||
* \param useTextureCoordinates determines whether or not to upload any vertex texture
|
||||
* coordinate data to the GPU.
|
||||
* \param useNormals determines whether or not to upload any vertex normal data
|
||||
* to the GPU.
|
||||
*/
|
||||
BasicGrid(unsigned int xSegments, unsigned int ySegments,
|
||||
TriangleSoup::Positions usePositions,
|
||||
TriangleSoup::TextureCoordinates useTextureCoordinates,
|
||||
TriangleSoup::Normals useNormals);
|
||||
|
||||
virtual int xSegments() const override;
|
||||
virtual int ySegments() const override;
|
||||
|
||||
private:
|
||||
std::vector<GLuint> createElements(int xSegments, int ySegments) override;
|
||||
std::vector<glm::vec4> createPositions(int xSegments, int ySegments) override;
|
||||
std::vector<glm::vec2> createTextureCoordinates(int xSegments,
|
||||
int ySegments) override;
|
||||
std::vector<glm::vec3> createNormals(int xSegments, int ySegments) override;
|
||||
|
||||
void validate(int xSegments, int ySegments);
|
||||
|
||||
inline size_t numElements(int xSegments, int ySegments);
|
||||
inline size_t numVertices(int xSegments, int ySegments);
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___BASICGRIDGEOMETRY___H__
|
||||
@@ -1,101 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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___GRIDGEOMETRY___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___GRIDGEOMETRY___H__
|
||||
|
||||
#include <ghoul/glm.h>
|
||||
#include <ghoul/opengl/ghoul_gl.h>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
class TriangleSoup;
|
||||
|
||||
/**
|
||||
* Abstract class defining an interface used for geometries with grid structures.
|
||||
* The class Grid should be extended for use of geometries with a 2D structure where the
|
||||
* number of segments in x and y direction represents the number of vertices + 1 in each
|
||||
* direction.
|
||||
*/
|
||||
class Grid {
|
||||
public:
|
||||
Grid(int xSegments, int ySegments);
|
||||
|
||||
virtual ~Grid();
|
||||
|
||||
TriangleSoup& geometry();
|
||||
|
||||
/**
|
||||
* Returns the number of grid cells in the x direction. Hence the number of vertices
|
||||
* in the x direction is xResolution + 1.
|
||||
*/
|
||||
virtual int xSegments() const = 0;
|
||||
|
||||
/**
|
||||
* Returns the number of grid cells in the y direction. Hence the number of vertices
|
||||
* in the y direction is xResolution + 1.
|
||||
*/
|
||||
virtual int ySegments() const = 0;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Should return the indices of vertices for a grid with size \c xSegments *
|
||||
* \c ySegments. Where the number of vertices in each direction is the number of
|
||||
* segments + 1.
|
||||
*/
|
||||
virtual std::vector<GLuint> createElements(int xSegments, int ySegments) = 0;
|
||||
|
||||
/**
|
||||
* Should return the positions of vertices for a grid with size \c xSegments *
|
||||
* \c ySegments. Where the number of vertices in each direction is the number of
|
||||
* segments + 1.
|
||||
*/
|
||||
virtual std::vector<glm::vec4> createPositions(int xSegments, int ySegments) = 0;
|
||||
|
||||
/**
|
||||
* Should return the texture coordinates of vertices for a grid with size
|
||||
* \c xSegments * \c ySegments. Where the number of vertices in each direction is the
|
||||
* number of segments + 1.
|
||||
*/
|
||||
virtual std::vector<glm::vec2> createTextureCoordinates(int xSegments,
|
||||
int ySegments) = 0;
|
||||
|
||||
/**
|
||||
* Should return the normals of vertices for a grid with size \c xSegments *
|
||||
* \c ySegments. Where the number of vertices in each direction is the number of
|
||||
* segments + 1.
|
||||
*/
|
||||
virtual std::vector<glm::vec3> createNormals(int xSegments, int ySegments) = 0;
|
||||
|
||||
std::unique_ptr<TriangleSoup> _geometry;
|
||||
|
||||
const int _xSegments;
|
||||
const int _ySegments;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___GRIDGEOMETRY___H__
|
||||
@@ -1,174 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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/meshes/skirtedgrid.h>
|
||||
|
||||
#include <ghoul/misc/assert.h>
|
||||
|
||||
namespace {
|
||||
size_t numElements(int xSegments, int ySegments) {
|
||||
return 3 * 2 * xSegments * ySegments;
|
||||
}
|
||||
|
||||
size_t numVertices(int xSegments, int ySegments) {
|
||||
return (xSegments + 1) * (ySegments + 1);
|
||||
}
|
||||
|
||||
void validate([[maybe_unused]] int xSegments, [[maybe_unused]] int ySegments) {
|
||||
ghoul_assert(
|
||||
xSegments > 0 && ySegments > 0,
|
||||
"Resolution must be at least 1x1. (" + std::to_string(xSegments) + ", " +
|
||||
std::to_string(ySegments) + ")"
|
||||
);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
SkirtedGrid::SkirtedGrid(unsigned int xSegments, unsigned int ySegments,
|
||||
TriangleSoup::Positions usePositions,
|
||||
TriangleSoup::TextureCoordinates useTextureCoordinates,
|
||||
TriangleSoup::Normals useNormals)
|
||||
: Grid(xSegments, ySegments)
|
||||
{
|
||||
_geometry = std::make_unique<TriangleSoup>(
|
||||
createElements(xSegments, ySegments),
|
||||
usePositions,
|
||||
useTextureCoordinates,
|
||||
useNormals
|
||||
);
|
||||
|
||||
if (usePositions) {
|
||||
_geometry->setVertexPositions(createPositions(_xSegments, _ySegments));
|
||||
}
|
||||
if (useTextureCoordinates) {
|
||||
_geometry->setVertexTextureCoordinates(
|
||||
createTextureCoordinates(_xSegments, _ySegments)
|
||||
);
|
||||
}
|
||||
if (useNormals) {
|
||||
_geometry->setVertexNormals(createNormals(_xSegments, _ySegments));
|
||||
}
|
||||
}
|
||||
|
||||
int SkirtedGrid::xSegments() const {
|
||||
return _xSegments;
|
||||
}
|
||||
|
||||
int SkirtedGrid::ySegments() const {
|
||||
return _ySegments;
|
||||
}
|
||||
|
||||
std::vector<GLuint> SkirtedGrid::createElements(int xSegments, int ySegments) {
|
||||
validate(xSegments, ySegments);
|
||||
|
||||
std::vector<GLuint> elements;
|
||||
elements.reserve(numElements(xSegments + 2, ySegments + 2));
|
||||
for (int y = 0; y < ySegments + 2; y++) {
|
||||
for (int x = 0; x < xSegments + 2; x++) {
|
||||
|
||||
// x v01---v11 x ..
|
||||
// | / |
|
||||
// x v00---v10 x ..
|
||||
//
|
||||
// x x x x ..
|
||||
// : : : :
|
||||
|
||||
const GLuint v00 = (y + 0) * (xSegments + 2 + 1) + x + 0;
|
||||
const GLuint v10 = (y + 0) * (xSegments + 2 + 1) + x + 1;
|
||||
const GLuint v01 = (y + 1) * (xSegments + 2 + 1) + x + 0;
|
||||
const GLuint v11 = (y + 1) * (xSegments + 2 + 1) + x + 1;
|
||||
|
||||
// add upper triangle
|
||||
elements.push_back(v00);
|
||||
elements.push_back(v10);
|
||||
elements.push_back(v11);
|
||||
|
||||
// add lower triangle
|
||||
elements.push_back(v00);
|
||||
elements.push_back(v11);
|
||||
elements.push_back(v01);
|
||||
}
|
||||
}
|
||||
|
||||
return elements;
|
||||
}
|
||||
|
||||
std::vector<glm::vec4> SkirtedGrid::createPositions(int xSegments, int ySegments) {
|
||||
validate(xSegments, ySegments);
|
||||
|
||||
// Copy from 2d texture coordinates and use as template to create positions
|
||||
const std::vector<glm::vec2>& templateTextureCoords = createTextureCoordinates(
|
||||
xSegments,
|
||||
ySegments
|
||||
);
|
||||
|
||||
std::vector<glm::vec4> positions;
|
||||
positions.reserve(numVertices(xSegments, ySegments));
|
||||
for (const glm::vec2& c : templateTextureCoords) {
|
||||
positions.emplace_back(c, 0.f, 1.f);
|
||||
}
|
||||
return positions;
|
||||
}
|
||||
|
||||
std::vector<glm::vec2> SkirtedGrid::createTextureCoordinates(int xSegments, int ySegments)
|
||||
{
|
||||
validate(xSegments, ySegments);
|
||||
|
||||
std::vector<glm::vec2> textureCoordinates;
|
||||
textureCoordinates.reserve(numVertices(xSegments + 2, ySegments + 2));
|
||||
for (int y = -1; y < ySegments + 2; y++) {
|
||||
for (int x = -1; x < xSegments + 2; x++) {
|
||||
textureCoordinates.emplace_back(
|
||||
glm::clamp(
|
||||
static_cast<float>(x) / static_cast<float>(xSegments),
|
||||
0 - 1.f / (2 * xSegments),
|
||||
1 + 1.f / (2 * xSegments)
|
||||
),
|
||||
glm::clamp(
|
||||
static_cast<float>(y) / static_cast<float>(ySegments),
|
||||
0 - 1.f / (2 * ySegments),
|
||||
1 + 1.f / (2 * ySegments)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
return textureCoordinates;
|
||||
}
|
||||
|
||||
std::vector<glm::vec3> SkirtedGrid::createNormals(int xSegments, int ySegments) {
|
||||
validate(xSegments, ySegments);
|
||||
|
||||
std::vector<glm::vec3> normals;
|
||||
normals.reserve(numVertices(xSegments + 2, ySegments + 2));
|
||||
for (int y = -1; y < ySegments + 2; y++) {
|
||||
for (int x = -1; x < xSegments + 2; x++) {
|
||||
normals.emplace_back(0.f, 0.f, 1.f);
|
||||
}
|
||||
}
|
||||
|
||||
return normals;
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -1,182 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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/meshes/trianglesoup.h>
|
||||
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "TriangleSoup";
|
||||
} // namespace
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
TriangleSoup::TriangleSoup(std::vector<unsigned int> elements, Positions usePositions,
|
||||
TextureCoordinates useTextures, Normals useNormals)
|
||||
: _useVertexPositions(usePositions)
|
||||
, _useTextureCoordinates(useTextures)
|
||||
, _useVertexNormals(useNormals)
|
||||
{
|
||||
setElements(std::move(elements));
|
||||
}
|
||||
|
||||
TriangleSoup::~TriangleSoup() {
|
||||
glDeleteBuffers(1, &_vertexBufferID);
|
||||
glDeleteBuffers(1, &_elementBufferID);
|
||||
glDeleteVertexArrays(1, &_vaoID);
|
||||
}
|
||||
|
||||
void TriangleSoup::setVertexPositions(std::vector<glm::vec4> positions) {
|
||||
_useVertexPositions = true;
|
||||
_gpuDataNeedUpdate = true;
|
||||
_vertexData.resize(positions.size());
|
||||
for (size_t i = 0; i < positions.size(); ++i) {
|
||||
_vertexData[i].position[0] = positions[i][0];
|
||||
_vertexData[i].position[1] = positions[i][1];
|
||||
_vertexData[i].position[2] = positions[i][2];
|
||||
//_vertexData[i].position[3] = positions[i][3];
|
||||
}
|
||||
}
|
||||
|
||||
void TriangleSoup::setVertexTextureCoordinates(std::vector<glm::vec2> textures) {
|
||||
_useTextureCoordinates = true;
|
||||
_gpuDataNeedUpdate = true;
|
||||
_vertexData.resize(textures.size());
|
||||
for (size_t i = 0; i < textures.size(); ++i) {
|
||||
_vertexData[i].texture[0] = textures[i][0];
|
||||
_vertexData[i].texture[1] = textures[i][1];
|
||||
}
|
||||
}
|
||||
|
||||
void TriangleSoup::setVertexNormals(std::vector<glm::vec3> normals) {
|
||||
_useVertexNormals = true;
|
||||
_gpuDataNeedUpdate = true;
|
||||
_vertexData.resize(normals.size());
|
||||
for (size_t i = 0; i < normals.size(); ++i) {
|
||||
_vertexData[i].normal[0] = normals[i][0];
|
||||
_vertexData[i].normal[1] = normals[i][1];
|
||||
_vertexData[i].normal[2] = normals[i][2];
|
||||
}
|
||||
}
|
||||
|
||||
void TriangleSoup::setElements(std::vector<unsigned int> elements) {
|
||||
_gpuDataNeedUpdate = true;
|
||||
_elementData = std::move(elements);
|
||||
}
|
||||
|
||||
bool TriangleSoup::updateDataOnGPU() {
|
||||
// Create VAO
|
||||
if (_vaoID == 0) {
|
||||
glGenVertexArrays(1, &_vaoID);
|
||||
}
|
||||
|
||||
// Create VBOs
|
||||
if (_vertexBufferID == 0 && !_vertexData.empty()) {
|
||||
glGenBuffers(1, &_vertexBufferID);
|
||||
if (_vertexBufferID == 0) {
|
||||
LERROR("Could not create vertex buffer");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (_elementBufferID == 0 && !_elementData.empty()) {
|
||||
glGenBuffers(1, &_elementBufferID);
|
||||
if (_elementBufferID == 0) {
|
||||
LERROR("Could not create vertex element buffer");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// First VAO setup
|
||||
glBindVertexArray(_vaoID);
|
||||
|
||||
// Vertex buffer
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferID);
|
||||
glBufferData(
|
||||
GL_ARRAY_BUFFER,
|
||||
_vertexData.size() * sizeof(Vertex),
|
||||
&_vertexData[0],
|
||||
GL_STATIC_DRAW
|
||||
);
|
||||
|
||||
// Positions at location 0
|
||||
if (_useVertexPositions) {
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), nullptr);
|
||||
}
|
||||
// Textures at location 1
|
||||
if (_useTextureCoordinates) {
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(
|
||||
1,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
sizeof(Vertex),
|
||||
reinterpret_cast<const GLvoid*>(offsetof(Vertex, texture)) // NOLINT
|
||||
);
|
||||
}
|
||||
// Normals at location 2
|
||||
if (_useVertexNormals) {
|
||||
glEnableVertexAttribArray(2);
|
||||
glVertexAttribPointer(
|
||||
2,
|
||||
3,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
sizeof(Vertex),
|
||||
reinterpret_cast<const GLvoid*>(offsetof(Vertex, normal)) // NOLINT
|
||||
);
|
||||
}
|
||||
|
||||
// Element buffer
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _elementBufferID);
|
||||
glBufferData(
|
||||
GL_ELEMENT_ARRAY_BUFFER,
|
||||
_elementData.size() * sizeof(GLint),
|
||||
&_elementData[0],
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
glBindVertexArray(0);
|
||||
|
||||
_gpuDataNeedUpdate = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TriangleSoup::drawUsingActiveProgram() {
|
||||
if (_gpuDataNeedUpdate) {
|
||||
updateDataOnGPU();
|
||||
}
|
||||
glBindVertexArray(_vaoID);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _elementBufferID);
|
||||
glDrawElements(
|
||||
GL_TRIANGLES,
|
||||
static_cast<GLsizei>(_elementData.size()),
|
||||
GL_UNSIGNED_INT,
|
||||
nullptr
|
||||
);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -1,103 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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___TRIANGLESOUP___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___TRIANGLESOUP___H__
|
||||
|
||||
#include <ghoul/glm.h>
|
||||
#include <ghoul/misc/boolean.h>
|
||||
#include <ghoul/opengl/ghoul_gl.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
/**
|
||||
* Class to hold vertex data and handling OpenGL interfacing and rendering.
|
||||
* A <code>TriangleSoup</code> has all data needed such as position buffer and normal
|
||||
* buffer but all data is not necessarily needed for all purpouses so some vertex buffers
|
||||
* such as normals can be disabled if not needed.
|
||||
*/
|
||||
|
||||
// TODO : Possibly render triangle strips in this class instead of triangles since
|
||||
// that is faster
|
||||
class TriangleSoup {
|
||||
public:
|
||||
BooleanType(Positions);
|
||||
BooleanType(TextureCoordinates);
|
||||
BooleanType(Normals);
|
||||
|
||||
TriangleSoup(std::vector<unsigned int> elements, // At least elements are required
|
||||
Positions usePositions = Positions::No,
|
||||
TextureCoordinates useTextures = TextureCoordinates::No,
|
||||
Normals useNormals = Normals::No);
|
||||
|
||||
~TriangleSoup();
|
||||
|
||||
// Setters
|
||||
void setVertexPositions(std::vector<glm::vec4> positions);
|
||||
void setVertexTextureCoordinates(std::vector<glm::vec2> textures);
|
||||
void setVertexNormals(std::vector<glm::vec3> normals);
|
||||
void setElements(std::vector<unsigned int> elements);
|
||||
|
||||
/**
|
||||
* Calls OpenGL's draw function to draw the triangles defined in the vertex buffers
|
||||
* using the current bound program object.
|
||||
* The vertex buffer attribute input locations to the shader program comes in the
|
||||
* order of positions (0), texture coordinates (1) and normals (2).
|
||||
* The input locations in the shader program should be specified to match these
|
||||
* locations.
|
||||
*/
|
||||
void drawUsingActiveProgram();
|
||||
|
||||
protected:
|
||||
// Determines what attribute data is in use
|
||||
bool _useVertexPositions;
|
||||
bool _useTextureCoordinates;
|
||||
bool _useVertexNormals;
|
||||
|
||||
struct Vertex {
|
||||
GLfloat position[3];
|
||||
GLfloat texture[2];
|
||||
GLfloat normal[3];
|
||||
};
|
||||
|
||||
// Vertex data
|
||||
std::vector<Vertex> _vertexData;
|
||||
std::vector<GLuint> _elementData;
|
||||
|
||||
private:
|
||||
bool updateDataOnGPU();
|
||||
|
||||
// GL handles
|
||||
GLuint _vaoID = 0;
|
||||
GLuint _vertexBufferID = 0;
|
||||
GLuint _elementBufferID = 0;
|
||||
|
||||
bool _gpuDataNeedUpdate = false;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___TRIANGLESOUP___H__
|
||||
@@ -1,87 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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/other/pixelbuffer.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "PixelBuffer";
|
||||
} // namespace
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
PixelBuffer::PixelBuffer(size_t numBytes, Usage usage)
|
||||
: _numBytes(numBytes)
|
||||
, _usage(usage)
|
||||
{
|
||||
glGenBuffers(1, &_id);
|
||||
bind();
|
||||
glBufferData(GL_PIXEL_UNPACK_BUFFER, _numBytes, nullptr, static_cast<GLenum>(_usage));
|
||||
unbind();
|
||||
}
|
||||
|
||||
PixelBuffer::~PixelBuffer() {
|
||||
glDeleteBuffers(1, &_id);
|
||||
}
|
||||
|
||||
void* PixelBuffer::mapBuffer(Access access) {
|
||||
void* dataPtr = glMapBuffer(GL_PIXEL_UNPACK_BUFFER, static_cast<GLenum>(access));
|
||||
_isMapped = dataPtr != nullptr;
|
||||
return dataPtr;
|
||||
}
|
||||
|
||||
void* PixelBuffer::mapBufferRange(GLintptr offset, GLsizeiptr length,
|
||||
BufferAccessMask access)
|
||||
{
|
||||
void* dataPtr = glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, offset, length, access);
|
||||
_isMapped = dataPtr;
|
||||
return dataPtr;
|
||||
}
|
||||
|
||||
bool PixelBuffer::unMapBuffer() {
|
||||
GLboolean success = glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
|
||||
if (!success) {
|
||||
LERROR("Unable to unmap pixel buffer, data may be corrupt!");
|
||||
}
|
||||
_isMapped = false;
|
||||
return success == GL_TRUE;
|
||||
}
|
||||
|
||||
void PixelBuffer::bind() {
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _id);
|
||||
}
|
||||
|
||||
void PixelBuffer::unbind() {
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
}
|
||||
|
||||
bool PixelBuffer::isMapped() const {
|
||||
return _isMapped;
|
||||
}
|
||||
|
||||
PixelBuffer::operator GLuint() const {
|
||||
return _id;
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -1,140 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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___PIXEL_BUFFER___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___PIXEL_BUFFER___H__
|
||||
|
||||
#include <ghoul/opengl/ghoul_gl.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
/**
|
||||
* Handles an OpenGL pixel buffer which contains data allocated on the GPU. A simple
|
||||
* class that wraps the standard functionality of OpenGL pixel buffer objects. Once
|
||||
* the PixelBuffer is created, data is allocated on the GPU. When mapping data to a
|
||||
* address pointer, the user needs to ensure the data is unmapped before the data can
|
||||
* be used on the GPU / CPU depending on Usage.
|
||||
*/
|
||||
class PixelBuffer {
|
||||
public:
|
||||
/**
|
||||
* All kinds of usage for pixel buffer objects as defined by the OpenGL standard.
|
||||
* See: https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glBufferData.xhtml
|
||||
*/
|
||||
enum class Usage : std::underlying_type_t<GLenum> {
|
||||
StreamDraw = static_cast<std::underlying_type_t<GLenum>>(GL_STREAM_DRAW),
|
||||
StreamRead = static_cast<std::underlying_type_t<GLenum>>(GL_STREAM_READ),
|
||||
StreamCopy = static_cast<std::underlying_type_t<GLenum>>(GL_STREAM_COPY),
|
||||
StaticDraw = static_cast<std::underlying_type_t<GLenum>>(GL_STATIC_DRAW),
|
||||
StaticRead = static_cast<std::underlying_type_t<GLenum>>(GL_STATIC_READ),
|
||||
StaticCopy = static_cast<std::underlying_type_t<GLenum>>(GL_STATIC_COPY),
|
||||
DynamicDraw = static_cast<std::underlying_type_t<GLenum>>(GL_DYNAMIC_DRAW),
|
||||
DynamicRead = static_cast<std::underlying_type_t<GLenum>>(GL_DYNAMIC_READ),
|
||||
DynamicCopy = static_cast<std::underlying_type_t<GLenum>>(GL_DYNAMIC_COPY)
|
||||
};
|
||||
|
||||
/**
|
||||
* Access hints for OpenGL buffer mapping
|
||||
* See: https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glMapBuffer.xml
|
||||
*/
|
||||
enum class Access : std::underlying_type_t<GLenum> {
|
||||
ReadOnly = static_cast<std::underlying_type_t<GLenum>>(GL_READ_ONLY),
|
||||
WriteOnly = static_cast<std::underlying_type_t<GLenum>>(GL_WRITE_ONLY),
|
||||
ReadWrite = static_cast<std::underlying_type_t<GLenum>>(GL_READ_WRITE)
|
||||
};
|
||||
|
||||
/**
|
||||
* Allocates <code>numBytes</code> bytes on the GPU and creates an ID for the pixel
|
||||
* buffer object.
|
||||
*
|
||||
* \param numBytes is the number of bytes to be allocated on GPU memory
|
||||
* \param usage is the Usage for the pixel buffer
|
||||
*/
|
||||
PixelBuffer(size_t numBytes, Usage usage);
|
||||
|
||||
/**
|
||||
* calls glDeleteBuffers().
|
||||
*/
|
||||
~PixelBuffer();
|
||||
|
||||
/**
|
||||
* Maps an address pointer to GPU direct memory access. The user must make sure the
|
||||
* buffer is bound before calling this function.
|
||||
*
|
||||
* \param access is the access to which can be any of <code>GL_READ_ONLY</code>,
|
||||
* <code>GL_WRITE_ONLY</code>, or <code>GL_READ_WRITE</code>
|
||||
* \return The DMA address to the mapped buffer. Returns nullptr if the mapping
|
||||
* failed
|
||||
*/
|
||||
void* mapBuffer(Access access);
|
||||
|
||||
/**
|
||||
* Maps an address pointer to GPU direct memory access. Gives access to a range of
|
||||
* the buffer. The user must make sure the buffer is bound before calling this
|
||||
* function.
|
||||
*
|
||||
* \param offet is the number of bytes to the first address to get in the buffer
|
||||
* \param length is the number of bytes to access in the buffer
|
||||
* \param access is a bitfield describing the access as described in:
|
||||
* https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glMapBufferRange.xhtml
|
||||
* \return The DMA address to the mapped buffer. Returns nullptr if the mapping
|
||||
* failed
|
||||
*/
|
||||
void* mapBufferRange(GLintptr offset, GLsizeiptr length, BufferAccessMask access);
|
||||
|
||||
/**
|
||||
* Maps the default buffer and makes the data available on the GPU
|
||||
*/
|
||||
bool unMapBuffer();
|
||||
|
||||
/**
|
||||
* Calls glBindBuffer()
|
||||
*/
|
||||
void bind();
|
||||
|
||||
/**
|
||||
* Calls glBindBuffer() with argument 0 to unmap any pixel buffer
|
||||
*/
|
||||
void unbind();
|
||||
|
||||
/**
|
||||
* \returns true of the buffer is mapped, otherwise false
|
||||
*/
|
||||
bool isMapped() const;
|
||||
|
||||
/**
|
||||
* \returns the OpenGL id of the pixel buffer object
|
||||
*/
|
||||
operator GLuint() const;
|
||||
|
||||
private:
|
||||
GLuint _id = 0;
|
||||
const size_t _numBytes;
|
||||
const Usage _usage;
|
||||
bool _isMapped = false;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___PIXEL_BUFFER___H__
|
||||
@@ -1,116 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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___PIXEL_BUFFER_CONTAINER___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___PIXEL_BUFFER_CONTAINER___H__
|
||||
|
||||
#include <modules/globebrowsing/other/pixelbuffer.h>
|
||||
#include <map>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
/**
|
||||
* Templated class which owns one or many PixelBuffer%s. The KeyType is used to map a
|
||||
* pixel buffer but only if it is not already mapped.
|
||||
*/
|
||||
template <class KeyType>
|
||||
class PixelBufferContainer {
|
||||
public:
|
||||
/**
|
||||
* Creates numPixelBuffers pixel buffer objects, each with numBytesPerBuffer bytes
|
||||
* allocated on the GPU.
|
||||
*
|
||||
* \param numBytesPerBuffer is the number of bytes per pixel buffer. All pixel
|
||||
* buffers within a <code>PixelBufferContainer</code> have the same number of
|
||||
* bytes
|
||||
* \param usage is the <code>Usage</code> as described by <code>PixelBuffer</code>
|
||||
* \param numPixelBuffers is the number of pixel buffers to create for this container.
|
||||
* If numPixelBuffers is omitted, no pixel buffers are created.
|
||||
*/
|
||||
PixelBufferContainer(size_t numBytesPerBuffer,
|
||||
globebrowsing::PixelBuffer::Usage usage, size_t numPixelBuffers = 0);
|
||||
~PixelBufferContainer() = default;
|
||||
|
||||
/**
|
||||
* Finds a Pixel buffer and maps it if it is available.
|
||||
*
|
||||
* \param key is the identifier for the pixel buffer which can be used later when
|
||||
* unmapping the mapped pixel buffer.
|
||||
* \param access is the access as described by <code>PixelBuffer</code>
|
||||
* \return An address pointer to DMA if the mapping succeeded. Otherwise a \c nullptr
|
||||
* is returned. The mapping can fail if the buffer identified with \p key is
|
||||
* already mapped or if something else failed.
|
||||
*/
|
||||
void* mapBuffer(KeyType key, PixelBuffer::Access access);
|
||||
|
||||
/**
|
||||
* Finds a Pixel buffer and maps a range of it if it is available.
|
||||
*
|
||||
* \param key is the identifier for the pixel buffer which can be used later when
|
||||
* unmapping the mapped pixel buffer.
|
||||
* \param offet is the number of bytes to the first address to get in the buffer
|
||||
* \param length is the number of bytes to access in the buffer
|
||||
* \param access is the access as described by <code>PixelBuffer</code>
|
||||
* \return An address pointer to DMA if the mapping succeeded. Otherwise a nullptr
|
||||
* is returned. The mapping can fail if the buffer identified with \p key is
|
||||
* already mapped or if something else failed.
|
||||
*/
|
||||
void* mapBufferRange(KeyType key, GLintptr offset, GLsizeiptr length,
|
||||
BufferAccessMask access);
|
||||
|
||||
/**
|
||||
* Unmaps all buffers in the PixelBufferContainer.
|
||||
*
|
||||
* \return \c true if the unmapping succeeded, otherwise \c false
|
||||
*/
|
||||
bool resetMappedBuffers();
|
||||
|
||||
/**
|
||||
* Unmaps a buffer that has previously been mapped. This buffer is identified using
|
||||
* \p key.
|
||||
*
|
||||
* \param key is the identifier of the mapped buffer.
|
||||
* \return \c true if the unmapping succeeded, otherwise \c false
|
||||
*/
|
||||
bool unMapBuffer(KeyType key);
|
||||
|
||||
/**
|
||||
* \return The \c GLuint id of a pixel buffer identified by \p key if it currently is
|
||||
* mapped.
|
||||
*/
|
||||
GLuint idOfMappedBuffer(KeyType key);
|
||||
private:
|
||||
const globebrowsing::PixelBuffer::Usage _usage;
|
||||
|
||||
std::vector<std::unique_ptr<PixelBuffer>> _pixelBuffers;
|
||||
|
||||
// Maps from KeyType to index of mapped buffers
|
||||
std::map<KeyType, int> _indexMap;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#include "pixelbuffercontainer.inl"
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___PIXEL_BUFFER_CONTAINER___H__
|
||||
@@ -1,129 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
****************************************************************************************/
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
template <class KeyType>
|
||||
PixelBufferContainer<KeyType>::PixelBufferContainer(size_t numBytesPerBuffer,
|
||||
PixelBuffer::Usage usage, size_t numPixelBuffers)
|
||||
: _usage(usage)
|
||||
{
|
||||
for (size_t i = 0; i < numPixelBuffers; ++i) {
|
||||
_pixelBuffers.push_back(std::make_unique<PixelBuffer>(numBytesPerBuffer, _usage));
|
||||
}
|
||||
}
|
||||
|
||||
template <class KeyType>
|
||||
void* PixelBufferContainer<KeyType>::mapBuffer(KeyType key, PixelBuffer::Access access) {
|
||||
const typename std::map<KeyType, int>::const_iterator iter = _indexMap.find(key);
|
||||
const bool notFoundAmongMappedBuffers = (iter == _indexMap.end());
|
||||
|
||||
if (!notFoundAmongMappedBuffers) { // This PBO is already mapped
|
||||
ghoul_assert(_pixelBuffers[iter->second], "Incorrect index map");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Find a pixel buffer that is unmapped
|
||||
for (size_t i = 0; i < _pixelBuffers.size(); ++i) {
|
||||
if (!_pixelBuffers[i]->isMapped()) {
|
||||
_pixelBuffers[i]->bind();
|
||||
void* dataPtr = _pixelBuffers[i]->mapBuffer(access);
|
||||
_pixelBuffers[i]->unbind();
|
||||
if (dataPtr) { // Success in mapping
|
||||
// Add this index to the map of mapped pixel buffers
|
||||
_indexMap.emplace(std::move(key), static_cast<int>(i));
|
||||
return dataPtr;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <class KeyType>
|
||||
void* PixelBufferContainer<KeyType>::mapBufferRange(KeyType key, GLintptr offset,
|
||||
GLsizeiptr length,
|
||||
BufferAccessMask access)
|
||||
{
|
||||
const typename std::map<KeyType, int>::const_iterator iter = _indexMap.find(key);
|
||||
const bool notFoundAmongMappedBuffers = (iter == _indexMap.end());
|
||||
|
||||
if (!notFoundAmongMappedBuffers) { // This PBO is already mapped
|
||||
ghoul_assert(_pixelBuffers[iter->second], "Incorrect index map");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Find a pixel buffer that is unmapped
|
||||
for (int i = 0; i < _pixelBuffers.size(); ++i) {
|
||||
const bool bufferIsMapped = _pixelBuffers[i]->isMapped();
|
||||
if (!bufferIsMapped) {
|
||||
_pixelBuffers[i]->bind();
|
||||
void* dataPtr = _pixelBuffers[i]->mapBufferRange(offset, length, access);
|
||||
_pixelBuffers[i]->unbind();
|
||||
if (dataPtr) { // Success in mapping
|
||||
_indexMap.emplace(std::move(key), i);
|
||||
return dataPtr;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <class KeyType>
|
||||
bool PixelBufferContainer<KeyType>::resetMappedBuffers() {
|
||||
bool success = true;
|
||||
for (auto iter = _indexMap.begin(); iter != _indexMap.end(); iter++) {
|
||||
const int index = iter->second; // Index where the mapped buffer is stored
|
||||
_pixelBuffers[index]->bind();
|
||||
success &= _pixelBuffers[index]->unMapBuffer();
|
||||
_pixelBuffers[index]->unbind();
|
||||
_indexMap.erase(iter); // This key should no longer be among the mapped buffers
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
template <class KeyType>
|
||||
bool PixelBufferContainer<KeyType>::unMapBuffer(KeyType key) {
|
||||
bool success = false;
|
||||
const typename std::map<KeyType, int>::const_iterator iter = _indexMap.find(key);
|
||||
if (iter != _indexMap.end()) { // Found a mapped pixel buffer
|
||||
const int index = iter->second; // Index where the mapped buffer is stored
|
||||
_pixelBuffers[index]->bind();
|
||||
success = _pixelBuffers[index]->unMapBuffer();
|
||||
_pixelBuffers[index]->unbind();
|
||||
_indexMap.erase(iter); // This key should no longer be among the mapped buffers
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
template <class KeyType>
|
||||
GLuint PixelBufferContainer<KeyType>::idOfMappedBuffer(KeyType key) {
|
||||
const typename std::map<KeyType, int>::const_iterator iter = _indexMap.find(key);
|
||||
if (iter != _indexMap.end()) { // Found a mapped pixel buffer
|
||||
int index = iter->second; // Index where the mapped buffer is stored
|
||||
return *_pixelBuffers[index];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -1,121 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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/other/statscollector.h>
|
||||
|
||||
#include <ghoul/misc/assert.h>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
StatsCollector::StatsCollector(std::string filename, int dumpEveryXRecord,
|
||||
Enabled enabled, std::string delimiter)
|
||||
: i(TemplatedStatsCollector<long long>(
|
||||
TemplatedStatsCollector<long long>::Enabled(enabled),
|
||||
delimiter
|
||||
))
|
||||
, d(TemplatedStatsCollector<double>(
|
||||
TemplatedStatsCollector<double>::Enabled(enabled),
|
||||
delimiter
|
||||
))
|
||||
, _filename(std::move(filename))
|
||||
, _delimiter(std::move(delimiter))
|
||||
, _dumpEveryXRecord(dumpEveryXRecord)
|
||||
{
|
||||
}
|
||||
|
||||
StatsCollector::~StatsCollector() {
|
||||
dumpToDisk();
|
||||
}
|
||||
|
||||
void StatsCollector::startNewRecord() {
|
||||
ghoul_assert(i.enabled() == d.enabled(), "Both Statscollector have to be synced");
|
||||
|
||||
if (i.enabled()) {
|
||||
if (_dumpEveryXRecord && (++_recordsSinceLastDump >= _dumpEveryXRecord)) {
|
||||
dumpToDisk();
|
||||
_recordsSinceLastDump = 0;
|
||||
}
|
||||
|
||||
i.startNewRecord();
|
||||
d.startNewRecord();
|
||||
}
|
||||
}
|
||||
|
||||
void StatsCollector::setEnabled(bool enabled) {
|
||||
i.setEnabled(enabled);
|
||||
d.setEnabled(enabled);
|
||||
}
|
||||
|
||||
int StatsCollector::hasHeaders() {
|
||||
return i.hasHeaders() || d.hasHeaders();
|
||||
}
|
||||
|
||||
void StatsCollector::dumpToDisk() {
|
||||
ghoul_assert(i.enabled() == d.enabled(), "Both Statscollector have to be synced");
|
||||
|
||||
if (i.enabled() && hasHeaders()) {
|
||||
if (!_hasWrittenHeader) {
|
||||
writeHeader();
|
||||
}
|
||||
writeData();
|
||||
}
|
||||
}
|
||||
|
||||
void StatsCollector::writeHeader() {
|
||||
std::ofstream ofs(_filename);
|
||||
if (i.hasHeaders()) {
|
||||
i.writeHeader(ofs);
|
||||
if (d.hasHeaders()) {
|
||||
ofs << _delimiter;
|
||||
d.writeHeader(ofs);
|
||||
}
|
||||
}
|
||||
else {
|
||||
d.writeHeader(ofs);
|
||||
}
|
||||
_hasWrittenHeader = true;
|
||||
ofs << std::endl;
|
||||
ofs.close();
|
||||
}
|
||||
|
||||
void StatsCollector::writeData() {
|
||||
std::ofstream ofs(_filename, std::ofstream::out | std::ofstream::app);
|
||||
ofs << std::setprecision(32);
|
||||
while (i.hasRecordsToWrite() || d.hasRecordsToWrite()) {
|
||||
if (i.hasHeaders() && d.hasHeaders()) {
|
||||
i.writeNextRecord(ofs); ofs << _delimiter; d.writeNextRecord(ofs);
|
||||
}
|
||||
else {
|
||||
i.writeNextRecord(ofs); d.writeNextRecord(ofs);
|
||||
}
|
||||
ofs << std::endl;
|
||||
}
|
||||
i.reset();
|
||||
d.reset();
|
||||
ofs.close();
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -1,73 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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___STATS_COLLECTOR___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___STATS_COLLECTOR___H__
|
||||
|
||||
#include <modules/globebrowsing/other/templatedstatscollector.h>
|
||||
|
||||
#include <ghoul/misc/boolean.h>
|
||||
#include <string>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
class StatsCollector {
|
||||
public:
|
||||
BooleanType(Enabled);
|
||||
|
||||
StatsCollector() = delete;
|
||||
|
||||
StatsCollector(std::string filename, int dumpEveryXRecord,
|
||||
Enabled enabled = Enabled::Yes, std::string delimiter = ",");
|
||||
|
||||
~StatsCollector();
|
||||
|
||||
void startNewRecord();
|
||||
|
||||
void setEnabled(bool enabled);
|
||||
|
||||
int hasHeaders();
|
||||
|
||||
void dumpToDisk();
|
||||
|
||||
TemplatedStatsCollector<long long> i;
|
||||
TemplatedStatsCollector<double> d;
|
||||
|
||||
private:
|
||||
void writeHeader();
|
||||
|
||||
void writeData();
|
||||
|
||||
std::string _filename;
|
||||
std::string _delimiter;
|
||||
|
||||
int _dumpEveryXRecord;
|
||||
int _recordsSinceLastDump = 0;
|
||||
|
||||
bool _hasWrittenHeader = false;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___STATS_COLLECTOR___H__
|
||||
@@ -1,81 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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___TEMPLATED_STATS_COLLECTOR___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___TEMPLATED_STATS_COLLECTOR___H__
|
||||
|
||||
#include <ghoul/misc/boolean.h>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
template <typename T>
|
||||
class TemplatedStatsCollector {
|
||||
public:
|
||||
BooleanType(Enabled);
|
||||
|
||||
TemplatedStatsCollector(Enabled enabled, std::string delimiter);
|
||||
~TemplatedStatsCollector() = default;
|
||||
|
||||
void startNewRecord();
|
||||
|
||||
T& operator[](const std::string& name);
|
||||
T previous(const std::string& name) const;
|
||||
|
||||
void setEnabled(bool enabled);
|
||||
bool enabled() const;
|
||||
|
||||
bool hasHeaders() const;
|
||||
bool hasRecordsToWrite() const;
|
||||
|
||||
void reset();
|
||||
|
||||
void writeHeader(std::ostream& os);
|
||||
void writeNextRecord(std::ostream& os);
|
||||
|
||||
private:
|
||||
template <typename U>
|
||||
using StatsRecord = std::unordered_map<std::string, U>;
|
||||
|
||||
template <typename U>
|
||||
struct StatsCollection : public std::vector<StatsRecord<U>> {
|
||||
std::set<std::string> keys;
|
||||
};
|
||||
|
||||
StatsCollection<T> _data;
|
||||
T _dummy; // used when disabled
|
||||
bool _enabled;
|
||||
|
||||
size_t _writePos = 0;
|
||||
std::string _delimiter;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#include "templatedstatscollector.inl"
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___TEMPLATED_STATS_COLLECTOR___H__
|
||||
@@ -1,118 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
****************************************************************************************/
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
template <typename T>
|
||||
TemplatedStatsCollector<T>::TemplatedStatsCollector(Enabled enabled,
|
||||
std::string delimiter)
|
||||
: _enabled(enabled)
|
||||
, _delimiter(std::move(delimiter))
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
void TemplatedStatsCollector<T>::startNewRecord() {
|
||||
if (_enabled) {
|
||||
_data.push_back(StatsRecord<T>());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T& TemplatedStatsCollector<T>::operator[](const std::string& name) {
|
||||
if (_enabled) {
|
||||
_data.keys.insert(name);
|
||||
return _data.back()[name];
|
||||
}
|
||||
else {
|
||||
return _dummy;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T TemplatedStatsCollector<T>::previous(const std::string& name) const {
|
||||
if (_data.size() > 1) {
|
||||
return _data[_data.size() - 2][name];
|
||||
}
|
||||
return T();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void TemplatedStatsCollector<T>::setEnabled(bool enabled) {
|
||||
_enabled = enabled;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool TemplatedStatsCollector<T>::enabled() const {
|
||||
return _enabled;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool TemplatedStatsCollector<T>::hasHeaders() const {
|
||||
return !_data.keys.empty();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool TemplatedStatsCollector<T>::hasRecordsToWrite() const {
|
||||
return _writePos < (_data.size() - 1);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void TemplatedStatsCollector<T>::reset() {
|
||||
// copy last, i.e. current record
|
||||
StatsRecord<T> lastRecord = _data.back();
|
||||
_data.clear();
|
||||
// add it again after cleared the vector
|
||||
_data.push_back(std::move(lastRecord));
|
||||
_writePos = 0;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void TemplatedStatsCollector<T>::writeHeader(std::ostream& os) {
|
||||
auto keyIt = _data.keys.begin();
|
||||
os << *keyIt;
|
||||
while (++keyIt != _data.keys.end()) {
|
||||
os << _delimiter << *keyIt;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void TemplatedStatsCollector<T>::writeNextRecord(std::ostream& os) {
|
||||
if (hasRecordsToWrite()) {
|
||||
// output line by line
|
||||
StatsRecord<T>& record = _data[_writePos];
|
||||
|
||||
// Access every key. Records with no entry will get a default value
|
||||
auto keyIt = _data.keys.begin();
|
||||
if (keyIt != _data.keys.end()) {
|
||||
os << record[(*keyIt)];
|
||||
while (++keyIt != _data.keys.end()) {
|
||||
os << _delimiter << record[(*keyIt)];
|
||||
}
|
||||
}
|
||||
|
||||
_writePos++;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -1,547 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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/rendering/chunkrenderer.h>
|
||||
|
||||
#include <modules/globebrowsing/chunk/chunk.h>
|
||||
#include <modules/globebrowsing/geometry/ellipsoid.h>
|
||||
#include <modules/globebrowsing/globes/renderableglobe.h>
|
||||
#include <modules/globebrowsing/meshes/grid.h>
|
||||
#include <modules/globebrowsing/meshes/trianglesoup.h>
|
||||
#include <modules/globebrowsing/rendering/layershadermanager.h>
|
||||
#include <modules/globebrowsing/rendering/layer/layermanager.h>
|
||||
#include <modules/globebrowsing/rendering/gpu/gpulayergroup.h>
|
||||
#include <modules/globebrowsing/rendering/gpu/gpulayermanager.h>
|
||||
#include <modules/globebrowsing/rendering/layer/layergroup.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
#include <openspace/util/spicemanager.h>
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
|
||||
namespace {
|
||||
constexpr const double KM_TO_M = 1000.0;
|
||||
} // namespace
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
ChunkRenderer::ChunkRenderer(std::shared_ptr<Grid> grid,
|
||||
std::shared_ptr<LayerManager> layerManager,
|
||||
Ellipsoid& ellipsoid)
|
||||
: _grid(std::move(grid))
|
||||
, _layerManager(std::move(layerManager))
|
||||
, _ellipsoid(ellipsoid)
|
||||
{
|
||||
_globalLayerShaderManager = std::make_shared<LayerShaderManager>(
|
||||
"GlobalChunkedLodPatch",
|
||||
"${MODULE_GLOBEBROWSING}/shaders/globalchunkedlodpatch_vs.glsl",
|
||||
"${MODULE_GLOBEBROWSING}/shaders/globalchunkedlodpatch_fs.glsl"
|
||||
);
|
||||
|
||||
_localLayerShaderManager = std::make_shared<LayerShaderManager>(
|
||||
"LocalChunkedLodPatch",
|
||||
"${MODULE_GLOBEBROWSING}/shaders/localchunkedlodpatch_vs.glsl",
|
||||
"${MODULE_GLOBEBROWSING}/shaders/localchunkedlodpatch_fs.glsl"
|
||||
);
|
||||
|
||||
_globalGpuLayerManager = std::make_shared<GPULayerManager>();
|
||||
_localGpuLayerManager = std::make_shared<GPULayerManager>();
|
||||
}
|
||||
|
||||
ChunkRenderer::~ChunkRenderer() {} // NOLINT
|
||||
|
||||
void ChunkRenderer::renderChunk(const Chunk& chunk, const RenderData& data) {
|
||||
// A little arbitrary with 10 but it works
|
||||
if (chunk.tileIndex().level <
|
||||
chunk.owner().debugProperties().modelSpaceRenderingCutoffLevel)
|
||||
{
|
||||
renderChunkGlobally(chunk, data);
|
||||
}
|
||||
else {
|
||||
renderChunkLocally(chunk, data);
|
||||
}
|
||||
}
|
||||
|
||||
void ChunkRenderer::update() {
|
||||
// unused atm. Could be used for caching or precalculating
|
||||
}
|
||||
|
||||
void ChunkRenderer::recompileShaders(const RenderableGlobe& globe) {
|
||||
LayerShaderManager::LayerShaderPreprocessingData preprocessingData =
|
||||
LayerShaderManager::LayerShaderPreprocessingData::get(globe);
|
||||
_globalLayerShaderManager->recompileShaderProgram(preprocessingData);
|
||||
_localLayerShaderManager->recompileShaderProgram(preprocessingData);
|
||||
}
|
||||
|
||||
ghoul::opengl::ProgramObject* ChunkRenderer::getActivatedProgramWithTileData(
|
||||
LayerShaderManager& layeredShaderManager,
|
||||
GPULayerManager& gpuLayerManager,
|
||||
const Chunk& chunk)
|
||||
{
|
||||
const TileIndex& tileIndex = chunk.tileIndex();
|
||||
|
||||
// Now the shader program can be accessed
|
||||
ghoul::opengl::ProgramObject* programObject = layeredShaderManager.programObject();
|
||||
|
||||
if (layeredShaderManager.updatedSinceLastCall()) {
|
||||
gpuLayerManager.bind(programObject, *_layerManager);
|
||||
}
|
||||
|
||||
// Activate the shader program
|
||||
programObject->activate();
|
||||
|
||||
gpuLayerManager.setValue(programObject, *_layerManager, tileIndex);
|
||||
|
||||
// The length of the skirts is proportional to its size
|
||||
programObject->setUniform(
|
||||
"skirtLength",
|
||||
static_cast<float>(
|
||||
glm::min(
|
||||
chunk.surfacePatch().halfSize().lat * 1000000,
|
||||
_ellipsoid.minimumRadius()
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
//programObject->setUniform("skirtLength",
|
||||
// glm::min(static_cast<float>(chunk.surfacePatch().halfSize().lat * 1000000),
|
||||
// 8700.0f));
|
||||
|
||||
programObject->setUniform("xSegments", _grid->xSegments());
|
||||
|
||||
if (chunk.owner().debugProperties().showHeightResolution) {
|
||||
programObject->setUniform(
|
||||
"vertexResolution",
|
||||
glm::vec2(_grid->xSegments(), _grid->ySegments())
|
||||
);
|
||||
}
|
||||
|
||||
return programObject;
|
||||
}
|
||||
|
||||
void ChunkRenderer::calculateEclipseShadows(const Chunk& chunk,
|
||||
ghoul::opengl::ProgramObject* programObject,
|
||||
const RenderData& data)
|
||||
{
|
||||
// Shadow calculations..
|
||||
if (chunk.owner().ellipsoid().hasEclipseShadows()) {
|
||||
std::vector<RenderableGlobe::ShadowRenderingStruct> shadowDataArray;
|
||||
std::vector<Ellipsoid::ShadowConfiguration> shadowConfArray =
|
||||
chunk.owner().ellipsoid().shadowConfigurationArray();
|
||||
shadowDataArray.reserve(shadowConfArray.size());
|
||||
double lt;
|
||||
for (const auto & shadowConf : shadowConfArray) {
|
||||
// TO REMEMBER: all distances and lengths in world coordinates are in
|
||||
// meters!!! We need to move this to view space...
|
||||
// Getting source and caster:
|
||||
glm::dvec3 sourcePos = SpiceManager::ref().targetPosition(
|
||||
shadowConf.source.first,
|
||||
"SUN",
|
||||
"GALACTIC",
|
||||
{},
|
||||
data.time.j2000Seconds(),
|
||||
lt
|
||||
);
|
||||
sourcePos *= KM_TO_M; // converting to meters
|
||||
glm::dvec3 casterPos = SpiceManager::ref().targetPosition(
|
||||
shadowConf.caster.first,
|
||||
"SUN",
|
||||
"GALACTIC",
|
||||
{},
|
||||
data.time.j2000Seconds(),
|
||||
lt
|
||||
);
|
||||
casterPos *= KM_TO_M; // converting to meters
|
||||
// psc caster_pos = PowerScaledCoordinate::CreatePowerScaledCoordinate(
|
||||
// casterPos.x,
|
||||
// casterPos.y,
|
||||
// casterPos.z
|
||||
// );
|
||||
|
||||
|
||||
// First we determine if the caster is shadowing the current planet (all
|
||||
// calculations in World Coordinates):
|
||||
const glm::dvec3 planetCasterVec = casterPos - data.position.dvec3();
|
||||
const glm::dvec3 sourceCasterVec = casterPos - sourcePos;
|
||||
const double sc_length = glm::length(sourceCasterVec);
|
||||
const glm::dvec3 planetCaster_proj =
|
||||
(glm::dot(planetCasterVec, sourceCasterVec) / (sc_length*sc_length)) *
|
||||
sourceCasterVec;
|
||||
const double d_test = glm::length(planetCasterVec - planetCaster_proj);
|
||||
const double xp_test = shadowConf.caster.second * sc_length /
|
||||
(shadowConf.source.second + shadowConf.caster.second);
|
||||
const double rp_test = shadowConf.caster.second *
|
||||
(glm::length(planetCaster_proj) + xp_test) / xp_test;
|
||||
|
||||
const glm::dvec3 sunPos = SpiceManager::ref().targetPosition(
|
||||
"SUN",
|
||||
"SUN",
|
||||
"GALACTIC",
|
||||
{},
|
||||
data.time.j2000Seconds(),
|
||||
lt
|
||||
);
|
||||
const double casterDistSun = glm::length(casterPos - sunPos);
|
||||
const double planetDistSun = glm::length(data.position.dvec3() - sunPos);
|
||||
|
||||
RenderableGlobe::ShadowRenderingStruct shadowData;
|
||||
shadowData.isShadowing = false;
|
||||
|
||||
// Eclipse shadows considers planets and moons as spheres
|
||||
if (((d_test - rp_test) < (chunk.owner().ellipsoid().radii().x * KM_TO_M)) &&
|
||||
(casterDistSun < planetDistSun))
|
||||
{
|
||||
// The current caster is shadowing the current planet
|
||||
shadowData.isShadowing = true;
|
||||
shadowData.rs = shadowConf.source.second;
|
||||
shadowData.rc = shadowConf.caster.second;
|
||||
shadowData.sourceCasterVec = glm::normalize(sourceCasterVec);
|
||||
shadowData.xp = xp_test;
|
||||
shadowData.xu = shadowData.rc * sc_length /
|
||||
(shadowData.rs - shadowData.rc);
|
||||
shadowData.casterPositionVec = casterPos;
|
||||
}
|
||||
shadowDataArray.push_back(shadowData);
|
||||
}
|
||||
|
||||
const std::string uniformVarName("shadowDataArray[");
|
||||
unsigned int counter = 0;
|
||||
for (const RenderableGlobe::ShadowRenderingStruct& sd : shadowDataArray) {
|
||||
constexpr const char* NameIsShadowing = "shadowDataArray[{}].isShadowing";
|
||||
constexpr const char* NameXp = "shadowDataArray[{}].xp";
|
||||
constexpr const char* NameXu = "shadowDataArray[{}].xu";
|
||||
constexpr const char* NameRc = "shadowDataArray[{}].rc";
|
||||
constexpr const char* NameSource = "shadowDataArray[{}].sourceCasterVec";
|
||||
constexpr const char* NamePos= "shadowDataArray[{}].casterPositionVec";
|
||||
|
||||
programObject->setUniform(
|
||||
fmt::format(NameIsShadowing, counter), sd.isShadowing
|
||||
);
|
||||
if (sd.isShadowing) {
|
||||
programObject->setUniform(fmt::format(NameXp, counter), sd.xp);
|
||||
programObject->setUniform(fmt::format(NameXu, counter), sd.xu);
|
||||
programObject->setUniform(fmt::format(NameRc, counter), sd.rc);
|
||||
programObject->setUniform(
|
||||
fmt::format(NameSource, counter), sd.sourceCasterVec
|
||||
);
|
||||
programObject->setUniform(
|
||||
fmt::format(NamePos, counter), sd.casterPositionVec
|
||||
);
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
|
||||
programObject->setUniform(
|
||||
"inverseViewTransform",
|
||||
glm::inverse(data.camera.combinedViewMatrix())
|
||||
);
|
||||
programObject->setUniform("modelTransform", chunk.owner().modelTransform());
|
||||
programObject->setUniform(
|
||||
"hardShadows",
|
||||
chunk.owner().generalProperties().eclipseHardShadows
|
||||
);
|
||||
programObject->setUniform("calculateEclipseShadows", true);
|
||||
}
|
||||
}
|
||||
|
||||
void ChunkRenderer::setCommonUniforms(ghoul::opengl::ProgramObject& programObject,
|
||||
const Chunk& chunk, const RenderData& data)
|
||||
{
|
||||
const glm::dmat4 modelTransform = chunk.owner().modelTransform();
|
||||
const glm::dmat4 viewTransform = data.camera.combinedViewMatrix();
|
||||
const glm::dmat4 modelViewTransform = viewTransform * modelTransform;
|
||||
|
||||
const bool nightLayersActive =
|
||||
!_layerManager->layerGroup(layergroupid::NightLayers).activeLayers().empty();
|
||||
const bool waterLayersActive =
|
||||
!_layerManager->layerGroup(layergroupid::WaterMasks).activeLayers().empty();
|
||||
|
||||
if (nightLayersActive || waterLayersActive ||
|
||||
chunk.owner().generalProperties().atmosphereEnabled ||
|
||||
chunk.owner().generalProperties().performShading)
|
||||
{
|
||||
const glm::dvec3 directionToSunWorldSpace =
|
||||
length(data.modelTransform.translation) > 0.0 ?
|
||||
glm::normalize(-data.modelTransform.translation) :
|
||||
glm::dvec3(0.0);
|
||||
|
||||
const glm::vec3 directionToSunCameraSpace = glm::vec3(viewTransform *
|
||||
glm::dvec4(directionToSunWorldSpace, 0));
|
||||
programObject.setUniform(
|
||||
"lightDirectionCameraSpace",
|
||||
-glm::normalize(directionToSunCameraSpace)
|
||||
);
|
||||
}
|
||||
|
||||
if (chunk.owner().generalProperties().performShading) {
|
||||
programObject.setUniform(
|
||||
"orenNayarRoughness",
|
||||
chunk.owner().generalProperties().orenNayarRoughness);
|
||||
}
|
||||
|
||||
if (chunk.owner().generalProperties().useAccurateNormals &&
|
||||
!_layerManager->layerGroup(layergroupid::HeightLayers).activeLayers().empty())
|
||||
{
|
||||
const glm::dvec3 corner00 = chunk.owner().ellipsoid().cartesianSurfacePosition(
|
||||
chunk.surfacePatch().corner(Quad::SOUTH_WEST)
|
||||
);
|
||||
const glm::dvec3 corner10 = chunk.owner().ellipsoid().cartesianSurfacePosition(
|
||||
chunk.surfacePatch().corner(Quad::SOUTH_EAST)
|
||||
);
|
||||
const glm::dvec3 corner01 = chunk.owner().ellipsoid().cartesianSurfacePosition(
|
||||
chunk.surfacePatch().corner(Quad::NORTH_WEST)
|
||||
);
|
||||
const glm::dvec3 corner11 = chunk.owner().ellipsoid().cartesianSurfacePosition(
|
||||
chunk.surfacePatch().corner(Quad::NORTH_EAST)
|
||||
);
|
||||
|
||||
// This is an assumption that the height tile has a resolution of 64 * 64
|
||||
// If it does not it will still produce "correct" normals. If the resolution is
|
||||
// higher the shadows will be softer, if it is lower, pixels will be visible.
|
||||
// Since default is 64 this will most likely work fine.
|
||||
|
||||
const glm::mat3& modelViewTransformMat3 = glm::mat3(modelViewTransform);
|
||||
|
||||
constexpr const float TileDelta = 1.f / 64.f;
|
||||
const glm::vec3 deltaTheta0 = modelViewTransformMat3 *
|
||||
(glm::vec3(corner10 - corner00) * TileDelta);
|
||||
const glm::vec3 deltaTheta1 = modelViewTransformMat3 *
|
||||
(glm::vec3(corner11 - corner01) * TileDelta);
|
||||
const glm::vec3 deltaPhi0 = modelViewTransformMat3 *
|
||||
(glm::vec3(corner01 - corner00) * TileDelta);
|
||||
const glm::vec3 deltaPhi1 = modelViewTransformMat3 *
|
||||
(glm::vec3(corner11 - corner10) * TileDelta);
|
||||
|
||||
// Upload uniforms
|
||||
programObject.setUniform("deltaTheta0", glm::length(deltaTheta0));
|
||||
programObject.setUniform("deltaTheta1", glm::length(deltaTheta1));
|
||||
programObject.setUniform("deltaPhi0", glm::length(deltaPhi0));
|
||||
programObject.setUniform("deltaPhi1", glm::length(deltaPhi1));
|
||||
programObject.setUniform("tileDelta", TileDelta);
|
||||
// This should not be needed once the light calculations for the atmosphere
|
||||
// is performed in view space..
|
||||
programObject.setUniform(
|
||||
"invViewModelTransform",
|
||||
glm::inverse(
|
||||
glm::mat4(data.camera.combinedViewMatrix()) *
|
||||
glm::mat4(chunk.owner().modelTransform())
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void ChunkRenderer::renderChunkGlobally(const Chunk& chunk, const RenderData& data) {
|
||||
ghoul::opengl::ProgramObject* programObject = getActivatedProgramWithTileData(
|
||||
*_globalLayerShaderManager,
|
||||
*_globalGpuLayerManager,
|
||||
chunk
|
||||
);
|
||||
if (!programObject) {
|
||||
return;
|
||||
}
|
||||
|
||||
const Ellipsoid& ellipsoid = chunk.owner().ellipsoid();
|
||||
|
||||
if (_layerManager->hasAnyBlendingLayersEnabled()) {
|
||||
// Calculations are done in the reference frame of the globe. Hence, the
|
||||
// camera position needs to be transformed with the inverse model matrix
|
||||
const glm::dmat4 inverseModelTransform = chunk.owner().inverseModelTransform();
|
||||
const glm::dvec3 cameraPosition = glm::dvec3(
|
||||
inverseModelTransform * glm::dvec4(data.camera.positionVec3(), 1.0)
|
||||
);
|
||||
const float distanceScaleFactor = static_cast<float>(
|
||||
chunk.owner().generalProperties().lodScaleFactor * ellipsoid.minimumRadius()
|
||||
);
|
||||
programObject->setUniform("cameraPosition", glm::vec3(cameraPosition));
|
||||
programObject->setUniform("distanceScaleFactor", distanceScaleFactor);
|
||||
programObject->setUniform("chunkLevel", chunk.tileIndex().level);
|
||||
}
|
||||
|
||||
// Calculate other uniform variables needed for rendering
|
||||
const Geodetic2 swCorner = chunk.surfacePatch().corner(Quad::SOUTH_WEST);
|
||||
const Geodetic2& patchSize = chunk.surfacePatch().size();
|
||||
|
||||
const glm::dmat4 modelTransform = chunk.owner().modelTransform();
|
||||
const glm::dmat4 viewTransform = data.camera.combinedViewMatrix();
|
||||
const glm::mat4 modelViewTransform = glm::mat4(viewTransform * modelTransform);
|
||||
const glm::mat4 modelViewProjectionTransform =
|
||||
data.camera.sgctInternal.projectionMatrix() * modelViewTransform;
|
||||
|
||||
// Upload the uniform variables
|
||||
programObject->setUniform(
|
||||
"modelViewProjectionTransform",
|
||||
modelViewProjectionTransform
|
||||
);
|
||||
programObject->setUniform("minLatLon", glm::vec2(swCorner.toLonLatVec2()));
|
||||
programObject->setUniform("lonLatScalingFactor", glm::vec2(patchSize.toLonLatVec2()));
|
||||
// Ellipsoid Radius (Model Space)
|
||||
programObject->setUniform("radiiSquared", glm::vec3(ellipsoid.radiiSquared()));
|
||||
|
||||
const bool hasNightLayers = !_layerManager->layerGroup(
|
||||
layergroupid::GroupID::NightLayers
|
||||
).activeLayers().empty();
|
||||
|
||||
const bool hasWaterLayer = !_layerManager->layerGroup(
|
||||
layergroupid::GroupID::WaterMasks
|
||||
).activeLayers().empty();
|
||||
|
||||
const bool hasHeightLayer = !_layerManager->layerGroup(
|
||||
layergroupid::HeightLayers
|
||||
).activeLayers().empty();
|
||||
|
||||
if (hasNightLayers || hasWaterLayer ||
|
||||
chunk.owner().generalProperties().atmosphereEnabled ||
|
||||
chunk.owner().generalProperties().performShading)
|
||||
{
|
||||
programObject->setUniform("modelViewTransform", modelViewTransform);
|
||||
}
|
||||
|
||||
if (chunk.owner().generalProperties().useAccurateNormals && hasHeightLayer) {
|
||||
// Apply an extra scaling to the height if the object is scaled
|
||||
programObject->setUniform(
|
||||
"heightScale",
|
||||
static_cast<float>(data.modelTransform.scale * data.camera.scaling())
|
||||
);
|
||||
}
|
||||
|
||||
setCommonUniforms(*programObject, chunk, data);
|
||||
|
||||
if (chunk.owner().ellipsoid().hasEclipseShadows()) {
|
||||
calculateEclipseShadows(chunk, programObject, data);
|
||||
}
|
||||
|
||||
// OpenGL rendering settings
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(GL_BACK);
|
||||
|
||||
// render
|
||||
_grid->geometry().drawUsingActiveProgram();
|
||||
|
||||
_globalGpuLayerManager->deactivate();
|
||||
|
||||
// disable shader
|
||||
programObject->deactivate();
|
||||
}
|
||||
|
||||
void ChunkRenderer::renderChunkLocally(const Chunk& chunk, const RenderData& data) {
|
||||
ghoul::opengl::ProgramObject* programObject = getActivatedProgramWithTileData(
|
||||
*_localLayerShaderManager,
|
||||
*_localGpuLayerManager,
|
||||
chunk
|
||||
);
|
||||
if (!programObject) {
|
||||
return;
|
||||
}
|
||||
|
||||
const Ellipsoid& ellipsoid = chunk.owner().ellipsoid();
|
||||
|
||||
if (_layerManager->hasAnyBlendingLayersEnabled()) {
|
||||
float distanceScaleFactor = static_cast<float>(
|
||||
chunk.owner().generalProperties().lodScaleFactor *
|
||||
chunk.owner().ellipsoid().minimumRadius()
|
||||
);
|
||||
|
||||
programObject->setUniform("distanceScaleFactor", distanceScaleFactor);
|
||||
programObject->setUniform("chunkLevel", chunk.tileIndex().level);
|
||||
}
|
||||
|
||||
// Calculate other uniform variables needed for rendering
|
||||
// Send the matrix inverse to the fragment for the global and local shader (JCC)
|
||||
const glm::dmat4 modelTransform = chunk.owner().modelTransform();
|
||||
const glm::dmat4 viewTransform = data.camera.combinedViewMatrix();
|
||||
const glm::dmat4 modelViewTransform = viewTransform * modelTransform;
|
||||
|
||||
|
||||
std::array<glm::dvec3, 4> cornersCameraSpace;
|
||||
std::array<glm::dvec3, 4> cornersModelSpace;
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
constexpr const std::array<const char*, 4> CornerNames = {
|
||||
"p01", "p11", "p00", "p10"
|
||||
};
|
||||
|
||||
const Quad q = static_cast<Quad>(i);
|
||||
const Geodetic2 corner = chunk.surfacePatch().corner(q);
|
||||
const glm::dvec3 cornerModelSpace = ellipsoid.cartesianSurfacePosition(corner);
|
||||
cornersModelSpace[i] = cornerModelSpace;
|
||||
const glm::dvec3 cornerCameraSpace = glm::dvec3(
|
||||
modelViewTransform * glm::dvec4(cornerModelSpace, 1)
|
||||
);
|
||||
cornersCameraSpace[i] = cornerCameraSpace;
|
||||
programObject->setUniform(CornerNames[i], glm::vec3(cornerCameraSpace));
|
||||
|
||||
}
|
||||
|
||||
// TODO: Patch normal can be calculated for all corners and then linearly
|
||||
// interpolated on the GPU to avoid cracks for high altitudes.
|
||||
const glm::vec3 patchNormalCameraSpace = normalize(
|
||||
cross(
|
||||
cornersCameraSpace[Quad::SOUTH_EAST] - cornersCameraSpace[Quad::SOUTH_WEST],
|
||||
cornersCameraSpace[Quad::NORTH_EAST] - cornersCameraSpace[Quad::SOUTH_WEST]
|
||||
)
|
||||
);
|
||||
|
||||
// In order to improve performance, lets use the normal in object space (model space)
|
||||
// for deferred rendering.
|
||||
const glm::vec3 patchNormalModelSpace = normalize(
|
||||
cross(
|
||||
cornersModelSpace[Quad::SOUTH_EAST] - cornersModelSpace[Quad::SOUTH_WEST],
|
||||
cornersModelSpace[Quad::NORTH_EAST] - cornersModelSpace[Quad::SOUTH_WEST]
|
||||
)
|
||||
);
|
||||
|
||||
programObject->setUniform("patchNormalModelSpace", patchNormalModelSpace);
|
||||
programObject->setUniform("patchNormalCameraSpace", patchNormalCameraSpace);
|
||||
programObject->setUniform(
|
||||
"projectionTransform",
|
||||
data.camera.sgctInternal.projectionMatrix()
|
||||
);
|
||||
|
||||
if (!_layerManager->layerGroup(layergroupid::HeightLayers).activeLayers().empty()) {
|
||||
// Apply an extra scaling to the height if the object is scaled
|
||||
programObject->setUniform(
|
||||
"heightScale",
|
||||
static_cast<float>(data.modelTransform.scale * data.camera.scaling())
|
||||
);
|
||||
}
|
||||
|
||||
setCommonUniforms(*programObject, chunk, data);
|
||||
|
||||
if (chunk.owner().ellipsoid().hasEclipseShadows()) {
|
||||
calculateEclipseShadows(chunk, programObject, data);
|
||||
}
|
||||
|
||||
// OpenGL rendering settings
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(GL_BACK);
|
||||
|
||||
// render
|
||||
_grid->geometry().drawUsingActiveProgram();
|
||||
|
||||
_localGpuLayerManager->deactivate();
|
||||
|
||||
// disable shader
|
||||
programObject->deactivate();
|
||||
}
|
||||
|
||||
} // namespace openspace:;globebrowsing
|
||||
@@ -1,111 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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___CHUNK_RENDERER___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___CHUNK_RENDERER___H__
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace ghoul::opengl { class ProgramObject; }
|
||||
|
||||
namespace openspace { struct RenderData; }
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
class Chunk;
|
||||
class Ellipsoid;
|
||||
class Grid;
|
||||
class GPULayerManager;
|
||||
class LayerManager;
|
||||
class LayerShaderManager;
|
||||
class RenderableGlobe;
|
||||
|
||||
class ChunkRenderer {
|
||||
public:
|
||||
ChunkRenderer(std::shared_ptr<Grid> grid, std::shared_ptr<LayerManager> layerManager,
|
||||
Ellipsoid& ellipsoid);
|
||||
|
||||
~ChunkRenderer();
|
||||
|
||||
/**
|
||||
* Chooses to render a chunk either locally or globally depending on the chunklevel
|
||||
* of the <code>Chunk</code>.
|
||||
*/
|
||||
void renderChunk(const Chunk& chunk, const RenderData& data);
|
||||
void update();
|
||||
|
||||
void recompileShaders(const RenderableGlobe& globe);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Chunks can be rendered either globally or locally. Global rendering is performed
|
||||
* in the model space of the globe. With global rendering, the vertex positions
|
||||
* of a chunk are calculated in the vertex shader by transforming the geodetic
|
||||
* coordinates of the chunk to model space coordinates. We can only achieve floating
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Local rendering of chunks are done using linear interpolation in camera space.
|
||||
* All four corner points of the chunk are calculated in double precision on the
|
||||
* CPU and transformed to camera space with double precision matrix transforms.
|
||||
* These positions can then be cast to floats and uploaded to the vertex shader.
|
||||
* The vertex shader rendering performs linear interpolation between the four
|
||||
* corner points to get the resulting chunk. This means that there will be an error
|
||||
* due to the curvature of the globe. The smaller the patch is (with higher chunk
|
||||
* 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);
|
||||
|
||||
ghoul::opengl::ProgramObject* getActivatedProgramWithTileData(
|
||||
LayerShaderManager& layeredShaderManager, GPULayerManager& gpuLayerManager,
|
||||
const Chunk& chunk);
|
||||
|
||||
void calculateEclipseShadows(const Chunk& chunk,
|
||||
ghoul::opengl::ProgramObject* programObject, const RenderData& data);
|
||||
|
||||
void setCommonUniforms(ghoul::opengl::ProgramObject& programObject,
|
||||
const Chunk& chunk, const RenderData& data);
|
||||
|
||||
// shared pointer to a grid which can be the same for all rendered chunks.
|
||||
std::shared_ptr<Grid> _grid;
|
||||
std::shared_ptr<LayerManager> _layerManager;
|
||||
|
||||
Ellipsoid& _ellipsoid;
|
||||
|
||||
// Two different shader programs. One for global and one for local rendering.
|
||||
std::shared_ptr<LayerShaderManager> _globalLayerShaderManager;
|
||||
std::shared_ptr<LayerShaderManager> _localLayerShaderManager;
|
||||
|
||||
// Layered texture uniforms are chached in the uniform ID handles.
|
||||
std::shared_ptr<GPULayerManager> _globalGpuLayerManager;
|
||||
std::shared_ptr<GPULayerManager> _localGpuLayerManager;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___CHUNK_RENDERER___H__
|
||||
@@ -1,50 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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/rendering/gpu/gpuchunktile.h>
|
||||
|
||||
#include <modules/globebrowsing/tile/chunktile.h>
|
||||
#include <modules/globebrowsing/tile/tile.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
void GPUChunkTile::setValue(ghoul::opengl::ProgramObject* programObject,
|
||||
const ChunkTile& chunkTile)
|
||||
{
|
||||
gpuTexture.setValue(programObject, chunkTile.tile.texture());
|
||||
gpuTileUvTransform.setValue(programObject, chunkTile.uvTransform);
|
||||
}
|
||||
|
||||
void GPUChunkTile::bind(ghoul::opengl::ProgramObject* programObject,
|
||||
const std::string& nameBase)
|
||||
{
|
||||
gpuTexture.bind(programObject, nameBase + "textureSampler");
|
||||
gpuTileUvTransform.bind(programObject, nameBase + "uvTransform.");
|
||||
}
|
||||
|
||||
void GPUChunkTile::deactivate() {
|
||||
gpuTexture.deactivate();
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -1,73 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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___GPUCHUNKTILE___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___GPUCHUNKTILE___H__
|
||||
|
||||
#include <modules/globebrowsing/rendering/gpu/gputileuvtransform.h>
|
||||
|
||||
#include <openspace/util/gpudata.h>
|
||||
#include <string>
|
||||
|
||||
namespace ghoul::opengl { class ProgramObject; }
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
struct ChunkTile;
|
||||
|
||||
/**
|
||||
* Manages a GPU representation of a <code>ChunkTile</code>
|
||||
*/
|
||||
class GPUChunkTile {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Sets the value of <code>ChunkTile</code> to its corresponding
|
||||
* GPU struct. OBS! Users must ensure bind has been
|
||||
* called before setting using this method.
|
||||
*/
|
||||
void setValue(ghoul::opengl::ProgramObject* programObject,
|
||||
const ChunkTile& chunkTile);
|
||||
|
||||
/**
|
||||
* Binds GLSL variables with identifiers starting with
|
||||
* nameBase within the provided shader program with this object.
|
||||
* After this method has been called, users may invoke setValue.
|
||||
*/
|
||||
void bind(ghoul::opengl::ProgramObject* programObject, const std::string& nameBase);
|
||||
|
||||
/**
|
||||
* Deactivates any <code>TextureUnit</code>s assigned by this object.
|
||||
* This method should be called after the OpenGL draw call.
|
||||
*/
|
||||
void deactivate();
|
||||
|
||||
private:
|
||||
GPUTexture gpuTexture;
|
||||
GPUTileUvTransform gpuTileUvTransform;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___GPUCHUNKTILE___H__
|
||||
@@ -1,59 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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/rendering/gpu/gpuchunktilepile.h>
|
||||
|
||||
#include <openspace/util/gpudata.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
void GPUChunkTilePile::setValue(ghoul::opengl::ProgramObject* programObject,
|
||||
const ChunkTilePile& chunkTilePile)
|
||||
{
|
||||
ghoul_assert(
|
||||
_gpuChunkTiles.size() == chunkTilePile.size(),
|
||||
"GPU and CPU ChunkTilePile must have same size!"
|
||||
);
|
||||
for (size_t i = 0; i < _gpuChunkTiles.size(); ++i) {
|
||||
_gpuChunkTiles[i].setValue(programObject, chunkTilePile[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void GPUChunkTilePile::bind(ghoul::opengl::ProgramObject* programObject,
|
||||
const std::string& nameBase, int pileSize)
|
||||
{
|
||||
_gpuChunkTiles.resize(pileSize);
|
||||
for (size_t i = 0; i < _gpuChunkTiles.size(); ++i) {
|
||||
std::string nameExtension = "chunkTile" + std::to_string(i) + ".";
|
||||
_gpuChunkTiles[i].bind(programObject, nameBase + nameExtension);
|
||||
}
|
||||
}
|
||||
|
||||
void GPUChunkTilePile::deactivate() {
|
||||
for (GPUChunkTile& t : _gpuChunkTiles) {
|
||||
t.deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -1,69 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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___GPUCHUNKTILEPILE___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___GPUCHUNKTILEPILE___H__
|
||||
|
||||
#include <modules/globebrowsing/rendering/gpu/gpuchunktile.h>
|
||||
#include <modules/globebrowsing/tile/chunktile.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace ghoul::opengl { class ProgramObject; }
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
/**
|
||||
* Manages a GPU representation of a <code>ChunkTilePile</code>
|
||||
*/
|
||||
class GPUChunkTilePile {
|
||||
public:
|
||||
/**
|
||||
* Sets the value of <code>ChunkTilePile</code> to its corresponding
|
||||
* GPU struct. OBS! Users must ensure bind has been
|
||||
* called before setting using this method.
|
||||
*/
|
||||
void setValue(ghoul::opengl::ProgramObject* programObject,
|
||||
const ChunkTilePile& chunkTilePile);
|
||||
|
||||
/**
|
||||
* Binds this object with GLSL variables with identifiers starting
|
||||
* with nameBase within the provided shader program.
|
||||
* After this method has been called, users may invoke setValue.
|
||||
*/
|
||||
void bind(ghoul::opengl::ProgramObject* programObject, const std::string& nameBase,
|
||||
int pileSize);
|
||||
/**
|
||||
* Deactivates any <code>TextureUnit</code>s assigned by this object.
|
||||
* This method should be called after the OpenGL draw call.
|
||||
*/
|
||||
void deactivate();
|
||||
|
||||
private:
|
||||
std::vector<GPUChunkTile> _gpuChunkTiles;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___GPUCHUNKTILEPILE___H__
|
||||
@@ -1,47 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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/rendering/gpu/gpuheightlayer.h>
|
||||
|
||||
#include <modules/globebrowsing/rendering/layer/layer.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
void GPUHeightLayer::setValue(ghoul::opengl::ProgramObject* programObject,
|
||||
const Layer& layer, const TileIndex& tileIndex,
|
||||
int pileSize)
|
||||
{
|
||||
GPULayer::setValue(programObject, layer, tileIndex, pileSize);
|
||||
_gpuDepthTransform.setValue(programObject, layer.depthTransform());
|
||||
}
|
||||
|
||||
void GPUHeightLayer::bind(ghoul::opengl::ProgramObject* programObject, const Layer& layer,
|
||||
const std::string& nameBase, int pileSize)
|
||||
{
|
||||
GPULayer::bind(programObject, layer, nameBase, pileSize);
|
||||
_gpuDepthTransform.bind(programObject, nameBase + "depthTransform.");
|
||||
}
|
||||
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -1,70 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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___GPUHEIGHTLAYER___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___GPUHEIGHTLAYER___H__
|
||||
|
||||
#include <modules/globebrowsing/rendering/gpu/gpulayer.h>
|
||||
|
||||
#include <modules/globebrowsing/rendering/gpu/gputiledepthtransform.h>
|
||||
#include <string>
|
||||
|
||||
namespace ghoul::opengl { class ProgramObject; }
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
class Layer;
|
||||
struct TileIndex;
|
||||
|
||||
/**
|
||||
* Manages a GPU representation of a <code>Layer</code> representing
|
||||
* a height map.
|
||||
*/
|
||||
class GPUHeightLayer : public GPULayer {
|
||||
public:
|
||||
virtual ~GPUHeightLayer() override = default;
|
||||
|
||||
/**
|
||||
* Sets the value of <code>Layer</code> to its corresponding
|
||||
* GPU struct. OBS! Users must ensure bind has been
|
||||
* called before setting using this method.
|
||||
*/
|
||||
virtual void setValue(ghoul::opengl::ProgramObject* programObject, const Layer& layer,
|
||||
const TileIndex& tileIndex, int pileSize) override;
|
||||
|
||||
/**
|
||||
* Binds this object with GLSL variables with identifiers starting
|
||||
* with nameBase within the provided shader program.
|
||||
* After this method has been called, users may invoke setValue.
|
||||
*/
|
||||
virtual void bind(ghoul::opengl::ProgramObject* programObject, const Layer& layer,
|
||||
const std::string& nameBase, int pileSize) override;
|
||||
|
||||
private:
|
||||
GPUTileDepthTransform _gpuDepthTransform;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___GPUHEIGHTLAYER___H__
|
||||
@@ -1,102 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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/rendering/gpu/gpulayer.h>
|
||||
|
||||
#include <modules/globebrowsing/rendering/layer/layer.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
void GPULayer::setValue(ghoul::opengl::ProgramObject* programObject, const Layer& layer,
|
||||
const TileIndex& tileIndex, int pileSize)
|
||||
{
|
||||
gpuRenderSettings.setValue(programObject, layer.renderSettings());
|
||||
gpuLayerAdjustment.setValue(programObject, layer.layerAdjustment());
|
||||
|
||||
switch (layer.type()) {
|
||||
// Intentional fall through. Same for all tile layers
|
||||
case layergroupid::TypeID::DefaultTileLayer:
|
||||
case layergroupid::TypeID::SingleImageTileLayer:
|
||||
case layergroupid::TypeID::SizeReferenceTileLayer:
|
||||
case layergroupid::TypeID::TemporalTileLayer:
|
||||
case layergroupid::TypeID::TileIndexTileLayer:
|
||||
case layergroupid::TypeID::ByIndexTileLayer:
|
||||
case layergroupid::TypeID::ByLevelTileLayer: {
|
||||
ChunkTilePile chunkTilePile = layer.chunkTilePile(tileIndex, pileSize);
|
||||
gpuChunkTilePile.setValue(programObject, chunkTilePile);
|
||||
paddingStartOffset.setValue(programObject, layer.tilePixelStartOffset());
|
||||
paddingSizeDifference.setValue(
|
||||
programObject,
|
||||
layer.tilePixelSizeDifference()
|
||||
);
|
||||
break;
|
||||
}
|
||||
case layergroupid::TypeID::SolidColor:
|
||||
gpuColor.setValue(programObject, layer.otherTypesProperties().color.value());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GPULayer::bind(ghoul::opengl::ProgramObject* programObject, const Layer& layer,
|
||||
const std::string& nameBase, int pileSize)
|
||||
{
|
||||
gpuRenderSettings.bind(layer.renderSettings(), programObject, nameBase + "settings.");
|
||||
gpuLayerAdjustment.bind(
|
||||
layer.layerAdjustment(),
|
||||
programObject,
|
||||
nameBase + "adjustment."
|
||||
);
|
||||
|
||||
switch (layer.type()) {
|
||||
// Intentional fall through. Same for all tile layers
|
||||
case layergroupid::TypeID::DefaultTileLayer:
|
||||
case layergroupid::TypeID::SingleImageTileLayer:
|
||||
case layergroupid::TypeID::SizeReferenceTileLayer:
|
||||
case layergroupid::TypeID::TemporalTileLayer:
|
||||
case layergroupid::TypeID::TileIndexTileLayer:
|
||||
case layergroupid::TypeID::ByIndexTileLayer:
|
||||
case layergroupid::TypeID::ByLevelTileLayer: {
|
||||
gpuChunkTilePile.bind(programObject, nameBase + "pile.", pileSize);
|
||||
paddingStartOffset.bind(programObject, nameBase + "padding.startOffset");
|
||||
paddingSizeDifference.bind(
|
||||
programObject,
|
||||
nameBase + "padding.sizeDifference"
|
||||
);
|
||||
break;
|
||||
}
|
||||
case layergroupid::TypeID::SolidColor:
|
||||
gpuColor.bind(programObject, nameBase + "color");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GPULayer::deactivate() {
|
||||
gpuChunkTilePile.deactivate();
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -1,83 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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___GPULAYER___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___GPULAYER___H__
|
||||
|
||||
#include <modules/globebrowsing/rendering/gpu/gpuchunktilepile.h>
|
||||
#include <modules/globebrowsing/rendering/gpu/gpulayeradjustment.h>
|
||||
#include <modules/globebrowsing/rendering/gpu/gpulayerrendersettings.h>
|
||||
#include <openspace/util/gpudata.h>
|
||||
#include <string>
|
||||
|
||||
namespace ghoul::opengl { class ProgramObject; }
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
class Layer;
|
||||
struct TileIndex;
|
||||
|
||||
/**
|
||||
* Manages a GPU representation of a <code>Layer</code>
|
||||
*/
|
||||
class GPULayer {
|
||||
public:
|
||||
virtual ~GPULayer() = default;
|
||||
|
||||
/**
|
||||
* Sets the value of <code>Layer</code> to its corresponding
|
||||
* GPU struct. OBS! Users must ensure bind has been
|
||||
* called before setting using this method.
|
||||
*/
|
||||
virtual void setValue(ghoul::opengl::ProgramObject* programObject, const Layer& layer,
|
||||
const TileIndex& tileIndex, int pileSize);
|
||||
|
||||
/**
|
||||
* Binds this object with GLSL variables with identifiers starting
|
||||
* with nameBase within the provided shader program.
|
||||
* After this method has been called, users may invoke setValue.
|
||||
*/
|
||||
virtual void bind(ghoul::opengl::ProgramObject* programObject, const Layer& layer,
|
||||
const std::string& nameBase, int pileSize);
|
||||
|
||||
/**
|
||||
* Deactivates any <code>TextureUnit</code>s assigned by this object.
|
||||
* This method should be called after the OpenGL draw call.
|
||||
*/
|
||||
virtual void deactivate();
|
||||
|
||||
private:
|
||||
GPUChunkTilePile gpuChunkTilePile;
|
||||
GPULayerRenderSettings gpuRenderSettings;
|
||||
GPULayerAdjustment gpuLayerAdjustment;
|
||||
|
||||
GPUData<glm::ivec2> paddingStartOffset;
|
||||
GPUData<glm::ivec2> paddingSizeDifference;
|
||||
// Adjustment layer stuff
|
||||
GPUData<glm::vec3> gpuColor;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___GPULAYER___H__
|
||||
@@ -1,70 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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/rendering/gpu/gpulayeradjustment.h>
|
||||
|
||||
#include <modules/globebrowsing/rendering/layer/layeradjustment.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
void GPULayerAdjustment::setValue(ghoul::opengl::ProgramObject* programObject,
|
||||
const LayerAdjustment& layerAdjustment)
|
||||
{
|
||||
switch (layerAdjustment.type()) {
|
||||
case layergroupid::AdjustmentTypeID::None:
|
||||
break;
|
||||
case layergroupid::AdjustmentTypeID::ChromaKey: {
|
||||
gpuChromaKeyColor.setValue(
|
||||
programObject,
|
||||
layerAdjustment.chromaKeyColor()
|
||||
);
|
||||
gpuChromaKeyTolerance.setValue(
|
||||
programObject,
|
||||
layerAdjustment.chromaKeyTolerance()
|
||||
);
|
||||
break;
|
||||
}
|
||||
case layergroupid::AdjustmentTypeID::TransferFunction:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GPULayerAdjustment::bind(const LayerAdjustment& layerAdjustment,
|
||||
ghoul::opengl::ProgramObject* programObject,
|
||||
const std::string& nameBase)
|
||||
{
|
||||
switch (layerAdjustment.type()) {
|
||||
case layergroupid::AdjustmentTypeID::None:
|
||||
break;
|
||||
case layergroupid::AdjustmentTypeID::ChromaKey: {
|
||||
gpuChromaKeyColor.bind(programObject, nameBase + "chromaKeyColor");
|
||||
gpuChromaKeyTolerance.bind(programObject, nameBase + "chromaKeyTolerance");
|
||||
break;
|
||||
}
|
||||
case layergroupid::AdjustmentTypeID::TransferFunction:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -1,51 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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___GPULAYER_ADJUSTMENT___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___GPULAYER_ADJUSTMENT___H__
|
||||
|
||||
#include <openspace/util/gpudata.h>
|
||||
|
||||
namespace ghoul::opengl { class ProgramObject; }
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
class LayerAdjustment;
|
||||
|
||||
class GPULayerAdjustment{
|
||||
public:
|
||||
void setValue(ghoul::opengl::ProgramObject* programObject,
|
||||
const LayerAdjustment& layerAdjustment);
|
||||
|
||||
void bind(const LayerAdjustment& layerAdjustment,
|
||||
ghoul::opengl::ProgramObject* programObject, const std::string& nameBase);
|
||||
|
||||
private:
|
||||
GPUData<glm::vec3> gpuChromaKeyColor;
|
||||
GPUData<float> gpuChromaKeyTolerance;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___GPULAYER_ADJUSTMENT___H__
|
||||
@@ -1,81 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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/rendering/gpu/gpulayergroup.h>
|
||||
|
||||
#include <modules/globebrowsing/rendering/layer/layergroup.h>
|
||||
#include <modules/globebrowsing/rendering/layer/layermanager.h>
|
||||
#include <modules/globebrowsing/rendering/gpu/gpuheightlayer.h>
|
||||
#include <modules/globebrowsing/rendering/gpu/gpulayer.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
GPULayerGroup::~GPULayerGroup() {} // NOLINT
|
||||
|
||||
void GPULayerGroup::setValue(ghoul::opengl::ProgramObject* programObject,
|
||||
const LayerGroup& layerGroup, const TileIndex& tileIndex)
|
||||
{
|
||||
auto& activeLayers = layerGroup.activeLayers();
|
||||
ghoul_assert(
|
||||
activeLayers.size() == _gpuActiveLayers.size(),
|
||||
"GPU and CPU active layers must have same size!"
|
||||
);
|
||||
for (unsigned int i = 0; i < activeLayers.size(); ++i) {
|
||||
_gpuActiveLayers[i]->setValue(
|
||||
programObject,
|
||||
*activeLayers[i],
|
||||
tileIndex,
|
||||
layerGroup.pileSize()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void GPULayerGroup::bind(ghoul::opengl::ProgramObject* programObject,
|
||||
const LayerGroup& layerGroup, const std::string& nameBase,
|
||||
int category)
|
||||
{
|
||||
const std::vector<std::shared_ptr<Layer>>& activeLayers = layerGroup.activeLayers();
|
||||
_gpuActiveLayers.resize(activeLayers.size());
|
||||
const int pileSize = layerGroup.pileSize();
|
||||
for (size_t i = 0; i < _gpuActiveLayers.size(); ++i) {
|
||||
// should maybe a proper GPULayer factory
|
||||
_gpuActiveLayers[i] = (category == layergroupid::GroupID::HeightLayers) ?
|
||||
std::make_unique<GPUHeightLayer>() :
|
||||
std::make_unique<GPULayer>();
|
||||
_gpuActiveLayers[i]->bind(
|
||||
programObject,
|
||||
*activeLayers[i],
|
||||
nameBase + "[" + std::to_string(i) + "].",
|
||||
pileSize
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void GPULayerGroup::deactivate() {
|
||||
for (std::unique_ptr<GPULayer>& l : _gpuActiveLayers) {
|
||||
l->deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -1,73 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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/rendering/gpu/gpulayermanager.h>
|
||||
|
||||
#include <modules/globebrowsing/rendering/layer/layermanager.h>
|
||||
#include <modules/globebrowsing/rendering/gpu/gpulayer.h>
|
||||
#include <modules/globebrowsing/rendering/gpu/gpulayergroup.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
GPULayerManager::~GPULayerManager() {} // NOLINT
|
||||
|
||||
void GPULayerManager::setValue(ghoul::opengl::ProgramObject* programObject,
|
||||
const LayerManager& manager, const TileIndex& tileIndex)
|
||||
{
|
||||
const std::vector<std::shared_ptr<LayerGroup>>& layerGroups = manager.layerGroups();
|
||||
|
||||
for (size_t i = 0; i < layerGroups.size(); ++i) {
|
||||
_gpuLayerGroups[i]->setValue(programObject, *layerGroups[i], tileIndex);
|
||||
}
|
||||
}
|
||||
|
||||
void GPULayerManager::bind(ghoul::opengl::ProgramObject* programObject,
|
||||
const LayerManager& manager)
|
||||
{
|
||||
const std::vector<std::shared_ptr<LayerGroup>>& layerGroups = manager.layerGroups();
|
||||
if (_gpuLayerGroups.size() != layerGroups.size()) {
|
||||
_gpuLayerGroups.resize(layerGroups.size());
|
||||
for (std::unique_ptr<GPULayerGroup>& gpuLayerGroup : _gpuLayerGroups) {
|
||||
gpuLayerGroup = std::make_unique<GPULayerGroup>();
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < layerGroups.size(); ++i) {
|
||||
const std::string& nameBase = layergroupid::LAYER_GROUP_IDENTIFIERS[i];
|
||||
_gpuLayerGroups[i]->bind(
|
||||
programObject,
|
||||
*layerGroups[i],
|
||||
nameBase,
|
||||
static_cast<int>(i)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void GPULayerManager::deactivate() {
|
||||
for (std::unique_ptr<GPULayerGroup>& l : _gpuLayerGroups) {
|
||||
l->deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -1,75 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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___GPULAYERMANAGER___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___GPULAYERMANAGER___H__
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace ghoul::opengl { class ProgramObject; }
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
class GPULayerGroup;
|
||||
class LayerManager;
|
||||
struct TileIndex;
|
||||
|
||||
/**
|
||||
* Manages a GPU representation of a <code>LayerGroup</code>
|
||||
*/
|
||||
class GPULayerManager {
|
||||
public:
|
||||
~GPULayerManager();
|
||||
|
||||
/**
|
||||
* Sets the value of <code>LayerGroup</code> to its corresponding
|
||||
* GPU struct. OBS! Users must ensure bind has been
|
||||
* called before setting using this method.
|
||||
*/
|
||||
void setValue(ghoul::opengl::ProgramObject* programObject,
|
||||
const LayerManager& manager, const TileIndex& tileIndex);
|
||||
|
||||
/**
|
||||
* Binds this object with GLSL variables with identifiers starting
|
||||
* with nameBase within the provided shader program.
|
||||
* After this method has been called, users may invoke setValue.
|
||||
*/
|
||||
void bind(ghoul::opengl::ProgramObject* programObject,
|
||||
const LayerManager& manager);
|
||||
|
||||
/**
|
||||
* Deactivates any <code>TextureUnit</code>s assigned by this object.
|
||||
* This method should be called after the OpenGL draw call.
|
||||
*/
|
||||
void deactivate();
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<GPULayerGroup>> _gpuLayerGroups;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___GPULAYERMANAGER___H__
|
||||
@@ -1,50 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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/rendering/gpu/gpulayerrendersettings.h>
|
||||
|
||||
#include <modules/globebrowsing/rendering/layer/layerrendersettings.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
void GPULayerRenderSettings::setValue(ghoul::opengl::ProgramObject* programObject,
|
||||
const LayerRenderSettings& layerSettings)
|
||||
{
|
||||
gpuOpacity.setValue(programObject, layerSettings.opacity.value());
|
||||
gpuGamma.setValue(programObject, layerSettings.gamma.value());
|
||||
gpuMultiplier.setValue(programObject, layerSettings.multiplier.value());
|
||||
gpuOffset.setValue(programObject, layerSettings.offset.value());
|
||||
}
|
||||
|
||||
void GPULayerRenderSettings::bind(const LayerRenderSettings&,
|
||||
ghoul::opengl::ProgramObject* programObject,
|
||||
const std::string& nameBase)
|
||||
{
|
||||
gpuOpacity.bind(programObject, nameBase + "opacity");
|
||||
gpuGamma.bind(programObject, nameBase + "gamma");
|
||||
gpuMultiplier.bind(programObject, nameBase + "multiplier");
|
||||
gpuOffset.bind(programObject, nameBase + "offset");
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -1,70 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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___GPULAYERRENDERSETTINGS___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___GPULAYERRENDERSETTINGS___H__
|
||||
|
||||
#include <openspace/util/gpudata.h>
|
||||
#include <string>
|
||||
|
||||
namespace ghoul::opengl { class ProgramObject; }
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
struct LayerRenderSettings;
|
||||
|
||||
/**
|
||||
* Manages a GPU representation of a <code>LayerRenderSettings</code>
|
||||
*/
|
||||
class GPULayerRenderSettings{
|
||||
public:
|
||||
/**
|
||||
* Sets the value of <code>LayerRenderSettings</code> to its corresponding
|
||||
* GPU struct. OBS! Users must ensure bind has been
|
||||
* called before setting using this method.
|
||||
*/
|
||||
void setValue(ghoul::opengl::ProgramObject* programObject,
|
||||
const LayerRenderSettings& layerSettings);
|
||||
|
||||
/**
|
||||
* Binds this object with GLSL variables with identifiers starting
|
||||
* with nameBase within the provided shader program.
|
||||
* After this method has been called, users may invoke setValue.
|
||||
*/
|
||||
void bind(const LayerRenderSettings& layerSettings,
|
||||
ghoul::opengl::ProgramObject* programObject, const std::string& nameBase);
|
||||
|
||||
private:
|
||||
GPUData<float> gpuOpacity;
|
||||
GPUData<float> gpuGamma;
|
||||
GPUData<float> gpuMultiplier;
|
||||
GPUData<float> gpuOffset;
|
||||
|
||||
// Optional
|
||||
GPUData<float> gpuValueBlending;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___GPULAYERRENDERSETTINGS___H__
|
||||
@@ -1,45 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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/rendering/gpu/gputiledepthtransform.h>
|
||||
|
||||
#include <modules/globebrowsing/tile/tiledepthtransform.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
void GPUTileDepthTransform::setValue(ghoul::opengl::ProgramObject* programObject,
|
||||
const TileDepthTransform& depthTransform)
|
||||
{
|
||||
_gpuDepthOffset.setValue(programObject, depthTransform.depthOffset);
|
||||
_gpuDepthScale.setValue(programObject, depthTransform.depthScale);
|
||||
}
|
||||
|
||||
void GPUTileDepthTransform::bind(ghoul::opengl::ProgramObject* programObject,
|
||||
const std::string& nameBase)
|
||||
{
|
||||
_gpuDepthOffset.bind(programObject, nameBase + "depthOffset");
|
||||
_gpuDepthScale.bind(programObject, nameBase + "depthScale");
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -1,65 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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___GPUTILEDEPTHTRANSFORM___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___GPUTILEDEPTHTRANSFORM___H__
|
||||
|
||||
#include <openspace/util/gpudata.h>
|
||||
#include <string>
|
||||
|
||||
namespace ghoul::opengl { class ProgramObject; }
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
struct TileDepthTransform;
|
||||
|
||||
/**
|
||||
* Manages a GPU representation of a <code>TileDepthTransform</code>
|
||||
*/
|
||||
class GPUTileDepthTransform {
|
||||
public:
|
||||
/**
|
||||
* Sets the value of <code>TileDepthTransform</code> to its corresponding
|
||||
* GPU struct. OBS! Users must ensure bind has been
|
||||
* called before setting using this method.
|
||||
*/
|
||||
void setValue(ghoul::opengl::ProgramObject* programObject,
|
||||
const TileDepthTransform& depthTransform);
|
||||
|
||||
/**
|
||||
* Binds GLSL variables with identifiers starting with
|
||||
* nameBase within the provided shader program with this object.
|
||||
* After this method has been called, users may invoke setValue.
|
||||
*/
|
||||
void bind(ghoul::opengl::ProgramObject* programObject,
|
||||
const std::string& nameBase);
|
||||
|
||||
private:
|
||||
GPUData<float> _gpuDepthOffset;
|
||||
GPUData<float> _gpuDepthScale;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___GPUTILEDEPTHTRANSFORM___H__
|
||||
@@ -1,46 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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/rendering/gpu/gputileuvtransform.h>
|
||||
|
||||
#include <modules/globebrowsing/tile/tileprovider/tileprovider.h>
|
||||
#include <modules/globebrowsing/tile/tileuvtransform.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
void GPUTileUvTransform::setValue(ghoul::opengl::ProgramObject* programObject,
|
||||
const TileUvTransform& uvTransform)
|
||||
{
|
||||
_gpuUvOffset.setValue(programObject, uvTransform.uvOffset);
|
||||
_gpuUvScale.setValue(programObject, uvTransform.uvScale);
|
||||
}
|
||||
|
||||
void GPUTileUvTransform::bind(ghoul::opengl::ProgramObject* programObject,
|
||||
const std::string& nameBase)
|
||||
{
|
||||
_gpuUvOffset.bind(programObject, nameBase + "uvOffset");
|
||||
_gpuUvScale.bind(programObject, nameBase + "uvScale");
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -1,64 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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___GPUTILEUVTRANSFORM___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___GPUTILEUVTRANSFORM___H__
|
||||
|
||||
#include <openspace/util/gpudata.h>
|
||||
#include <string>
|
||||
|
||||
namespace ghoul::opengl { class ProgramObject; }
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
struct TileUvTransform;
|
||||
|
||||
/**
|
||||
* Manages a GPU representation of a <code>TileUvTransform</code>
|
||||
*/
|
||||
class GPUTileUvTransform {
|
||||
public:
|
||||
/**
|
||||
* Sets the value of <code>TileUvTransform</code> to its corresponding
|
||||
* GPU struct. OBS! Users must ensure bind has been
|
||||
* called before setting using this method.
|
||||
*/
|
||||
void setValue(ghoul::opengl::ProgramObject* programObject,
|
||||
const TileUvTransform& uvTransform);
|
||||
|
||||
/**
|
||||
* Binds GLSL variables with identifiers starting with
|
||||
* nameBase within the provided shader program with this object.
|
||||
* After this method has been called, users may invoke setValue.
|
||||
*/
|
||||
void bind(ghoul::opengl::ProgramObject* programObject, const std::string& nameBase);
|
||||
|
||||
private:
|
||||
GPUData<glm::vec2> _gpuUvOffset;
|
||||
GPUData<glm::vec2> _gpuUvScale;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___GPUTILEUVTRANSFORM___H__
|
||||
@@ -1,228 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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/rendering/layer/layermanager.h>
|
||||
|
||||
#include <modules/globebrowsing/rendering/layer/layer.h>
|
||||
#include <modules/globebrowsing/rendering/layer/layergroup.h>
|
||||
#include <modules/globebrowsing/tile/tiletextureinitdata.h>
|
||||
#include <modules/globebrowsing/tile/tileprovider/tileprovider.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "LayerManager";
|
||||
} // namespace
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
LayerManager::LayerManager(const ghoul::Dictionary& layerGroupsDict)
|
||||
: properties::PropertyOwner({ "Layers" })
|
||||
{
|
||||
// First create empty layer groups in case not all are specified
|
||||
_layerGroups.resize(layergroupid::NUM_LAYER_GROUPS);
|
||||
for (size_t i = 0; i < _layerGroups.size(); ++i) {
|
||||
ghoul::Dictionary emptyDict;
|
||||
_layerGroups[i] = std::make_shared<LayerGroup>(
|
||||
static_cast<layergroupid::GroupID>(i), emptyDict
|
||||
);
|
||||
}
|
||||
|
||||
const std::vector<std::string>& layerGroupNamesInDict = layerGroupsDict.keys();
|
||||
|
||||
// Create all the layer groups
|
||||
for (const std::string& groupName : layerGroupNamesInDict) {
|
||||
layergroupid::GroupID groupId = layergroupid::getGroupIDFromName(groupName);
|
||||
|
||||
if (groupId != layergroupid::GroupID::Unknown) {
|
||||
ghoul::Dictionary layerGroupDict = layerGroupsDict.value<ghoul::Dictionary>(
|
||||
groupName
|
||||
);
|
||||
_layerGroups[static_cast<int>(groupId)] = std::make_shared<LayerGroup>(
|
||||
groupId,
|
||||
layerGroupDict
|
||||
);
|
||||
}
|
||||
else {
|
||||
LWARNING("Unknown layer group: " + groupName);
|
||||
}
|
||||
}
|
||||
|
||||
for (const std::shared_ptr<LayerGroup>& layerGroup : _layerGroups) {
|
||||
addPropertySubOwner(layerGroup.get());
|
||||
}
|
||||
}
|
||||
|
||||
void LayerManager::initialize() {
|
||||
for (const std::shared_ptr<LayerGroup>& lg : _layerGroups) {
|
||||
lg->initialize();
|
||||
}
|
||||
}
|
||||
|
||||
void LayerManager::deinitialize() {
|
||||
for (const std::shared_ptr<LayerGroup>& lg : _layerGroups) {
|
||||
lg->deinitialize();
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<Layer> LayerManager::addLayer(layergroupid::GroupID groupId,
|
||||
const ghoul::Dictionary& layerDict)
|
||||
{
|
||||
ghoul_assert(groupId != layergroupid::Unknown, "Layer group ID must be known");
|
||||
|
||||
return _layerGroups[groupId]->addLayer(layerDict);
|
||||
}
|
||||
|
||||
void LayerManager::deleteLayer(layergroupid::GroupID groupId,
|
||||
const std::string& layerName)
|
||||
{
|
||||
ghoul_assert(groupId != layergroupid::Unknown, "Layer group ID must be known");
|
||||
|
||||
_layerGroups[groupId]->deleteLayer(layerName);
|
||||
}
|
||||
|
||||
const LayerGroup& LayerManager::layerGroup(size_t groupId) {
|
||||
return *_layerGroups[groupId];
|
||||
}
|
||||
|
||||
const LayerGroup& LayerManager::layerGroup(layergroupid::GroupID groupId) {
|
||||
return *_layerGroups[groupId];
|
||||
}
|
||||
|
||||
bool LayerManager::hasAnyBlendingLayersEnabled() const {
|
||||
return std::any_of(
|
||||
_layerGroups.begin(),
|
||||
_layerGroups.end(),
|
||||
[](const std::shared_ptr<LayerGroup>& layerGroup) {
|
||||
return layerGroup->layerBlendingEnabled() &&
|
||||
!layerGroup->activeLayers().empty();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const std::vector<std::shared_ptr<LayerGroup>>& LayerManager::layerGroups() const {
|
||||
return _layerGroups;
|
||||
}
|
||||
|
||||
void LayerManager::update() {
|
||||
for (std::shared_ptr<LayerGroup>& layerGroup : _layerGroups) {
|
||||
layerGroup->update();
|
||||
}
|
||||
}
|
||||
|
||||
void LayerManager::reset(bool includeDisabled) {
|
||||
for (std::shared_ptr<LayerGroup>& layerGroup : _layerGroups) {
|
||||
for (const std::shared_ptr<Layer>& layer : layerGroup->layers()) {
|
||||
if (layer->enabled() || includeDisabled) {
|
||||
layer->tileProvider()->reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TileTextureInitData LayerManager::getTileTextureInitData(layergroupid::GroupID id,
|
||||
PadTiles padTiles,
|
||||
size_t preferredTileSize)
|
||||
{
|
||||
switch (id) {
|
||||
case layergroupid::GroupID::HeightLayers: {
|
||||
const size_t tileSize = preferredTileSize ? preferredTileSize : 64;
|
||||
return TileTextureInitData(
|
||||
tileSize,
|
||||
tileSize,
|
||||
GL_FLOAT,
|
||||
ghoul::opengl::Texture::Format::Red,
|
||||
TileTextureInitData::PadTiles(padTiles),
|
||||
TileTextureInitData::ShouldAllocateDataOnCPU::Yes
|
||||
);
|
||||
}
|
||||
case layergroupid::GroupID::ColorLayers: {
|
||||
const size_t tileSize = preferredTileSize ? preferredTileSize : 512;
|
||||
return TileTextureInitData(
|
||||
tileSize,
|
||||
tileSize,
|
||||
GL_UNSIGNED_BYTE,
|
||||
ghoul::opengl::Texture::Format::BGRA,
|
||||
TileTextureInitData::PadTiles(padTiles)
|
||||
);
|
||||
}
|
||||
case layergroupid::GroupID::Overlays: {
|
||||
const size_t tileSize = preferredTileSize ? preferredTileSize : 512;
|
||||
return TileTextureInitData(
|
||||
tileSize,
|
||||
tileSize,
|
||||
GL_UNSIGNED_BYTE,
|
||||
ghoul::opengl::Texture::Format::BGRA,
|
||||
TileTextureInitData::PadTiles(padTiles)
|
||||
);
|
||||
}
|
||||
case layergroupid::GroupID::NightLayers: {
|
||||
const size_t tileSize = preferredTileSize ? preferredTileSize : 512;
|
||||
return TileTextureInitData(
|
||||
tileSize,
|
||||
tileSize,
|
||||
GL_UNSIGNED_BYTE,
|
||||
ghoul::opengl::Texture::Format::BGRA,
|
||||
TileTextureInitData::PadTiles(padTiles)
|
||||
);
|
||||
}
|
||||
case layergroupid::GroupID::WaterMasks: {
|
||||
const size_t tileSize = preferredTileSize ? preferredTileSize : 512;
|
||||
return TileTextureInitData(
|
||||
tileSize,
|
||||
tileSize,
|
||||
GL_UNSIGNED_BYTE,
|
||||
ghoul::opengl::Texture::Format::BGRA,
|
||||
TileTextureInitData::PadTiles(padTiles)
|
||||
);
|
||||
}
|
||||
default: {
|
||||
ghoul_assert(false, "Unknown layer group ID");
|
||||
|
||||
const size_t tileSize = preferredTileSize ? preferredTileSize : 512;
|
||||
return TileTextureInitData(
|
||||
tileSize,
|
||||
tileSize,
|
||||
GL_UNSIGNED_BYTE,
|
||||
ghoul::opengl::Texture::Format::BGRA,
|
||||
TileTextureInitData::PadTiles(padTiles)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LayerManager::shouldPerformPreProcessingOnLayergroup(layergroupid::GroupID id) {
|
||||
// Only preprocess height layers by default
|
||||
switch (id) {
|
||||
case layergroupid::GroupID::HeightLayers: return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
void LayerManager::onChange(std::function<void(void)> callback) {
|
||||
for (std::shared_ptr<LayerGroup>& layerGroup : _layerGroups) {
|
||||
layerGroup->onChange(callback);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -1,256 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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/rendering/layershadermanager.h>
|
||||
|
||||
#include <modules/globebrowsing/chunk/chunk.h>
|
||||
#include <modules/globebrowsing/globes/chunkedlodglobe.h>
|
||||
#include <modules/globebrowsing/globes/renderableglobe.h>
|
||||
#include <modules/globebrowsing/rendering/layer/layer.h>
|
||||
#include <modules/globebrowsing/rendering/layer/layergroup.h>
|
||||
#include <modules/globebrowsing/rendering/layer/layermanager.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
bool
|
||||
LayerShaderManager::LayerShaderPreprocessingData::LayerGroupPreprocessingData::operator==(
|
||||
const LayerGroupPreprocessingData& other) const
|
||||
{
|
||||
return layerType == other.layerType &&
|
||||
blendMode == other.blendMode &&
|
||||
layerAdjustmentType == other.layerAdjustmentType &&
|
||||
lastLayerIdx == other.lastLayerIdx &&
|
||||
layerBlendingEnabled == other.layerBlendingEnabled;
|
||||
}
|
||||
|
||||
bool LayerShaderManager::LayerShaderPreprocessingData::operator==(
|
||||
const LayerShaderPreprocessingData& other) const
|
||||
{
|
||||
if (layeredTextureInfo.size() != other.layeredTextureInfo.size() ||
|
||||
keyValuePairs.size() != other.keyValuePairs.size()) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
bool equal = true;
|
||||
for (size_t i = 0; i < layeredTextureInfo.size(); i++) {
|
||||
equal &= (layeredTextureInfo[i] == other.layeredTextureInfo[i]);
|
||||
}
|
||||
for (size_t i = 0; i < keyValuePairs.size(); i++) {
|
||||
equal &= (keyValuePairs[i] == other.keyValuePairs[i]);
|
||||
}
|
||||
return equal;
|
||||
}
|
||||
}
|
||||
|
||||
LayerShaderManager::LayerShaderPreprocessingData
|
||||
LayerShaderManager::LayerShaderPreprocessingData::get(const RenderableGlobe& globe)
|
||||
{
|
||||
LayerShaderManager::LayerShaderPreprocessingData preprocessingData;
|
||||
|
||||
std::shared_ptr<LayerManager> layerManager = globe.chunkedLodGlobe()->layerManager();
|
||||
for (size_t i = 0; i < layergroupid::NUM_LAYER_GROUPS; i++) {
|
||||
LayerShaderManager::LayerShaderPreprocessingData::LayerGroupPreprocessingData
|
||||
layeredTextureInfo;
|
||||
|
||||
const LayerGroup& layerGroup = layerManager->layerGroup(i);
|
||||
const std::vector<std::shared_ptr<Layer>>& layers = layerGroup.activeLayers();
|
||||
|
||||
// This check was implicit before; not sure if it will fire or will be handled
|
||||
// elsewhere
|
||||
//ghoul_assert(
|
||||
// !layerGroup.activeLayers().empty(),
|
||||
// "If activeLayers is empty the following line will lead to an overflow"
|
||||
//);
|
||||
layeredTextureInfo.lastLayerIdx = static_cast<int>(
|
||||
layerGroup.activeLayers().size() - 1
|
||||
);
|
||||
layeredTextureInfo.layerBlendingEnabled = layerGroup.layerBlendingEnabled();
|
||||
|
||||
for (const std::shared_ptr<Layer>& layer : layers) {
|
||||
layeredTextureInfo.layerType.push_back(layer->type());
|
||||
layeredTextureInfo.blendMode.push_back(layer->blendMode());
|
||||
layeredTextureInfo.layerAdjustmentType.push_back(
|
||||
layer->layerAdjustment().type()
|
||||
);
|
||||
}
|
||||
|
||||
preprocessingData.layeredTextureInfo[i] = layeredTextureInfo;
|
||||
}
|
||||
|
||||
const RenderableGlobe::GeneralProperties& generalProps = globe.generalProperties();
|
||||
const RenderableGlobe::DebugProperties& debugProps = globe.debugProperties();
|
||||
std::vector<std::pair<std::string, std::string>>& pairs =
|
||||
preprocessingData.keyValuePairs;
|
||||
|
||||
pairs.emplace_back("useAccurateNormals",
|
||||
std::to_string(generalProps.useAccurateNormals)
|
||||
);
|
||||
pairs.emplace_back("useAtmosphere", std::to_string(generalProps.atmosphereEnabled));
|
||||
pairs.emplace_back("performShading", std::to_string(generalProps.performShading));
|
||||
pairs.emplace_back(
|
||||
"useEclipseShadows",
|
||||
std::to_string(generalProps.eclipseShadowsEnabled)
|
||||
);
|
||||
pairs.emplace_back(
|
||||
"useEclipseHardShadows",
|
||||
std::to_string(generalProps.eclipseHardShadows)
|
||||
);
|
||||
pairs.emplace_back("showChunkEdges", std::to_string(debugProps.showChunkEdges));
|
||||
pairs.emplace_back("showHeightResolution",
|
||||
std::to_string(debugProps.showHeightResolution)
|
||||
);
|
||||
pairs.emplace_back("showHeightIntensities",
|
||||
std::to_string(debugProps.showHeightIntensities)
|
||||
);
|
||||
pairs.emplace_back("defaultHeight", std::to_string(Chunk::DefaultHeight));
|
||||
|
||||
return preprocessingData;
|
||||
}
|
||||
|
||||
LayerShaderManager::LayerShaderManager(std::string shaderName, std::string vsPath,
|
||||
std::string fsPath)
|
||||
: _shaderName(std::move(shaderName))
|
||||
, _vsPath(std::move(vsPath))
|
||||
, _fsPath(std::move(fsPath))
|
||||
{}
|
||||
|
||||
LayerShaderManager::~LayerShaderManager() {
|
||||
if (_programObject) {
|
||||
global::renderEngine.removeRenderProgram(_programObject.get());
|
||||
_programObject = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
ghoul::opengl::ProgramObject* LayerShaderManager::programObject() const {
|
||||
ghoul_assert(_programObject, "Program does not exist. Needs to be compiled!");
|
||||
|
||||
return _programObject.get();
|
||||
}
|
||||
|
||||
void LayerShaderManager::recompileShaderProgram(
|
||||
LayerShaderPreprocessingData preprocessingData)
|
||||
{
|
||||
_preprocessingData = std::move(preprocessingData);
|
||||
ghoul::Dictionary shaderDictionary;
|
||||
|
||||
// Different layer types can be height layers or color layers for example.
|
||||
// These are used differently within the shaders.
|
||||
const std::array<
|
||||
LayerShaderPreprocessingData::LayerGroupPreprocessingData,
|
||||
layergroupid::NUM_LAYER_GROUPS
|
||||
>& textureTypes = _preprocessingData.layeredTextureInfo;
|
||||
|
||||
for (size_t i = 0; i < textureTypes.size(); i++) {
|
||||
// lastLayerIndex must be at least 0 for the shader to compile,
|
||||
// the layer type is inactivated by setting use to false
|
||||
const std::string& groupName = layergroupid::LAYER_GROUP_IDENTIFIERS[i];
|
||||
shaderDictionary.setValue(
|
||||
"lastLayerIndex" + groupName,
|
||||
glm::max(textureTypes[i].lastLayerIdx, 0)
|
||||
);
|
||||
shaderDictionary.setValue(
|
||||
"use" + groupName,
|
||||
textureTypes[i].lastLayerIdx >= 0
|
||||
);
|
||||
shaderDictionary.setValue(
|
||||
"blend" + groupName,
|
||||
textureTypes[i].layerBlendingEnabled
|
||||
);
|
||||
|
||||
// This is to avoid errors from shader preprocessor
|
||||
shaderDictionary.setValue(groupName + "0" + "LayerType", 0);
|
||||
|
||||
for (int j = 0; j < textureTypes[i].lastLayerIdx + 1; ++j) {
|
||||
shaderDictionary.setValue(
|
||||
groupName + std::to_string(j) + "LayerType",
|
||||
static_cast<int>(textureTypes[i].layerType[j])
|
||||
);
|
||||
}
|
||||
|
||||
// This is to avoid errors from shader preprocessor
|
||||
shaderDictionary.setValue(groupName + "0" + "BlendMode", 0);
|
||||
|
||||
for (int j = 0; j < textureTypes[i].lastLayerIdx + 1; ++j) {
|
||||
shaderDictionary.setValue(
|
||||
groupName + std::to_string(j) + "BlendMode",
|
||||
static_cast<int>(textureTypes[i].blendMode[j])
|
||||
);
|
||||
}
|
||||
|
||||
// This is to avoid errors from shader preprocessor
|
||||
std::string keyLayerAdjustmentType = groupName + "0" + "LayerAdjustmentType";
|
||||
shaderDictionary.setValue(keyLayerAdjustmentType, 0);
|
||||
|
||||
for (int j = 0; j < textureTypes[i].lastLayerIdx + 1; ++j) {
|
||||
shaderDictionary.setValue(
|
||||
groupName + std::to_string(j) + "LayerAdjustmentType",
|
||||
static_cast<int>(textureTypes[i].layerAdjustmentType[j])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ghoul::Dictionary layerGroupNames;
|
||||
for (int i = 0; i < layergroupid::NUM_LAYER_GROUPS; ++i) {
|
||||
layerGroupNames.setValue(
|
||||
std::to_string(i),
|
||||
layergroupid::LAYER_GROUP_IDENTIFIERS[i]
|
||||
);
|
||||
}
|
||||
shaderDictionary.setValue("layerGroups", layerGroupNames);
|
||||
|
||||
// Other settings such as "useAtmosphere"
|
||||
for (const std::pair<std::string, std::string>& p : _preprocessingData.keyValuePairs)
|
||||
{
|
||||
shaderDictionary.setValue(p.first, p.second);
|
||||
}
|
||||
|
||||
// Remove old program
|
||||
global::renderEngine.removeRenderProgram(_programObject.get());
|
||||
|
||||
_programObject = global::renderEngine.buildRenderProgram(
|
||||
_shaderName,
|
||||
absPath(_vsPath),
|
||||
absPath(_fsPath),
|
||||
shaderDictionary
|
||||
);
|
||||
|
||||
ghoul_assert(_programObject != nullptr, "Failed to initialize programObject!");
|
||||
|
||||
using IgnoreError = ghoul::opengl::ProgramObject::ProgramObject::IgnoreError;
|
||||
_programObject->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes);
|
||||
_programObject->setIgnoreUniformLocationError(IgnoreError::Yes);
|
||||
_updatedSinceLastCall = true;
|
||||
}
|
||||
|
||||
bool LayerShaderManager::updatedSinceLastCall() {
|
||||
const bool updated = _updatedSinceLastCall;
|
||||
_updatedSinceLastCall = false;
|
||||
return updated;
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -1,103 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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___LAYER_SHADER_MANAGER___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___LAYER_SHADER_MANAGER___H__
|
||||
|
||||
#include <modules/globebrowsing/rendering/layershadermanager.h>
|
||||
#include <modules/globebrowsing/rendering/layer/layergroupid.h>
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace ghoul::opengl { class ProgramObject; }
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
class RenderableGlobe;
|
||||
|
||||
/**
|
||||
* This class has ownership of an updated shader program for rendering tiles.
|
||||
*/
|
||||
class LayerShaderManager {
|
||||
public:
|
||||
/**
|
||||
* Data needed for shader preprocessing before compiling a layered texture shader
|
||||
* program.
|
||||
*
|
||||
* If a <code>LayerShaderPreprocessingData</code> is compared with another it can
|
||||
* be determined wheter or not a <code>LayerShaderManager</code> needs to
|
||||
* recompile its shader program. For each <code>TextureGroup</code> there is
|
||||
* information about how many layers it has and whether or not to blend the texture
|
||||
* levels.
|
||||
*/
|
||||
struct LayerShaderPreprocessingData {
|
||||
/**
|
||||
* Settings per texture group that contains shader preprocessing information.
|
||||
*/
|
||||
struct LayerGroupPreprocessingData {
|
||||
bool operator==(const LayerGroupPreprocessingData& other) const;
|
||||
|
||||
int lastLayerIdx;
|
||||
bool layerBlendingEnabled;
|
||||
std::vector<layergroupid::TypeID> layerType;
|
||||
std::vector<layergroupid::BlendModeID> blendMode;
|
||||
std::vector<layergroupid::AdjustmentTypeID> layerAdjustmentType;
|
||||
};
|
||||
|
||||
bool operator==(const LayerShaderPreprocessingData& other) const;
|
||||
static LayerShaderPreprocessingData get(const RenderableGlobe&);
|
||||
|
||||
std::array<LayerGroupPreprocessingData, layergroupid::NUM_LAYER_GROUPS>
|
||||
layeredTextureInfo;
|
||||
std::vector<std::pair<std::string, std::string>> keyValuePairs;
|
||||
};
|
||||
|
||||
LayerShaderManager(std::string shaderName, std::string vsPath, std::string fsPath);
|
||||
~LayerShaderManager();
|
||||
|
||||
/**
|
||||
* Returns a pointer to a <code>ProgramObject</code> for rendering tiles.
|
||||
*/
|
||||
ghoul::opengl::ProgramObject* programObject() const;
|
||||
|
||||
bool updatedSinceLastCall();
|
||||
|
||||
void recompileShaderProgram(LayerShaderPreprocessingData preprocessingData);
|
||||
|
||||
private:
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _programObject;
|
||||
LayerShaderPreprocessingData _preprocessingData;
|
||||
|
||||
const std::string _shaderName;
|
||||
const std::string _vsPath;
|
||||
const std::string _fsPath;
|
||||
|
||||
bool _updatedSinceLastCall = false;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___LAYER_SHADER_MANAGER___H__
|
||||
@@ -27,10 +27,10 @@
|
||||
|
||||
vec4 blendNormal(vec4 oldColor, vec4 newColor) {
|
||||
vec4 toReturn;
|
||||
toReturn.a = mix(oldColor.a, 1.0, newColor.a);
|
||||
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);
|
||||
toReturn.a;
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
@@ -46,28 +46,6 @@ vec4 blendSubtract(vec4 oldColor, vec4 newColor) {
|
||||
return oldColor - newColor;
|
||||
}
|
||||
|
||||
/*
|
||||
vec3 rgb2hsv(vec3 c)
|
||||
{
|
||||
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
|
||||
//vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
|
||||
//vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
|
||||
vec4 p = c.g < c.b ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy);
|
||||
vec4 q = c.r < p.x ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx);
|
||||
|
||||
float d = q.x - min(q.w, q.y);
|
||||
float e = 1.0e-10;
|
||||
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
|
||||
}
|
||||
|
||||
vec3 hsv2rgb(vec3 c)
|
||||
{
|
||||
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
||||
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
|
||||
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
||||
}
|
||||
*/
|
||||
|
||||
vec3 hsl2rgb(in vec3 c) {
|
||||
vec3 rgb = clamp(abs(mod(c.x * 6.0 + vec3(0.0, 4.0, 2.0), 6.0) - 3.0) - 1.0, 0.0, 1.0);
|
||||
|
||||
@@ -78,30 +56,29 @@ vec3 HueShift(in vec3 color, in float shift) {
|
||||
vec3 P = vec3(0.55735) * dot(vec3(0.55735), color);
|
||||
vec3 U = color - P;
|
||||
vec3 V = cross(vec3(0.55735), U);
|
||||
vec3 c = U*cos(shift*6.2832) + V*sin(shift*6.2832) + P;
|
||||
vec3 c = U * cos(shift*6.2832) + V * sin(shift*6.2832) + P;
|
||||
return c;
|
||||
}
|
||||
|
||||
vec3 rgb2hsl(in vec3 c) {
|
||||
float h = 0.0;
|
||||
float s = 0.0;
|
||||
float l = 0.0;
|
||||
float r = c.r;
|
||||
float g = c.g;
|
||||
float b = c.b;
|
||||
float cMin = min(r, min(g, b));
|
||||
float cMax = max(r, max(g, b));
|
||||
|
||||
l = (cMax + cMin) / 2.0;
|
||||
if (cMax > cMin) {
|
||||
float l = (cMax + cMin) / 2.0;
|
||||
|
||||
float cDelta = cMax - cMin;
|
||||
|
||||
//s = l < .05 ? cDelta / ( cMax + cMin ) : cDelta / ( 2.0 - ( cMax + cMin ) ); Original
|
||||
s = (l < 0.0) ? cDelta / (cMax + cMin) : cDelta / (2.0 - (cMax + cMin));
|
||||
float s = (l < 0.0) ? cDelta / (cMax + cMin) : cDelta / (2.0 - (cMax + cMin));
|
||||
|
||||
if ( r == cMax ) {
|
||||
float h = 0.0;
|
||||
if (r == cMax) {
|
||||
h = (g - b) / cDelta;
|
||||
} else if ( g == cMax ) {
|
||||
} else if (g == cMax) {
|
||||
h = 2.0 + (b - r) / cDelta;
|
||||
} else {
|
||||
h = 4.0 + (r - g) / cDelta;
|
||||
@@ -111,14 +88,16 @@ vec3 rgb2hsl(in vec3 c) {
|
||||
h += 6.0;
|
||||
}
|
||||
h = h / 6.0;
|
||||
|
||||
return vec3(h, s, l);
|
||||
}
|
||||
else {
|
||||
return vec3(0.0);
|
||||
}
|
||||
return vec3(h, s, l);
|
||||
}
|
||||
|
||||
vec3 rgb2hsv(vec3 c) {
|
||||
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
|
||||
//vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
|
||||
//vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
|
||||
vec4 p = (c.g < c.b) ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy);
|
||||
vec4 q = (c.r < p.x) ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx);
|
||||
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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 ELLIPSOID_HGLSL
|
||||
#define ELLIPSOID_HGLSL
|
||||
|
||||
struct PositionNormalPair {
|
||||
vec3 position;
|
||||
vec3 normal;
|
||||
};
|
||||
|
||||
struct Intersection {
|
||||
bool intersects;
|
||||
float nearParameter; // Along ray
|
||||
float farParameter; // Along ray
|
||||
};
|
||||
|
||||
vec3 geodeticSurfaceNormal(float latitude, float longitude) {
|
||||
float cosLat = cos(latitude);
|
||||
return vec3(
|
||||
cosLat * cos(longitude),
|
||||
cosLat * sin(longitude),
|
||||
sin(latitude)
|
||||
);
|
||||
}
|
||||
|
||||
PositionNormalPair geodetic3ToCartesian(float latitude, float longitude, float height,
|
||||
vec3 radiiSquared)
|
||||
{
|
||||
vec3 normal = geodeticSurfaceNormal(latitude, longitude);
|
||||
vec3 k = radiiSquared * normal;
|
||||
float gamma = sqrt(dot(k, normal));
|
||||
vec3 rSurface = k / gamma;
|
||||
PositionNormalPair toReturn;
|
||||
toReturn.position = rSurface + height * normal;
|
||||
toReturn.normal = normal;
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
PositionNormalPair geodetic2ToCartesian(float latitude, float longitude,
|
||||
vec3 radiiSquared)
|
||||
{
|
||||
// Position on surface : height = 0
|
||||
return geodetic3ToCartesian(latitude, longitude, 0, radiiSquared);
|
||||
}
|
||||
|
||||
vec3 latLonToCartesian(float latitude, float longitude, float radius) {
|
||||
return radius * vec3(
|
||||
cos(latitude) * cos(longitude),
|
||||
cos(latitude) * sin(longitude),
|
||||
sin(latitude)
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Assumes ellipsoid is at (0, 0, 0)
|
||||
//
|
||||
Intersection rayIntersectEllipsoid(vec3 rayOrigin, vec3 rayOriginSquared,
|
||||
vec3 rayDirection, vec3 oneOverEllipsoidRadiiSquared)
|
||||
{
|
||||
float a = dot(rayDirection * rayDirection, oneOverEllipsoidRadiiSquared);
|
||||
float b = 2.0 * dot(rayOrigin * rayDirection, oneOverEllipsoidRadiiSquared);
|
||||
float c = dot(rayOriginSquared, oneOverEllipsoidRadiiSquared) - 1.0;
|
||||
float discriminant = b * b - 4.0 * a * c;
|
||||
|
||||
if (discriminant < 0.0) {
|
||||
return Intersection(false, 0.0, 0.0);
|
||||
}
|
||||
else if (discriminant == 0.0) {
|
||||
float time = -0.5 * b / a;
|
||||
return Intersection(true, time, time);
|
||||
}
|
||||
|
||||
float t = -0.5 * (b + (b > 0.0 ? 1.0 : -1.0) * sqrt(discriminant));
|
||||
float root1 = t / a;
|
||||
float root2 = c / t;
|
||||
|
||||
return Intersection(true, min(root1, root2), max(root1, root2));
|
||||
}
|
||||
|
||||
#endif // ELLIPSOID_HGLSL
|
||||
@@ -1,37 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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 <${MODULE_GLOBEBROWSING}/shaders/tilefragment.hglsl>
|
||||
#include "fragment.glsl"
|
||||
|
||||
Fragment getFragment() {
|
||||
Fragment frag;
|
||||
frag = getTileFragment();
|
||||
|
||||
#if SHOW_CHUNK_EDGES
|
||||
frag.color += patchBorderOverlay(fs_uv, vec3(0.0, 1.0, 0.0), 0.02);
|
||||
#endif // SHOW_CHUNK_EDGES
|
||||
|
||||
return frag;
|
||||
}
|
||||
@@ -25,7 +25,6 @@
|
||||
#version __CONTEXT__
|
||||
|
||||
#include "PowerScaling/powerScaling_vs.hglsl"
|
||||
#include <${MODULE_GLOBEBROWSING}/shaders/ellipsoid.hglsl>
|
||||
#include <${MODULE_GLOBEBROWSING}/shaders/tile.hglsl>
|
||||
#include <${MODULE_GLOBEBROWSING}/shaders/texturetilemapping.hglsl>
|
||||
#include <${MODULE_GLOBEBROWSING}/shaders/tileheight.hglsl>
|
||||
@@ -33,21 +32,21 @@
|
||||
|
||||
layout(location = 1) in vec2 in_uv;
|
||||
|
||||
out vec2 fs_uv;
|
||||
out vec4 fs_position;
|
||||
out vec3 fs_normal;
|
||||
out vec2 fs_uv;
|
||||
out vec3 ellipsoidNormalCameraSpace;
|
||||
out LevelWeights levelWeights;
|
||||
out vec3 levelWeights;
|
||||
out vec3 positionCameraSpace;
|
||||
|
||||
#if USE_ACCURATE_NORMALS
|
||||
out vec3 ellipsoidTangentThetaCameraSpace;
|
||||
out vec3 ellipsoidTangentPhiCameraSpace;
|
||||
#endif //USE_ACCURATE_NORMALS
|
||||
out vec3 ellipsoidTangentThetaCameraSpace;
|
||||
out vec3 ellipsoidTangentPhiCameraSpace;
|
||||
#endif // USE_ACCURATE_NORMALS
|
||||
|
||||
#if USE_ECLIPSE_SHADOWS
|
||||
out vec3 positionWorldSpace;
|
||||
uniform dmat4 modelTransform;
|
||||
out vec3 positionWorldSpace;
|
||||
uniform dmat4 modelTransform;
|
||||
#endif
|
||||
|
||||
uniform mat4 modelViewProjectionTransform;
|
||||
@@ -63,49 +62,55 @@ uniform float distanceScaleFactor;
|
||||
uniform int chunkLevel;
|
||||
|
||||
|
||||
struct PositionNormalPair {
|
||||
vec3 position;
|
||||
vec3 normal;
|
||||
};
|
||||
|
||||
PositionNormalPair globalInterpolation(vec2 uv) {
|
||||
vec2 lonLatInput;
|
||||
lonLatInput.y = minLatLon.y + lonLatScalingFactor.y * uv.y; // Lat
|
||||
lonLatInput.x = minLatLon.x + lonLatScalingFactor.x * uv.x; // Lon
|
||||
PositionNormalPair positionPairModelSpace = geodetic2ToCartesian(
|
||||
lonLatInput.y,
|
||||
lonLatInput.x,
|
||||
radiiSquared
|
||||
vec2 lonlat = lonLatScalingFactor * uv + minLatLon;
|
||||
|
||||
// geodetic surface normal
|
||||
float cosLat = cos(lonlat.y);
|
||||
vec3 normal = vec3(cosLat * cos(lonlat.x), cosLat * sin(lonlat.x), sin(lonlat.y));
|
||||
vec3 k = radiiSquared * normal;
|
||||
float gamma = sqrt(dot(k, normal));
|
||||
|
||||
PositionNormalPair result;
|
||||
result.position = k / gamma;
|
||||
result.normal = normal;
|
||||
return result;
|
||||
}
|
||||
|
||||
vec3 getLevelWeights(float distToVertexOnEllipsoid) {
|
||||
float projectedScaleFactor = distanceScaleFactor / distToVertexOnEllipsoid;
|
||||
float desiredLevel = log2(projectedScaleFactor);
|
||||
float levelInterp = chunkLevel - desiredLevel;
|
||||
|
||||
return vec3(
|
||||
clamp(1.0 - levelInterp, 0.0, 1.0),
|
||||
clamp(levelInterp, 0.0, 1.0) - clamp(levelInterp - 1.0, 0.0, 1.0),
|
||||
clamp(levelInterp - 1.0, 0.0, 1.0)
|
||||
);
|
||||
return positionPairModelSpace;
|
||||
}
|
||||
|
||||
void main() {
|
||||
PositionNormalPair pair = globalInterpolation(in_uv);
|
||||
float distToVertexOnEllipsoid =
|
||||
length(pair.position + pair.normal * chunkMinHeight - cameraPosition);
|
||||
|
||||
float levelInterpolationParameter =
|
||||
getLevelInterpolationParameter(
|
||||
chunkLevel,
|
||||
distanceScaleFactor,
|
||||
distToVertexOnEllipsoid);
|
||||
float distToVertexOnEllipsoid = length((pair.normal * chunkMinHeight + pair.position) - cameraPosition);
|
||||
|
||||
// use level weight for height sampling, and output to fragment shader
|
||||
levelWeights = getLevelWeights(levelInterpolationParameter);
|
||||
levelWeights = getLevelWeights(distToVertexOnEllipsoid);
|
||||
|
||||
// Get the height value
|
||||
float height = getTileHeight(in_uv, levelWeights);
|
||||
|
||||
// Apply skirts
|
||||
height -= getTileVertexSkirtLength();
|
||||
// Get the height value and apply skirts
|
||||
float height = getTileHeight(in_uv, levelWeights) - getTileVertexSkirtLength();
|
||||
|
||||
#if USE_ACCURATE_NORMALS
|
||||
// Calculate tangents
|
||||
// tileDelta is a step length (epsilon). Should be small enough for accuracy but not
|
||||
// Too small for precision. 1 / 512 is good.
|
||||
const float tileDelta = 1.0 / 512.0;
|
||||
PositionNormalPair pair10 = globalInterpolation(
|
||||
in_uv + vec2(1.0, 0.0) * tileDelta
|
||||
);
|
||||
PositionNormalPair pair01 = globalInterpolation(
|
||||
in_uv + vec2(0.0, 1.0) * tileDelta
|
||||
);
|
||||
PositionNormalPair pair10 = globalInterpolation(vec2(1.0, 0.0) * tileDelta + in_uv);
|
||||
PositionNormalPair pair01 = globalInterpolation(vec2(0.0, 1.0) * tileDelta + in_uv);
|
||||
vec3 ellipsoidTangentTheta = normalize(pair10.position - pair.position);
|
||||
vec3 ellipsoidTangentPhi = normalize(pair01.position - pair.position);
|
||||
ellipsoidTangentThetaCameraSpace = mat3(modelViewTransform) * ellipsoidTangentTheta;
|
||||
@@ -113,9 +118,8 @@ void main() {
|
||||
#endif // USE_ACCURATE_NORMALS
|
||||
|
||||
// Add the height in the direction of the normal
|
||||
pair.position += pair.normal * height;
|
||||
vec4 positionClippingSpace =
|
||||
modelViewProjectionTransform * vec4(pair.position, 1.0);
|
||||
pair.position = pair.normal * height + pair.position;
|
||||
vec4 positionClippingSpace = modelViewProjectionTransform * vec4(pair.position, 1.0);
|
||||
|
||||
// Write output
|
||||
fs_uv = in_uv;
|
||||
@@ -1,56 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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 GLOBESHADING_HGLSL
|
||||
#define GLOBESHADING_HGLSL
|
||||
|
||||
float orenNayarDiffuse(vec3 lightDirection, vec3 viewDirection, vec3 surfaceNormal,
|
||||
float roughness)
|
||||
{
|
||||
// calculate intermediary values
|
||||
float NdotL = dot(surfaceNormal, lightDirection);
|
||||
float NdotV = dot(surfaceNormal, viewDirection);
|
||||
|
||||
float angleVN = acos(NdotV);
|
||||
float angleLN = acos(NdotL);
|
||||
|
||||
float alpha = max(angleVN, angleLN);
|
||||
float beta = min(angleVN, angleLN);
|
||||
float gamma = dot(
|
||||
viewDirection - surfaceNormal * dot(viewDirection, surfaceNormal),
|
||||
lightDirection - surfaceNormal * dot(lightDirection, surfaceNormal)
|
||||
);
|
||||
|
||||
float roughnessSquared = roughness * roughness;
|
||||
|
||||
// calculate A and B
|
||||
float A = 1.0 - 0.5 * (roughnessSquared / (roughnessSquared + 0.57));
|
||||
float B = 0.45 * (roughnessSquared / (roughnessSquared + 0.09));
|
||||
float C = sin(alpha) * tan(beta);
|
||||
|
||||
// put it all together
|
||||
return max(0.0, NdotL) * (A + B * max(0.0, gamma) * C);
|
||||
}
|
||||
|
||||
#endif // GLOBESHADING_HGLSL
|
||||
@@ -1,37 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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 <${MODULE_GLOBEBROWSING}/shaders/tilefragment.hglsl>
|
||||
#include "fragment.glsl"
|
||||
|
||||
Fragment getFragment() {
|
||||
Fragment frag;
|
||||
frag = getTileFragment();
|
||||
|
||||
#if SHOW_CHUNK_EDGES
|
||||
frag.color += patchBorderOverlay(fs_uv, vec3(1,0,0), 0.005);
|
||||
#endif // SHOW_CHUNK_EDGES
|
||||
|
||||
return frag;
|
||||
}
|
||||
@@ -25,7 +25,6 @@
|
||||
#version __CONTEXT__
|
||||
|
||||
#include "PowerScaling/powerScaling_vs.hglsl"
|
||||
#include <${MODULE_GLOBEBROWSING}/shaders/ellipsoid.hglsl>
|
||||
#include <${MODULE_GLOBEBROWSING}/shaders/tile.hglsl>
|
||||
#include <${MODULE_GLOBEBROWSING}/shaders/texturetilemapping.hglsl>
|
||||
#include <${MODULE_GLOBEBROWSING}/shaders/tileheight.hglsl>
|
||||
@@ -37,12 +36,12 @@ out vec2 fs_uv;
|
||||
out vec4 fs_position;
|
||||
out vec3 fs_normal;
|
||||
out vec3 ellipsoidNormalCameraSpace;
|
||||
out LevelWeights levelWeights;
|
||||
out vec3 levelWeights;
|
||||
out vec3 positionCameraSpace;
|
||||
|
||||
#if USE_ACCURATE_NORMALS
|
||||
out vec3 ellipsoidTangentThetaCameraSpace;
|
||||
out vec3 ellipsoidTangentPhiCameraSpace;
|
||||
out vec3 ellipsoidTangentThetaCameraSpace;
|
||||
out vec3 ellipsoidTangentPhiCameraSpace;
|
||||
#endif // USE_ACCURATE_NORMALS
|
||||
|
||||
#if USE_ECLIPSE_SHADOWS
|
||||
@@ -64,10 +63,21 @@ uniform float distanceScaleFactor;
|
||||
uniform int chunkLevel;
|
||||
|
||||
vec3 bilinearInterpolation(vec2 uv) {
|
||||
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;
|
||||
vec3 p0 = mix(p00, p10, uv.x);
|
||||
vec3 p1 = mix(p01, p11, uv.x);
|
||||
return mix(p0, p1, uv.y);
|
||||
}
|
||||
|
||||
vec3 getLevelWeights(float distToVertexOnEllipsoid) {
|
||||
float projectedScaleFactor = distanceScaleFactor / distToVertexOnEllipsoid;
|
||||
float desiredLevel = log2(projectedScaleFactor);
|
||||
float levelInterp = chunkLevel - desiredLevel;
|
||||
|
||||
return vec3(
|
||||
clamp(1.0 - levelInterp, 0.0, 1.0),
|
||||
clamp(levelInterp, 0.0, 1.0) - clamp(levelInterp - 1.0, 0.0, 1.0),
|
||||
clamp(levelInterp - 1.0, 0.0, 1.0)
|
||||
);
|
||||
}
|
||||
|
||||
void main() {
|
||||
@@ -76,31 +86,24 @@ void main() {
|
||||
|
||||
// Calculate desired level based on distance to the vertex on the ellipsoid
|
||||
// Before any heightmapping is done
|
||||
float distToVertexOnEllipsoid =
|
||||
length(p + patchNormalCameraSpace * chunkMinHeight);
|
||||
float levelInterpolationParameter =
|
||||
getLevelInterpolationParameter(
|
||||
chunkLevel,
|
||||
distanceScaleFactor,
|
||||
distToVertexOnEllipsoid);
|
||||
|
||||
float distToVertexOnEllipsoid = length(p + patchNormalCameraSpace * chunkMinHeight);
|
||||
|
||||
// use level weight for height sampling, and output to fragment shader
|
||||
levelWeights = getLevelWeights(levelInterpolationParameter);
|
||||
levelWeights = getLevelWeights(distToVertexOnEllipsoid);
|
||||
|
||||
// Get the height value and apply skirts
|
||||
float height =
|
||||
getTileHeightScaled(in_uv, levelWeights) - getTileVertexSkirtLength();
|
||||
float height = getTileHeightScaled(in_uv, levelWeights) - getTileVertexSkirtLength();
|
||||
|
||||
// Translate the point along normal
|
||||
p += patchNormalCameraSpace * height;
|
||||
|
||||
vec4 positionClippingSpace = projectionTransform * vec4(p, 1);
|
||||
|
||||
#if USE_ACCURATE_NORMALS
|
||||
|
||||
#if USE_ACCURATE_NORMALS
|
||||
// Calculate tangents
|
||||
ellipsoidTangentThetaCameraSpace = normalize(p10 - p00);
|
||||
ellipsoidTangentPhiCameraSpace = normalize(p01 - p00);
|
||||
#endif // USE_ACCURATE_NORMALS
|
||||
#endif // USE_ACCURATE_NORMALS
|
||||
|
||||
// Write output
|
||||
fs_uv = in_uv;
|
||||
@@ -110,7 +113,7 @@ void main() {
|
||||
fs_normal = patchNormalModelSpace;
|
||||
positionCameraSpace = p;
|
||||
|
||||
#if USE_ECLIPSE_SHADOWS
|
||||
#if USE_ECLIPSE_SHADOWS
|
||||
positionWorldSpace = vec3(inverseViewTransform * dvec4(p, 1.0));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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 "fragment.glsl"
|
||||
|
||||
in vec4 vs_positionClipSpace;
|
||||
in vec2 vs_positionModelSpace;
|
||||
|
||||
//uniform vec3 directionToSunViewSpace;
|
||||
uniform vec3 positionCameraSpace;
|
||||
//uniform float lightOverflow;
|
||||
|
||||
|
||||
Fragment getFragment() {
|
||||
float alpha =
|
||||
1.0 - sqrt(pow(vs_positionModelSpace.x, 2) + pow(vs_positionModelSpace.y, 2));
|
||||
alpha = pow(alpha, 3);
|
||||
Fragment frag;
|
||||
frag.color = vec4(1.0, 1.0, 1.0, alpha);
|
||||
frag.depth = vs_positionClipSpace.w;
|
||||
frag.blend = BLEND_MODE_ADDITIVE;
|
||||
return frag;
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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;
|
||||
|
||||
out vec4 vs_positionClipSpace;
|
||||
out vec4 vs_positionCameraSpace;
|
||||
out vec2 vs_positionModelSpace;
|
||||
|
||||
uniform float lightIntensityClamped;
|
||||
uniform mat4 modelViewTransform;
|
||||
uniform mat4 projectionTransform;
|
||||
uniform mat4 directionToSunViewSpace;
|
||||
|
||||
void main() {
|
||||
vs_positionModelSpace = in_position;
|
||||
|
||||
float totalIntensity = lightIntensityClamped;
|
||||
|
||||
vec4 positionCameraSpace = modelViewTransform * vec4(
|
||||
in_position * totalIntensity,
|
||||
0.0,
|
||||
1.0
|
||||
);
|
||||
|
||||
vec4 positionClipSpace = projectionTransform * positionCameraSpace;
|
||||
vs_positionClipSpace = z_normalization(positionClipSpace);
|
||||
gl_Position = z_normalization(positionClipSpace);
|
||||
}
|
||||
@@ -22,14 +22,12 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef TILE_FRAG_COLOR_HGLSL
|
||||
#define TILE_FRAG_COLOR_HGLSL
|
||||
#include "fragment.glsl"
|
||||
|
||||
#include <${MODULE_GLOBEBROWSING}/shaders/tile.hglsl>
|
||||
#include <${MODULE_GLOBEBROWSING}/shaders/texturetilemapping.hglsl>
|
||||
#include <${MODULE_GLOBEBROWSING}/shaders/tileheight.hglsl>
|
||||
#include "PowerScaling/powerScaling_fs.hglsl"
|
||||
#include "fragment.glsl"
|
||||
|
||||
// Below are all the tiles that are used for contributing the actual fragment color
|
||||
|
||||
@@ -47,18 +45,13 @@ uniform Layer Overlays[NUMLAYERS_OVERLAY];
|
||||
|
||||
#if USE_WATERMASK
|
||||
uniform Layer WaterMasks[NUMLAYERS_WATERMASK];
|
||||
float waterReflectance = 0.0;
|
||||
#endif // USE_WATERMASK
|
||||
|
||||
#if SHOW_HEIGHT_RESOLUTION
|
||||
uniform vec2 vertexResolution;
|
||||
#endif
|
||||
|
||||
#if USE_ATMOSPHERE
|
||||
// TODO atmosphere uniforms here
|
||||
#endif // USE_ATMOSPHERE
|
||||
|
||||
#if USE_NIGHTTEXTURE || USE_WATERMASK || USE_ATMOSPHERE || PERFORM_SHADING
|
||||
#if USE_NIGHTTEXTURE || USE_WATERMASK || PERFORM_SHADING
|
||||
uniform vec3 lightDirectionCameraSpace;
|
||||
#endif
|
||||
|
||||
@@ -67,7 +60,6 @@ uniform float orenNayarRoughness;
|
||||
#endif
|
||||
|
||||
#if USE_ECLIPSE_SHADOWS
|
||||
in vec3 positionWorldSpace;
|
||||
|
||||
/*******************************************************************************
|
||||
***** ALL CALCULATIONS FOR ECLIPSE ARE IN METERS AND IN WORLD SPACE SYSTEM ****
|
||||
@@ -77,60 +69,61 @@ in vec3 positionWorldSpace;
|
||||
const uint numberOfShadows = 1;
|
||||
|
||||
struct ShadowRenderingStruct {
|
||||
double xu, xp;
|
||||
double rs, rc;
|
||||
dvec3 sourceCasterVec;
|
||||
dvec3 casterPositionVec;
|
||||
bool isShadowing;
|
||||
double xu, xp;
|
||||
double rs, rc;
|
||||
dvec3 sourceCasterVec;
|
||||
dvec3 casterPositionVec;
|
||||
bool isShadowing;
|
||||
};
|
||||
|
||||
// Eclipse shadow data
|
||||
// JCC: Remove and use dictionary to
|
||||
// JCC: Remove and use dictionary to
|
||||
// decides the number of shadows
|
||||
uniform ShadowRenderingStruct shadowDataArray[numberOfShadows];
|
||||
uniform int shadows;
|
||||
uniform bool hardShadows;
|
||||
|
||||
vec4 butterworthFunc(const float d, const float r, const float n) {
|
||||
return vec4(vec3(sqrt(r/(r + pow(d, 2*n)))), 1.0);
|
||||
}
|
||||
|
||||
vec4 calcShadow(const ShadowRenderingStruct shadowInfoArray[numberOfShadows], const dvec3 position,
|
||||
const bool ground) {
|
||||
vec4 calcShadow(const ShadowRenderingStruct shadowInfoArray[numberOfShadows],
|
||||
const dvec3 position, const bool ground)
|
||||
{
|
||||
if (shadowInfoArray[0].isShadowing) {
|
||||
dvec3 pc = shadowInfoArray[0].casterPositionVec - position;
|
||||
dvec3 sc_norm = shadowInfoArray[0].sourceCasterVec;
|
||||
dvec3 pc_proj = dot(pc, sc_norm) * sc_norm;
|
||||
dvec3 d = pc - pc_proj;
|
||||
|
||||
|
||||
float length_d = float(length(d));
|
||||
double length_pc_proj = length(pc_proj);
|
||||
|
||||
|
||||
float r_p_pi = float(shadowInfoArray[0].rc * (length_pc_proj + shadowInfoArray[0].xp) / shadowInfoArray[0].xp);
|
||||
float r_u_pi = float(shadowInfoArray[0].rc * (shadowInfoArray[0].xu - length_pc_proj) / shadowInfoArray[0].xu);
|
||||
|
||||
if ( length_d < r_u_pi ) { // umbra
|
||||
|
||||
if (length_d < r_u_pi) { // umbra
|
||||
if (ground) {
|
||||
#if USE_ECLIPSE_HARD_SHADOWS
|
||||
#if USE_ECLIPSE_HARD_SHADOWS
|
||||
return vec4(0.2, 0.2, 0.2, 1.0);
|
||||
#else
|
||||
// butterworthFunc
|
||||
return vec4(vec3(sqrt(r_u_pi / (r_u_pi + pow(length_d, 8.0)))), 1.0);
|
||||
#endif
|
||||
return butterworthFunc(length_d, r_u_pi, 4.0);
|
||||
}
|
||||
else {
|
||||
#if USE_ECLIPSE_HARD_SHADOWS
|
||||
#if USE_ECLIPSE_HARD_SHADOWS
|
||||
return vec4(0.5, 0.5, 0.5, 1.0);
|
||||
#endif
|
||||
return vec4(vec3(length_d/r_p_pi), 1.0);
|
||||
#else
|
||||
return vec4(vec3(length_d / r_p_pi), 1.0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else if ( length_d < r_p_pi ) {// penumbra
|
||||
#if USE_ECLIPSE_HARD_SHADOWS
|
||||
return vec4(0.5, 0.5, 0.5, 1.0);
|
||||
#endif
|
||||
return vec4(vec3(length_d/r_p_pi), 1.0);
|
||||
else if (length_d < r_p_pi) {// penumbra
|
||||
#if USE_ECLIPSE_HARD_SHADOWS
|
||||
return vec4(0.5, 0.5, 0.5, 1.0);
|
||||
#else
|
||||
return vec4(vec3(length_d / r_p_pi), 1.0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return vec4(1.0);
|
||||
}
|
||||
#endif
|
||||
@@ -139,28 +132,27 @@ in vec4 fs_position;
|
||||
in vec3 fs_normal;
|
||||
in vec2 fs_uv;
|
||||
in vec3 ellipsoidNormalCameraSpace;
|
||||
in vec3 levelWeights;
|
||||
in vec3 positionCameraSpace;
|
||||
|
||||
#if USE_ACCURATE_NORMALS
|
||||
in vec3 ellipsoidTangentThetaCameraSpace;
|
||||
in vec3 ellipsoidTangentPhiCameraSpace;
|
||||
in vec3 ellipsoidTangentThetaCameraSpace;
|
||||
in vec3 ellipsoidTangentPhiCameraSpace;
|
||||
|
||||
// Once deferred light calculations are done in view space this can be removed
|
||||
// so that we only need one normal; in view space.
|
||||
uniform mat4 invViewModelTransform;
|
||||
// Once deferred light calculations are done in view space this can be removed
|
||||
// so that we only need one normal; in view space.
|
||||
uniform mat4 invViewModelTransform;
|
||||
#endif // USE_ACCURATE_NORMALS
|
||||
|
||||
// levelInterpolationParameter is used to interpolate between a tile and its parent tiles
|
||||
// The value increases with the distance from the vertex (or fragment) to the camera
|
||||
in LevelWeights levelWeights;
|
||||
#if USE_ECLIPSE_SHADOWS
|
||||
in vec3 positionWorldSpace;
|
||||
#endif // USE_ECLIPSE_SHADOWS
|
||||
|
||||
/**
|
||||
* This method defines the fragment color pipeline which is used in both
|
||||
* the local and global chunk rendering.
|
||||
*
|
||||
*/
|
||||
Fragment getTileFragment() {
|
||||
|
||||
|
||||
Fragment getFragment() {
|
||||
Fragment frag;
|
||||
|
||||
frag.color = vec4(0.3, 0.3, 0.3, 1.0);
|
||||
|
||||
vec3 normal = normalize(ellipsoidNormalCameraSpace);
|
||||
@@ -179,15 +171,11 @@ Fragment getTileFragment() {
|
||||
#endif /// USE_ACCURATE_NORMALS
|
||||
|
||||
#if USE_COLORTEXTURE
|
||||
frag.color = calculateColor(
|
||||
frag.color,
|
||||
fs_uv,
|
||||
levelWeights,
|
||||
ColorLayers
|
||||
);
|
||||
frag.color = calculateColor(frag.color, fs_uv, levelWeights, ColorLayers);
|
||||
#endif // USE_COLORTEXTURE
|
||||
|
||||
#if USE_WATERMASK
|
||||
float waterReflectance = 0.0;
|
||||
frag.color = calculateWater(
|
||||
frag.color,
|
||||
fs_uv,
|
||||
@@ -223,45 +211,16 @@ Fragment getTileFragment() {
|
||||
);
|
||||
#endif // PERFORM_SHADING
|
||||
|
||||
#if USE_ATMOSPHERE
|
||||
// Temporary until the real atmosphere code is here
|
||||
//frag.color = frag.color + vec4(0.5,0.5,1,0) * 0.3; // Just to see something for now
|
||||
const vec3 n = normalize(ellipsoidNormalCameraSpace);
|
||||
const vec3 l = lightDirectionCameraSpace;
|
||||
const vec3 c = normalize(positionCameraSpace);
|
||||
float cosFactor = 1 - clamp(dot(-n * 0.9, c), 0, 1);
|
||||
cosFactor *= 1.1;
|
||||
cosFactor -= 0.1;
|
||||
cosFactor = clamp(cosFactor, 0.0, 1.0);
|
||||
cosFactor = cosFactor + pow(cosFactor, 5);
|
||||
|
||||
const float shadowLight = 0.15;
|
||||
float cosFactorLight = pow(max(dot(-l, n), -shadowLight) + shadowLight, 0.8);
|
||||
//float cosFactorScatter = pow(max(dot(l, n) + shadowLight, 0), 5);
|
||||
//float cosFactorLight = max(dot(-lightDirectionCameraSpace, normalize(ellipsoidNormalCameraSpace)), 0);
|
||||
//vec3 r = reflect(l, n);
|
||||
//float scatteredLight = pow(clamp(dot(-r,c), 0, 1), 20);
|
||||
const vec3 atmosphereColor = vec3(0.5, 0.5, 1.0) * 2.0;
|
||||
frag.color += vec4(atmosphereColor,0) * cosFactor * cosFactorLight * 0.5;
|
||||
#endif // USE_ATMOSPHERE
|
||||
|
||||
#if USE_ECLIPSE_SHADOWS
|
||||
frag.color *= calcShadow(shadowDataArray, dvec3(positionWorldSpace), true);
|
||||
#endif
|
||||
|
||||
#if USE_OVERLAY
|
||||
frag.color = calculateOverlay(
|
||||
frag.color,
|
||||
fs_uv,
|
||||
levelWeights,
|
||||
Overlays
|
||||
);
|
||||
frag.color = calculateOverlay(frag.color, fs_uv, levelWeights, Overlays);
|
||||
#endif // USE_OVERLAY
|
||||
|
||||
#if SHOW_HEIGHT_INTENSITIES
|
||||
frag.color.r *= 0.1;
|
||||
frag.color.g *= 0.1;
|
||||
frag.color.b *= 0.1;
|
||||
frag.color.rgb *= vec3(0.1);
|
||||
|
||||
float untransformedHeight = getUntransformedTileVertexHeight(fs_uv, levelWeights);
|
||||
float contourLine = fract(10.0 * untransformedHeight) > 0.98 ? 1.0 : 0.0;
|
||||
@@ -270,7 +229,7 @@ Fragment getTileFragment() {
|
||||
#endif
|
||||
|
||||
#if SHOW_HEIGHT_RESOLUTION
|
||||
frag.color += 0.0001*calculateDebugColor(fs_uv, fs_position, vertexResolution);
|
||||
frag.color += 0.0001 * calculateDebugColor(fs_uv, fs_position, vertexResolution);
|
||||
#if USE_HEIGHTMAP
|
||||
frag.color.r = min(frag.color.r, 0.8);
|
||||
frag.color.r += tileResolution(fs_uv, HeightLayers[0].pile.chunkTile0) > 0.9 ? 1 : 0;
|
||||
@@ -292,7 +251,18 @@ Fragment getTileFragment() {
|
||||
frag.gPosition = vec4(positionCameraSpace, 1.0); // in Camera Rig Space
|
||||
|
||||
frag.depth = fs_position.w;
|
||||
|
||||
#if SHOW_CHUNK_EDGES
|
||||
const float BorderSize = 0.005;
|
||||
const vec3 BorderColor = vec3(1.0, 0.0, 0.0);
|
||||
|
||||
vec2 uvOffset = fs_uv - vec2(0.5);
|
||||
float thres = 0.5 - BorderSize * 0.5;
|
||||
bool isBorder = abs(uvOffset.x) > thres || abs(uvOffset.y) > thres;
|
||||
if (isBorder) {
|
||||
frag.color.rgb += BorderColor;
|
||||
}
|
||||
#endif // SHOW_CHUNK_EDGES
|
||||
|
||||
return frag;
|
||||
}
|
||||
|
||||
#endif ///TILE_FRAG_COLOR_HGLSL
|
||||
@@ -27,7 +27,6 @@
|
||||
|
||||
#include <${MODULE_GLOBEBROWSING}/shaders/tile.hglsl>
|
||||
#include <${MODULE_GLOBEBROWSING}/shaders/blending.hglsl>
|
||||
#include <${MODULE_GLOBEBROWSING}/shaders/globeshading.hglsl>
|
||||
|
||||
// First layer type from LayerShaderManager is height map
|
||||
#define NUMLAYERS_HEIGHTMAP #{lastLayerIndexHeightLayers} + 1
|
||||
@@ -58,7 +57,6 @@
|
||||
#define CHUNK_DEFAULT_HEIGHT #{defaultHeight}
|
||||
|
||||
// Other key value pairs used for settings
|
||||
#define USE_ATMOSPHERE #{useAtmosphere}
|
||||
#define USE_ACCURATE_NORMALS #{useAccurateNormals}
|
||||
#define PERFORM_SHADING #{performShading}
|
||||
#define USE_ECLIPSE_SHADOWS #{useEclipseShadows}
|
||||
@@ -67,58 +65,88 @@
|
||||
#define SHOW_HEIGHT_RESOLUTION #{showHeightResolution}
|
||||
#define SHOW_HEIGHT_INTENSITIES #{showHeightIntensities}
|
||||
|
||||
float performLayerSettingsRGB(float currentValue, LayerSettings settings) {
|
||||
float newValue = currentValue;
|
||||
const vec3 DefaultLevelWeights = vec3(1.0, 0.0, 0.0);
|
||||
|
||||
newValue = sign(newValue) * pow(abs(newValue), settings.gamma);
|
||||
newValue = newValue * settings.multiplier;
|
||||
newValue = newValue + settings.offset;
|
||||
float orenNayarDiffuse(vec3 lightDirection, vec3 viewDirection, vec3 surfaceNormal,
|
||||
float roughness)
|
||||
{
|
||||
// calculate intermediary values
|
||||
float NdotL = dot(surfaceNormal, lightDirection);
|
||||
float NdotV = dot(surfaceNormal, viewDirection);
|
||||
|
||||
return newValue;
|
||||
}
|
||||
|
||||
vec4 performLayerSettingsRGB(vec4 currentValue, LayerSettings settings) {
|
||||
vec4 newValue = vec4(
|
||||
performLayerSettingsRGB(currentValue.r, settings),
|
||||
performLayerSettingsRGB(currentValue.g, settings),
|
||||
performLayerSettingsRGB(currentValue.b, settings),
|
||||
currentValue.a
|
||||
float angleVN = acos(NdotV);
|
||||
float angleLN = acos(NdotL);
|
||||
|
||||
float alpha = max(angleVN, angleLN);
|
||||
float beta = min(angleVN, angleLN);
|
||||
float gamma = dot(
|
||||
viewDirection - surfaceNormal * dot(viewDirection, surfaceNormal),
|
||||
lightDirection - surfaceNormal * dot(lightDirection, surfaceNormal)
|
||||
);
|
||||
|
||||
return newValue;
|
||||
}
|
||||
|
||||
float performLayerSettingsAlpha(float currentValue, LayerSettings settings) {
|
||||
return currentValue * settings.opacity;
|
||||
}
|
||||
|
||||
vec4 performLayerSettingsAlpha(vec4 currentValue, LayerSettings settings) {
|
||||
return vec4(currentValue.rgb, performLayerSettingsAlpha(currentValue.a, settings));
|
||||
|
||||
float roughnessSquared = roughness * roughness;
|
||||
|
||||
// calculate A and B
|
||||
float A = 1.0 - 0.5 * (roughnessSquared / (roughnessSquared + 0.57));
|
||||
float B = 0.45 * (roughnessSquared / (roughnessSquared + 0.09));
|
||||
float C = sin(alpha) * tan(beta);
|
||||
|
||||
// put it all together
|
||||
return max(0.0, NdotL) * (A + B * max(0.0, gamma) * C);
|
||||
}
|
||||
|
||||
float performLayerSettings(float currentValue, LayerSettings settings) {
|
||||
return performLayerSettingsAlpha(
|
||||
performLayerSettingsRGB(currentValue, settings),
|
||||
settings
|
||||
);
|
||||
float v = sign(currentValue) * pow(abs(currentValue), settings.gamma) *
|
||||
settings.multiplier + settings.offset;
|
||||
return v * settings.opacity;
|
||||
}
|
||||
|
||||
vec4 performLayerSettings(vec4 currentValue, LayerSettings settings) {
|
||||
return performLayerSettingsAlpha(
|
||||
performLayerSettingsRGB(currentValue, settings),
|
||||
settings
|
||||
);
|
||||
vec3 newValue = sign(currentValue.rgb) * pow(abs(currentValue.rgb), vec3(settings.gamma)) *
|
||||
settings.multiplier + settings.offset;
|
||||
return vec4(newValue, currentValue.a * settings.opacity);
|
||||
}
|
||||
|
||||
vec2 tileUVToTextureSamplePosition(ChunkTile chunkTile, vec2 tileUV,
|
||||
PixelPadding padding)
|
||||
{
|
||||
vec2 uv = chunkTile.uvTransform.uvOffset + chunkTile.uvTransform.uvScale * tileUV;
|
||||
|
||||
// compensateSourceTextureSampling
|
||||
ivec2 resolution = textureSize(chunkTile.textureSampler, 0);
|
||||
vec2 sourceSize = vec2(resolution) + padding.sizeDifference;
|
||||
vec2 currentSize = vec2(resolution);
|
||||
vec2 sourceToCurrentSize = currentSize / sourceSize;
|
||||
return sourceToCurrentSize * (uv - padding.startOffset / sourceSize);
|
||||
}
|
||||
|
||||
vec4 getTexVal(ChunkTilePile chunkTilePile, vec3 w, vec2 uv,
|
||||
PixelPadding padding)
|
||||
{
|
||||
vec4 v1 = texture(
|
||||
chunkTilePile.chunkTile0.textureSampler,
|
||||
tileUVToTextureSamplePosition(chunkTilePile.chunkTile0, uv, padding)
|
||||
);
|
||||
vec4 v2 = texture(
|
||||
chunkTilePile.chunkTile1.textureSampler,
|
||||
tileUVToTextureSamplePosition(chunkTilePile.chunkTile1, uv, padding)
|
||||
);
|
||||
vec4 v3 = texture(
|
||||
chunkTilePile.chunkTile2.textureSampler,
|
||||
tileUVToTextureSamplePosition(chunkTilePile.chunkTile2, uv, padding)
|
||||
);
|
||||
|
||||
return w.x * v1 + w.y * v2 + w.z * v3;
|
||||
}
|
||||
|
||||
#for id, layerGroup in layerGroups
|
||||
#for i in 0..#{lastLayerIndex#{layerGroup}}
|
||||
|
||||
vec4 getSample#{layerGroup}#{i}(vec2 uv, LevelWeights levelWeights,
|
||||
vec4 getSample#{layerGroup}#{i}(vec2 uv, vec3 levelWeights,
|
||||
Layer #{layerGroup}[#{lastLayerIndex#{layerGroup}} + 1])
|
||||
{
|
||||
vec4 color = vec4(0,0,0,1);
|
||||
|
||||
vec4 color = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
|
||||
// All tile layers are the same. Sample from texture
|
||||
#if (#{#{layerGroup}#{i}LayerType} == 0) // DefaultTileLayer
|
||||
color = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv, #{layerGroup}[#{i}].padding);
|
||||
@@ -203,7 +231,7 @@ vec4 performAdjustment#{layerGroup}#{i}(vec4 currentColor,
|
||||
#endfor
|
||||
#endfor
|
||||
|
||||
float calculateUntransformedHeight(vec2 uv, LevelWeights levelWeights,
|
||||
float calculateUntransformedHeight(vec2 uv, vec3 levelWeights,
|
||||
Layer HeightLayers[NUMLAYERS_HEIGHTMAP])
|
||||
{
|
||||
|
||||
@@ -212,7 +240,7 @@ float calculateUntransformedHeight(vec2 uv, LevelWeights levelWeights,
|
||||
// The shader compiler will remove unused code when variables are multiplied by
|
||||
// a constant 0
|
||||
#if !HEIGHTMAP_BLENDING_ENABLED
|
||||
levelWeights = getDefaultLevelWeights();
|
||||
levelWeights = DefaultLevelWeights;
|
||||
#endif // HEIGHTMAP_BLENDING_ENABLED
|
||||
|
||||
#for i in 0..#{lastLayerIndexHeightLayers}
|
||||
@@ -227,17 +255,14 @@ float calculateUntransformedHeight(vec2 uv, LevelWeights levelWeights,
|
||||
return height;
|
||||
}
|
||||
|
||||
float calculateHeight(
|
||||
vec2 uv,
|
||||
LevelWeights levelWeights,
|
||||
Layer HeightLayers[NUMLAYERS_HEIGHTMAP]) {
|
||||
|
||||
float calculateHeight(vec2 uv, vec3 levelWeights, Layer HeightLayers[NUMLAYERS_HEIGHTMAP])
|
||||
{
|
||||
float height = 0;
|
||||
|
||||
// The shader compiler will remove unused code when variables are multiplied by
|
||||
// a constant 0
|
||||
#if !HEIGHTMAP_BLENDING_ENABLED
|
||||
levelWeights = getDefaultLevelWeights();
|
||||
levelWeights = DefaultLevelWeights;
|
||||
#endif // HEIGHTMAP_BLENDING_ENABLED
|
||||
|
||||
|
||||
@@ -247,7 +272,9 @@ float calculateHeight(
|
||||
colorSample = performAdjustmentHeightLayers#{i}(colorSample, HeightLayers[#{i}].adjustment);
|
||||
float untransformedHeight = colorSample.r;
|
||||
|
||||
float heightSample = getTransformedTexVal(HeightLayers[#{i}].depthTransform, untransformedHeight);
|
||||
TileDepthTransform transform = HeightLayers[#{i}].depthTransform;
|
||||
float heightSample =
|
||||
transform.depthScale * untransformedHeight + transform.depthOffset;
|
||||
if (heightSample > -100000) {
|
||||
heightSample = performLayerSettings(heightSample, HeightLayers[#{i}].settings);
|
||||
height = heightSample;
|
||||
@@ -257,7 +284,7 @@ float calculateHeight(
|
||||
return height;
|
||||
}
|
||||
|
||||
vec4 calculateColor(vec4 currentColor, vec2 uv, LevelWeights levelWeights,
|
||||
vec4 calculateColor(vec4 currentColor, vec2 uv, vec3 levelWeights,
|
||||
Layer ColorLayers[NUMLAYERS_COLORTEXTURE])
|
||||
{
|
||||
vec4 color = currentColor;
|
||||
@@ -265,7 +292,7 @@ vec4 calculateColor(vec4 currentColor, vec2 uv, LevelWeights levelWeights,
|
||||
// The shader compiler will remove unused code when variables are multiplied by
|
||||
// a constant 0
|
||||
#if !COLORTEXTURE_BLENDING_ENABLED
|
||||
levelWeights = getDefaultLevelWeights();
|
||||
levelWeights = DefaultLevelWeights;
|
||||
#endif // COLORTEXTURE_BLENDING_ENABLED
|
||||
|
||||
#for i in 0..#{lastLayerIndexColorLayers}
|
||||
@@ -278,20 +305,20 @@ vec4 calculateColor(vec4 currentColor, vec2 uv, LevelWeights levelWeights,
|
||||
}
|
||||
#endfor
|
||||
|
||||
return color;
|
||||
return color;
|
||||
}
|
||||
|
||||
float gridDots(vec2 uv, vec2 gridResolution){
|
||||
float gridDots(vec2 uv, vec2 gridResolution) {
|
||||
vec2 uvVertexSpace = fract((gridResolution) * uv) + 0.5;
|
||||
|
||||
vec2 uvDotSpace = abs(2*(uvVertexSpace-0.5));
|
||||
return 1-length(1-uvDotSpace);
|
||||
vec2 uvDotSpace = abs(2.0 * (uvVertexSpace - 0.5));
|
||||
return 1.0 - length(1.0 - uvDotSpace);
|
||||
}
|
||||
|
||||
vec4 calculateDebugColor(vec2 uv, vec4 fragPos, vec2 vertexResolution) {
|
||||
vec2 uvVertexSpace = fract(vertexResolution * uv);
|
||||
vec3 colorUv = vec3(0.3 * uv.x, 0.3 * uv.y, 0);
|
||||
vec3 colorDistance = vec3(0, 0, min( 0.4 * log(fragPos.w) - 3.9, 1));
|
||||
vec3 colorDistance = vec3(0.0, 0.0, min(0.4 * log(fragPos.w) - 3.9, 1));
|
||||
vec3 colorVertex = (1.0 - length(uvVertexSpace)) * vec3(0.5);
|
||||
vec3 colorSum = colorUv + colorDistance + colorVertex;
|
||||
return vec4(0.5 * colorSum, 1);
|
||||
@@ -303,12 +330,12 @@ float tileResolution(vec2 tileUV, ChunkTile chunkTile) {
|
||||
padding.sizeDifference = ivec2(0);
|
||||
|
||||
vec2 heightResolution = textureSize(chunkTile.textureSampler, 0);
|
||||
vec2 uv = TileUVToTextureSamplePosition(chunkTile, tileUV, padding);
|
||||
vec2 uv = tileUVToTextureSamplePosition(chunkTile, tileUV, padding);
|
||||
return gridDots(uv, heightResolution);
|
||||
}
|
||||
|
||||
vec4 calculateNight(vec4 currentColor, vec2 uv, LevelWeights levelWeights,
|
||||
Layer NightLayers[NUMLAYERS_NIGHTTEXTURE],
|
||||
vec4 calculateNight(vec4 currentColor, vec2 uv, vec3 levelWeights,
|
||||
Layer NightLayers[NUMLAYERS_NIGHTTEXTURE],
|
||||
vec3 ellipsoidNormalCameraSpace,
|
||||
vec3 lightDirectionCameraSpace)
|
||||
{
|
||||
@@ -318,7 +345,7 @@ vec4 calculateNight(vec4 currentColor, vec2 uv, LevelWeights levelWeights,
|
||||
// The shader compiler will remove unused code when variables are multiplied by
|
||||
// a constant 0
|
||||
#if !NIGHTTEXTURE_BLENDING_ENABLED
|
||||
levelWeights = getDefaultLevelWeights();
|
||||
levelWeights = DefaultLevelWeights;
|
||||
#endif // NIGHTTEXTURE_BLENDING_ENABLED
|
||||
|
||||
vec3 n = normalize(ellipsoidNormalCameraSpace);
|
||||
@@ -363,7 +390,7 @@ vec4 calculateShadedColor(vec4 currentColor, vec3 ellipsoidNormalCameraSpace,
|
||||
return color;
|
||||
}
|
||||
|
||||
vec4 calculateOverlay(vec4 currentColor, vec2 uv, LevelWeights levelWeights,
|
||||
vec4 calculateOverlay(vec4 currentColor, vec2 uv, vec3 levelWeights,
|
||||
Layer Overlays[NUMLAYERS_OVERLAY])
|
||||
{
|
||||
vec4 color = currentColor;
|
||||
@@ -371,7 +398,7 @@ vec4 calculateOverlay(vec4 currentColor, vec2 uv, LevelWeights levelWeights,
|
||||
// The shader compiler will remove unused code when variables are multiplied by
|
||||
// a constant 0
|
||||
#if !OVERLAY_BLENDING_ENABLED
|
||||
levelWeights = getDefaultLevelWeights();
|
||||
levelWeights = DefaultLevelWeights;
|
||||
#endif // OVERLAY_BLENDING_ENABLED
|
||||
|
||||
#for i in 0..#{lastLayerIndexOverlays}
|
||||
@@ -389,7 +416,7 @@ vec4 calculateOverlay(vec4 currentColor, vec2 uv, LevelWeights levelWeights,
|
||||
return color;
|
||||
}
|
||||
|
||||
vec4 calculateWater(vec4 currentColor, vec2 uv, LevelWeights levelWeights,
|
||||
vec4 calculateWater(vec4 currentColor, vec2 uv, vec3 levelWeights,
|
||||
Layer WaterMasks[NUMLAYERS_WATERMASK],
|
||||
vec3 ellipsoidNormalCameraSpace,
|
||||
vec3 lightDirectionCameraSpace, vec3 positionCameraSpace,
|
||||
@@ -400,7 +427,7 @@ vec4 calculateWater(vec4 currentColor, vec2 uv, LevelWeights levelWeights,
|
||||
// The shader compiler will remove unused code when variables are multiplied by
|
||||
// a constant 0
|
||||
#if !WATERMASK_BLENDING_ENABLED
|
||||
levelWeights = getDefaultLevelWeights();
|
||||
levelWeights = DefaultLevelWeights;
|
||||
#endif // WATERMASK_BLENDING_ENABLED
|
||||
|
||||
#for i in 0..#{lastLayerIndexWaterMasks}
|
||||
@@ -408,8 +435,7 @@ vec4 calculateWater(vec4 currentColor, vec2 uv, LevelWeights levelWeights,
|
||||
vec4 colorSample = getSampleWaterMasks#{i}(uv, levelWeights, WaterMasks);
|
||||
colorSample = performAdjustmentWaterMasks#{i}(colorSample, WaterMasks[#{i}].adjustment);
|
||||
|
||||
colorSample = performLayerSettingsAlpha(colorSample, WaterMasks[#{i}].settings);
|
||||
colorSample.a = performLayerSettingsRGB(colorSample.a, WaterMasks[#{i}].settings);
|
||||
colorSample.a = performLayerSettings(colorSample.a, WaterMasks[#{i}].settings);
|
||||
|
||||
waterColor = blendWaterMasks#{i}(waterColor, colorSample, 1.0);
|
||||
}
|
||||
@@ -420,8 +446,8 @@ vec4 calculateWater(vec4 currentColor, vec2 uv, LevelWeights levelWeights,
|
||||
float cosineFactor = clamp(dot(-reflectionDirectionCameraSpace, directionToFragmentCameraSpace), 0, 1);
|
||||
cosineFactor = pow(cosineFactor, 100);
|
||||
|
||||
vec3 specularColor = vec3(1, 1, 1);
|
||||
float specularIntensity = 0.4;
|
||||
const vec3 specularColor = vec3(1.0);
|
||||
const float specularIntensity = 0.4;
|
||||
|
||||
vec3 specularTotal = specularColor * cosineFactor * specularIntensity * waterColor.a;
|
||||
|
||||
|
||||
@@ -75,91 +75,4 @@ struct Layer {
|
||||
vec3 color;
|
||||
};
|
||||
|
||||
struct LevelWeights {
|
||||
float w1;
|
||||
float w2;
|
||||
float w3;
|
||||
};
|
||||
|
||||
vec4 patchBorderOverlay(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);
|
||||
}
|
||||
|
||||
float getTransformedTexVal(TileDepthTransform transform, float val) {
|
||||
return transform.depthOffset + transform.depthScale * val;
|
||||
}
|
||||
|
||||
vec4 getTransformedTexVal(TileDepthTransform transform, vec4 val) {
|
||||
return transform.depthOffset + transform.depthScale * val;
|
||||
}
|
||||
|
||||
vec2 compensateSourceTextureSampling(vec2 startOffset, vec2 sizeDiff, ChunkTile chunkTile,
|
||||
vec2 tileUV)
|
||||
{
|
||||
ivec2 resolution = textureSize(chunkTile.textureSampler, 0);
|
||||
|
||||
vec2 sourceSize = vec2(resolution) + sizeDiff;
|
||||
vec2 currentSize = vec2(resolution);
|
||||
vec2 sourceToCurrentSize = currentSize / sourceSize;
|
||||
return sourceToCurrentSize * (tileUV - startOffset / sourceSize);
|
||||
}
|
||||
|
||||
vec2 TileUVToTextureSamplePosition(ChunkTile chunkTile, vec2 tileUV,
|
||||
PixelPadding padding)
|
||||
{
|
||||
vec2 uv = chunkTile.uvTransform.uvOffset + chunkTile.uvTransform.uvScale * tileUV;
|
||||
return compensateSourceTextureSampling(
|
||||
padding.startOffset,
|
||||
padding.sizeDifference,
|
||||
chunkTile,
|
||||
uv
|
||||
);
|
||||
}
|
||||
|
||||
vec4 getTexVal(ChunkTile chunkTile, vec2 tileUV, PixelPadding padding) {
|
||||
return texture(
|
||||
chunkTile.textureSampler,
|
||||
TileUVToTextureSamplePosition(chunkTile, tileUV, padding)
|
||||
);
|
||||
}
|
||||
|
||||
float getLevelInterpolationParameter(int chunkLevel, float distanceScaleFactor,
|
||||
float distToVertexOnEllipsoid)
|
||||
{
|
||||
float projectedScaleFactor = distanceScaleFactor / distToVertexOnEllipsoid;
|
||||
float desiredLevel = log2(projectedScaleFactor);
|
||||
return chunkLevel - desiredLevel;
|
||||
}
|
||||
|
||||
LevelWeights getLevelWeights(float levelInterpolationParameter) {
|
||||
LevelWeights levelWeights;
|
||||
levelWeights.w1 = clamp(1.0 - levelInterpolationParameter, 0.0, 1.0);
|
||||
levelWeights.w2 = (
|
||||
clamp(levelInterpolationParameter, 0.0, 1.0) -
|
||||
clamp(levelInterpolationParameter - 1.0, 0.0, 1.0)
|
||||
);
|
||||
levelWeights.w3 = clamp(levelInterpolationParameter - 1.0, 0.0, 1.0);
|
||||
return levelWeights;
|
||||
}
|
||||
|
||||
LevelWeights getDefaultLevelWeights() {
|
||||
LevelWeights levelWeights;
|
||||
levelWeights.w1 = 1;
|
||||
levelWeights.w2 = 0;
|
||||
levelWeights.w3 = 0;
|
||||
return levelWeights;
|
||||
}
|
||||
|
||||
vec4 getTexVal(ChunkTilePile chunkTilePile, LevelWeights w, vec2 uv,
|
||||
PixelPadding padding)
|
||||
{
|
||||
return w.w1 * getTexVal(chunkTilePile.chunkTile0, uv, padding) +
|
||||
w.w2 * getTexVal(chunkTilePile.chunkTile1, uv, padding) +
|
||||
w.w3 * getTexVal(chunkTilePile.chunkTile2, uv, padding);
|
||||
}
|
||||
|
||||
#endif // TEXTURETILE_HGLSL
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include "PowerScaling/powerScaling_vs.hglsl"
|
||||
|
||||
#include <${MODULE_GLOBEBROWSING}/shaders/tile.hglsl>
|
||||
#include <${MODULE_GLOBEBROWSING}/shaders/ellipsoid.hglsl>
|
||||
|
||||
#ifndef USE_HEIGHTMAP
|
||||
#define USE_HEIGHTMAP #{useAccurateNormals}
|
||||
@@ -51,7 +50,7 @@ uniform float deltaPhi1;
|
||||
uniform float tileDelta;
|
||||
#endif //USE_ACCURATE_NORMALS && USE_HEIGHTMAP
|
||||
|
||||
float getUntransformedTileHeight(vec2 uv, LevelWeights levelWeights) {
|
||||
float getUntransformedTileHeight(vec2 uv, vec3 levelWeights) {
|
||||
float height = CHUNK_DEFAULT_HEIGHT;
|
||||
|
||||
#if USE_HEIGHTMAP
|
||||
@@ -67,7 +66,7 @@ float getUntransformedTileHeight(vec2 uv, LevelWeights levelWeights) {
|
||||
return height;
|
||||
}
|
||||
|
||||
float getTileHeight(vec2 uv, LevelWeights levelWeights) {
|
||||
float getTileHeight(vec2 uv, vec3 levelWeights) {
|
||||
float height = CHUNK_DEFAULT_HEIGHT;
|
||||
|
||||
#if USE_HEIGHTMAP
|
||||
@@ -83,7 +82,7 @@ float getTileHeight(vec2 uv, LevelWeights levelWeights) {
|
||||
return height;
|
||||
}
|
||||
|
||||
float getTileHeightScaled(vec2 uv, LevelWeights levelWeights) {
|
||||
float getTileHeightScaled(vec2 uv, vec3 levelWeights) {
|
||||
float height = getTileHeight(uv, levelWeights);
|
||||
|
||||
#if USE_HEIGHTMAP
|
||||
@@ -93,7 +92,7 @@ float getTileHeightScaled(vec2 uv, LevelWeights levelWeights) {
|
||||
return height;
|
||||
}
|
||||
|
||||
vec3 getTileNormal(vec2 uv, LevelWeights levelWeights, vec3 ellipsoidNormalCameraSpace,
|
||||
vec3 getTileNormal(vec2 uv, vec3 levelWeights, vec3 ellipsoidNormalCameraSpace,
|
||||
vec3 ellipsoidTangentThetaCameraSpace,
|
||||
vec3 ellipsoidTangentPhiCameraSpace)
|
||||
{
|
||||
|
||||
@@ -22,13 +22,12 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/globebrowsing/tile/asynctiledataprovider.h>
|
||||
#include <modules/globebrowsing/src/asynctiledataprovider.h>
|
||||
|
||||
#include <modules/globebrowsing/cache/memoryawaretilecache.h>
|
||||
#include <modules/globebrowsing/globebrowsingmodule.h>
|
||||
#include <modules/globebrowsing/other/pixelbuffercontainer.h>
|
||||
#include <modules/globebrowsing/tile/tileloadjob.h>
|
||||
#include <modules/globebrowsing/tile/rawtiledatareader/rawtiledatareader.h>
|
||||
#include <modules/globebrowsing/src/memoryawaretilecache.h>
|
||||
#include <modules/globebrowsing/src/rawtiledatareader.h>
|
||||
#include <modules/globebrowsing/src/tileloadjob.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
@@ -41,7 +40,7 @@ namespace {
|
||||
} // namespace
|
||||
|
||||
AsyncTileDataProvider::AsyncTileDataProvider(std::string name,
|
||||
const std::shared_ptr<RawTileDataReader> rawTileDataReader)
|
||||
std::unique_ptr<RawTileDataReader> rawTileDataReader)
|
||||
: _name(std::move(name))
|
||||
, _rawTileDataReader(std::move(rawTileDataReader))
|
||||
, _concurrentJobManager(LRUThreadPool<TileIndex::TileHashKey>(1, 10))
|
||||
@@ -52,72 +51,49 @@ AsyncTileDataProvider::AsyncTileDataProvider(std::string name,
|
||||
|
||||
AsyncTileDataProvider::~AsyncTileDataProvider() {} // NOLINT
|
||||
|
||||
std::shared_ptr<RawTileDataReader> AsyncTileDataProvider::rawTileDataReader() const {
|
||||
return _rawTileDataReader;
|
||||
const RawTileDataReader& AsyncTileDataProvider::rawTileDataReader() const {
|
||||
return *_rawTileDataReader;
|
||||
}
|
||||
|
||||
bool AsyncTileDataProvider::enqueueTileIO(const TileIndex& tileIndex) {
|
||||
if (_resetMode == ResetMode::ShouldNotReset && satisfiesEnqueueCriteria(tileIndex)) {
|
||||
if (_pboContainer) {
|
||||
char* dataPtr = static_cast<char*>(_pboContainer->mapBuffer(
|
||||
tileIndex.hashKey(), PixelBuffer::Access::WriteOnly));
|
||||
if (dataPtr) {
|
||||
auto job = std::make_shared<TileLoadJob>(_rawTileDataReader, tileIndex,
|
||||
dataPtr);
|
||||
_concurrentJobManager.enqueueJob(job, tileIndex.hashKey());
|
||||
_enqueuedTileRequests.insert(tileIndex.hashKey());
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
auto job = std::make_shared<TileLoadJob>(_rawTileDataReader, tileIndex);
|
||||
_concurrentJobManager.enqueueJob(job, tileIndex.hashKey());
|
||||
_enqueuedTileRequests.insert(tileIndex.hashKey());
|
||||
}
|
||||
auto job = std::make_unique<TileLoadJob>(*_rawTileDataReader, tileIndex);
|
||||
_concurrentJobManager.enqueueJob(std::move(job), tileIndex.hashKey());
|
||||
_enqueuedTileRequests.insert(tileIndex.hashKey());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<RawTile>> AsyncTileDataProvider::rawTiles() {
|
||||
std::vector<std::shared_ptr<RawTile>> readyResults;
|
||||
std::shared_ptr<RawTile> finishedJob = popFinishedRawTile();
|
||||
std::vector<RawTile> AsyncTileDataProvider::rawTiles() {
|
||||
std::vector<RawTile> readyResults;
|
||||
std::optional<RawTile> finishedJob = popFinishedRawTile();
|
||||
while (finishedJob) {
|
||||
readyResults.push_back(finishedJob);
|
||||
readyResults.push_back(std::move(finishedJob.value()));
|
||||
finishedJob = popFinishedRawTile();
|
||||
}
|
||||
return readyResults;
|
||||
}
|
||||
|
||||
std::shared_ptr<RawTile> AsyncTileDataProvider::popFinishedRawTile() {
|
||||
std::optional<RawTile> AsyncTileDataProvider::popFinishedRawTile() {
|
||||
if (_concurrentJobManager.numFinishedJobs() > 0) {
|
||||
// Now the tile load job looses ownerwhip of the data pointer
|
||||
std::shared_ptr<RawTile> product =
|
||||
_concurrentJobManager.popFinishedJob()->product();
|
||||
RawTile product = _concurrentJobManager.popFinishedJob()->product();
|
||||
|
||||
const TileIndex::TileHashKey key = product->tileIndex.hashKey();
|
||||
const TileIndex::TileHashKey key = product.tileIndex.hashKey();
|
||||
// No longer enqueued. Remove from set of enqueued tiles
|
||||
_enqueuedTileRequests.erase(key);
|
||||
// Pbo is still mapped. Set the id for the raw tile
|
||||
if (_pboContainer) {
|
||||
product->pbo = _pboContainer->idOfMappedBuffer(key);
|
||||
// Now we are finished with the mapping of this pbo
|
||||
_pboContainer->unMapBuffer(key);
|
||||
}
|
||||
else {
|
||||
product->pbo = 0;
|
||||
if (product->error != RawTile::ReadError::None) {
|
||||
delete[] product->imageData;
|
||||
return nullptr;
|
||||
}
|
||||
product.pbo = 0;
|
||||
if (product.error != RawTile::ReadError::None) {
|
||||
product.imageData = nullptr;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return product;
|
||||
}
|
||||
else {
|
||||
return nullptr;
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,10 +113,6 @@ void AsyncTileDataProvider::endUnfinishedJobs() {
|
||||
std::vector<TileIndex::TileHashKey> unfinishedJobs =
|
||||
_concurrentJobManager.keysToUnfinishedJobs();
|
||||
for (const TileIndex::TileHashKey& unfinishedJob : unfinishedJobs) {
|
||||
// Unmap unfinished jobs
|
||||
if (_pboContainer) {
|
||||
_pboContainer->unMapBuffer(unfinishedJob);
|
||||
}
|
||||
// When erasing the job before
|
||||
_enqueuedTileRequests.erase(unfinishedJob);
|
||||
}
|
||||
@@ -150,31 +122,11 @@ void AsyncTileDataProvider::endEnqueuedJobs() {
|
||||
std::vector<TileIndex::TileHashKey> enqueuedJobs =
|
||||
_concurrentJobManager.keysToEnqueuedJobs();
|
||||
for (const TileIndex::TileHashKey& enqueuedJob : enqueuedJobs) {
|
||||
// Unmap unfinished jobs
|
||||
if (_pboContainer) {
|
||||
_pboContainer->unMapBuffer(enqueuedJob);
|
||||
}
|
||||
// When erasing the job before
|
||||
_enqueuedTileRequests.erase(enqueuedJob);
|
||||
}
|
||||
}
|
||||
|
||||
void AsyncTileDataProvider::updatePboUsage() {
|
||||
const bool usingPbo = _pboContainer != nullptr;
|
||||
const bool shouldUsePbo = _globeBrowsingModule->tileCache()->shouldUsePbo();
|
||||
|
||||
// If changed, we need to reset the async tile data provider.
|
||||
// No need to reset the raw tile data reader when changing PBO usage.
|
||||
if (usingPbo != shouldUsePbo &&
|
||||
_resetMode != ResetMode::ShouldResetAllButRawTileDataReader)
|
||||
{
|
||||
_resetMode = ResetMode::ShouldResetAllButRawTileDataReader;
|
||||
LINFO(fmt::format(
|
||||
"PBO usage updated, prepairing for resetting of tile reader '{}'", _name
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
void AsyncTileDataProvider::update() {
|
||||
endUnfinishedJobs();
|
||||
|
||||
@@ -210,7 +162,6 @@ void AsyncTileDataProvider::update() {
|
||||
break;
|
||||
}
|
||||
case ResetMode::ShouldNotReset: {
|
||||
updatePboUsage();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -226,7 +177,7 @@ void AsyncTileDataProvider::reset() {
|
||||
LINFO(fmt::format("Prepairing for resetting of tile reader '{}'", _name));
|
||||
}
|
||||
|
||||
void AsyncTileDataProvider::prepairToBeDeleted() {
|
||||
void AsyncTileDataProvider::prepareToBeDeleted() {
|
||||
_resetMode = ResetMode::ShouldBeDeleted;
|
||||
endEnqueuedJobs();
|
||||
}
|
||||
@@ -238,19 +189,6 @@ bool AsyncTileDataProvider::shouldBeDeleted() {
|
||||
void AsyncTileDataProvider::performReset(ResetRawTileDataReader resetRawTileDataReader) {
|
||||
ghoul_assert(_enqueuedTileRequests.empty(), "No enqueued requests left");
|
||||
|
||||
// Re-initialize PBO container
|
||||
if (_globeBrowsingModule->tileCache()->shouldUsePbo()) {
|
||||
size_t pboNumBytes = _rawTileDataReader->tileTextureInitData().totalNumBytes();
|
||||
_pboContainer = std::make_unique<PixelBufferContainer<TileIndex::TileHashKey>>(
|
||||
pboNumBytes,
|
||||
PixelBuffer::Usage::StreamDraw,
|
||||
10
|
||||
);
|
||||
}
|
||||
else {
|
||||
_pboContainer = nullptr;
|
||||
}
|
||||
|
||||
// Reset raw tile data reader
|
||||
if (resetRawTileDataReader == ResetRawTileDataReader::Yes) {
|
||||
_rawTileDataReader->reset();
|
||||
@@ -25,20 +25,19 @@
|
||||
#ifndef __OPENSPACE_MODULE_GLOBEBROWSING___ASYNC_TILE_DATAPROVIDER___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___ASYNC_TILE_DATAPROVIDER___H__
|
||||
|
||||
#include <modules/globebrowsing/other/prioritizingconcurrentjobmanager.h>
|
||||
#include <modules/globebrowsing/tile/tileindex.h>
|
||||
#include <modules/globebrowsing/src/prioritizingconcurrentjobmanager.h>
|
||||
#include <modules/globebrowsing/src/rawtiledatareader.h>
|
||||
#include <modules/globebrowsing/src/tileindex.h>
|
||||
#include <ghoul/misc/boolean.h>
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
|
||||
namespace openspace { class GlobeBrowsingModule; }
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
template <typename T> class PixelBufferContainer;
|
||||
|
||||
struct RawTile;
|
||||
class RawTileDataReader;
|
||||
|
||||
/**
|
||||
* The responsibility of this class is to enqueue tile requests and fetching finished
|
||||
@@ -51,7 +50,7 @@ public:
|
||||
* tile loading.
|
||||
*/
|
||||
AsyncTileDataProvider(std::string name,
|
||||
std::shared_ptr<RawTileDataReader> rawTileDataReader);
|
||||
std::unique_ptr<RawTileDataReader> rawTileDataReader);
|
||||
|
||||
~AsyncTileDataProvider();
|
||||
|
||||
@@ -63,20 +62,20 @@ public:
|
||||
/**
|
||||
* Get all finished jobs.
|
||||
*/
|
||||
std::vector<std::shared_ptr<RawTile>> rawTiles();
|
||||
std::vector<RawTile> rawTiles();
|
||||
|
||||
/**
|
||||
* Get one finished job.
|
||||
*/
|
||||
std::shared_ptr<RawTile> popFinishedRawTile();
|
||||
std::optional<RawTile> popFinishedRawTile();
|
||||
|
||||
void update();
|
||||
void reset();
|
||||
void prepairToBeDeleted();
|
||||
void prepareToBeDeleted();
|
||||
|
||||
bool shouldBeDeleted();
|
||||
|
||||
std::shared_ptr<RawTileDataReader> rawTileDataReader() const;
|
||||
const RawTileDataReader& rawTileDataReader() const;
|
||||
float noDataValueAsFloat() const;
|
||||
|
||||
protected:
|
||||
@@ -103,21 +102,17 @@ protected:
|
||||
|
||||
void endEnqueuedJobs();
|
||||
|
||||
void updatePboUsage();
|
||||
|
||||
void performReset(ResetRawTileDataReader resetRawTileDataReader);
|
||||
|
||||
private:
|
||||
const std::string _name;
|
||||
GlobeBrowsingModule* _globeBrowsingModule;
|
||||
/// The reader used for asynchronous reading
|
||||
std::shared_ptr<RawTileDataReader> _rawTileDataReader;
|
||||
std::unique_ptr<RawTileDataReader> _rawTileDataReader;
|
||||
|
||||
PrioritizingConcurrentJobManager<RawTile, TileIndex::TileHashKey>
|
||||
_concurrentJobManager;
|
||||
|
||||
/// nullptr if pbo is not used for texture uploading. Otherwise initialized.
|
||||
std::unique_ptr<PixelBufferContainer<TileIndex::TileHashKey>> _pboContainer;
|
||||
std::set<TileIndex::TileHashKey> _enqueuedTileRequests;
|
||||
|
||||
ResetMode _resetMode = ResetMode::ShouldResetAllButRawTileDataReader;
|
||||
@@ -22,27 +22,95 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_GLOBEBROWSING___TILE___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___TILE___H__
|
||||
#ifndef __OPENSPACE_MODULE_GLOBEBROWSING__BASICTYPES___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING__BASICTYPES___H__
|
||||
|
||||
#include <modules/globebrowsing/tile/tilemetadata.h>
|
||||
#include <ghoul/glm.h>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
namespace ghoul::opengl { class Texture; }
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
struct TileUvTransform;
|
||||
struct AABB3 {
|
||||
glm::vec3 min = glm::vec3(std::numeric_limits<float>::max());
|
||||
glm::vec3 max = glm::vec3(-std::numeric_limits<float>::max());
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct Geodetic2 {
|
||||
double lat;
|
||||
double lon;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct Geodetic3 {
|
||||
Geodetic2 geodetic2;
|
||||
double height;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct PixelRegion {
|
||||
glm::ivec2 start = glm::ivec2(0);
|
||||
glm::ivec2 numPixels = glm::ivec2(0);
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct IODescription {
|
||||
struct ReadData {
|
||||
int overview;
|
||||
PixelRegion region;
|
||||
PixelRegion fullRegion;
|
||||
} read;
|
||||
|
||||
struct WriteData {
|
||||
PixelRegion region;
|
||||
size_t bytesPerLine;
|
||||
size_t totalNumBytes;
|
||||
} write;
|
||||
};
|
||||
|
||||
|
||||
|
||||
enum Quad {
|
||||
NORTH_WEST = 0,
|
||||
NORTH_EAST,
|
||||
SOUTH_WEST,
|
||||
SOUTH_EAST
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct TileDepthTransform {
|
||||
float scale;
|
||||
float offset;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct TileMetaData {
|
||||
std::vector<float> maxValues;
|
||||
std::vector<float> minValues;
|
||||
std::vector<bool> hasMissingData;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Defines a status and may have a Texture and TileMetaData
|
||||
*/
|
||||
class Tile {
|
||||
public:
|
||||
/**
|
||||
* Describe if this Tile is good for usage (OK) or otherwise
|
||||
* the reason why it is not.
|
||||
*/
|
||||
/**
|
||||
* Describe if this Tile is good for usage (OK) or otherwise
|
||||
* the reason why it is not.
|
||||
*/
|
||||
enum class Status {
|
||||
/**
|
||||
* E.g when texture data is not currently in memory.
|
||||
@@ -71,27 +139,30 @@ public:
|
||||
OK
|
||||
};
|
||||
|
||||
Tile(ghoul::opengl::Texture* texture, std::shared_ptr<TileMetaData> metaData,
|
||||
Status status);
|
||||
~Tile() = default;
|
||||
|
||||
TileMetaData* metaData() const;
|
||||
Status status() const;
|
||||
ghoul::opengl::Texture* texture() const;
|
||||
|
||||
/**
|
||||
* A tile with status unavailable that any user can return to
|
||||
* indicate that a tile was unavailable.
|
||||
*/
|
||||
static const Tile TileUnavailable;
|
||||
|
||||
private:
|
||||
ghoul::opengl::Texture* _texture;
|
||||
std::shared_ptr<TileMetaData> _metaData;
|
||||
Status _status;
|
||||
ghoul::opengl::Texture* texture = nullptr;
|
||||
std::optional<TileMetaData> metaData = std::nullopt;
|
||||
Status status = Status::Unavailable;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct TileUvTransform {
|
||||
glm::vec2 uvOffset;
|
||||
glm::vec2 uvScale;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct ChunkTile {
|
||||
Tile tile;
|
||||
TileUvTransform uvTransform;
|
||||
TileDepthTransform depthTransform;
|
||||
};
|
||||
|
||||
|
||||
|
||||
using ChunkTilePile = std::vector<ChunkTile>;
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___TILE___H__
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING__BASICTYPES___H__
|
||||
@@ -22,10 +22,10 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/globebrowsing/dashboard/dashboarditemglobelocation.h>
|
||||
#include <modules/globebrowsing/src/dashboarditemglobelocation.h>
|
||||
|
||||
#include <modules/globebrowsing/geometry/geodetic2.h>
|
||||
#include <modules/globebrowsing/globes/renderableglobe.h>
|
||||
#include <modules/globebrowsing/src/basictypes.h>
|
||||
#include <modules/globebrowsing/src/renderableglobe.h>
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
@@ -115,7 +115,7 @@ DashboardItemGlobeLocation::DashboardItemGlobeLocation(
|
||||
const ghoul::Dictionary& dictionary)
|
||||
: DashboardItem(dictionary)
|
||||
, _fontName(FontNameInfo, KeyFontMono)
|
||||
, _fontSize(FontSizeInfo, DefaultFontSize, 6.f, 144.f, 1.f)
|
||||
, _fontSize(FontSizeInfo, DefaultFontSize, 10.f, 144.f, 1.f)
|
||||
, _font(global::fontManager.font(KeyFontMono, 10))
|
||||
{
|
||||
documentation::testSpecificationAndThrow(
|
||||
@@ -148,14 +148,13 @@ void DashboardItemGlobeLocation::render(glm::vec2& penPosition) {
|
||||
using namespace globebrowsing;
|
||||
|
||||
SceneGraphNode* n = global::navigationHandler.focusNode();
|
||||
const RenderableGlobe* globe = dynamic_cast<const RenderableGlobe*>(n->renderable());
|
||||
const RenderableGlobe* globe = dynamic_cast<const RenderableGlobe*>(n->renderable());
|
||||
if (!globe) {
|
||||
return;
|
||||
}
|
||||
|
||||
const glm::dvec3 cameraPosition = global::navigationHandler.camera()->positionVec3();
|
||||
const glm::dmat4 inverseModelTransform =
|
||||
global::navigationHandler.focusNode()->inverseModelTransform();
|
||||
const glm::dmat4 inverseModelTransform = n->inverseModelTransform();
|
||||
const glm::dvec3 cameraPositionModelSpace =
|
||||
glm::dvec3(inverseModelTransform * glm::dvec4(cameraPosition, 1.0));
|
||||
const SurfacePositionHandle posHandle = globe->calculateSurfacePositionHandle(
|
||||
@@ -175,8 +174,9 @@ void DashboardItemGlobeLocation::render(glm::vec2& penPosition) {
|
||||
bool isEast = lon > 0.0;
|
||||
lon = std::abs(lon);
|
||||
|
||||
const double altitude = glm::length(cameraPositionModelSpace -
|
||||
posHandle.centerToReferenceSurface);
|
||||
const double altitude = glm::length(
|
||||
cameraPositionModelSpace - posHandle.centerToReferenceSurface
|
||||
);
|
||||
std::pair<double, std::string> dist = simplifyDistance(altitude);
|
||||
|
||||
penPosition.y -= _font->height();
|
||||
@@ -187,7 +187,8 @@ void DashboardItemGlobeLocation::render(glm::vec2& penPosition) {
|
||||
"Position: {:03.2f}{}, {:03.2f}{} Altitude: {} {}",
|
||||
lat, isNorth ? "N" : "S",
|
||||
lon, isEast ? "E" : "W",
|
||||
dist.first, dist.second)
|
||||
dist.first, dist.second
|
||||
)
|
||||
);
|
||||
}
|
||||
glm::vec2 DashboardItemGlobeLocation::size() const {
|
||||
@@ -22,18 +22,16 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/globebrowsing/geometry/ellipsoid.h>
|
||||
|
||||
#include <modules/globebrowsing/geometry/geodetic2.h>
|
||||
#include <modules/globebrowsing/geometry/geodetic3.h>
|
||||
#include <modules/globebrowsing/src/ellipsoid.h>
|
||||
|
||||
#include <modules/globebrowsing/src/basictypes.h>
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
constexpr const size_t MaxIterations = 8;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
@@ -42,30 +40,25 @@ Ellipsoid::Ellipsoid(glm::dvec3 radii) : _radii(radii) {
|
||||
}
|
||||
|
||||
void Ellipsoid::updateInternalCache() {
|
||||
_cached._radiiSquared = glm::dvec3(
|
||||
_radii.x * _radii.x,
|
||||
_radii.y * _radii.y,
|
||||
_radii.z * _radii.z
|
||||
);
|
||||
_cached.radiiSquared = _radii * _radii;
|
||||
|
||||
_cached._oneOverRadiiSquared = glm::dvec3(1.0) / _cached._radiiSquared;
|
||||
_cached._radiiToTheFourth = _cached._radiiSquared * _cached._radiiSquared;
|
||||
_cached.oneOverRadiiSquared = glm::dvec3(1.0) / _cached.radiiSquared;
|
||||
_cached.radiiToTheFourth = _cached.radiiSquared * _cached.radiiSquared;
|
||||
|
||||
std::array<double, 3> radii = { _radii.x, _radii.y, _radii.z };
|
||||
std::sort(radii.begin(), radii.end());
|
||||
_cached._minimumRadius = radii[0];
|
||||
_cached._medianRadius = radii[1];
|
||||
_cached._maximumRadius = radii[2];
|
||||
_cached.minimumRadius = radii[0];
|
||||
_cached.maximumRadius = radii[2];
|
||||
}
|
||||
|
||||
glm::dvec3 Ellipsoid::geocentricSurfaceProjection(const glm::dvec3& p) const {
|
||||
const double beta = 1.0 / sqrt(dot(p * p, _cached._oneOverRadiiSquared));
|
||||
const double beta = 1.0 / sqrt(dot(p * p, _cached.oneOverRadiiSquared));
|
||||
return beta * p;
|
||||
}
|
||||
|
||||
glm::dvec3 Ellipsoid::geodeticSurfaceProjection(const glm::dvec3& p) const {
|
||||
const double beta = 1.0 / sqrt(dot(p * p, _cached._oneOverRadiiSquared));
|
||||
const double n = glm::length(beta * p * _cached._oneOverRadiiSquared);
|
||||
const double beta = 1.0 / sqrt(dot(p * p, _cached.oneOverRadiiSquared));
|
||||
const double n = glm::length(beta * p * _cached.oneOverRadiiSquared);
|
||||
double alpha = (1.0 - beta) * (glm::length(p) / n);
|
||||
|
||||
const glm::dvec3 p2 = p * p;
|
||||
@@ -79,13 +72,13 @@ glm::dvec3 Ellipsoid::geodeticSurfaceProjection(const glm::dvec3& p) const {
|
||||
do {
|
||||
alpha -= (s / dSdA);
|
||||
|
||||
d = glm::dvec3(1.0) + alpha * _cached._oneOverRadiiSquared;
|
||||
d = glm::dvec3(1.0) + alpha * _cached.oneOverRadiiSquared;
|
||||
const glm::dvec3 d2 = d * d;
|
||||
const glm::dvec3 d3 = d * d2;
|
||||
|
||||
s = glm::dot(p2 / (_cached._radiiSquared * d2), glm::dvec3(1.0)) - 1.0;
|
||||
s = glm::dot(p2 / (_cached.radiiSquared * d2), glm::dvec3(1.0)) - 1.0;
|
||||
|
||||
dSdA = -2.0 * glm::dot(p2 / (_cached._radiiToTheFourth * d3), glm::dvec3(1.0));
|
||||
dSdA = -2.0 * glm::dot(p2 / (_cached.radiiToTheFourth * d3), glm::dvec3(1.0));
|
||||
++nIterations;
|
||||
}
|
||||
while (std::abs(s) > epsilon && nIterations < MaxIterations);
|
||||
@@ -96,7 +89,7 @@ glm::dvec3 Ellipsoid::geodeticSurfaceProjection(const glm::dvec3& p) const {
|
||||
glm::dvec3 Ellipsoid::geodeticSurfaceNormalForGeocentricallyProjectedPoint(
|
||||
const glm::dvec3& p) const
|
||||
{
|
||||
const glm::dvec3 normal = p * _cached._oneOverRadiiSquared;
|
||||
const glm::dvec3 normal = p * _cached.oneOverRadiiSquared;
|
||||
return glm::normalize(normal);
|
||||
}
|
||||
|
||||
@@ -114,28 +107,12 @@ const glm::dvec3& Ellipsoid::radii() const {
|
||||
return _radii;
|
||||
}
|
||||
|
||||
const glm::dvec3& Ellipsoid::radiiSquared() const {
|
||||
return _cached._radiiSquared;
|
||||
}
|
||||
|
||||
const glm::dvec3& Ellipsoid::oneOverRadiiSquared() const {
|
||||
return _cached._oneOverRadiiSquared;
|
||||
}
|
||||
|
||||
const glm::dvec3& Ellipsoid::radiiToTheFourth() const {
|
||||
return _cached._radiiToTheFourth;
|
||||
}
|
||||
|
||||
double Ellipsoid::minimumRadius() const {
|
||||
return _cached._minimumRadius;
|
||||
return _cached.minimumRadius;
|
||||
}
|
||||
|
||||
double Ellipsoid::maximumRadius() const {
|
||||
return _cached._maximumRadius;
|
||||
}
|
||||
|
||||
double Ellipsoid::averageRadius() const {
|
||||
return (_radii.x + _radii.y + _radii.z) / 3.0;
|
||||
return _cached.maximumRadius;
|
||||
}
|
||||
|
||||
double Ellipsoid::longitudalDistance(double lat, double lon1, double lon2) const {
|
||||
@@ -155,7 +132,10 @@ double Ellipsoid::greatCircleDistance(const Geodetic2& p1, const Geodetic2& p2)
|
||||
glm::length(glm::cross(n1, n2)) / glm::dot(n1, n2)
|
||||
);
|
||||
|
||||
const Geodetic2 pMid = (p1 + p2) / 2;
|
||||
const Geodetic2 pMid = {
|
||||
(p1.lat + p2.lat) / 2.0,
|
||||
(p1.lon + p2.lon) / 2.0
|
||||
};
|
||||
const glm::dvec3 centralNormal = cartesianSurfacePosition(pMid);
|
||||
|
||||
return centralAngle * glm::length(centralNormal);
|
||||
@@ -163,10 +143,10 @@ double Ellipsoid::greatCircleDistance(const Geodetic2& p1, const Geodetic2& p2)
|
||||
|
||||
Geodetic2 Ellipsoid::cartesianToGeodetic2(const glm::dvec3& p) const {
|
||||
const glm::dvec3 normal = geodeticSurfaceNormalForGeocentricallyProjectedPoint(p);
|
||||
return Geodetic2(
|
||||
asin(normal.z / length(normal)), // Latitude
|
||||
atan2(normal.y, normal.x) // Longitude
|
||||
);
|
||||
Geodetic2 res;
|
||||
res.lat = asin(normal.z / length(normal));
|
||||
res.lon = atan2(normal.y, normal.x);
|
||||
return res;
|
||||
}
|
||||
|
||||
glm::dvec3 Ellipsoid::cartesianSurfacePosition(const Geodetic2& geodetic2) const {
|
||||
@@ -176,24 +156,22 @@ glm::dvec3 Ellipsoid::cartesianSurfacePosition(const Geodetic2& geodetic2) const
|
||||
|
||||
glm::dvec3 Ellipsoid::cartesianPosition(const Geodetic3& geodetic3) const {
|
||||
const glm::dvec3 normal = geodeticSurfaceNormal(geodetic3.geodetic2);
|
||||
const glm::dvec3 k = _cached._radiiSquared * normal;
|
||||
const glm::dvec3 k = _cached.radiiSquared * normal;
|
||||
const double gamma = sqrt(dot(k, normal));
|
||||
const glm::dvec3 rSurface = k / gamma;
|
||||
return rSurface + geodetic3.height * normal;
|
||||
}
|
||||
|
||||
void Ellipsoid::setShadowConfigurationArray(
|
||||
const std::vector<Ellipsoid::ShadowConfiguration>& shadowConfArray)
|
||||
std::vector<Ellipsoid::ShadowConfiguration> shadowConfArray)
|
||||
{
|
||||
_shadowConfArray = shadowConfArray;
|
||||
_shadowConfArray = std::move(shadowConfArray);
|
||||
}
|
||||
|
||||
std::vector<Ellipsoid::ShadowConfiguration> Ellipsoid::shadowConfigurationArray() const {
|
||||
const std::vector<Ellipsoid::ShadowConfiguration>&
|
||||
Ellipsoid::shadowConfigurationArray() const
|
||||
{
|
||||
return _shadowConfArray;
|
||||
}
|
||||
|
||||
bool Ellipsoid::hasEclipseShadows() const {
|
||||
return !_shadowConfArray.empty();
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -77,13 +77,9 @@ public:
|
||||
glm::dvec3 geodeticSurfaceNormal(const Geodetic2& geodetic2) const;
|
||||
|
||||
const glm::dvec3& radii() const;
|
||||
const glm::dvec3& radiiSquared() const;
|
||||
const glm::dvec3& oneOverRadiiSquared() const;
|
||||
const glm::dvec3& radiiToTheFourth() const;
|
||||
|
||||
double minimumRadius() const;
|
||||
double maximumRadius() const;
|
||||
double averageRadius() const;
|
||||
|
||||
double longitudalDistance(double lat, double lon1, double lon2) const;
|
||||
double greatCircleDistance(const Geodetic2& p1, const Geodetic2& p2) const;
|
||||
@@ -93,19 +89,17 @@ public:
|
||||
glm::dvec3 cartesianPosition(const Geodetic3& geodetic3) const;
|
||||
|
||||
void setShadowConfigurationArray(
|
||||
const std::vector<Ellipsoid::ShadowConfiguration>& shadowConfArray
|
||||
std::vector<Ellipsoid::ShadowConfiguration> shadowConfArray
|
||||
);
|
||||
std::vector<Ellipsoid::ShadowConfiguration> shadowConfigurationArray() const;
|
||||
bool hasEclipseShadows() const;
|
||||
const std::vector<Ellipsoid::ShadowConfiguration>& shadowConfigurationArray() const;
|
||||
|
||||
private:
|
||||
struct EllipsoidCache {
|
||||
glm::dvec3 _radiiSquared;
|
||||
glm::dvec3 _oneOverRadiiSquared;
|
||||
glm::dvec3 _radiiToTheFourth;
|
||||
double _minimumRadius;
|
||||
double _maximumRadius;
|
||||
double _medianRadius;
|
||||
glm::dvec3 radiiSquared;
|
||||
glm::dvec3 oneOverRadiiSquared;
|
||||
glm::dvec3 radiiToTheFourth;
|
||||
double minimumRadius;
|
||||
double maximumRadius;
|
||||
} _cached;
|
||||
|
||||
void updateInternalCache();
|
||||
@@ -22,20 +22,16 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifdef GLOBEBROWSING_USE_GDAL
|
||||
|
||||
#include <modules/globebrowsing/tile/rawtiledatareader/gdalwrapper.h>
|
||||
#include <modules/globebrowsing/src/gdalwrapper.h>
|
||||
|
||||
#include <openspace/engine/configuration.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/ghoul.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/logging/consolelog.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <gdal.h>
|
||||
|
||||
#include <cpl_conv.h>
|
||||
#include <gdal.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "GdalWrapper";
|
||||
@@ -53,22 +49,25 @@ namespace {
|
||||
"This function sets the maximum amount of RAM memory in MB that GDAL is "
|
||||
"permitted to use for caching."
|
||||
};
|
||||
|
||||
void gdalErrorHandler(CPLErr eErrClass, int, const char* msg) {
|
||||
// No need to try to do this check earlier and only install this method as an error
|
||||
// handler if the logging is desired as the default behavior of GDAL is to log errors
|
||||
// to stderr.
|
||||
if (openspace::globebrowsing::GdalWrapper::ref().logGdalErrors()) {
|
||||
switch (eErrClass) {
|
||||
case CE_None: break;
|
||||
case CE_Debug: LDEBUGC("GDAL", msg); break;
|
||||
case CE_Warning: LWARNINGC("GDAL", msg); break;
|
||||
case CE_Failure: LERRORC("GDAL", msg); break;
|
||||
case CE_Fatal: LFATALC("GDAL", msg); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
void gdalErrorHandler(CPLErr eErrClass, int, const char* msg) {
|
||||
if (GdalWrapper::ref().logGdalErrors()) {
|
||||
switch (eErrClass) {
|
||||
case CE_None: break;
|
||||
case CE_Debug: LDEBUGC ("GDAL", msg); break;
|
||||
case CE_Warning: LWARNINGC("GDAL", msg); break;
|
||||
case CE_Failure: LERRORC ("GDAL", msg); break;
|
||||
case CE_Fatal: LFATALC ("GDAL", msg); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GdalWrapper* GdalWrapper::_singleton = nullptr;
|
||||
|
||||
void GdalWrapper::create(size_t maximumCacheSize, size_t maximumMaximumCacheSize) {
|
||||
@@ -85,11 +84,11 @@ GdalWrapper& GdalWrapper::ref() {
|
||||
return *_singleton;
|
||||
}
|
||||
|
||||
size_t GDALCacheUsed() {
|
||||
int64_t GDALCacheUsed() {
|
||||
return GDALGetCacheUsed64();
|
||||
}
|
||||
|
||||
size_t GDALMaximumCacheSize() {
|
||||
int64_t GDALMaximumCacheSize() {
|
||||
return GDALGetCacheMax64();
|
||||
}
|
||||
|
||||
@@ -100,7 +99,7 @@ bool GdalWrapper::logGdalErrors() const {
|
||||
GdalWrapper::GdalWrapper(size_t maximumCacheSize, size_t maximumMaximumCacheSize)
|
||||
: PropertyOwner({ "GdalWrapper" })
|
||||
, _logGdalErrors(LogGdalErrorInfo, false)
|
||||
, _gdalMaximumCacheSize (
|
||||
, _gdalMaximumCacheSize(
|
||||
GdalMaximumCacheInfo,
|
||||
static_cast<int>(maximumCacheSize / (1024ULL * 1024ULL)), // Default
|
||||
0, // Minimum: No caching
|
||||
@@ -124,8 +123,7 @@ GdalWrapper::GdalWrapper(size_t maximumCacheSize, size_t maximumMaximumCacheSize
|
||||
_gdalMaximumCacheSize.onChange([&] {
|
||||
// MB to Bytes
|
||||
GDALSetCacheMax64(
|
||||
static_cast<size_t>(_gdalMaximumCacheSize) *
|
||||
1024ULL * 1024ULL
|
||||
static_cast<int64_t>(_gdalMaximumCacheSize) * 1024ULL * 1024ULL
|
||||
);
|
||||
});
|
||||
}
|
||||
@@ -158,5 +156,3 @@ void GdalWrapper::setGdalProxyConfiguration() {
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // GLOBEBROWSING_USE_GDAL
|
||||
@@ -25,8 +25,6 @@
|
||||
#ifndef __OPENSPACE_MODULE_GLOBEBROWSING___GDAL_WRAPPER___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___GDAL_WRAPPER___H__
|
||||
|
||||
#ifdef GLOBEBROWSING_USE_GDAL
|
||||
|
||||
#include <openspace/properties/propertyowner.h>
|
||||
|
||||
#include <openspace/properties/scalar/boolproperty.h>
|
||||
@@ -36,11 +34,6 @@
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
/**
|
||||
* Function for passing GDAL error messages to the GHOUL logging system.
|
||||
*/
|
||||
void gdalErrorHandler(CPLErr eErrClass, int errNo, const char* msg);
|
||||
|
||||
/**
|
||||
* Singleton class interfacing with global GDAL functions.
|
||||
*/
|
||||
@@ -62,13 +55,13 @@ public:
|
||||
* Get the current size of the GDAL in memory cache.
|
||||
* \returns the number of bytes currently in the GDAL memory cache.
|
||||
*/
|
||||
static size_t GDALCacheUsed();
|
||||
static int64_t GDALCacheUsed();
|
||||
|
||||
/**
|
||||
* Get the maximum GDAL in memory cache size.
|
||||
* \returns the maximum number of bytes allowed for the GDAL cache.
|
||||
*/
|
||||
static size_t GDALMaximumCacheSize();
|
||||
static int64_t GDALMaximumCacheSize();
|
||||
|
||||
bool logGdalErrors() const;
|
||||
|
||||
@@ -86,6 +79,4 @@ private:
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // GLOBEBROWSING_USE_GDAL
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___GDAL_WRAPPER___H__
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user