Merge pull request #1468 from OpenSpace/issue/1438

Add habitable zone for our Sun and some useful generic classes
This commit is contained in:
Emma Broman
2021-02-03 08:39:12 +01:00
committed by GitHub
32 changed files with 1466 additions and 205 deletions

View File

@@ -7,6 +7,7 @@ asset.require('./base_blank')
-- Specifying which other assets should be loaded in this scene
asset.require('scene/solarsystem/sun/sun')
asset.require('scene/solarsystem/sun/glare')
asset.require('scene/solarsystem/sun/habitablezone')
asset.require('scene/solarsystem/sun/default_layers')
asset.require('scene/solarsystem/planets/planets')
asset.require('scene/solarsystem/planets/default_layers')
@@ -19,9 +20,11 @@ asset.require('scene/milkyway/constellations/constellation_keybinds')
asset.require('scene/milkyway/objects/orionnebula/orionnebula')
asset.require('util/launcher_images')
local assetHelper = asset.require('util/asset_helper')
-- For exoplanet system visualizations
asset.require('scene/milkyway/exoplanets/exoplanets_data')
asset.require('scene/milkyway/exoplanets/exoplanets_textures')
local assetHelper = asset.require('util/asset_helper')
asset.require('scene/digitaluniverse/2dF')
asset.require('scene/digitaluniverse/2mass')
asset.require('scene/digitaluniverse/6dF')

View File

@@ -0,0 +1,25 @@
local assetHelper = asset.require('util/asset_helper')
local color = {0.0, 1.0, 1.0}
-- @TODO (emmbr 2020-02-03) Potential threading issue later on? This will run on the main thread
local singeColorTexturePath = openspace.createSingeColorImage("example_ring_color", color)
local BasicDisc = {
Identifier = "BasicDisc",
Parent = "Root",
Renderable = {
Type = "RenderableDisc",
Texture = singeColorTexturePath,
Size = 1e10,
Width = 0.5
},
GUI = {
Name = "Basic Disc",
Path = "/Examples/Discs"
}
}
assetHelper.registerSceneGraphNodesAndExport(asset, {
BasicDisc
})

View File

@@ -5,3 +5,14 @@ local DataPath = asset.syncedResource({
Version = 2
})
asset.export("DataPath", DataPath)
asset.meta = {
Name = "Exoplanet Data",
Version = "2.0",
Description = [[ The data that is used for the exoplanet systems. The data has been
derived from the 'Planetary Systems Composite Data' dataset from the NASA Exoplanet
Archive]],
Author = "OpenSpace Team",
URL = "https://exoplanetarchive.ipac.caltech.edu/docs/data.html",
License = "MIT license",
}

View File

@@ -1,7 +1,19 @@
asset.require('./../habitable_zones/habitable_zone_textures')
local TexturesPath = asset.syncedResource({
Name = "Exoplanet Textures",
Type = "HttpSynchronization",
Identifier = "exoplanets_textures",
Version = 1
Version = 2
})
asset.export("TexturesPath", TexturesPath)
asset.meta = {
Name = "Exoplanet Textures",
Version = "2.0",
Description = [[ Adds all textures that are required for the exoplanet system
visualizations]],
Author = "OpenSpace Team",
URL = "http://openspaceproject.com",
License = "MIT license",
}

View File

@@ -0,0 +1,17 @@
local TexturesPath = asset.syncedResource({
Name = "Habitable Zone Textures",
Type = "HttpSynchronization",
Identifier = "habitable_zone_textures",
Version = 1
})
asset.export("TexturesPath", TexturesPath)
asset.meta = {
Name = "Habitable Zone Textures",
Version = "1.0",
Description = [[ Default textures that can be used for the habitable zone
rendering]],
Author = "OpenSpace Team",
URL = "http://openspaceproject.com",
License = "MIT license",
}

View File

@@ -0,0 +1,34 @@
local assetHelper = asset.require("util/asset_helper")
local transforms = asset.require("./transforms")
local textures = asset.require('scene/milkyway/habitable_zones/habitable_zone_textures').TexturesPath
local HabitableZone = {
Identifier = "SunHabitableZone",
Parent = transforms.SunECLIPJ2000.Identifier,
Renderable = {
Type = "RenderableHabitableZone",
Enabled = false,
Texture = textures .. "/hot_to_cold_faded.png",
EffectiveTemperature = 5780, -- Kelvin
Luminosity = 1, -- solar
Opacity = 0.1
},
GUI = {
Name = "Sun Habitable Zone",
Path = "/Solar System/Sun",
Description = "Habitable zone for the sun in our solar system."
}
}
assetHelper.registerSceneGraphNodesAndExport(asset, { HabitableZone })
asset.meta = {
Name = "Sun Habitable Zone",
Version = "1.0",
Description = [[ The habitable zone around our sun, computed using formula and
coefficients by Kopparapu et al. (2015) https://arxiv.org/abs/1404.5292]],
Author = "OpenSpace Team",
URL = "http://openspaceproject.com",
License = "MIT license",
Identifiers = {"SunHabitableZone"}
}

View File

@@ -0,0 +1,72 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* *
* 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___TEXTURECOMPONENT___H__
#define __OPENSPACE_CORE___TEXTURECOMPONENT___H__
#include <ghoul/opengl/texture.h>
namespace ghoul::filesystem { class File; }
namespace ghoul::opengl {class Texture; }
namespace openspace {
class TextureComponent {
public:
using Texture = ghoul::opengl::Texture;
const Texture* texture() const;
Texture* texture();
void setFilterMode(Texture::FilterMode filterMode);
void setWrapping(Texture::WrappingMode wrapping);
void setShouldWatchFileForChanges(bool value);
void setShouldPurgeFromRAM(bool value);
void bind();
void uploadToGpu();
// Loads a texture from a file on disk
void loadFromFile(const std::string& path);
// Function to call in a renderable's update function to make sure
// the texture is kept up to date
void update();
private:
std::unique_ptr<ghoul::filesystem::File> _textureFile;
std::unique_ptr<Texture> _texture;
Texture::FilterMode _filterMode = Texture::FilterMode::LinearMipMap;
Texture::WrappingMode _wrappingMode = Texture::WrappingMode::Repeat;
bool _shouldWatchFile = true;
bool _shouldPurgeFromRAM = true;
bool _fileIsDirty = false;
bool _textureIsDirty = false;
};
} // namespace openspace
#endif // __OPENSPACE_CORE___TEXTURECOMPONENT___H__

View File

@@ -0,0 +1,57 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* *
* 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___PLANEGEOMETRY___H__
#define __OPENSPACE_CORE___PLANEGEOMETRY___H__
#include <ghoul/glm.h>
#include <ghoul/opengl/ghoul_gl.h>
namespace openspace {
class PlaneGeometry {
public:
PlaneGeometry(glm::vec2 size);
PlaneGeometry(float size);
~PlaneGeometry();
void initialize();
void deinitialize();
void render();
void updateSize(const glm::vec2& size);
void updateSize(const float size);
private:
void updateGeometry();
GLuint _vaoId = 0;
GLuint _vBufferId = 0;
glm::vec2 _size = glm::vec2(0.f);
};
} // namespace openspace
#endif // __OPENSPACE_CORE___PLANEGEOMETRY___H__

View File

@@ -45,6 +45,7 @@ set(HEADER_FILES
rendering/grids/renderableradialgrid.h
rendering/grids/renderablesphericalgrid.h
rendering/renderablecartesianaxes.h
rendering/renderabledisc.h
rendering/renderablelabels.h
rendering/renderablemodel.h
rendering/renderablenodeline.h
@@ -73,7 +74,6 @@ set(HEADER_FILES
translation/luatranslation.h
translation/statictranslation.h
translation/timelinetranslation.h
)
source_group("Header Files" FILES ${HEADER_FILES})
@@ -98,6 +98,7 @@ set(SOURCE_FILES
rendering/grids/renderableradialgrid.cpp
rendering/grids/renderablesphericalgrid.cpp
rendering/renderablecartesianaxes.cpp
rendering/renderabledisc.cpp
rendering/renderablelabels.cpp
rendering/renderablemodel.cpp
rendering/renderablenodeline.cpp
@@ -132,6 +133,8 @@ source_group("Source Files" FILES ${SOURCE_FILES})
set(SHADER_FILES
shaders/axes_fs.glsl
shaders/axes_vs.glsl
shaders/disc_fs.glsl
shaders/disc_vs.glsl
shaders/grid_vs.glsl
shaders/grid_fs.glsl
shaders/imageplane_fs.glsl

View File

@@ -42,6 +42,7 @@
#include <modules/base/rendering/grids/renderableradialgrid.h>
#include <modules/base/rendering/grids/renderablesphericalgrid.h>
#include <modules/base/rendering/renderablecartesianaxes.h>
#include <modules/base/rendering/renderabledisc.h>
#include <modules/base/rendering/renderablelabels.h>
#include <modules/base/rendering/renderablemodel.h>
#include <modules/base/rendering/renderablenodeline.h>
@@ -129,6 +130,7 @@ void BaseModule::internalInitialize(const ghoul::Dictionary&) {
fRenderable->registerClass<RenderableBoxGrid>("RenderableBoxGrid");
fRenderable->registerClass<RenderableCartesianAxes>("RenderableCartesianAxes");
fRenderable->registerClass<RenderableDisc>("RenderableDisc");
fRenderable->registerClass<RenderableGrid>("RenderableGrid");
fRenderable->registerClass<RenderableLabels>("RenderableLabels");
fRenderable->registerClass<RenderableModel>("RenderableModel");
@@ -206,6 +208,7 @@ std::vector<documentation::Documentation> BaseModule::documentations() const {
RenderableNodeLine::Documentation(),
RenderablePlane::Documentation(),
RenderableRadialGrid::Documentation(),
RenderableDisc::Documentation(),
RenderableSphere::Documentation(),
RenderableSphericalGrid::Documentation(),
RenderableTrailOrbit::Documentation(),

View File

@@ -0,0 +1,230 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* *
* 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/base/rendering/renderabledisc.h>
#include <openspace/documentation/documentation.h>
#include <openspace/documentation/verifier.h>
#include <openspace/engine/globals.h>
#include <openspace/rendering/renderengine.h>
#include <openspace/scene/scene.h>
#include <openspace/util/updatestructures.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/opengl/openglstatecache.h>
#include <ghoul/opengl/programobject.h>
#include <ghoul/opengl/textureunit.h>
namespace {
constexpr const char _loggerCat[] = "RenderableDisc";
constexpr const std::array<const char*, 4> UniformNames = {
"modelViewProjectionTransform", "opacity", "width", "colorTexture"
};
constexpr openspace::properties::Property::PropertyInfo TextureInfo = {
"Texture",
"Texture",
"This value is the path to a texture on disk that contains a one-dimensional "
"texture to be used for the color."
};
constexpr openspace::properties::Property::PropertyInfo SizeInfo = {
"Size",
"Size",
"This value specifies the outer radius of the disc in meter."
};
constexpr openspace::properties::Property::PropertyInfo WidthInfo = {
"Width",
"Width",
"This value is used to set the width of the disc. The actual width is set "
"based on the given size and this value should be set between 0 and 1. A value "
"of 1 results in a full circle and 0.5 a disc with an inner radius of 0.5*size."
};
} // namespace
namespace openspace {
documentation::Documentation RenderableDisc::Documentation() {
using namespace documentation;
return {
"Renderable Disc",
"renderable_disc",
{
{
TextureInfo.identifier,
new StringVerifier,
Optional::No,
TextureInfo.description
},
{
SizeInfo.identifier,
new DoubleVerifier,
Optional::Yes,
SizeInfo.description
},
{
WidthInfo.identifier,
new DoubleVerifier,
Optional::Yes,
WidthInfo.description
}
}
};
}
RenderableDisc::RenderableDisc(const ghoul::Dictionary& dictionary)
: Renderable(dictionary)
, _texturePath(TextureInfo)
, _size(SizeInfo, 1.f, 0.f, 1e13f)
, _width(WidthInfo, 0.5f, 0.f, 1.f)
{
documentation::testSpecificationAndThrow(
Documentation(),
dictionary,
"RenderableDisc"
);
_texturePath = absPath(dictionary.value<std::string>(TextureInfo.identifier));
_texturePath.onChange([&]() { _texture->loadFromFile(_texturePath); });
addProperty(_texturePath);
if (dictionary.hasKey(SizeInfo.identifier)) {
_size = static_cast<float>(dictionary.value<double>(SizeInfo.identifier));
}
setBoundingSphere(_size);
_size.onChange([&]() { _planeIsDirty = true; });
addProperty(_size);
if (dictionary.hasKey(WidthInfo.identifier)) {
_width = static_cast<float>(dictionary.value<double>(WidthInfo.identifier));
}
addProperty(_width);
addProperty(_opacity);
setRenderBin(Renderable::RenderBin::PostDeferredTransparent);
}
bool RenderableDisc::isReady() const {
return _shader && _texture && _plane;
}
void RenderableDisc::initialize() {
_texture = std::make_unique<TextureComponent>();
_texture->setFilterMode(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap);
_texture->setWrapping(ghoul::opengl::Texture::WrappingMode::ClampToEdge);
_texture->setShouldWatchFileForChanges(true);
_plane = std::make_unique<PlaneGeometry>(planeSize());
}
void RenderableDisc::initializeGL() {
initializeShader();
_texture->loadFromFile(_texturePath);
_texture->uploadToGpu();
_plane->initialize();
}
void RenderableDisc::deinitializeGL() {
_plane->deinitialize();
_plane = nullptr;
_texture = nullptr;
global::renderEngine->removeRenderProgram(_shader.get());
_shader = nullptr;
}
void RenderableDisc::render(const RenderData& data, RendererTasks&) {
_shader->activate();
glm::dmat4 modelTransform =
glm::translate(glm::dmat4(1.0), data.modelTransform.translation) *
glm::dmat4(data.modelTransform.rotation) *
glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale));
glm::dmat4 modelViewTransform = data.camera.combinedViewMatrix() * modelTransform;
_shader->setUniform(
_uniformCache.modelViewProjection,
data.camera.projectionMatrix() * glm::mat4(modelViewTransform)
);
_shader->setUniform(_uniformCache.width, _width);
_shader->setUniform(_uniformCache.opacity, _opacity);
ghoul::opengl::TextureUnit unit;
unit.activate();
_texture->bind();
_shader->setUniform(_uniformCache.texture, unit);
glEnablei(GL_BLEND, 0);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthMask(false);
glDisable(GL_CULL_FACE);
_plane->render();
_shader->deactivate();
// Restores GL State
global::renderEngine->openglStateCache().resetBlendState();
global::renderEngine->openglStateCache().resetDepthState();
global::renderEngine->openglStateCache().resetPolygonAndClippingState();
}
void RenderableDisc::update(const UpdateData&) {
if (_shader->isDirty()) {
_shader->rebuildFromFile();
updateUniformLocations();
}
if (_planeIsDirty) {
_plane->updateSize(planeSize());
_planeIsDirty = false;
}
_texture->update();
}
void RenderableDisc::initializeShader() {
_shader = global::renderEngine->buildRenderProgram(
"DiscProgram",
absPath("${MODULE_BASE}/shaders/disc_vs.glsl"),
absPath("${MODULE_BASE}/shaders/disc_fs.glsl")
);
updateUniformLocations();
}
void RenderableDisc::updateUniformLocations() {
ghoul::opengl::updateUniformLocations(*_shader, _uniformCache, UniformNames);
}
float RenderableDisc::planeSize() const {
return _size;
}
} // namespace openspace

View File

@@ -0,0 +1,81 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* *
* 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_BASE___RENDERABLEDISC___H__
#define __OPENSPACE_MODULE_BASE___RENDERABLEDISC___H__
#include <openspace/properties/stringproperty.h>
#include <openspace/properties/scalar/floatproperty.h>
#include <openspace/rendering/renderable.h>
#include <openspace/rendering/texturecomponent.h>
#include <openspace/util/planegeometry.h>
#include <ghoul/opengl/uniformcache.h>
#include <ghoul/opengl/ghoul_gl.h>
namespace ghoul::filesystem { class File; }
namespace ghoul::opengl { class ProgramObject; }
namespace openspace {
namespace documentation { struct Documentation; }
class RenderableDisc : public Renderable {
public:
RenderableDisc(const ghoul::Dictionary& dictionary);
void initialize() override;
void initializeGL() override;
void deinitializeGL() override;
bool isReady() const override;
void render(const RenderData& data, RendererTasks& rendererTask) override;
void update(const UpdateData& data) override;
static documentation::Documentation Documentation();
protected:
virtual void initializeShader();
virtual void updateUniformLocations();
virtual float planeSize() const;
properties::StringProperty _texturePath;
properties::FloatProperty _size;
properties::FloatProperty _width;
std::unique_ptr<ghoul::opengl::ProgramObject> _shader;
std::unique_ptr<PlaneGeometry> _plane;
std::unique_ptr<TextureComponent> _texture;
private:
UniformCache(modelViewProjection, opacity, width, texture) _uniformCache;
bool _planeIsDirty = false;
};
} // namespace openspace
#endif // __OPENSPACE_MODULE_BASE___RENDERABLEDISC___H__

View File

@@ -0,0 +1,58 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* *
* 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 vec2 vs_st;
in float vs_screenSpaceDepth;
uniform sampler1D colorTexture;
uniform float width;
uniform float opacity;
Fragment getFragment() {
// The length of the texture coordinates vector is our distance from the center
float radius = length(vs_st);
// We only want to consider ring-like objects so we need to discard everything else
if (radius > 1.0) {
discard;
}
// Remapping the texture coordinates
// Radius \in [0,1],
float inner = 1.0 - width;
float texCoord = (radius - inner) / (1.0 - inner);
if (texCoord < 0.0 || texCoord > 1.0) {
discard;
}
vec4 diffuse = texture(colorTexture, texCoord);
diffuse.a *= opacity;
Fragment frag;
frag.color = diffuse;
frag.depth = vs_screenSpaceDepth;
return frag;
}

View File

@@ -0,0 +1,47 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#version __CONTEXT__
#include "PowerScaling/powerScaling_vs.hglsl"
layout(location = 0) in vec2 in_position;
layout(location = 1) in vec2 in_st;
out vec2 vs_st;
out float vs_screenSpaceDepth;
uniform mat4 modelViewProjectionTransform;
void main() {
vec4 position = vec4(in_position.xy, 0.0, 1.0);
vec4 positionScreenSpace = z_normalization(modelViewProjectionTransform * position);
// Moving the origin to the center
vs_st = (in_st - vec2(0.5)) * 2.0;
vs_screenSpaceDepth = positionScreenSpace.w;
gl_Position = positionScreenSpace;
}

View File

@@ -136,50 +136,6 @@ glm::dmat3 computeSystemRotation(glm::dvec3 starPosition) {
);
}
glm::vec2 computeHabitableZone(float teff, float luminosity) {
// Kopparapu's formula only considers stars with teff in range [2600, 7200] K.
// However, we want to use the formula for more stars, so add some flexibility to
// the teff boundaries
if (teff > 8000.f || teff < 2000.f) {
// For the other stars, use a method by Tom E. Morris:
// https://www.planetarybiology.com/calculating_habitable_zone.html
float inner = std::sqrt(luminosity / 1.1f);
float outer = std::sqrt(luminosity / 0.53f);
return glm::vec2(inner, outer);
}
struct Coefficients {
float seffSun;
float a;
float b;
float c;
float d;
};
// Coefficients for planets of 1 Earth mass. Received from:
// https://depts.washington.edu/naivpl/sites/default/files/HZ_coefficients.dat
constexpr const Coefficients coefficients[] = {
// Inner boundary - Runaway greenhouse
{1.10700E+00f, 1.33200E-04f, 1.58000E-08f, -8.30800E-12f, -1.93100E-15f},
// Outer boundary - Maximum greenhouse
{3.56000E-01f, 6.17100E-05f, 1.69800E-09f, -3.19800E-12f, -5.57500E-16f}
};
const float tstar = teff - 5780.f;
const float tstar2 = tstar * tstar;
glm::vec2 distances;
for (int i = 0; i < 2; ++i) {
const Coefficients& coeffs = coefficients[i];
float seff = coeffs.seffSun + (coeffs.a * tstar) + (coeffs.b * tstar2) +
(coeffs.c * tstar * tstar2) + (coeffs.d * tstar2 * tstar2);
distances[i] = std::pow(luminosity / seff, 0.5f);
}
return distances;
}
std::string createIdentifier(std::string name) {
std::replace(name.begin(), name.end(), ' ', '_');
std::replace(name.begin(), name.end(), '.', '-');

View File

@@ -108,17 +108,6 @@ glm::dmat4 computeOrbitPlaneRotationMatrix(float i, float bigom = 180.f,
// so that x is pointing from star to the sun.
glm::dmat3 computeSystemRotation(glm::dvec3 starPosition);
/**
* Compute the inner and outer boundary of the habitable zone of a star, accordring to
* formula and coefficients by Kopparapu et al. (2015) https://arxiv.org/abs/1404.5292
*
* \param teff The effective temperature of the star, in Kelvin
* \param luminosity The luminosity of the star, in solar luminosities
* \return A vec2 with the lower and upper boundary in atronomical units, if a habitable
zone could be computed. Otherwise an std::nullopt
*/
glm::vec2 computeHabitableZone(float teff, float luminosity);
// Create an identifier without whitespaces
std::string createIdentifier(std::string name);

View File

@@ -39,22 +39,24 @@
#include <sstream>
namespace {
constexpr const char* _loggerCat = "ExoplanetsModule";
constexpr const char _loggerCat[] = "ExoplanetsModule";
} // namespace
namespace openspace::exoplanets::luascriptfunctions {
constexpr const char* ExoplanetsGuiPath = "/Milky Way/Exoplanets/Exoplanet Systems/";
constexpr const char ExoplanetsGuiPath[] = "/Milky Way/Exoplanets/Exoplanet Systems/";
constexpr const char* LookUpTablePath = "${SYNC}/http/exoplanets_data/2/lookup.txt";
constexpr const char* ExoplanetsDataPath =
constexpr const char LookUpTablePath[] = "${SYNC}/http/exoplanets_data/2/lookup.txt";
constexpr const char ExoplanetsDataPath[] =
"${SYNC}/http/exoplanets_data/2/exoplanets_data.bin";
constexpr const char* StarTextureFile = "${SYNC}/http/exoplanets_textures/1/sun.jpg";
constexpr const char* NoDataTextureFile =
"${SYNC}/http/exoplanets_textures/1/grid-32.png";
constexpr const char* DiscTextureFile =
"${SYNC}/http/exoplanets_textures/1/disc_texture.png";
constexpr const char StarTextureFile[] = "${SYNC}/http/exoplanets_textures/2/sun.jpg";
constexpr const char NoDataTextureFile[] =
"${SYNC}/http/exoplanets_textures/2/grid-32.png";
constexpr const char DiscTextureFile[] =
"${SYNC}/http/exoplanets_textures/2/disc_bw_texture.png";
constexpr const char HabitableZoneTextureFile[] =
"${SYNC}/http/habitable_zone_textures/1/hot_to_cold_faded.png";
constexpr const float AU = static_cast<float>(distanceconstants::AstronomicalUnit);
constexpr const float SolarRadius = static_cast<float>(distanceconstants::SolarRadius);
@@ -387,7 +389,7 @@ void createExoplanetSystem(const std::string& starName) {
std::to_string(lowerOffset) + ", " +
std::to_string(upperOffset) +
"}," //min / max extend
"Opacity = 0.3"
"Opacity = 0.25"
"},"
"Transform = {"
"Rotation = {"
@@ -451,16 +453,6 @@ void createExoplanetSystem(const std::string& starName) {
bool hasLuminosity = !std::isnan(system.starData.luminosity);
if (hasTeff && hasLuminosity) {
const glm::vec2 zone = computeHabitableZone(
system.starData.teff,
system.starData.luminosity
);
glm::vec2 limitsInMeter = zone * AU;
float half = 0.5f * (limitsInMeter[1] - limitsInMeter[0]);
float center = limitsInMeter[0] + half;
float relativeOffset = half / center;
constexpr const char* description =
"The habitable zone is the region around a star in which an Earth-like "
"planet can potentially have liquid water on its surface."
@@ -476,17 +468,12 @@ void createExoplanetSystem(const std::string& starName) {
"Parent = '" + starIdentifier + "',"
"Enabled = true,"
"Renderable = {"
"Type = 'RenderableOrbitDisc',"
"Texture = openspace.absPath("
"openspace.createPixelImage('exo_habitable_zone', {0, 0.92, 0.81})"
"),"
"Size = " + std::to_string(center) + ","
"Eccentricity = 0,"
"Offset = { " +
std::to_string(relativeOffset) + ", " +
std::to_string(relativeOffset) +
"}," //min / max extend
"Opacity = 0.05"
"Type = 'RenderableHabitableZone',"
"Texture = openspace.absPath('" + HabitableZoneTextureFile + "'),"
"Luminosity = " + std::to_string(system.starData.luminosity) + ","
"EffectiveTemperature = " + std::to_string(system.starData.teff) + ","
"Optimistic = true,"
"Opacity = 0.07"
"},"
"Transform = {"
"Rotation = {"

View File

@@ -1 +1,4 @@
set(DEFAULT_MODULE ON)
set (OPENSPACE_DEPENDENCIES
space
)

View File

@@ -33,10 +33,8 @@
#include <openspace/util/distanceconstants.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/opengl/openglstatecache.h>
#include <ghoul/opengl/programobject.h>
#include <ghoul/opengl/texture.h>
#include <ghoul/opengl/textureunit.h>
namespace {
@@ -49,7 +47,7 @@ namespace {
"Texture",
"Texture",
"This value is the path to a texture on disk that contains a one-dimensional "
"texture which is used for these rings."
"texture which is used for the color."
};
static const openspace::properties::Property::PropertyInfo SizeInfo = {
@@ -123,8 +121,6 @@ RenderableOrbitDisc::RenderableOrbitDisc(const ghoul::Dictionary& dictionary)
, _eccentricity(EccentricityInfo, 0.f, 0.f, 1.f)
, _offset(OffsetInfo, glm::vec2(0.f), glm::vec2(0.f), glm::vec2(1.f))
{
using ghoul::filesystem::File;
documentation::testSpecificationAndThrow(
Documentation(),
dictionary,
@@ -144,13 +140,9 @@ RenderableOrbitDisc::RenderableOrbitDisc(const ghoul::Dictionary& dictionary)
setBoundingSphere(_size + _offset.value().y * _size);
_texturePath = absPath(dictionary.value<std::string>(TextureInfo.identifier));
_textureFile = std::make_unique<File>(_texturePath);
_texturePath.onChange([&]() { _textureIsDirty = true; });
_texturePath.onChange([&]() { _texture->loadFromFile(_texturePath); });
addProperty(_texturePath);
_textureFile->setCallback([&](const File&) { _textureIsDirty = true; });
_eccentricity = static_cast<float>(
dictionary.value<double>(EccentricityInfo.identifier)
);
@@ -161,33 +153,34 @@ RenderableOrbitDisc::RenderableOrbitDisc(const ghoul::Dictionary& dictionary)
}
bool RenderableOrbitDisc::isReady() const {
return _shader && _texture;
return _shader && _texture && _plane;
}
void RenderableOrbitDisc::initialize() {
_texture = std::make_unique<TextureComponent>();
_texture->setFilterMode(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap);
_texture->setWrapping(ghoul::opengl::Texture::WrappingMode::ClampToEdge);
_plane = std::make_unique<PlaneGeometry>(planeSize());
}
void RenderableOrbitDisc::initializeGL() {
_shader = global::renderEngine->buildRenderProgram(
"OrbitdiscProgram",
"OrbitDiscProgram",
absPath("${BASE}/modules/exoplanets/shaders/orbitdisc_vs.glsl"),
absPath("${BASE}/modules/exoplanets/shaders/orbitdisc_fs.glsl")
);
ghoul::opengl::updateUniformLocations(*_shader, _uniformCache, UniformNames);
glGenVertexArrays(1, &_quad);
glGenBuffers(1, &_vertexPositionBuffer);
_texture->loadFromFile(_texturePath);
_texture->uploadToGpu();
createPlane();
loadTexture();
_plane->initialize();
}
void RenderableOrbitDisc::deinitializeGL() {
glDeleteVertexArrays(1, &_quad);
_quad = 0;
glDeleteBuffers(1, &_vertexPositionBuffer);
_vertexPositionBuffer = 0;
_textureFile = nullptr;
_plane->deinitialize();
_plane = nullptr;
_texture = nullptr;
global::renderEngine->removeRenderProgram(_shader.get());
@@ -223,8 +216,7 @@ void RenderableOrbitDisc::render(const RenderData& data, RendererTasks&) {
glDepthMask(false);
glDisable(GL_CULL_FACE);
glBindVertexArray(_quad);
glDrawArrays(GL_TRIANGLES, 0, 6);
_plane->render();
_shader->deactivate();
@@ -241,80 +233,17 @@ void RenderableOrbitDisc::update(const UpdateData&) {
}
if (_planeIsDirty) {
createPlane();
_plane->updateSize(planeSize());
_planeIsDirty = false;
}
if (_textureIsDirty) {
loadTexture();
_textureIsDirty = false;
}
_texture->update();
}
void RenderableOrbitDisc::loadTexture() {
if (!_texturePath.value().empty()) {
std::unique_ptr<ghoul::opengl::Texture> texture =
ghoul::io::TextureReader::ref().loadTexture(absPath(_texturePath));
if (texture) {
LDEBUGC(
"RenderableOrbitDisc",
fmt::format("Loaded texture from '{}'", absPath(_texturePath))
);
_texture = std::move(texture);
_texture->uploadTexture();
_texture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap);
_textureFile = std::make_unique<ghoul::filesystem::File>(_texturePath);
_textureFile->setCallback(
[&](const ghoul::filesystem::File&) { _textureIsDirty = true; }
);
}
}
}
void RenderableOrbitDisc::createPlane() {
const GLfloat outerDistance = (_size + _offset.value().y * _size);
const GLfloat size = outerDistance * (1.f + _eccentricity);
struct VertexData {
GLfloat x;
GLfloat y;
GLfloat s;
GLfloat t;
};
VertexData data[] = {
{ -size, -size, 0.f, 0.f },
{ size, size, 1.f, 1.f },
{ -size, size, 0.f, 1.f },
{ -size, -size, 0.f, 0.f },
{ size, -size, 1.f, 0.f },
{ size, size, 1.f, 1.f },
};
glBindVertexArray(_quad);
glBindBuffer(GL_ARRAY_BUFFER, _vertexPositionBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(
0,
2,
GL_FLOAT,
GL_FALSE,
sizeof(VertexData),
nullptr
);
glEnableVertexAttribArray(1);
glVertexAttribPointer(
1,
2,
GL_FLOAT,
GL_FALSE,
sizeof(VertexData),
reinterpret_cast<void*>(offsetof(VertexData, s))
);
float RenderableOrbitDisc::planeSize() const {
float maxRadius = _size + _offset.value().y * _size;
maxRadius *= (1.f + _eccentricity);
return maxRadius;
}
} // namespace openspace

View File

@@ -29,14 +29,13 @@
#include <openspace/properties/scalar/floatproperty.h>
#include <openspace/properties/vector/vec2property.h>
#include <openspace/rendering/renderable.h>
#include <openspace/rendering/texturecomponent.h>
#include <openspace/util/planegeometry.h>
#include <openspace/util/updatestructures.h>
#include <ghoul/opengl/texture.h>
#include <ghoul/opengl/uniformcache.h>
namespace ghoul::filesystem { class File; }
namespace ghoul::opengl {
class ProgramObject;
} // namespace ghoul::opengl
namespace ghoul::opengl { class ProgramObject; } // namespace ghoul::opengl
namespace openspace {
@@ -46,6 +45,7 @@ class RenderableOrbitDisc : public Renderable {
public:
RenderableOrbitDisc(const ghoul::Dictionary& dictionary);
void initialize() override;
void initializeGL() override;
void deinitializeGL() override;
@@ -57,8 +57,8 @@ public:
static documentation::Documentation Documentation();
private:
void loadTexture();
void createPlane();
// Computes the size of the plane quad using the relevant properties
float planeSize() const;
properties::StringProperty _texturePath;
properties::FloatProperty _size;
@@ -68,13 +68,11 @@ private:
std::unique_ptr<ghoul::opengl::ProgramObject> _shader = nullptr;
UniformCache(modelViewProjection, offset, opacity, texture,
eccentricity, semiMajorAxis) _uniformCache;
std::unique_ptr<ghoul::opengl::Texture> _texture = nullptr;
std::unique_ptr<ghoul::filesystem::File> _textureFile;
bool _textureIsDirty = false;
std::unique_ptr<PlaneGeometry> _plane;
std::unique_ptr<TextureComponent> _texture;
bool _planeIsDirty = false;
GLuint _quad = 0;
GLuint _vertexPositionBuffer = 0;
};
} // namespace openspace

View File

@@ -27,6 +27,7 @@ include(${OPENSPACE_CMAKE_EXT_DIR}/module_definition.cmake)
set(HEADER_FILES
rendering/planetgeometry.h
rendering/renderableconstellationbounds.h
rendering/renderablehabitablezone.h
rendering/renderablerings.h
rendering/renderableorbitalkepler.h
rendering/renderablesatellites.h
@@ -44,6 +45,7 @@ source_group("Header Files" FILES ${HEADER_FILES})
set(SOURCE_FILES
rendering/planetgeometry.cpp
rendering/renderableconstellationbounds.cpp
rendering/renderablehabitablezone.cpp
rendering/renderablerings.cpp
rendering/renderableorbitalkepler.cpp
rendering/renderablesatellites.cpp
@@ -63,6 +65,8 @@ set(SHADER_FILES
shaders/constellationbounds_vs.glsl
shaders/debrisViz_fs.glsl
shaders/debrisViz_vs.glsl
shaders/habitablezone_vs.glsl
shaders/habitablezone_fs.glsl
shaders/rings_vs.glsl
shaders/rings_fs.glsl
shaders/star_fs.glsl

View File

@@ -1 +1,4 @@
set(DEFAULT_MODULE ON)
set (OPENSPACE_DEPENDENCIES
base
)

View File

@@ -0,0 +1,302 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* *
* 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/space/rendering/renderablehabitablezone.h>
#include <openspace/documentation/documentation.h>
#include <openspace/documentation/verifier.h>
#include <openspace/engine/globals.h>
#include <openspace/rendering/renderengine.h>
#include <openspace/scene/scenegraphnode.h>
#include <openspace/scene/scene.h>
#include <openspace/util/distanceconstants.h>
#include <openspace/util/updatestructures.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/opengl/openglstatecache.h>
#include <ghoul/opengl/programobject.h>
#include <ghoul/opengl/textureunit.h>
namespace {
constexpr const char _loggerCat[] = "RenderableHabitableZone";
constexpr const std::array<const char*, 6> UniformNames = {
"modelViewProjectionTransform", "opacity", "width", "transferFunctionTexture",
"conservativeBounds", "showOptimistic"
};
constexpr openspace::properties::Property::PropertyInfo EffectiveTemperatureInfo = {
"EffectiveTemperature",
"Effective Temperature",
"The effective temperature of the corresponding star, in Kelvin. "
"Used to compute the width and size of the disc."
};
constexpr openspace::properties::Property::PropertyInfo LuminosityInfo = {
"Luminosity",
"Luminosity",
"The luminosity of the corresponding star, in units of solar luminosities. "
"Used to compute the width and size of the disc."
};
constexpr openspace::properties::Property::PropertyInfo OptimisticInfo = {
"Optimistic",
"Optimistic" ,
"If true, the habitable zone disc is rendered with the optimistic boundaries "
"rather than the conservative ones."
};
constexpr openspace::properties::Property::PropertyInfo KopparapuTeffIntervalInfo = {
"KopparapuTeffInterval",
"Effective Temperature Interval (Kopparapu's formula)" ,
"The range for which Kopparapu's formula is used for the habitable zone "
"computation. For stars with effective temperatures outside the range, a "
"simpler method by Tom E. Harris is used. This method only uses the star "
"luminosity and does not include computation of the optimistic boundaries."
};
} // namespace
namespace openspace {
documentation::Documentation RenderableHabitableZone::Documentation() {
using namespace documentation;
documentation::Documentation doc {
"Renderable Habitable Zone",
"exoplanets_renderable_habitable_zone",
{
{
EffectiveTemperatureInfo.identifier,
new DoubleVerifier,
Optional::No,
EffectiveTemperatureInfo.description
},
{
LuminosityInfo.identifier,
new DoubleVerifier,
Optional::No,
LuminosityInfo.description
},
{
OptimisticInfo.identifier,
new BoolVerifier,
Optional::Yes,
OptimisticInfo.description
},
{
KopparapuTeffIntervalInfo.identifier,
new DoubleVector2Verifier,
Optional::Yes,
KopparapuTeffIntervalInfo.description
}
}
};
// @TODO cleanup
// Insert the parents documentation entries until we have a verifier that can deal
// with class hierarchy
documentation::Documentation parentDoc = RenderableDisc::Documentation();
doc.entries.insert(
doc.entries.end(),
parentDoc.entries.begin(),
parentDoc.entries.end()
);
return doc;
}
RenderableHabitableZone::RenderableHabitableZone(const ghoul::Dictionary& dictionary)
: RenderableDisc(dictionary)
, _teff(EffectiveTemperatureInfo, 5780.f, 0.f, 7.5e4f)
, _luminosity(LuminosityInfo, 1.f, 0.f, 1e8f)
, _showOptimistic(OptimisticInfo, false)
, _kopparapuTeffInterval(KopparapuTeffIntervalInfo, glm::vec2(2000.f, 8000.f))
{
documentation::testSpecificationAndThrow(
Documentation(),
dictionary,
"RenderableHabitableZone"
);
if (dictionary.hasKey(EffectiveTemperatureInfo.identifier)) {
_teff = static_cast<float>(
dictionary.value<double>(EffectiveTemperatureInfo.identifier)
);
}
_teff.onChange([this]() { computeZone(); });
addProperty(_teff);
if (dictionary.hasKey(LuminosityInfo.identifier)) {
_luminosity = static_cast<float>(
dictionary.value<double>(LuminosityInfo.identifier)
);
}
_luminosity.onChange([this]() { computeZone(); });
addProperty(_luminosity);
if (dictionary.hasKey(OptimisticInfo.identifier)) {
_showOptimistic = dictionary.value<bool>(OptimisticInfo.identifier);
}
addProperty(_showOptimistic);
// The user should not be able to change this property. It's just used to communicate
// the different rendering that happens outside of this interval
addProperty(_kopparapuTeffInterval);
_kopparapuTeffInterval.setReadOnly(true);
// Make parent's size related properties read only. We want to set them based on the
// given temperature and luminosity
_size.setReadOnly(true);
_width.setReadOnly(true);
computeZone();
}
void RenderableHabitableZone::render(const RenderData& data, RendererTasks&) {
_shader->activate();
glm::dmat4 modelTransform =
glm::translate(glm::dmat4(1.0), data.modelTransform.translation) *
glm::dmat4(data.modelTransform.rotation) *
glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale));
glm::dmat4 modelViewTransform = data.camera.combinedViewMatrix() * modelTransform;
_shader->setUniform(
_uniformCache.modelViewProjection,
data.camera.projectionMatrix() * glm::mat4(modelViewTransform)
);
_shader->setUniform(_uniformCache.width, _width);
_shader->setUniform(_uniformCache.opacity, _opacity);
_shader->setUniform(_uniformCache.conservativeBounds, _conservativeBounds);
_shader->setUniform(_uniformCache.showOptimistic, _showOptimistic);
ghoul::opengl::TextureUnit unit;
unit.activate();
_texture->bind();
_shader->setUniform(_uniformCache.texture, unit);
glEnablei(GL_BLEND, 0);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthMask(false);
glDisable(GL_CULL_FACE);
_plane->render();
_shader->deactivate();
// Restores GL State
global::renderEngine->openglStateCache().resetBlendState();
global::renderEngine->openglStateCache().resetDepthState();
global::renderEngine->openglStateCache().resetPolygonAndClippingState();
}
void RenderableHabitableZone::initializeShader() {
_shader = global::renderEngine->buildRenderProgram(
"HabitableZoneProgram",
absPath("${MODULE_SPACE}/shaders/habitablezone_vs.glsl"),
absPath("${MODULE_SPACE}/shaders/habitablezone_fs.glsl")
);
ghoul::opengl::updateUniformLocations(*_shader, _uniformCache, UniformNames);
}
void RenderableHabitableZone::updateUniformLocations() {
ghoul::opengl::updateUniformLocations(*_shader, _uniformCache, UniformNames);
}
void RenderableHabitableZone::computeZone() {
glm::dvec4 distancesInAu = computeKopparapuZoneBoundaries(_teff, _luminosity);
constexpr const double AU = distanceconstants::AstronomicalUnit;
const double inner = distancesInAu[0] * AU;
const double innerConservative = distancesInAu[1] * AU;
const double outerConservative = distancesInAu[2] * AU;
const double outer = distancesInAu[3] * AU;
double discWidth = 0.0;
if (outer > 0.0) {
discWidth = (outer - inner) / outer;
}
_size = static_cast<float>(outer);
_width = static_cast<float>(discWidth);
// Compute the coservative bounds normalized by the size of the disc, i.e. in [0, 1]
_conservativeBounds = glm::vec2(innerConservative, outerConservative);
_conservativeBounds /= _size;
}
glm::dvec4 RenderableHabitableZone::computeKopparapuZoneBoundaries(float teff,
float luminosity)
{
// Kopparapu's formula only considers stars with teff in range [2600, 7200] K.
// However, we want to use the formula for more stars, so add some flexibility to
// the teff boundaries (see constructor).
// OBS! This also prevents problems with too large teff values in the computation
const glm::vec2 teffBounds = _kopparapuTeffInterval;
if (teff > teffBounds.y || teff < teffBounds.x) {
// For the other stars, use a method by Tom E. Morris:
// https://www.planetarybiology.com/calculating_habitable_zone.html
const double L = static_cast<double>(luminosity);
double inner = std::sqrt(L / 1.1);
double outer = std::sqrt(L / 0.53);
return glm::dvec4(inner, inner, outer, outer);
}
struct Coefficients {
double seffSun;
double a;
double b;
double c;
double d;
};
// Coefficients for planets of 1 Earth mass. Received from:
// https://depts.washington.edu/naivpl/sites/default/files/HZ_coefficients.dat
constexpr const Coefficients coefficients[] = {
// Optimistic Inner boundary - Recent Venus
{1.77600E+00, 2.13600E-04, 2.53300E-08, -1.33200E-11, -3.09700E-15},
// Conservative Inner boundary - Runaway greenhouse
{1.10700E+00, 1.33200E-04, 1.58000E-08, -8.30800E-12, -1.93100E-15},
// Conservative Outer boundary - Maximum greenhouse
{3.56000E-01, 6.17100E-05, 1.69800E-09, -3.19800E-12, -5.57500E-16},
// Optimistic Outer boundary - Early Mars
{3.20000E-01, 5.54700E-05, 1.52600E-09, -2.87400E-12, -5.01100E-16}
};
const double tstar = static_cast<double>(teff - 5780.f);
const double tstar2 = tstar * tstar;
const double L = static_cast<double>(luminosity);
glm::dvec4 distances;
for (int i = 0; i < 4; ++i) {
const Coefficients& coeffs = coefficients[i];
double seff = coeffs.seffSun + (coeffs.a * tstar) + (coeffs.b * tstar2) +
(coeffs.c * tstar * tstar2) + (coeffs.d * tstar2 * tstar2);
distances[i] = std::pow(L / seff, 0.5);
}
return distances;
}
} // namespace openspace

View File

@@ -0,0 +1,75 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* *
* 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_EXOPLANETS___RENDERABLEHABITABLEZONE___H__
#define __OPENSPACE_MODULE_EXOPLANETS___RENDERABLEHABITABLEZONE___H__
#include <modules/base/rendering/renderabledisc.h>
#include <openspace/properties/scalar/boolproperty.h>
#include <openspace/properties/scalar/floatproperty.h>
#include <openspace/properties/vector/vec2property.h>
namespace openspace {
namespace documentation { struct Documentation; }
class RenderableHabitableZone : public RenderableDisc {
public:
RenderableHabitableZone(const ghoul::Dictionary& dictionary);
void render(const RenderData& data, RendererTasks& rendererTask) override;
static documentation::Documentation Documentation();
private:
void initializeShader() override;
void updateUniformLocations() override;
void computeZone();
/**
* Compute the inner and outer boundary of the habitable zone of a star, according to
* formula and coefficients by Kopparapu et al. (2015) https://arxiv.org/abs/1404.5292
*
* \param teff The effective temperature of the star, in Kelvin
* \param luminosity The luminosity of the star, in solar luminosities
* \return A vec4 with the boundaries in atronomical units, in the order:
optimistic inner, conservative inner, conservative outer, optimistic outer
*/
glm::dvec4 computeKopparapuZoneBoundaries(float teff, float luminosity);
properties::FloatProperty _teff;
properties::FloatProperty _luminosity;
properties::BoolProperty _showOptimistic;
properties::Vec2Property _kopparapuTeffInterval;
glm::vec2 _conservativeBounds;
UniformCache(modelViewProjection, opacity, width, texture,
conservativeBounds, showOptimistic) _uniformCache;
};
} // namespace openspace
#endif // __OPENSPACE_MODULE_EXOPLANETS___RENDERABLEHABITABLEZONE___H__

View File

@@ -0,0 +1,87 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* *
* 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 vec2 vs_st;
in float vs_screenSpaceDepth;
uniform sampler1D transferFunctionTexture;
uniform float width;
uniform float opacity;
uniform vec2 conservativeBounds;
uniform bool showOptimistic;
// Remap the radius to texture coordinates in the trasfer function texture. The texture
// is treated as a linear scale where the color represent too cold to too hot. Account
// for the conservative bounds my mapping one third of the texture ouside each boundary.
// All parameters \in [0,1], where 1.0 corresponds to the max radius.
float computeTextureCoord(float radius, float innerRadius,
float conservativeInner, float conservativeOuter)
{
const float t1 = 1.0 / 3.0;
const float t2 = 2.0 / 3.0;
if (radius < conservativeInner) {
float t = (radius - innerRadius) / (conservativeInner - innerRadius);
return mix(0.0, t1, t);
}
else if (radius > conservativeOuter) {
float t = (radius - conservativeOuter) / (1.0 - conservativeOuter);
return mix(t2, 1.0, t);
}
else {
float t = (radius - conservativeInner) / (conservativeOuter - conservativeInner);
return mix(t1, t2, t);
}
}
Fragment getFragment() {
// The length of the texture coordinates vector is our distance from the center
float radius = length(vs_st);
float innerRadius = 1.0 - width;
// We only want to consider ring-like objects so we need to discard everything else
if (radius > 1.0 || radius < innerRadius) {
discard;
}
float consInner = conservativeBounds.x;
float consOuter = conservativeBounds.y;
bool outsideConservative = (radius < consInner) || (radius > consOuter);
if (!showOptimistic && outsideConservative) {
discard;
}
float texCoord = computeTextureCoord(radius, innerRadius, consInner, consOuter);
vec4 diffuse = texture(transferFunctionTexture, texCoord);
diffuse.a *= opacity;
Fragment frag;
frag.color = diffuse;
frag.depth = vs_screenSpaceDepth;
return frag;
}

View File

@@ -0,0 +1,47 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#version __CONTEXT__
#include "PowerScaling/powerScaling_vs.hglsl"
layout(location = 0) in vec2 in_position;
layout(location = 1) in vec2 in_st;
out vec2 vs_st;
out float vs_screenSpaceDepth;
uniform mat4 modelViewProjectionTransform;
void main() {
vec4 position = vec4(in_position.xy, 0.0, 1.0);
vec4 positionScreenSpace = z_normalization(modelViewProjectionTransform * position);
// Moving the origin to the center
vs_st = (in_st - vec2(0.5)) * 2.0;
vs_screenSpaceDepth = positionScreenSpace.w;
gl_Position = positionScreenSpace;
}

View File

@@ -24,8 +24,8 @@
#include <modules/space/spacemodule.h>
#include <modules/space/rendering/renderablesatellites.h>
#include <modules/space/rendering/renderableconstellationbounds.h>
#include <modules/space/rendering/renderablehabitablezone.h>
#include <modules/space/rendering/renderablerings.h>
#include <modules/space/rendering/renderablesatellites.h>
#include <modules/space/rendering/renderablesmallbody.h>
@@ -80,7 +80,7 @@ void SpaceModule::internalInitialize(const ghoul::Dictionary& dictionary) {
fRenderable->registerClass<RenderableConstellationBounds>(
"RenderableConstellationBounds"
);
fRenderable->registerClass<RenderableHabitableZone>("RenderableHabitableZone");
fRenderable->registerClass<RenderableRings>("RenderableRings");
fRenderable->registerClass<RenderableSatellites>("RenderableSatellites");
fRenderable->registerClass<RenderableSmallBody>("RenderableSmallBody");
@@ -119,6 +119,7 @@ void SpaceModule::internalDeinitializeGL() {
std::vector<documentation::Documentation> SpaceModule::documentations() const {
return {
RenderableConstellationBounds::Documentation(),
RenderableHabitableZone::Documentation(),
RenderableRings::Documentation(),
RenderableSatellites::Documentation(),
RenderableSmallBody::Documentation(),

View File

@@ -143,6 +143,7 @@ set(OPENSPACE_SOURCE
${OPENSPACE_BASE_DIR}/src/rendering/renderengine.cpp
${OPENSPACE_BASE_DIR}/src/rendering/renderengine_lua.inl
${OPENSPACE_BASE_DIR}/src/rendering/screenspacerenderable.cpp
${OPENSPACE_BASE_DIR}/src/rendering/texturecomponent.cpp
${OPENSPACE_BASE_DIR}/src/rendering/transferfunction.cpp
${OPENSPACE_BASE_DIR}/src/rendering/volumeraycaster.cpp
${OPENSPACE_BASE_DIR}/src/scene/asset.cpp
@@ -178,6 +179,7 @@ set(OPENSPACE_SOURCE
${OPENSPACE_BASE_DIR}/src/util/httprequest.cpp
${OPENSPACE_BASE_DIR}/src/util/keys.cpp
${OPENSPACE_BASE_DIR}/src/util/openspacemodule.cpp
${OPENSPACE_BASE_DIR}/src/util/planegeometry.cpp
${OPENSPACE_BASE_DIR}/src/util/progressbar.cpp
${OPENSPACE_BASE_DIR}/src/util/resourcesynchronization.cpp
${OPENSPACE_BASE_DIR}/src/util/screenlog.cpp
@@ -322,6 +324,7 @@ set(OPENSPACE_HEADER
${OPENSPACE_BASE_DIR}/include/openspace/rendering/dashboard.h
${OPENSPACE_BASE_DIR}/include/openspace/rendering/dashboarditem.h
${OPENSPACE_BASE_DIR}/include/openspace/rendering/framebufferrenderer.h
${OPENSPACE_BASE_DIR}/include/openspace/rendering/deferredcaster.h
${OPENSPACE_BASE_DIR}/include/openspace/rendering/deferredcasterlistener.h
${OPENSPACE_BASE_DIR}/include/openspace/rendering/deferredcastermanager.h
${OPENSPACE_BASE_DIR}/include/openspace/rendering/loadingscreen.h
@@ -332,11 +335,11 @@ set(OPENSPACE_HEADER
${OPENSPACE_BASE_DIR}/include/openspace/rendering/renderable.h
${OPENSPACE_BASE_DIR}/include/openspace/rendering/renderer.h
${OPENSPACE_BASE_DIR}/include/openspace/rendering/renderengine.h
${OPENSPACE_BASE_DIR}/include/openspace/rendering/volume.h
${OPENSPACE_BASE_DIR}/include/openspace/rendering/screenspacerenderable.h
${OPENSPACE_BASE_DIR}/include/openspace/rendering/deferredcaster.h
${OPENSPACE_BASE_DIR}/include/openspace/rendering/volumeraycaster.h
${OPENSPACE_BASE_DIR}/include/openspace/rendering/texturecomponent.h
${OPENSPACE_BASE_DIR}/include/openspace/rendering/transferfunction.h
${OPENSPACE_BASE_DIR}/include/openspace/rendering/volume.h
${OPENSPACE_BASE_DIR}/include/openspace/rendering/volumeraycaster.h
${OPENSPACE_BASE_DIR}/include/openspace/scene/asset.h
${OPENSPACE_BASE_DIR}/include/openspace/scene/assetlistener.h
${OPENSPACE_BASE_DIR}/include/openspace/scene/assetloader.h
@@ -373,6 +376,7 @@ set(OPENSPACE_HEADER
${OPENSPACE_BASE_DIR}/include/openspace/util/memorymanager.h
${OPENSPACE_BASE_DIR}/include/openspace/util/mouse.h
${OPENSPACE_BASE_DIR}/include/openspace/util/openspacemodule.h
${OPENSPACE_BASE_DIR}/include/openspace/util/planegeometry.h
${OPENSPACE_BASE_DIR}/include/openspace/util/progressbar.h
${OPENSPACE_BASE_DIR}/include/openspace/util/resourcesynchronization.h
${OPENSPACE_BASE_DIR}/include/openspace/util/screenlog.h

View File

@@ -1540,8 +1540,8 @@ scripting::LuaLibrary OpenSpaceEngine::luaLibrary() {
"Removes a tag (second argument) from a scene graph node (first argument)"
},
{
"createPixelImage",
&luascriptfunctions::createPixelImage,
"createSingeColorImage",
&luascriptfunctions::createSingeColorImage,
{},
"string, vec3",
"Creates a 1 pixel image with a certain color in the cache folder and "

View File

@@ -294,11 +294,11 @@ int downloadFile(lua_State* L) {
/**
* \ingroup LuaScripts
* createPixelImage():
* Creates a one pixel image with a given color and returns the p
* createSingeColorImage():
* Creates a one pixel image with a given color and returns the path to the cached file
*/
int createPixelImage(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::createPixelImage");
int createSingeColorImage(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::createSingeColorImage");
const std::string& name = ghoul::lua::value<std::string>(L, 1);
const ghoul::Dictionary& d = ghoul::lua::value<ghoul::Dictionary>(L, 2);

View File

@@ -0,0 +1,115 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* *
* 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 <openspace/rendering/texturecomponent.h>
#include <ghoul/filesystem/file.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/logging/logmanager.h>
namespace {
constexpr const char _loggerCat[] = "TextureComponent";
} // namespace
namespace openspace {
const ghoul::opengl::Texture* TextureComponent::texture() const {
return _texture.get();
}
ghoul::opengl::Texture* TextureComponent::texture() {
return _texture.get();
}
void TextureComponent::setFilterMode(Texture::FilterMode filterMode) {
_filterMode = filterMode;
}
void TextureComponent::setWrapping(Texture::WrappingMode wrapping) {
_wrappingMode = wrapping;
}
void TextureComponent::setShouldWatchFileForChanges(bool value) {
_shouldWatchFile = value;
}
void TextureComponent::setShouldPurgeFromRAM(bool value) {
_shouldPurgeFromRAM = value;
}
void TextureComponent::bind() {
ghoul_assert(_texture, "Texture must be loaded before binding");
_texture->bind();
}
void TextureComponent::uploadToGpu() {
if (!_texture) {
LERROR("Could not upload texture to GPU. Texture not loaded");
return;
}
_texture->uploadTexture();
_texture->setFilter(_filterMode);
_texture->setWrapping(_wrappingMode);
if (_shouldPurgeFromRAM) {
_texture->purgeFromRAM();
}
}
void TextureComponent::loadFromFile(const std::string& path) {
if (!path.empty()) {
using namespace ghoul::io;
using namespace ghoul::opengl;
std::unique_ptr<Texture> texture = TextureReader::ref().loadTexture(
absPath(path)
);
if (texture) {
LDEBUG(fmt::format("Loaded texture from '{}'", absPath(path)));
_texture = std::move(texture);
_textureFile = std::make_unique<ghoul::filesystem::File>(path);
if (_shouldWatchFile) {
_textureFile->setCallback(
[&](const ghoul::filesystem::File&) { _fileIsDirty = true; }
);
}
_fileIsDirty = false;
_textureIsDirty = true;
}
}
}
void TextureComponent::update() {
if (_fileIsDirty) {
loadFromFile(_textureFile->path());
}
if (_textureIsDirty) {
uploadToGpu();
_textureIsDirty = false;
}
}
} // namespace openspace

108
src/util/planegeometry.cpp Normal file
View File

@@ -0,0 +1,108 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* *
* 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 <openspace/util/planegeometry.h>
#include <ghoul/logging/logmanager.h>
#include <string>
namespace {
constexpr const char* _loggerCat = "PlaneGeometry";
} // namespace
namespace openspace {
PlaneGeometry::PlaneGeometry(glm::vec2 size) : _size(std::move(size)) {}
PlaneGeometry::PlaneGeometry(float size) : PlaneGeometry(glm::vec2(size, size)) {}
PlaneGeometry::~PlaneGeometry() {
glDeleteBuffers(1, &_vBufferId);
glDeleteVertexArrays(1, &_vaoId);
}
void PlaneGeometry::initialize() {
glGenVertexArrays(1, &_vaoId);
glGenBuffers(1, &_vBufferId);
updateGeometry();
}
void PlaneGeometry::deinitialize() {
glDeleteVertexArrays(1, &_vaoId);
_vaoId = 0;
glDeleteBuffers(1, &_vBufferId);
_vBufferId = 0;
}
void PlaneGeometry::render() {
glBindVertexArray(_vaoId);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
}
void PlaneGeometry::updateSize(const glm::vec2& size) {
_size = size;
updateGeometry();
}
void PlaneGeometry::updateSize(const float size) {
updateSize(glm::vec2(size));
}
void PlaneGeometry::updateGeometry() {
const glm::vec2 size = _size;
struct VertexData {
GLfloat x;
GLfloat y;
GLfloat s;
GLfloat t;
};
VertexData vertices[] = {
{ -size.x, -size.y, 0.f, 0.f },
{ size.x, size.y, 1.f, 1.f },
{ -size.x, size.y, 0.f, 1.f },
{ -size.x, -size.y, 0.f, 0.f },
{ size.x, -size.y, 1.f, 0.f },
{ size.x, size.y, 1.f, 1.f }
};
glBindVertexArray(_vaoId);
glBindBuffer(GL_ARRAY_BUFFER, _vBufferId);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), &vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), nullptr);
glEnableVertexAttribArray(1);
glVertexAttribPointer(
1,
2,
GL_FLOAT,
GL_FALSE,
sizeof(VertexData),
reinterpret_cast<void*>(offsetof(VertexData, s)) // NOLINT
);
}
} // namespace openspace