diff --git a/src/celengine/CMakeLists.txt b/src/celengine/CMakeLists.txt index 6d828ac2..31d95f79 100644 --- a/src/celengine/CMakeLists.txt +++ b/src/celengine/CMakeLists.txt @@ -12,6 +12,8 @@ set(CELENGINE_SOURCES body.h boundaries.cpp boundaries.h + boundariesrenderer.cpp + boundariesrenderer.h catalogxref.cpp catalogxref.h category.cpp diff --git a/src/celengine/boundaries.cpp b/src/celengine/boundaries.cpp index 9bbcd5ca..efb348f8 100644 --- a/src/celengine/boundaries.cpp +++ b/src/celengine/boundaries.cpp @@ -1,6 +1,6 @@ // boundaries.cpp // -// Copyright (C) 2002-2009, the Celestia Development Team +// Copyright (C) 2002-2019, the Celestia Development Team // Original version by Chris Laurel // // This program is free software; you can redistribute it and/or @@ -9,11 +9,8 @@ // of the License, or (at your option) any later version. #include -#include -#include #include "boundaries.h" #include "astro.h" -#include "render.h" using namespace Eigen; using namespace std; @@ -27,21 +24,19 @@ ConstellationBoundaries::ConstellationBoundaries() } ConstellationBoundaries::~ConstellationBoundaries() -{ - cleanup(); -} - -void ConstellationBoundaries::cleanup() { for (const auto chain : chains) delete chain; chains.clear(); delete currentChain; - currentChain = nullptr; +} - delete[] vtx_buf; - vtx_buf = nullptr; + +const std::vector& +ConstellationBoundaries::getChains() const +{ + return chains; } @@ -69,56 +64,6 @@ void ConstellationBoundaries::lineto(float ra, float dec) } -void ConstellationBoundaries::render(const Color& color, const Renderer& renderer) -{ - m_vo.bind(); - if (!m_vo.initialized()) - { - prepare(); - m_vo.allocate(vtx_num * 3 * sizeof(GLshort), vtx_buf); - cleanup(); - m_vo.setVertices(3, GL_SHORT, false, 0, 0); - } - - CelestiaGLProgram* prog = renderer.getShaderManager().getShader(shadprop); - if (prog == nullptr) - return; - - prog->use(); - prog->color = color.toVector4(); - m_vo.draw(GL_LINES, vtx_num); - - glUseProgram(0); - m_vo.unbind(); -} - - -void ConstellationBoundaries::prepare() -{ - vtx_num = accumulate(chains.begin(), chains.end(), 0, - [](int a, Chain* b) { return a + b->size(); }); - - // as we use GL_LINES we should double the number of vertices - vtx_num *= 2; - - vtx_buf = new GLshort[vtx_num * 3]; - GLshort* ptr = vtx_buf; - for (const auto chain : chains) - { - for (unsigned j = 0; j < 3; j++, ptr++) - *ptr = (GLshort) (*chain)[0][j]; - for (unsigned i = 1; i < chain->size(); i++) - { - for (unsigned j = 0; j < 3; j++) - ptr[j] = ptr[j + 3] = (GLshort) (*chain)[i][j]; - ptr += 6; - } - for (unsigned j = 0; j < 3; j++, ptr++) - *ptr = (GLshort) (*chain)[0][j]; - } -} - - ConstellationBoundaries* ReadBoundaries(istream& in) { auto* boundaries = new ConstellationBoundaries(); diff --git a/src/celengine/boundaries.h b/src/celengine/boundaries.h index 280d14ce..dc8e3deb 100644 --- a/src/celengine/boundaries.h +++ b/src/celengine/boundaries.h @@ -1,6 +1,6 @@ // boundaries.h // -// Copyright (C) 2002-2009, the Celestia Development Team +// Copyright (C) 2002-2019, the Celestia Development Team // Original version by Chris Laurel // // This program is free software; you can redistribute it and/or @@ -12,20 +12,14 @@ #define _CELENGINE_BOUNDARIES_H_ #include -#include #include #include -#include -#include "shadermanager.h" -#include "vertexobject.h" - -class Renderer; class ConstellationBoundaries { + public: using Chain = std::vector; - public: ConstellationBoundaries(); ~ConstellationBoundaries(); ConstellationBoundaries(const ConstellationBoundaries&) = delete; @@ -35,20 +29,12 @@ class ConstellationBoundaries void moveto(float ra, float dec); void lineto(float ra, float dec); - void render(const Color& color, const Renderer& renderer); + + const std::vector& getChains() const; private: - void cleanup(); - void prepare(); - Chain* currentChain{ nullptr }; std::vector chains; - - GLshort *vtx_buf{ nullptr }; - GLsizei vtx_num{ 0 }; - celgl::VertexObject m_vo{GL_ARRAY_BUFFER, 0, GL_STATIC_DRAW}; - - ShaderProperties shadprop{ ShaderProperties::UniformColor }; }; ConstellationBoundaries* ReadBoundaries(std::istream&); diff --git a/src/celengine/boundariesrenderer.cpp b/src/celengine/boundariesrenderer.cpp new file mode 100644 index 00000000..285b9d2b --- /dev/null +++ b/src/celengine/boundariesrenderer.cpp @@ -0,0 +1,89 @@ +// boundariesrenderer.cpp +// +// Copyright (C) 2018-2019, the Celestia Development Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. + +#include +#include +#include +#include +#include "boundariesrenderer.h" +#include "render.h" + +using namespace Eigen; +using namespace std; + +BoundariesRenderer::BoundariesRenderer(const ConstellationBoundaries *boundaries) : + m_boundaries(boundaries) +{ +} + +bool BoundariesRenderer::sameBoundaries(const ConstellationBoundaries *boundaries) const +{ + return m_boundaries == boundaries; +} + +void BoundariesRenderer::render(const Renderer &renderer, const Color &color) +{ + auto *prog = renderer.getShaderManager().getShader(m_shadprop); + if (prog == nullptr) + return; + + m_vo.bind(); + if (!m_vo.initialized()) + { + auto *vtx_buf = prepare(); + if (vtx_buf == nullptr) + { + m_vo.unbind(); + return; + } + m_vo.allocate(m_vtxTotal * 3 * sizeof(GLshort), vtx_buf); + m_vo.setVertices(3, GL_SHORT, false, 0, 0); + delete[] vtx_buf; + } + + prog->use(); + prog->color = color.toVector4(); + m_vo.draw(GL_LINES, m_vtxTotal); + + glUseProgram(0); + m_vo.unbind(); +} + + +GLshort* BoundariesRenderer::prepare() +{ + auto chains = m_boundaries->getChains(); + auto vtx_num = accumulate(chains.begin(), chains.end(), 0, + [](int a, ConstellationBoundaries::Chain* b) { return a + b->size(); }); + + if (vtx_num == 0) + return nullptr; + + // as we use GL_LINES we should double the number of vertices + vtx_num *= 2; + m_vtxTotal = vtx_num; + + auto *vtx_buf = new GLshort[vtx_num * 3]; + GLshort* ptr = vtx_buf; + for (const auto chain : chains) + { + for (unsigned j = 0; j < 3; j++, ptr++) + *ptr = (GLshort) (*chain)[0][j]; + for (unsigned i = 1; i < chain->size(); i++) + { + for (unsigned j = 0; j < 3; j++) + ptr[j] = ptr[j + 3] = (GLshort) (*chain)[i][j]; + ptr += 6; + } + for (unsigned j = 0; j < 3; j++, ptr++) + *ptr = (GLshort) (*chain)[0][j]; + } + + return vtx_buf; +} diff --git a/src/celengine/boundariesrenderer.h b/src/celengine/boundariesrenderer.h new file mode 100644 index 00000000..800917e2 --- /dev/null +++ b/src/celengine/boundariesrenderer.h @@ -0,0 +1,40 @@ +// boundariesrenderer.h +// +// Copyright (C) 2018-2019, the Celestia Development Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. + +#pragma once + +#include "shadermanager.h" +#include "vertexobject.h" + +class Color; +class ConstellationBoundaries; +class Renderer; + +class BoundariesRenderer +{ + public: + BoundariesRenderer(const ConstellationBoundaries*); + ~BoundariesRenderer() = default; + BoundariesRenderer() = delete; + BoundariesRenderer(const BoundariesRenderer&) = delete; + BoundariesRenderer(BoundariesRenderer&&) = delete; + BoundariesRenderer& operator=(const BoundariesRenderer&) = delete; + BoundariesRenderer& operator=(BoundariesRenderer&&) = delete; + + void render(const Renderer &renderer, const Color &color); + bool sameBoundaries(const ConstellationBoundaries*) const; + + private: + GLshort* prepare(); + + celgl::VertexObject m_vo { GL_ARRAY_BUFFER, 0, GL_STATIC_DRAW }; + ShaderProperties m_shadprop { ShaderProperties::UniformColor }; + const ConstellationBoundaries *m_boundaries { nullptr }; + GLsizei m_vtxTotal { 0 }; +}; diff --git a/src/celengine/render.cpp b/src/celengine/render.cpp index 413b5bfe..d3a8cd97 100644 --- a/src/celengine/render.cpp +++ b/src/celengine/render.cpp @@ -63,6 +63,7 @@ std::ofstream hdrlog; #include "pointstarrenderer.h" #include "orbitsampler.h" #include "asterismrenderer.h" +#include "boundariesrenderer.h" #include #include #include @@ -384,6 +385,7 @@ Renderer::~Renderer() delete shaderManager; delete m_asterismRenderer; + delete m_boundariesRenderer; } @@ -4929,9 +4931,20 @@ void Renderer::renderAsterisms(const Universe& universe, float dist) void Renderer::renderBoundaries(const Universe& universe, float dist) { - if ((renderFlags & ShowBoundaries) == 0 || universe.getBoundaries() == nullptr) + auto boundaries = universe.getBoundaries(); + if ((renderFlags & ShowBoundaries) == 0 || boundaries == nullptr) return; + if (m_boundariesRenderer == nullptr) + { + m_boundariesRenderer = new BoundariesRenderer(boundaries); + } + else if (!m_boundariesRenderer->sameBoundaries(boundaries)) + { + delete m_boundariesRenderer; + m_boundariesRenderer = new BoundariesRenderer(boundaries); + } + /* We'll linearly fade the boundaries as a function of the observer's distance to the origin of coordinates: */ float opacity = 1.0f; @@ -4941,9 +4954,8 @@ void Renderer::renderBoundaries(const Universe& universe, float dist) (MaxAsterismLabelsDist - MaxAsterismLabelsConstDist) + 1); } - glDisable(GL_TEXTURE_2D); enableSmoothLines(renderFlags); - universe.getBoundaries()->render(Color(BoundaryColor, opacity), *this); + m_boundariesRenderer->render(*this, Color(BoundaryColor, opacity)); disableSmoothLines(renderFlags); } diff --git a/src/celengine/render.h b/src/celengine/render.h index 3de39705..86207a01 100644 --- a/src/celengine/render.h +++ b/src/celengine/render.h @@ -40,6 +40,7 @@ class CurvePlot; class Rect; class PointStarVertexBuffer; class AsterismRenderer; +class BoundariesRenderer; struct LightSource { @@ -753,6 +754,7 @@ class Renderer bool settingsChanged; AsterismRenderer* m_asterismRenderer { nullptr }; + BoundariesRenderer* m_boundariesRenderer { nullptr }; // True if we're in between a begin/endObjectAnnotations bool objectAnnotationSetOpen;