Refactor asterisms rendering to have common and rendering parts

pull/3/head
Hleb Valoshka 2019-12-03 14:11:10 +03:00
parent 8778c07ccb
commit c21934aee3
7 changed files with 204 additions and 144 deletions

View File

@ -1,6 +1,8 @@
set(CELENGINE_SOURCES
asterism.cpp
asterism.h
asterismrenderer.cpp
asterismrenderer.h
astro.cpp
astro.h
atmosphere.h

View File

@ -8,13 +8,12 @@
// of the License, or (at your option) any later version.
#include <config.h>
#include <cstring>
#include <GL/glew.h>
#include <celutil/util.h>
#include <celutil/debug.h>
#include "stardb.h"
#include "asterism.h"
#include "parser.h"
#include "render.h"
using namespace std;
@ -75,7 +74,7 @@ Color Asterism::getOverrideColor() const
* for contellations. Calling unsetOverrideColor will remove the
* override color.
*/
void Asterism::setOverrideColor(Color c)
void Asterism::setOverrideColor(const Color &c)
{
color = c;
useOverrideColor = true;
@ -99,113 +98,6 @@ bool Asterism::isColorOverridden() const
return useOverrideColor;
}
/*! Draw visible asterisms.
*/
void AsterismList::render(const Color& defaultColor, const Renderer& renderer)
{
m_vo.bind();
if (!m_vo.initialized())
{
prepare();
if (vtx_num == 0)
return;
m_vo.allocate(vtx_num * 3 * sizeof(GLfloat), vtx_buf);
cleanup();
m_vo.setVertices(3, GL_FLOAT, false, 0, 0);
}
CelestiaGLProgram* prog = renderer.getShaderManager().getShader(shadprop);
if (prog == nullptr)
return;
prog->use();
prog->color = defaultColor.toVector4();
m_vo.draw(GL_LINES, vtx_num);
ptrdiff_t offset = 0;
float opacity = defaultColor.alpha();
for (const auto ast : *this)
{
if (!ast->getActive() || !ast->isColorOverridden())
{
offset += ast->vertex_count;
continue;
}
prog->color = Color(ast->getOverrideColor(), opacity).toVector4();
m_vo.draw(GL_LINES, ast->vertex_count, offset);
offset += ast->vertex_count;
}
glUseProgram(0);
m_vo.unbind();
}
void AsterismList::prepare()
{
if (prepared)
return;
// calculate required vertices number
vtx_num = 0;
for (const auto ast : *this)
{
uint16_t ast_vtx_num = 0;
for (int k = 0; k < ast->getChainCount(); k++)
{
// as we use GL_LINES we should double the number of vertices
// as we don't need closed figures we have only one copy of
// the 1st and last vertexes
auto s = (uint16_t) ast->getChain(k).size();
if (s > 1)
ast_vtx_num += 2 * s - 2;
}
ast->vertex_count = ast_vtx_num;
vtx_num += ast_vtx_num;
}
if (vtx_num == 0)
return;
vtx_buf = new GLfloat[vtx_num * 3];
GLfloat* ptr = vtx_buf;
for (const auto ast : *this)
{
for (int k = 0; k < ast->getChainCount(); k++)
{
const auto& chain = ast->getChain(k);
// skip empty (without starts or only with one star) chains
if (chain.size() <= 1)
continue;
memcpy(ptr, chain[0].data(), 3 * sizeof(float));
ptr += 3;
for (unsigned i = 1; i < chain.size() - 1; i++)
{
memcpy(ptr, chain[i].data(), 3 * sizeof(float));
memcpy(ptr + 3, chain[i].data(), 3 * sizeof(float));
ptr += 6;
}
memcpy(ptr, chain[chain.size() - 1].data(), 3 * sizeof(float));
ptr += 3;
}
}
prepared = true;
}
void AsterismList::cleanup()
{
delete[] vtx_buf;
// TODO: delete chains
}
AsterismList* ReadAsterismList(istream& in, const StarDatabase& stardb)
{
@ -258,7 +150,8 @@ AsterismList* ReadAsterismList(istream& in, const StarDatabase& stardb)
star = stardb.find(ReplaceGreekLetterAbbr(i->getString()));
if (star != nullptr)
new_chain->push_back(star->getPosition());
else DPRINTF(LOG_LEVEL_ERROR, "Error loading star \"%s\" for asterism \"%s\".\n", name.c_str(), i->getString().c_str());
else
DPRINTF(LOG_LEVEL_ERROR, "Error loading star \"%s\" for asterism \"%s\".\n", name.c_str(), i->getString().c_str());
}
}

View File

@ -15,18 +15,19 @@
#include <vector>
#include <iostream>
#include <celutil/color.h>
#include "stardb.h"
#include "shadermanager.h"
#include "vertexobject.h"
class Renderer;
class AsterismList;
class StarDatabase;
class Asterism
{
public:
Asterism(std::string);
~Asterism() = default;
Asterism() = delete;
Asterism(const Asterism&) = delete;
Asterism(Asterism&&) = delete;
Asterism& operator=(const Asterism&) = delete;
Asterism& operator=(Asterism&&) = delete;
typedef std::vector<Eigen::Vector3f> Chain;
@ -38,7 +39,7 @@ class Asterism
void setActive(bool _active);
Color getOverrideColor() const;
void setOverrideColor(Color c);
void setOverrideColor(const Color &c);
void unsetOverrideColor();
bool isColorOverridden() const;
@ -48,33 +49,13 @@ class Asterism
std::string name;
std::string i18nName;
std::vector<Chain*> chains;
// total number of vertexes in the asterism
uint16_t vertex_count{ 0 };
bool active{ true };
bool useOverrideColor{ false };
Color color;
friend class AsterismList;
bool active { true };
bool useOverrideColor { false };
};
class AsterismList : public std::vector<Asterism*>
{
public:
void render(const Color& color, const Renderer& renderer);
private:
void cleanup();
void prepare();
GLfloat *vtx_buf{ nullptr };
GLsizei vtx_num{ 0 };
bool prepared{ false };
celgl::VertexObject m_vo{GL_ARRAY_BUFFER, 0, GL_STATIC_DRAW};
ShaderProperties shadprop{ ShaderProperties::UniformColor };
};
typedef std::vector<Asterism*> AsterismList;
AsterismList* ReadAsterismList(std::istream&, const StarDatabase&);

View File

@ -0,0 +1,126 @@
// asterismrenderer.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 <cassert>
#include "asterismrenderer.h"
#include "render.h"
using namespace std;
AsterismRenderer::AsterismRenderer(const AsterismList *asterisms) :
m_asterisms(asterisms)
{
}
bool AsterismRenderer::sameAsterisms(const AsterismList *asterisms) const
{
return m_asterisms == asterisms;
}
/*! Draw visible asterisms.
*/
void AsterismRenderer::render(const Renderer &renderer, const Color &defaultColor)
{
auto *prog = renderer.getShaderManager().getShader(m_shadprop);
if (prog == nullptr)
return;
m_vo.bind();
if (!m_vo.initialized())
{
auto *vtxBuf = prepare();
if (vtxBuf == nullptr)
{
m_vo.unbind();
return;
}
m_vo.allocate(m_vtxTotal * 3 * sizeof(GLfloat), vtxBuf);
m_vo.setVertices(3, GL_FLOAT, false, 0, 0);
delete[] vtxBuf;
}
prog->use();
prog->color = defaultColor.toVector4();
m_vo.draw(GL_LINES, m_vtxTotal);
assert(m_asterisms->size() == m_vtxCount.size());
ptrdiff_t offset = 0;
float opacity = defaultColor.alpha();
for (size_t size = m_asterisms->size(), i = 0; i < size; i++)
{
auto *ast = (*m_asterisms)[i];
if (!ast->getActive() || !ast->isColorOverridden())
{
offset += m_vtxCount[i];
continue;
}
prog->color = Color(ast->getOverrideColor(), opacity).toVector4();
m_vo.draw(GL_LINES, m_vtxCount[i], offset);
offset += m_vtxCount[i];
}
glUseProgram(0);
m_vo.unbind();
}
GLfloat* AsterismRenderer::prepare()
{
// calculate required vertices number
GLsizei vtx_num = 0;
for (const auto ast : *m_asterisms)
{
GLsizei ast_vtx_num = 0;
for (int k = 0; k < ast->getChainCount(); k++)
{
// as we use GL_LINES we should double the number of vertices
// as we don't need closed figures we have only one copy of
// the 1st and last vertexes
GLsizei s = ast->getChain(k).size();
if (s > 1)
ast_vtx_num += 2 * s - 2;
}
m_vtxCount.push_back(ast_vtx_num);
vtx_num += ast_vtx_num;
}
if (vtx_num == 0)
return nullptr;
m_vtxTotal = vtx_num;
GLfloat* vtx_buf = new GLfloat[vtx_num * 3];
GLfloat* ptr = vtx_buf;
for (const auto ast : *m_asterisms)
{
for (int k = 0; k < ast->getChainCount(); k++)
{
const auto& chain = ast->getChain(k);
// skip empty (without starts or only with one star) chains
if (chain.size() <= 1)
continue;
memcpy(ptr, chain[0].data(), 3 * sizeof(float));
ptr += 3;
for (unsigned i = 1; i < chain.size() - 1; i++)
{
memcpy(ptr, chain[i].data(), 3 * sizeof(float));
memcpy(ptr + 3, chain[i].data(), 3 * sizeof(float));
ptr += 6;
}
memcpy(ptr, chain[chain.size() - 1].data(), 3 * sizeof(float));
ptr += 3;
}
}
return vtx_buf;
}

View File

@ -0,0 +1,43 @@
// asterismrenderer.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 <vector>
#include <celengine/asterism.h>
#include <celutil/color.h>
#include "shadermanager.h"
#include "vertexobject.h"
class Renderer;
class AsterismRenderer
{
public:
AsterismRenderer(const AsterismList *asterisms);
~AsterismRenderer() = default;
AsterismRenderer() = delete;
AsterismRenderer(const AsterismRenderer&) = delete;
AsterismRenderer(AsterismRenderer&&) = delete;
AsterismRenderer& operator=(const AsterismRenderer&) = delete;
AsterismRenderer& operator=(AsterismRenderer&&) = delete;
void render(const Renderer &renderer, const Color &color);
bool sameAsterisms(const AsterismList *asterisms) const;
private:
GLfloat* prepare();
celgl::VertexObject m_vo { GL_ARRAY_BUFFER, 0, GL_STATIC_DRAW };
ShaderProperties m_shadprop { ShaderProperties::UniformColor };
std::vector<GLsizei> m_vtxCount;
const AsterismList *m_asterisms { nullptr };
GLsizei m_vtxTotal { 0 };
};

View File

@ -62,6 +62,7 @@ std::ofstream hdrlog;
#include "pointstarvertexbuffer.h"
#include "pointstarrenderer.h"
#include "orbitsampler.h"
#include "asterismrenderer.h"
#include <celutil/debug.h>
#include <celmath/frustum.h>
#include <celmath/distance.h>
@ -382,6 +383,7 @@ Renderer::~Renderer()
delete tex;
delete shaderManager;
delete m_asterismRenderer;
}
@ -4897,9 +4899,21 @@ void Renderer::renderReferenceMark(const ReferenceMark& refMark,
void Renderer::renderAsterisms(const Universe& universe, float dist)
{
if ((renderFlags & ShowDiagrams) == 0 || universe.getAsterisms() == nullptr)
auto *asterisms = universe.getAsterisms();
if ((renderFlags & ShowDiagrams) == 0 || asterisms == nullptr)
return;
if (m_asterismRenderer == nullptr)
{
m_asterismRenderer = new AsterismRenderer(asterisms);
}
else if (!m_asterismRenderer->sameAsterisms(asterisms))
{
delete m_asterismRenderer;
m_asterismRenderer = new AsterismRenderer(asterisms);
}
float opacity = 1.0f;
if (dist > MaxAsterismLinesConstDist)
{
@ -4907,9 +4921,8 @@ void Renderer::renderAsterisms(const Universe& universe, float dist)
(MaxAsterismLinesDist - MaxAsterismLinesConstDist) + 1);
}
glDisable(GL_TEXTURE_2D);
enableSmoothLines(renderFlags);
universe.getAsterisms()->render(Color(ConstellationColor, opacity), *this);
m_asterismRenderer->render(*this, Color(ConstellationColor, opacity));
disableSmoothLines(renderFlags);
}

View File

@ -37,9 +37,9 @@ class RendererWatcher;
class FrameTree;
class ReferenceMark;
class CurvePlot;
class AsterismList;
class Rect;
class PointStarVertexBuffer;
class AsterismRenderer;
struct LightSource
{
@ -752,6 +752,8 @@ class Renderer
bool videoSync;
bool settingsChanged;
AsterismRenderer* m_asterismRenderer { nullptr };
// True if we're in between a begin/endObjectAnnotations
bool objectAnnotationSetOpen;