Refactor boundaries rendering to have common and rendering parts

pull/3/head
Hleb Valoshka 2019-12-03 14:46:48 +03:00
parent c21934aee3
commit 3e133ba119
7 changed files with 159 additions and 83 deletions

View File

@ -12,6 +12,8 @@ set(CELENGINE_SOURCES
body.h
boundaries.cpp
boundaries.h
boundariesrenderer.cpp
boundariesrenderer.h
catalogxref.cpp
catalogxref.h
category.cpp

View File

@ -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 <claurel@gmail.com>
//
// 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 <cassert>
#include <numeric>
#include <GL/glew.h>
#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::Chain*>&
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();

View File

@ -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 <claurel@gmail.com>
//
// This program is free software; you can redistribute it and/or
@ -12,20 +12,14 @@
#define _CELENGINE_BOUNDARIES_H_
#include <Eigen/Core>
#include <string>
#include <vector>
#include <iostream>
#include <celutil/color.h>
#include "shadermanager.h"
#include "vertexobject.h"
class Renderer;
class ConstellationBoundaries
{
public:
using Chain = std::vector<Eigen::Vector3f>;
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<Chain*>& getChains() const;
private:
void cleanup();
void prepare();
Chain* currentChain{ nullptr };
std::vector<Chain*> 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&);

View File

@ -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 <cassert>
#include <numeric>
#include <celengine/boundaries.h>
#include <celutil/color.h>
#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;
}

View File

@ -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 };
};

View File

@ -63,6 +63,7 @@ std::ofstream hdrlog;
#include "pointstarrenderer.h"
#include "orbitsampler.h"
#include "asterismrenderer.h"
#include "boundariesrenderer.h"
#include <celutil/debug.h>
#include <celmath/frustum.h>
#include <celmath/distance.h>
@ -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);
}

View File

@ -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;