diff --git a/include/openspace/rendering/planets/simplespheregeometry.h b/include/openspace/rendering/planets/simplespheregeometry.h index 2bbc012261..f2e7df8691 100644 --- a/include/openspace/rendering/planets/simplespheregeometry.h +++ b/include/openspace/rendering/planets/simplespheregeometry.h @@ -52,7 +52,7 @@ private: properties::Vec2Property _radius; properties::IntProperty _segments; - PowerScaledSphere* _planet; + PowerScaledSphere* _sphere; }; } // namespace planetgeometry diff --git a/include/openspace/rendering/renderablesphere.h b/include/openspace/rendering/renderablesphere.h new file mode 100644 index 0000000000..de5ecdbe3f --- /dev/null +++ b/include/openspace/rendering/renderablesphere.h @@ -0,0 +1,75 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#ifndef __RENDERABLESPHERE_H__ +#define __RENDERABLESPHERE_H__ + +#include +#include + +#include +#include +#include +#include +#include + +namespace openspace { + +class PowerScaledSphere; + +class RenderableSphere : public Renderable { +public: + RenderableSphere(const ghoul::Dictionary& dictionary); + ~RenderableSphere(); + + bool initialize() override; + bool deinitialize() override; + + bool isReady() const override; + + void render(const RenderData& data) override; + void update(const UpdateData& data) override; + +private: + void loadTexture(); + + properties::StringProperty _texturePath; + properties::OptionProperty _orientation; + + properties::Vec2Property _size; + properties::IntProperty _segments; + + properties::FloatProperty _transparency; + + ghoul::opengl::ProgramObject* _shader; + ghoul::opengl::Texture* _texture; + + PowerScaledSphere* _sphere; + + bool _programIsDirty; + bool _sphereIsDirty; +}; + +} // namespace openspace +#endif // __RENDERABLESPHERE_H__ diff --git a/shaders/modules/sphere/sphere_fs.glsl b/shaders/modules/sphere/sphere_fs.glsl new file mode 100644 index 0000000000..046dd1bcdd --- /dev/null +++ b/shaders/modules/sphere/sphere_fs.glsl @@ -0,0 +1,74 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#version __CONTEXT__ + +uniform float time; +uniform sampler2D texture1; +uniform float alpha; + +in vec2 vs_st; +in vec4 vs_position; + +#include "ABuffer/abufferStruct.hglsl" +#include "ABuffer/abufferAddToBuffer.hglsl" +#include "PowerScaling/powerScaling_fs.hglsl" + +void main() +{ + vec4 position = vs_position; + // This has to be fixed with the ScaleGraph in place (precision deficiency in depth buffer) ---abock + // float depth = pscDepth(position); + float depth = 1000.0; + vec4 diffuse; + // if(gl_FrontFacing) + diffuse = texture(texture1, vs_st); + // else + // diffuse = texture(texture1, vec2(1-vs_st.s,vs_st.t)); + + diffuse.a *= alpha; + + //vec4 diffuse = vec4(1,vs_st,1); + //vec4 diffuse = vec4(1,0,0,1); + // if(position.w > 9.0) { + // diffuse = vec4(1,0,0,1); + // } + + + // #if 0 + // diffuse = vec4(vs_position.xyz / 10, 1.0); + // #else + // // if (abs(vs_st.r - 0.75) <= 0.01 && abs(vs_st.g - 0.5) <= 0.01) + // if (abs(vs_st.g - 0.5) <= 0.01) + // diffuse = vec4(vec2(vs_st), 0.0, 1.0); + // else + // diffuse = vec4(0.0); + // #endif + + // diffuse = vec4(1.0, 0.0, 0.0, 1.0); + + ABufferStruct_t frag = createGeometryFragment(diffuse, position, depth); + addToBuffer(frag); + +} \ No newline at end of file diff --git a/shaders/modules/sphere/sphere_vs.glsl b/shaders/modules/sphere/sphere_vs.glsl new file mode 100644 index 0000000000..8933103c00 --- /dev/null +++ b/shaders/modules/sphere/sphere_vs.glsl @@ -0,0 +1,57 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#version __CONTEXT__ + +uniform mat4 ViewProjection; +uniform mat4 ModelTransform; + +layout(location = 0) in vec4 in_position; +layout(location = 1) in vec2 in_st; + +out vec2 vs_st; +out vec4 vs_position; +out float s; + +#include "PowerScaling/powerScaling_vs.hglsl" + +void main() +{ + vec4 tmp = in_position; + + mat4 mt = ModelTransform; + + mt = mat4(0, -1, 0, 0, + 1, 0, 0, 0, + 0, 0, -1, 0, + 0, 0, 0, 1) * mt; + + vec4 position = pscTransform(tmp, mt); + + vs_position = in_position; + vs_st = in_st; + + position = ViewProjection * position; + gl_Position = z_normalization(position); +} \ No newline at end of file diff --git a/src/rendering/planets/simplespheregeometry.cpp b/src/rendering/planets/simplespheregeometry.cpp index d57ce7de9d..7a5dd02f17 100644 --- a/src/rendering/planets/simplespheregeometry.cpp +++ b/src/rendering/planets/simplespheregeometry.cpp @@ -46,7 +46,7 @@ SimpleSphereGeometry::SimpleSphereGeometry(const ghoul::Dictionary& dictionary) , _radius("radius", "Radius", glm::vec2(1.f, 0.f), glm::vec2(-10.f, -20.f), glm::vec2(10.f, 20.f)) , _segments("segments", "Segments", 20, 1, 50) - , _planet(nullptr) + , _sphere(nullptr) { using constants::scenegraphnode::keyName; using constants::simplespheregeometry::keyRadius; @@ -94,14 +94,14 @@ bool SimpleSphereGeometry::initialize(RenderablePlanet* parent) void SimpleSphereGeometry::deinitialize() { - if (_planet) - delete _planet; - _planet = nullptr; + if (_sphere) + delete _sphere; + _sphere = nullptr; } void SimpleSphereGeometry::render() { - _planet->render(); + _sphere->render(); } void SimpleSphereGeometry::createSphere() @@ -111,11 +111,11 @@ void SimpleSphereGeometry::createSphere() PowerScaledScalar planetSize(_radius); _parent->setBoundingSphere(planetSize); - if(_planet) - delete _planet; + if(_sphere) + delete _sphere; - _planet = new PowerScaledSphere(planetSize, _segments); - _planet->initialize(); + _sphere = new PowerScaledSphere(planetSize, _segments); + _sphere->initialize(); } } // namespace planetgeometry diff --git a/src/rendering/renderablesphere.cpp b/src/rendering/renderablesphere.cpp new file mode 100644 index 0000000000..7f52897b37 --- /dev/null +++ b/src/rendering/renderablesphere.cpp @@ -0,0 +1,206 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include +#include + +#include +#include +#include +#include + +#include + + +namespace { + const std::string _loggerCat = "RenderableSphere"; + + const std::string keySize = "Size"; + const std::string keySegments = "Segments"; + const std::string keyTexture = "Texture"; + const std::string keyOrientation = "Orientation"; + + enum Orientation { + Outside = 1, + Inside = 2 + }; +} + +namespace openspace { + +RenderableSphere::RenderableSphere(const ghoul::Dictionary& dictionary) + : Renderable(dictionary) + , _texturePath("texture", "Texture") + , _orientation("orientation", "Orientation") + , _size("size", "Size", glm::vec2(1.f, 1.f), glm::vec2(0.f), glm::vec2(100.f)) + , _segments("segments", "Segments", 8, 4, 100) + , _transparency("transparency", "Transparency", 1.f, 0.f, 1.f) + , _shader(nullptr) + , _texture(nullptr) + , _sphere(nullptr) + , _programIsDirty(false) + , _sphereIsDirty(false) +{ + std::string path; + bool success = dictionary.getValue(constants::scenegraph::keyPathModule, path); + ghoul_assert(success, + "RenderablePlanet need the '" << constants::scenegraph::keyPathModule << "' be specified"); + + if (dictionary.hasKeyAndValue(keySize)) { + glm::vec2 size; + dictionary.getValue(keySize, size); + _size = size; + } + + if (dictionary.hasKeyAndValue(keySegments)) { + int segments; + dictionary.getValue(keySegments, segments); + _segments = segments; + } + + if (dictionary.hasKeyAndValue(keyTexture)) { + std::string texture; + dictionary.getValue(keyTexture, texture); + _texturePath = path + '/' + texture; + } + + _orientation.addOption(Outside, "Outside"); + _orientation.addOption(Inside, "Inside"); + _orientation.addOption(Outside | Inside, "Outside + Inside"); + + if (dictionary.hasKeyAndValue(keyOrientation)) { + std::string orientation; + dictionary.getValue(keyOrientation, orientation); + if (orientation == "Outside") + _orientation = Outside; + else if (orientation == "Inside") + _orientation = Inside; + else + _orientation = Outside | Inside; + } + + addProperty(_orientation); + addProperty(_size); + _size.onChange([this](){ _sphereIsDirty = true; }); + addProperty(_segments); + _segments.onChange([this](){ _sphereIsDirty = true; }); + + addProperty(_transparency); + + addProperty(_texturePath); + _texturePath.onChange(std::bind(&RenderableSphere::loadTexture, this)); +} + +RenderableSphere::~RenderableSphere() { +} + +bool RenderableSphere::isReady() const { + return (_sphere != nullptr) && (_shader != nullptr) && (_texture != nullptr); +} + +bool RenderableSphere::initialize() { + _sphere = new PowerScaledSphere(_size.value(), _segments); + _sphere->initialize(); + + // pscstandard + _shader = ghoul::opengl::ProgramObject::Build("Sphere", + "${SHADERS}/modules/sphere/sphere_vs.glsl", + "${SHADERS}/modules/sphere/sphere_fs.glsl"); + if (!_shader) + return false; + _shader->setProgramObjectCallback([&](ghoul::opengl::ProgramObject*){ _programIsDirty = true; }); + + loadTexture(); + + return isReady(); +} + +bool RenderableSphere::deinitialize() { + delete _sphere; + delete _texture; + return true; +} + +void RenderableSphere::render(const RenderData& data) { + + glm::mat4 transform = glm::mat4(1.0); + + transform = glm::rotate(transform, 90.f, glm::vec3(1, 0, 0)); + + + // Activate shader + _shader->activate(); + _shader->setIgnoreUniformLocationError(true); + + _shader->setUniform("ViewProjection", data.camera.viewProjectionMatrix()); + _shader->setUniform("ModelTransform", transform); + setPscUniforms(_shader, &data.camera, data.position); + + _shader->setUniform("alpha", _transparency); + + ghoul::opengl::TextureUnit unit; + unit.activate(); + _texture->bind(); + _shader->setUniform("texture1", unit); + + _sphere->render(); + + _shader->setIgnoreUniformLocationError(false); + _shader->deactivate(); +} + +void RenderableSphere::update(const UpdateData& data) { + if (_programIsDirty) { + _shader->rebuildFromFile(); + _programIsDirty = false; + } + + if (_sphereIsDirty) { + delete _sphere; + _sphere = new PowerScaledSphere(_size.value(), _segments); + _sphere->initialize(); + _sphereIsDirty = false; + } +} + +void RenderableSphere::loadTexture() { + LDEBUG("loadTexture"); + if (_texturePath.value() != "") { + LDEBUG("loadTexture2"); + ghoul::opengl::Texture* texture = ghoul::io::TextureReader::ref().loadTexture(absPath(_texturePath)); + if (texture) { + LDEBUG("Loaded texture from '" << absPath(_texturePath) << "'"); + texture->uploadTexture(); + + // Textures of planets looks much smoother with AnisotropicMipMap rather than linear + texture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); + + if (_texture) + delete _texture; + _texture = texture; + } + } +} + +} // namespace openspace diff --git a/src/util/factorymanager.cpp b/src/util/factorymanager.cpp index b219a47cb1..10122c69c6 100644 --- a/src/util/factorymanager.cpp +++ b/src/util/factorymanager.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -73,6 +74,8 @@ void FactoryManager::initialize() "RenderableTrail"); _manager->factory()->registerClass( "RenderableFov"); + _manager->factory()->registerClass( + "RenderableSphere"); _manager->factory()->registerClass( "RenderableSphericalGrid"); _manager->factory()->registerClass(