Render lines with triangles
parent
7d4398c088
commit
668fd219cc
|
@ -1,6 +0,0 @@
|
|||
uniform vec4 color;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
gl_FragColor = color;
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
attribute vec2 in_Position;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec4 p = vec4(in_Position.x, 0.0, in_Position.y, 1.0);
|
||||
set_vp(p);
|
||||
}
|
|
@ -17,7 +17,7 @@ using namespace std;
|
|||
AsterismRenderer::AsterismRenderer(const AsterismList *asterisms) :
|
||||
m_asterisms(asterisms)
|
||||
{
|
||||
m_shadprop.texUsage = ShaderProperties::VertexColors;
|
||||
m_shadprop.texUsage = ShaderProperties::VertexColors | ShaderProperties::LineAsTriangles;
|
||||
m_shadprop.lightModel = ShaderProperties::UnlitModel;
|
||||
}
|
||||
|
||||
|
@ -37,22 +37,25 @@ void AsterismRenderer::render(const Renderer &renderer, const Color &defaultColo
|
|||
m_vo.bind();
|
||||
if (!m_vo.initialized())
|
||||
{
|
||||
auto *vtxBuf = prepare();
|
||||
if (vtxBuf == nullptr)
|
||||
std::vector<LineEnds> data;
|
||||
if (!prepare(data))
|
||||
{
|
||||
m_vo.unbind();
|
||||
return;
|
||||
}
|
||||
|
||||
m_vo.allocate(m_vtxTotal * 3 * sizeof(GLfloat), vtxBuf);
|
||||
m_vo.setVertices(3, GL_FLOAT, false, 0, 0);
|
||||
delete[] vtxBuf;
|
||||
m_vo.allocate(data.size() * sizeof(LineEnds), data.data());
|
||||
m_vo.setVertices(3, GL_FLOAT, false, sizeof(LineEnds), offsetof(LineEnds, point1));
|
||||
m_vo.setVertexAttribArray(CelestiaGLProgram::NextVCoordAttributeIndex, 3, GL_FLOAT, false, sizeof(LineEnds), offsetof(LineEnds, point2));
|
||||
m_vo.setVertexAttribArray(CelestiaGLProgram::ScaleFactorAttributeIndex, 1, GL_FLOAT, false, sizeof(LineEnds), offsetof(LineEnds, scale));
|
||||
}
|
||||
|
||||
prog->use();
|
||||
prog->setMVPMatrices(*mvp.projection, *mvp.modelview);
|
||||
prog->lineWidthX = renderer.getLineWidthX();
|
||||
prog->lineWidthY = renderer.getLineWidthY();
|
||||
glVertexAttrib(CelestiaGLProgram::ColorAttributeIndex, defaultColor);
|
||||
m_vo.draw(GL_LINES, m_vtxTotal);
|
||||
m_vo.draw(GL_TRIANGLES, m_vtxTotal);
|
||||
|
||||
assert(m_asterisms->size() == m_vtxCount.size());
|
||||
|
||||
|
@ -67,16 +70,16 @@ void AsterismRenderer::render(const Renderer &renderer, const Color &defaultColo
|
|||
continue;
|
||||
}
|
||||
|
||||
Color color = {ast->getOverrideColor(), opacity};
|
||||
Color color = {ast->getOverrideColor(), opacity};
|
||||
glVertexAttrib(CelestiaGLProgram::ColorAttributeIndex, color);
|
||||
m_vo.draw(GL_LINES, m_vtxCount[i], offset);
|
||||
m_vo.draw(GL_TRIANGLES, m_vtxCount[i], offset);
|
||||
offset += m_vtxCount[i];
|
||||
}
|
||||
|
||||
m_vo.unbind();
|
||||
}
|
||||
|
||||
GLfloat* AsterismRenderer::prepare()
|
||||
bool AsterismRenderer::prepare(std::vector<LineEnds> &data)
|
||||
{
|
||||
// calculate required vertices number
|
||||
GLsizei vtx_num = 0;
|
||||
|
@ -85,12 +88,12 @@ GLfloat* AsterismRenderer::prepare()
|
|||
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
|
||||
// as we use GL_TRIANGLES we should six times 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;
|
||||
ast_vtx_num += (s - 1) * 6;
|
||||
}
|
||||
|
||||
m_vtxCount.push_back(ast_vtx_num);
|
||||
|
@ -98,11 +101,9 @@ GLfloat* AsterismRenderer::prepare()
|
|||
}
|
||||
|
||||
if (vtx_num == 0)
|
||||
return nullptr;
|
||||
return false;
|
||||
m_vtxTotal = vtx_num;
|
||||
|
||||
GLfloat* vtx_buf = new GLfloat[vtx_num * 3];
|
||||
GLfloat* ptr = vtx_buf;
|
||||
data.reserve(m_vtxTotal);
|
||||
|
||||
for (const auto ast : *m_asterisms)
|
||||
{
|
||||
|
@ -114,17 +115,18 @@ GLfloat* AsterismRenderer::prepare()
|
|||
if (chain.size() <= 1)
|
||||
continue;
|
||||
|
||||
memcpy(ptr, chain[0].data(), 3 * sizeof(float));
|
||||
ptr += 3;
|
||||
for (unsigned i = 1; i < chain.size() - 1; i++)
|
||||
for (unsigned i = 1; i < chain.size(); i++)
|
||||
{
|
||||
memcpy(ptr, chain[i].data(), 3 * sizeof(float));
|
||||
memcpy(ptr + 3, chain[i].data(), 3 * sizeof(float));
|
||||
ptr += 6;
|
||||
Eigen::Vector3f prev = chain[i - 1];
|
||||
Eigen::Vector3f cur = chain[i];
|
||||
data.emplace_back(prev, cur, -0.5);
|
||||
data.emplace_back(prev ,cur, 0.5);
|
||||
data.emplace_back(cur, prev, -0.5);
|
||||
data.emplace_back(cur, prev, -0.5);
|
||||
data.emplace_back(cur, prev, 0.5);
|
||||
data.emplace_back(prev, cur, -0.5);
|
||||
}
|
||||
memcpy(ptr, chain[chain.size() - 1].data(), 3 * sizeof(float));
|
||||
ptr += 3;
|
||||
}
|
||||
}
|
||||
return vtx_buf;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
class Renderer;
|
||||
struct Matrices;
|
||||
struct LineEnds;
|
||||
|
||||
class AsterismRenderer
|
||||
{
|
||||
|
@ -33,7 +34,7 @@ class AsterismRenderer
|
|||
bool sameAsterisms(const AsterismList *asterisms) const;
|
||||
|
||||
private:
|
||||
GLfloat* prepare();
|
||||
bool prepare(std::vector<LineEnds> &data);
|
||||
|
||||
celgl::VertexObject m_vo { GL_ARRAY_BUFFER, 0, GL_STATIC_DRAW };
|
||||
ShaderProperties m_shadprop;
|
||||
|
|
|
@ -37,7 +37,7 @@ constexpr const float headRadius = 0.025f;
|
|||
constexpr const unsigned nSections = 30;
|
||||
|
||||
|
||||
static size_t initArrowAndLetters(VertexObject &vo)
|
||||
static size_t initArrow(VertexObject &vo)
|
||||
{
|
||||
static_assert(sizeof(Vector3f) == 3*sizeof(GLfloat), "sizeof(Vector3f) != 3*sizeof(GLfloat)");
|
||||
static size_t count = 0; // number of vertices in the arrow
|
||||
|
@ -122,31 +122,9 @@ static size_t initArrowAndLetters(VertexObject &vo)
|
|||
#endif
|
||||
head.push_back(head[1]);
|
||||
|
||||
|
||||
GLfloat lettersVtx[] =
|
||||
{
|
||||
// X
|
||||
0, 0, 0,
|
||||
1, 0, 1,
|
||||
1, 0, 0,
|
||||
0, 0, 1,
|
||||
// Y
|
||||
0, 0, 1,
|
||||
0.5f, 0, 0.5f,
|
||||
1, 0, 1,
|
||||
0.5f, 0, 0.5f,
|
||||
0.5f, 0, 0,
|
||||
0.5f, 0, 0.5f,
|
||||
// Z
|
||||
0, 0, 1,
|
||||
1, 0, 1,
|
||||
0, 0, 0,
|
||||
1, 0, 0
|
||||
};
|
||||
|
||||
GLintptr offset = 0;
|
||||
count = circle.size() + shaft.size() + annulus.size() + head.size();
|
||||
GLsizeiptr size = sizeof(lettersVtx) + count * sizeof(GLfloat) * 3;
|
||||
GLsizeiptr size = count * sizeof(GLfloat) * 3;
|
||||
GLsizeiptr s = 0;
|
||||
|
||||
vo.allocate(size);
|
||||
|
@ -167,16 +145,88 @@ static size_t initArrowAndLetters(VertexObject &vo)
|
|||
vo.setBufferData(head.data(), offset, s);
|
||||
offset += s;
|
||||
|
||||
vo.setBufferData(lettersVtx, offset, sizeof(lettersVtx));
|
||||
|
||||
vo.setVertices(3, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static void initLetters(VertexObject &vo)
|
||||
{
|
||||
vo.bind();
|
||||
if (vo.initialized())
|
||||
return;
|
||||
|
||||
GLfloat lettersVtx[] =
|
||||
{
|
||||
// X
|
||||
0, 0, 0, 1, 0, 1, -0.5f,
|
||||
0, 0, 0, 1, 0, 1, 0.5f,
|
||||
1, 0, 1, 0, 0, 0, -0.5f,
|
||||
1, 0, 1, 0, 0, 0, -0.5f,
|
||||
1, 0, 1, 0, 0, 0, 0.5f,
|
||||
0, 0, 0, 1, 0, 1, -0.5f,
|
||||
|
||||
1, 0, 0, 0, 0, 1, -0.5f,
|
||||
1, 0, 0, 0, 0, 1, 0.5f,
|
||||
0, 0, 1, 1, 0, 0, -0.5f,
|
||||
0, 0, 1, 1, 0, 0, -0.5f,
|
||||
0, 0, 1, 1, 0, 0, 0.5f,
|
||||
1, 0, 0, 0, 0, 1, -0.5f,
|
||||
// Y
|
||||
0, 0, 1, 0.5f, 0, 0.5f, -0.5f,
|
||||
0, 0, 1, 0.5f, 0, 0.5f, 0.5f,
|
||||
0.5f, 0, 0.5f, 0, 0, 1, -0.5f,
|
||||
0.5f, 0, 0.5f, 0, 0, 1, -0.5f,
|
||||
0.5f, 0, 0.5f, 0, 0, 1, 0.5f,
|
||||
0, 0, 1, 0.5f, 0, 0.5f, -0.5f,
|
||||
|
||||
1, 0, 1, 0.5f, 0, 0.5f, -0.5f,
|
||||
1, 0, 1, 0.5f, 0, 0.5f, 0.5f,
|
||||
0.5f, 0, 0.5f, 1, 0, 1, -0.5f,
|
||||
0.5f, 0, 0.5f, 1, 0, 1, -0.5f,
|
||||
0.5f, 0, 0.5f, 1, 0, 1, 0.5f,
|
||||
1, 0, 1, 0.5f, 0, 0.5f, -0.5f,
|
||||
|
||||
0.5f, 0, 0, 0.5f, 0, 0.5f, -0.5f,
|
||||
0.5f, 0, 0, 0.5f, 0, 0.5f, 0.5f,
|
||||
0.5f, 0, 0.5f, 0.5f, 0, 0, -0.5f,
|
||||
0.5f, 0, 0.5f, 0.5f, 0, 0, -0.5f,
|
||||
0.5f, 0, 0.5f, 0.5f, 0, 0, 0.5f,
|
||||
0.5f, 0, 0, 0.5f, 0, 0.5f, -0.5f,
|
||||
// Z
|
||||
0, 0, 1, 1, 0, 1, -0.5f,
|
||||
0, 0, 1, 1, 0, 1, 0.5f,
|
||||
1, 0, 1, 0, 0, 1, -0.5f,
|
||||
1, 0, 1, 0, 0, 1, -0.5f,
|
||||
1, 0, 1, 0, 0, 1, 0.5f,
|
||||
0, 0, 1, 1, 0, 1, -0.5f,
|
||||
|
||||
1, 0, 1, 0, 0, 0, -0.5f,
|
||||
1, 0, 1, 0, 0, 0, 0.5f,
|
||||
0, 0, 0, 1, 0, 1, -0.5f,
|
||||
0, 0, 0, 1, 0, 1, -0.5f,
|
||||
0, 0, 0, 1, 0, 1, 0.5f,
|
||||
1, 0, 1, 0, 0, 0, -0.5f,
|
||||
|
||||
0, 0, 0, 1, 0, 0, -0.5f,
|
||||
0, 0, 0, 1, 0, 0, 0.5f,
|
||||
1, 0, 0, 0, 0, 0, -0.5f,
|
||||
1, 0, 0, 0, 0, 0, -0.5f,
|
||||
1, 0, 0, 0, 0, 0, 0.5f,
|
||||
0, 0, 0, 1, 0, 0, -0.5f,
|
||||
};
|
||||
|
||||
vo.allocate(sizeof(lettersVtx));
|
||||
|
||||
vo.setBufferData(lettersVtx, 0, sizeof(lettersVtx));
|
||||
vo.setVertices(3, GL_FLOAT, GL_FALSE, sizeof(float) * 7, 0);
|
||||
vo.setVertexAttribArray(CelestiaGLProgram::NextVCoordAttributeIndex, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 7, sizeof(float) * 3);
|
||||
vo.setVertexAttribArray(CelestiaGLProgram::ScaleFactorAttributeIndex, 1, GL_FLOAT, GL_FALSE, sizeof(float) * 7, sizeof(float) * 6);
|
||||
}
|
||||
|
||||
static void RenderArrow(VertexObject& vo)
|
||||
{
|
||||
auto count = initArrowAndLetters(vo);
|
||||
auto count = initArrow(vo);
|
||||
vo.draw(GL_TRIANGLES, count);
|
||||
vo.unbind();
|
||||
}
|
||||
|
@ -184,8 +234,8 @@ static void RenderArrow(VertexObject& vo)
|
|||
// Draw letter x in xz plane
|
||||
static void RenderX(VertexObject& vo)
|
||||
{
|
||||
auto offset = initArrowAndLetters(vo);
|
||||
vo.draw(GL_LINES, 4, offset);
|
||||
initLetters(vo);
|
||||
vo.draw(GL_TRIANGLES, 12);
|
||||
vo.unbind();
|
||||
}
|
||||
|
||||
|
@ -193,8 +243,8 @@ static void RenderX(VertexObject& vo)
|
|||
// Draw letter y in xz plane
|
||||
static void RenderY(VertexObject& vo)
|
||||
{
|
||||
auto offset = initArrowAndLetters(vo);
|
||||
vo.draw(GL_LINES, 6, offset+4);
|
||||
initLetters(vo);
|
||||
vo.draw(GL_TRIANGLES, 18, 12);
|
||||
vo.unbind();
|
||||
}
|
||||
|
||||
|
@ -202,8 +252,8 @@ static void RenderY(VertexObject& vo)
|
|||
// Draw letter z in xz plane
|
||||
static void RenderZ(VertexObject& vo)
|
||||
{
|
||||
auto offset = initArrowAndLetters(vo);
|
||||
vo.draw(GL_LINE_STRIP, 4, offset+10);
|
||||
initLetters(vo);
|
||||
vo.draw(GL_TRIANGLES, 18, 30);
|
||||
vo.unbind();
|
||||
}
|
||||
|
||||
|
@ -387,35 +437,49 @@ AxesReferenceMark::render(Renderer* renderer,
|
|||
return;
|
||||
prog->use();
|
||||
|
||||
auto &vo = renderer->getVertexObject(VOType::AxisArrow, GL_ARRAY_BUFFER, 0, GL_STATIC_DRAW);
|
||||
auto &arrowVo = renderer->getVertexObject(VOType::AxisArrow, GL_ARRAY_BUFFER, 0, GL_STATIC_DRAW);
|
||||
|
||||
Affine3f labelTransform = Translation3f(Vector3f(0.1f, 0.0f, 0.75f)) * Scaling(labelScale);
|
||||
Matrix4f labelTransformMatrix = labelTransform.matrix();
|
||||
Matrix4f tModelView;
|
||||
|
||||
// x-axis
|
||||
tModelView = modelView * vecgl::rotate(AngleAxisf(90.0_deg, Vector3f::UnitY()));
|
||||
Matrix4f xModelView = modelView * vecgl::rotate(AngleAxisf(90.0_deg, Vector3f::UnitY()));
|
||||
glVertexAttrib4f(CelestiaGLProgram::ColorAttributeIndex, 1.0f, 0.0f, 0.0f, opacity);
|
||||
prog->setMVPMatrices(projection, tModelView);
|
||||
RenderArrow(vo);
|
||||
prog->setMVPMatrices(projection, tModelView * labelTransformMatrix);
|
||||
RenderX(vo);
|
||||
prog->setMVPMatrices(projection, xModelView);
|
||||
RenderArrow(arrowVo);
|
||||
|
||||
// y-axis
|
||||
tModelView = modelView * vecgl::rotate(AngleAxisf(180.0_deg, Vector3f::UnitY()));
|
||||
Matrix4f yModelView = modelView * vecgl::rotate(AngleAxisf(180.0_deg, Vector3f::UnitY()));
|
||||
glVertexAttrib4f(CelestiaGLProgram::ColorAttributeIndex, 0.0f, 1.0f, 0.0f, opacity);
|
||||
prog->setMVPMatrices(projection, tModelView);
|
||||
RenderArrow(vo);
|
||||
prog->setMVPMatrices(projection, tModelView * labelTransformMatrix);
|
||||
RenderY(vo);
|
||||
prog->setMVPMatrices(projection, yModelView);
|
||||
RenderArrow(arrowVo);
|
||||
|
||||
// z-axis
|
||||
tModelView = modelView *vecgl::rotate(AngleAxisf(-90.0_deg, Vector3f::UnitX()));
|
||||
Matrix4f zModelView = modelView *vecgl::rotate(AngleAxisf(-90.0_deg, Vector3f::UnitX()));
|
||||
glVertexAttrib4f(CelestiaGLProgram::ColorAttributeIndex, 0.0f, 0.0f, 1.0f, opacity);
|
||||
prog->setMVPMatrices(projection, tModelView);
|
||||
RenderArrow(vo);
|
||||
prog->setMVPMatrices(projection, tModelView * labelTransformMatrix);
|
||||
RenderZ(vo);
|
||||
prog->setMVPMatrices(projection, zModelView);
|
||||
RenderArrow(arrowVo);
|
||||
|
||||
ShaderProperties letterProp = shadprop;
|
||||
letterProp.texUsage |= ShaderProperties::LineAsTriangles;
|
||||
prog = renderer->getShaderManager().getShader(letterProp);
|
||||
if (prog == nullptr)
|
||||
return;
|
||||
|
||||
prog->use();
|
||||
prog->lineWidthX = renderer->getLineWidthX();
|
||||
prog->lineWidthY = renderer->getLineWidthY();
|
||||
|
||||
auto &letterVo = renderer->getVertexObject(VOType::AxisLetter, GL_ARRAY_BUFFER, 0, GL_STATIC_DRAW);
|
||||
glVertexAttrib4f(CelestiaGLProgram::ColorAttributeIndex, 1.0f, 0.0f, 0.0f, opacity);
|
||||
prog->setMVPMatrices(projection, xModelView * labelTransformMatrix);
|
||||
RenderX(letterVo);
|
||||
glVertexAttrib4f(CelestiaGLProgram::ColorAttributeIndex, 0.0f, 1.0f, 0.0f, opacity);
|
||||
prog->setMVPMatrices(projection, yModelView * labelTransformMatrix);
|
||||
RenderY(letterVo);
|
||||
glVertexAttrib4f(CelestiaGLProgram::ColorAttributeIndex, 0.0f, 0.0f, 1.0f, opacity);
|
||||
prog->setMVPMatrices(projection, zModelView * labelTransformMatrix);
|
||||
RenderZ(letterVo);
|
||||
|
||||
renderer->enableBlending();
|
||||
renderer->setBlendingFactors(GL_SRC_ALPHA, GL_ONE);
|
||||
|
|
|
@ -21,7 +21,7 @@ using namespace std;
|
|||
BoundariesRenderer::BoundariesRenderer(const ConstellationBoundaries *boundaries) :
|
||||
m_boundaries(boundaries)
|
||||
{
|
||||
m_shadprop.texUsage = ShaderProperties::VertexColors;
|
||||
m_shadprop.texUsage = ShaderProperties::VertexColors | ShaderProperties::LineAsTriangles;
|
||||
m_shadprop.lightModel = ShaderProperties::UnlitModel;
|
||||
}
|
||||
|
||||
|
@ -39,54 +39,57 @@ void BoundariesRenderer::render(const Renderer &renderer, const Color &color, co
|
|||
m_vo.bind();
|
||||
if (!m_vo.initialized())
|
||||
{
|
||||
auto *vtx_buf = prepare();
|
||||
if (vtx_buf == nullptr)
|
||||
std::vector<LineEnds> data;
|
||||
if (!prepare(data))
|
||||
{
|
||||
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;
|
||||
m_vo.allocate(m_vtxTotal * sizeof(LineEnds), data.data());
|
||||
m_vo.setVertices(3, GL_FLOAT, false, sizeof(LineEnds), offsetof(LineEnds, point1));
|
||||
m_vo.setVertexAttribArray(CelestiaGLProgram::NextVCoordAttributeIndex, 3, GL_FLOAT, false, sizeof(LineEnds), offsetof(LineEnds, point2));
|
||||
m_vo.setVertexAttribArray(CelestiaGLProgram::ScaleFactorAttributeIndex, 1, GL_FLOAT, false, sizeof(LineEnds), offsetof(LineEnds, scale));
|
||||
}
|
||||
|
||||
prog->use();
|
||||
prog->setMVPMatrices(*mvp.projection, *mvp.modelview);
|
||||
prog->lineWidthX = renderer.getLineWidthX();
|
||||
prog->lineWidthY = renderer.getLineWidthY();
|
||||
glVertexAttrib(CelestiaGLProgram::ColorAttributeIndex, color);
|
||||
m_vo.draw(GL_LINES, m_vtxTotal);
|
||||
m_vo.draw(GL_TRIANGLES, m_vtxTotal);
|
||||
|
||||
m_vo.unbind();
|
||||
}
|
||||
|
||||
|
||||
GLshort* BoundariesRenderer::prepare()
|
||||
bool BoundariesRenderer::prepare(std::vector<LineEnds> &data)
|
||||
{
|
||||
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;
|
||||
return false;
|
||||
|
||||
// as we use GL_LINES we should double the number of vertices
|
||||
vtx_num *= 2;
|
||||
// as we use GL_TRIANGLES we should six times the number of vertices
|
||||
vtx_num *= 6;
|
||||
m_vtxTotal = vtx_num;
|
||||
|
||||
auto *vtx_buf = new GLshort[vtx_num * 3];
|
||||
GLshort* ptr = vtx_buf;
|
||||
data.reserve(m_vtxTotal);
|
||||
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;
|
||||
Eigen::Vector3f prev = (*chain)[i - 1];
|
||||
Eigen::Vector3f cur = (*chain)[i];
|
||||
data.emplace_back(prev, cur, -0.5);
|
||||
data.emplace_back(prev ,cur, 0.5);
|
||||
data.emplace_back(cur, prev, -0.5);
|
||||
data.emplace_back(cur, prev, -0.5);
|
||||
data.emplace_back(cur, prev, 0.5);
|
||||
data.emplace_back(prev, cur, -0.5);
|
||||
}
|
||||
for (unsigned j = 0; j < 3; j++, ptr++)
|
||||
*ptr = (GLshort) (*chain)[0][j];
|
||||
}
|
||||
|
||||
return vtx_buf;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ class Color;
|
|||
class ConstellationBoundaries;
|
||||
class Renderer;
|
||||
struct Matrices;
|
||||
struct LineEnds;
|
||||
|
||||
class BoundariesRenderer
|
||||
{
|
||||
|
@ -32,7 +33,7 @@ class BoundariesRenderer
|
|||
bool sameBoundaries(const ConstellationBoundaries*) const;
|
||||
|
||||
private:
|
||||
GLshort* prepare();
|
||||
bool prepare(std::vector<LineEnds> &data);
|
||||
|
||||
celgl::VertexObject m_vo { GL_ARRAY_BUFFER, 0, GL_STATIC_DRAW };
|
||||
ShaderProperties m_shadprop;
|
||||
|
|
|
@ -165,7 +165,7 @@ public:
|
|||
vbobj(0),
|
||||
currentStripLength(0)
|
||||
{
|
||||
data = new Vertex[capacity];
|
||||
data = new Vertex[(capacity + 1) * 2];
|
||||
}
|
||||
|
||||
~HighPrec_VertexBuffer()
|
||||
|
@ -183,6 +183,8 @@ public:
|
|||
|
||||
glEnableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
|
||||
glEnableVertexAttribArray(CelestiaGLProgram::ColorAttributeIndex);
|
||||
glEnableVertexAttribArray(CelestiaGLProgram::NextVCoordAttributeIndex);
|
||||
glEnableVertexAttribArray(CelestiaGLProgram::ScaleFactorAttributeIndex);
|
||||
|
||||
Vector4f* vertexBase = vbobj ? (Vector4f*) offsetof(Vertex, position) : &data[0].position;
|
||||
glVertexAttribPointer(CelestiaGLProgram::VertexCoordAttributeIndex,
|
||||
|
@ -192,6 +194,14 @@ public:
|
|||
glVertexAttribPointer(CelestiaGLProgram::ColorAttributeIndex,
|
||||
4, GL_FLOAT, GL_FALSE, sizeof(Vertex), colorBase);
|
||||
|
||||
float* scaleBase = vbobj ? (float*) offsetof(Vertex, scale) : &data[0].scale;
|
||||
glVertexAttribPointer(CelestiaGLProgram::ScaleFactorAttributeIndex,
|
||||
1, GL_FLOAT, GL_FALSE, sizeof(Vertex), scaleBase);
|
||||
|
||||
Vector4f* nextVertexBase = vbobj ? (Vector4f*) (offsetof(Vertex, position) + (2 * sizeof(Vertex))) : &data[2].position;
|
||||
glVertexAttribPointer(CelestiaGLProgram::NextVCoordAttributeIndex,
|
||||
4, GL_FLOAT, GL_FALSE, sizeof(Vertex), nextVertexBase);
|
||||
|
||||
stripLengths.clear();
|
||||
currentStripLength = 0;
|
||||
currentPosition = 0;
|
||||
|
@ -205,6 +215,8 @@ public:
|
|||
{
|
||||
glDisableVertexAttribArray(CelestiaGLProgram::ColorAttributeIndex);
|
||||
glDisableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
|
||||
glDisableVertexAttribArray(CelestiaGLProgram::NextVCoordAttributeIndex);
|
||||
glDisableVertexAttribArray(CelestiaGLProgram::ScaleFactorAttributeIndex);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
#endif
|
||||
|
@ -213,16 +225,26 @@ public:
|
|||
inline void vertex(const Vector3d& v)
|
||||
{
|
||||
#if USE_VERTEX_BUFFER
|
||||
data[currentPosition].position.segment<3>(0) = v.cast<float>();
|
||||
data[currentPosition].color = color;
|
||||
Vector3f pos = v.cast<float>();
|
||||
int index = currentPosition * 2;
|
||||
data[index].position.segment<3>(0) = pos;
|
||||
data[index].color = color;
|
||||
data[index].scale = -0.5f;
|
||||
data[index + 1].position.segment<3>(0) = pos;
|
||||
data[index + 1].color = color;
|
||||
data[index + 1].scale = 0.5f;
|
||||
++currentPosition;
|
||||
++currentStripLength;
|
||||
if (currentPosition == capacity)
|
||||
{
|
||||
flush();
|
||||
|
||||
data[0].position.segment<3>(0) = v.cast<float>();
|
||||
data[0].position.segment<3>(0) = pos;
|
||||
data[0].color = color;
|
||||
data[0].scale = -0.5f;
|
||||
data[1].position.segment<3>(0) = pos;
|
||||
data[1].color = color;
|
||||
data[1].scale = 0.5f;
|
||||
currentPosition = 1;
|
||||
currentStripLength = 1;
|
||||
}
|
||||
|
@ -233,38 +255,32 @@ public:
|
|||
|
||||
inline void vertex(const Vector4d& v)
|
||||
{
|
||||
#if USE_VERTEX_BUFFER
|
||||
data[currentPosition].position = v.cast<float>();
|
||||
data[currentPosition].color = color;
|
||||
++currentPosition;
|
||||
++currentStripLength;
|
||||
if (currentPosition == capacity)
|
||||
{
|
||||
flush();
|
||||
|
||||
data[0].position = v.cast<float>();
|
||||
data[0].color = color;
|
||||
currentPosition = 1;
|
||||
currentStripLength = 1;
|
||||
}
|
||||
#else
|
||||
glVertex3dv(v.data());
|
||||
#endif
|
||||
vertex(v, color);
|
||||
}
|
||||
|
||||
inline void vertex(const Vector4d& v, const Vector4f& color)
|
||||
{
|
||||
#if USE_VERTEX_BUFFER
|
||||
data[currentPosition].position = v.cast<float>();
|
||||
data[currentPosition].color = color;
|
||||
Vector4f pos = v.cast<float>();
|
||||
int index = currentPosition * 2;
|
||||
data[index].position = pos;
|
||||
data[index].color = color;
|
||||
data[index].scale = -0.5f;
|
||||
data[index + 1].position = pos;
|
||||
data[index + 1].color = color;
|
||||
data[index + 1].scale = 0.5f;
|
||||
++currentPosition;
|
||||
++currentStripLength;
|
||||
if (currentPosition == capacity)
|
||||
{
|
||||
flush();
|
||||
|
||||
data[0].position = v.cast<float>();
|
||||
data[0].position = pos;
|
||||
data[0].color = color;
|
||||
data[0].scale = -0.5f;
|
||||
data[1].position = pos;
|
||||
data[1].color = color;
|
||||
data[1].scale = 0.5f;
|
||||
currentPosition = 1;
|
||||
currentStripLength = 1;
|
||||
}
|
||||
|
@ -284,6 +300,12 @@ public:
|
|||
inline void end()
|
||||
{
|
||||
#if USE_VERTEX_BUFFER
|
||||
if (currentPosition > 1)
|
||||
{
|
||||
int index = currentPosition * 2;
|
||||
memcpy(&data[index], &data[index - 4], 2 * sizeof(Vertex));
|
||||
currentPosition += 1;
|
||||
}
|
||||
stripLengths.push_back(currentStripLength);
|
||||
currentStripLength = 0;
|
||||
#else
|
||||
|
@ -296,7 +318,7 @@ public:
|
|||
#if USE_VERTEX_BUFFER
|
||||
if (currentPosition > 0)
|
||||
{
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vertex) * currentPosition, data);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vertex) * (currentPosition + 1) * 2, data);
|
||||
|
||||
// Finish the current line strip
|
||||
if (currentStripLength > 1)
|
||||
|
@ -305,8 +327,9 @@ public:
|
|||
unsigned int startIndex = 0;
|
||||
for (vector<unsigned int>::const_iterator iter = stripLengths.begin(); iter != stripLengths.end(); ++iter)
|
||||
{
|
||||
glDrawArrays(GL_LINE_STRIP, startIndex, *iter);
|
||||
startIndex += *iter;
|
||||
unsigned int drawCount = *iter * 2;
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, startIndex, drawCount);
|
||||
startIndex += drawCount + 2;
|
||||
}
|
||||
|
||||
currentPosition = 0;
|
||||
|
@ -325,7 +348,7 @@ public:
|
|||
glGenBuffers(1, &vbobj);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbobj);
|
||||
glBufferData(GL_ARRAY_BUFFER,
|
||||
capacity * sizeof(Vertex),
|
||||
(2 * (capacity + 1)) * sizeof(Vertex),
|
||||
nullptr,
|
||||
GL_STREAM_DRAW);
|
||||
}
|
||||
|
@ -349,6 +372,7 @@ private:
|
|||
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
|
||||
Vector4f position;
|
||||
Vector4f color;
|
||||
float scale;
|
||||
};
|
||||
Vertex* data;
|
||||
GLuint vbobj;
|
||||
|
|
|
@ -24,38 +24,7 @@ using namespace celmath;
|
|||
using namespace celestia;
|
||||
using namespace Eigen;
|
||||
|
||||
|
||||
constexpr const int DiamondOffset = 0;
|
||||
constexpr const int DiamondCount = 4;
|
||||
static GLfloat Diamond[DiamondCount * 2] =
|
||||
{
|
||||
0.0f, 1.0f,
|
||||
1.0f, 0.0f,
|
||||
0.0f, -1.0f,
|
||||
-1.0f, 0.0f
|
||||
};
|
||||
|
||||
constexpr const int PlusOffset = DiamondOffset + DiamondCount;
|
||||
constexpr const int PlusCount = 4;
|
||||
static GLfloat Plus[PlusCount * 2] =
|
||||
{
|
||||
0.0f, 1.0f,
|
||||
0.0f, -1.0f,
|
||||
1.0f, 0.0f,
|
||||
-1.0f, 0.0f
|
||||
};
|
||||
|
||||
constexpr const int XOffset = PlusOffset + PlusCount;
|
||||
constexpr const int XCount = 4;
|
||||
static GLfloat X[XCount * 2] =
|
||||
{
|
||||
-1.0f, -1.0f,
|
||||
1.0f, 1.0f,
|
||||
1.0f, -1.0f,
|
||||
-1.0f, 1.0f
|
||||
};
|
||||
|
||||
constexpr const int SquareOffset = XOffset + XCount;
|
||||
constexpr const int SquareOffset = 0;
|
||||
constexpr const int SquareCount = 4;
|
||||
static GLfloat Square[SquareCount * 2] =
|
||||
{
|
||||
|
@ -145,7 +114,7 @@ static GLfloat SelPointer[SelPointerCount * 2] =
|
|||
|
||||
constexpr const int CrosshairOffset = SelPointerOffset + SelPointerCount;
|
||||
constexpr const int CrosshairCount = 3;
|
||||
static GLfloat Crosshair[CrosshairCount * 2 ] =
|
||||
static GLfloat Crosshair[CrosshairCount * 2] =
|
||||
{
|
||||
0.0f, 0.0f,
|
||||
1.0f, -1.0f,
|
||||
|
@ -155,49 +124,117 @@ static GLfloat Crosshair[CrosshairCount * 2 ] =
|
|||
constexpr const int StaticVtxCount = CrosshairOffset + CrosshairCount;
|
||||
|
||||
constexpr const int SmallCircleOffset = StaticVtxCount;
|
||||
static int SmallCircleCount = 0;
|
||||
static int LargeCircleOffset = 0;
|
||||
static int LargeCircleCount = 0;
|
||||
static int EclipticOffset = 0;
|
||||
constexpr const int EclipticCount = 200;
|
||||
constexpr const int SmallCircleCount = 10;
|
||||
constexpr const int LargeCircleOffset = SmallCircleOffset + SmallCircleCount;
|
||||
constexpr const int LargeCircleCount = 60;
|
||||
|
||||
static int DiamondLineOffset = 0;
|
||||
static int DiamondLineCount = 0;
|
||||
static int PlusLineOffset = 0;
|
||||
static int PlusLineCount = 0;
|
||||
static int XLineOffset = 0;
|
||||
static int XLineCount = 0;
|
||||
static int TriangleLineOffset = 0;
|
||||
static int TriangleLineCount = 0;
|
||||
static int SquareLineOffset = 0;
|
||||
static int SquareLineCount = 0;
|
||||
static int SmallCircleLineOffset = 0;
|
||||
static int SmallCircleLineCount = 0;
|
||||
static int LargeCircleLineOffset = 0;
|
||||
static int LargeCircleLineCount = 0;
|
||||
static int EclipticLineCount = 0;
|
||||
|
||||
static void fillCircleValue(GLfloat* data, int size, float scale)
|
||||
{
|
||||
float s, c;
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
sincos((float) (2 * i) / (float) size * ((float) PI), s, c);
|
||||
data[i * 2] = c * scale;
|
||||
data[i * 2 + 1] = s * scale;
|
||||
}
|
||||
}
|
||||
|
||||
static int bufferVertices(VertexObject& vo, GLfloat* data, int vertexCount, int& offset)
|
||||
{
|
||||
int dataSize = vertexCount * 2 * sizeof(GLfloat);
|
||||
vo.setBufferData(data, offset, dataSize);
|
||||
offset += dataSize;
|
||||
return vertexCount;
|
||||
}
|
||||
|
||||
static int bufferLineVertices(VertexObject& vo, GLfloat* data, int vertexSize, int vertexCount, int& offset)
|
||||
{
|
||||
int dataSize = vertexCount * 3 * (2 * vertexSize + 1) * sizeof(GLfloat);
|
||||
GLfloat* tranformed = new GLfloat[dataSize];
|
||||
GLfloat* ptr = tranformed;
|
||||
for (int i = 0; i < vertexCount; i += 2)
|
||||
{
|
||||
int index = i * vertexSize;
|
||||
GLfloat* thisVert = &data[index];
|
||||
GLfloat* nextVert = &data[index + vertexSize];
|
||||
#define STREAM_AND_ADVANCE(firstVertex, secondVertex, scale) do {\
|
||||
memcpy(ptr, firstVertex, vertexSize * sizeof(GLfloat));\
|
||||
memcpy(ptr + vertexSize, secondVertex, vertexSize * sizeof(GLfloat));\
|
||||
ptr[2 * vertexSize] = scale;\
|
||||
ptr += 2 * vertexSize + 1;\
|
||||
} while (0)
|
||||
STREAM_AND_ADVANCE(thisVert, nextVert, -0.5);
|
||||
STREAM_AND_ADVANCE(thisVert, nextVert, 0.5);
|
||||
STREAM_AND_ADVANCE(nextVert, thisVert, -0.5);
|
||||
STREAM_AND_ADVANCE(nextVert, thisVert, -0.5);
|
||||
STREAM_AND_ADVANCE(nextVert, thisVert, 0.5);
|
||||
STREAM_AND_ADVANCE(thisVert, nextVert, -0.5);
|
||||
#undef STREAM_AND_ADVANCE
|
||||
}
|
||||
vo.setBufferData(tranformed, offset, dataSize);
|
||||
offset += dataSize;
|
||||
delete[] tranformed;
|
||||
return vertexCount * 3;
|
||||
}
|
||||
|
||||
static int bufferLineLoopVertices(VertexObject& vo, GLfloat* data, int vertexSize, int vertexCount, int& offset)
|
||||
{
|
||||
int dataSize = vertexCount * 6 * (2 * vertexSize + 1) * sizeof(GLfloat);
|
||||
GLfloat* tranformed = new GLfloat[dataSize];
|
||||
GLfloat* ptr = tranformed;
|
||||
for (int i = 0; i < vertexCount; i += 1)
|
||||
{
|
||||
int index = i * vertexSize;
|
||||
int nextIndex = ((i + 1) % vertexCount) * vertexSize;
|
||||
GLfloat* thisVert = &data[index];
|
||||
GLfloat* nextVert = &data[nextIndex];
|
||||
#define STREAM_AND_ADVANCE(firstVertex, secondVertex, scale) do {\
|
||||
memcpy(ptr, firstVertex, vertexSize * sizeof(GLfloat));\
|
||||
memcpy(ptr + vertexSize, secondVertex, vertexSize * sizeof(GLfloat));\
|
||||
ptr[2 * vertexSize] = scale;\
|
||||
ptr += 2 * vertexSize + 1;\
|
||||
} while (0)
|
||||
STREAM_AND_ADVANCE(thisVert, nextVert, -0.5);
|
||||
STREAM_AND_ADVANCE(thisVert, nextVert, 0.5);
|
||||
STREAM_AND_ADVANCE(nextVert, thisVert, -0.5);
|
||||
STREAM_AND_ADVANCE(nextVert, thisVert, -0.5);
|
||||
STREAM_AND_ADVANCE(nextVert, thisVert, 0.5);
|
||||
STREAM_AND_ADVANCE(thisVert, nextVert, -0.5);
|
||||
#undef STREAM_AND_ADVANCE
|
||||
}
|
||||
vo.setBufferData(tranformed, offset, dataSize);
|
||||
offset += dataSize;
|
||||
delete[] tranformed;
|
||||
return vertexCount * 6;
|
||||
}
|
||||
|
||||
static void initVO(VertexObject& vo)
|
||||
{
|
||||
float c, s;
|
||||
GLfloat SmallCircle[SmallCircleCount * 2];
|
||||
GLfloat LargeCircle[LargeCircleCount * 2];
|
||||
fillCircleValue(SmallCircle, SmallCircleCount, 1.0f);
|
||||
fillCircleValue(LargeCircle, LargeCircleCount, 1.0f);
|
||||
|
||||
vector<GLfloat> small, large;
|
||||
for (int i = 0; i < 360; i += 36)
|
||||
{
|
||||
sincos(degToRad(static_cast<float>(i)), s, c);
|
||||
small.push_back(c); small.push_back(s);
|
||||
large.push_back(c); large.push_back(s);
|
||||
for (int j = i+6; j < i+36; j += 6)
|
||||
{
|
||||
sincos(degToRad(static_cast<float>(j)), s, c);
|
||||
large.push_back(c); large.push_back(s);
|
||||
}
|
||||
};
|
||||
vo.allocate((LargeCircleOffset + LargeCircleCount) * sizeof(GLfloat) * 2);
|
||||
|
||||
SmallCircleCount = small.size() / 2;
|
||||
LargeCircleCount = large.size() / 2;
|
||||
LargeCircleOffset = SmallCircleOffset + SmallCircleCount;
|
||||
|
||||
vector<GLfloat> ecliptic;
|
||||
for (int i = 0; i < EclipticCount; i++)
|
||||
{
|
||||
sincos((float) (2 * i) / (float) EclipticCount * ((float) PI), s, c);
|
||||
ecliptic.push_back(c * 1000.0f);
|
||||
ecliptic.push_back(s * 1000.0f);
|
||||
}
|
||||
EclipticOffset = LargeCircleOffset + LargeCircleCount;
|
||||
|
||||
#define VTXTOMEM(a) ((a) * sizeof(GLfloat) * 2)
|
||||
vo.allocate(VTXTOMEM(StaticVtxCount + SmallCircleCount + LargeCircleCount + EclipticCount));
|
||||
|
||||
#define VOSTREAM(a) vo.setBufferData(a, VTXTOMEM(a ## Offset), sizeof(a))
|
||||
VOSTREAM(Diamond);
|
||||
VOSTREAM(Plus);
|
||||
VOSTREAM(X);
|
||||
int offset = 0;
|
||||
#define VOSTREAM(a) bufferVertices(vo, a, a##Count, offset)
|
||||
VOSTREAM(Square);
|
||||
VOSTREAM(Triangle);
|
||||
VOSTREAM(RightArrow);
|
||||
|
@ -206,57 +243,162 @@ static void initVO(VertexObject& vo)
|
|||
VOSTREAM(DownArrow);
|
||||
VOSTREAM(SelPointer);
|
||||
VOSTREAM(Crosshair);
|
||||
VOSTREAM(SmallCircle);
|
||||
VOSTREAM(LargeCircle);
|
||||
#undef VOSTREAM
|
||||
|
||||
vo.setBufferData(small.data(), VTXTOMEM(SmallCircleOffset), memsize(small));
|
||||
vo.setBufferData(large.data(), VTXTOMEM(LargeCircleOffset), memsize(large));
|
||||
vo.setBufferData(ecliptic.data(), VTXTOMEM(EclipticOffset), memsize(ecliptic));
|
||||
#undef VTXTOMEM
|
||||
|
||||
vo.setVertices(2, GL_FLOAT, false, 0, 0);
|
||||
}
|
||||
|
||||
static void initLineVO(VertexObject& vo)
|
||||
{
|
||||
constexpr const int DiamondCount = 4;
|
||||
static GLfloat Diamond[DiamondCount * 2] =
|
||||
{
|
||||
0.0f, 1.0f,
|
||||
1.0f, 0.0f,
|
||||
0.0f, -1.0f,
|
||||
-1.0f, 0.0f
|
||||
};
|
||||
constexpr const int PlusCount = 4;
|
||||
GLfloat Plus[PlusCount * 2] =
|
||||
{
|
||||
0.0f, 1.0f,
|
||||
0.0f, -1.0f,
|
||||
1.0f, 0.0f,
|
||||
-1.0f, 0.0f
|
||||
};
|
||||
constexpr const int XCount = 4;
|
||||
GLfloat X[XCount * 2] =
|
||||
{
|
||||
-1.0f, -1.0f,
|
||||
1.0f, 1.0f,
|
||||
1.0f, -1.0f,
|
||||
-1.0f, 1.0f
|
||||
};
|
||||
|
||||
GLfloat SmallCircle[SmallCircleCount * 2];
|
||||
GLfloat LargeCircle[LargeCircleCount * 2];
|
||||
fillCircleValue(SmallCircle, SmallCircleCount, 1.0f);
|
||||
fillCircleValue(LargeCircle, LargeCircleCount, 1.0f);
|
||||
|
||||
int stride = sizeof(GLfloat) * 5;
|
||||
int size = ((DiamondCount + SquareCount + TriangleCount + SmallCircleCount + LargeCircleCount) * 6 + (PlusCount + XCount) * 3) * stride;
|
||||
|
||||
vo.allocate(size);
|
||||
|
||||
int offset = 0;
|
||||
#define VOSTREAM_LINES(a) do { \
|
||||
a##LineOffset = offset / stride;\
|
||||
a##LineCount = bufferLineVertices(vo, a, 2, a##Count, offset); \
|
||||
} while (0)
|
||||
#define VOSTREAM_LINE_LOOP(a) do { \
|
||||
a##LineOffset = offset / stride;\
|
||||
a##LineCount = bufferLineLoopVertices(vo, a, 2, a##Count, offset); \
|
||||
} while (0)
|
||||
VOSTREAM_LINE_LOOP(Diamond);
|
||||
VOSTREAM_LINES(Plus);
|
||||
VOSTREAM_LINES(X);
|
||||
VOSTREAM_LINE_LOOP(Square);
|
||||
VOSTREAM_LINE_LOOP(Triangle);
|
||||
VOSTREAM_LINE_LOOP(SmallCircle);
|
||||
VOSTREAM_LINE_LOOP(LargeCircle);
|
||||
#undef VOSTREAM_LINES
|
||||
#undef VOSTREAM_LINE_LOOP
|
||||
|
||||
vo.setVertices(2, GL_FLOAT, false, stride, 0);
|
||||
vo.setVertexAttribArray(CelestiaGLProgram::NextVCoordAttributeIndex, 2, GL_FLOAT, false, stride, sizeof(GLfloat) * 2);
|
||||
vo.setVertexAttribArray(CelestiaGLProgram::ScaleFactorAttributeIndex, 1, GL_FLOAT, false, stride, sizeof(GLfloat) * 4);
|
||||
}
|
||||
|
||||
static void initEclipticVO(VertexObject& vo)
|
||||
{
|
||||
constexpr const int eclipticCount = 200;
|
||||
GLfloat ecliptic[eclipticCount * 3];
|
||||
float s, c;
|
||||
float scale = 1000.0f;
|
||||
for (int i = 0; i < eclipticCount; i++)
|
||||
{
|
||||
sincos((float) (2 * i) / (float) eclipticCount * ((float) PI), s, c);
|
||||
ecliptic[i * 3] = c * scale;
|
||||
ecliptic[i * 3 + 1] = 0;
|
||||
ecliptic[i * 3 + 2] = s * scale;
|
||||
}
|
||||
|
||||
int stride = sizeof(GLfloat) * 7;
|
||||
vo.allocate(eclipticCount * 6 * stride);
|
||||
int offset = 0;
|
||||
EclipticLineCount = bufferLineLoopVertices(vo, ecliptic, 3, eclipticCount, offset);
|
||||
|
||||
vo.setVertices(3, GL_FLOAT, false, stride, 0);
|
||||
vo.setVertexAttribArray(CelestiaGLProgram::NextVCoordAttributeIndex, 3, GL_FLOAT, false, stride, sizeof(GLfloat) * 3);
|
||||
vo.setVertexAttribArray(CelestiaGLProgram::ScaleFactorAttributeIndex, 1, GL_FLOAT, false, stride, sizeof(GLfloat) * 6);
|
||||
}
|
||||
|
||||
void Renderer::renderMarker(MarkerRepresentation::Symbol symbol,
|
||||
float size,
|
||||
const Color &color,
|
||||
const Matrices &m)
|
||||
{
|
||||
assert(shaderManager != nullptr);
|
||||
|
||||
bool solid = true;
|
||||
|
||||
switch (symbol)
|
||||
{
|
||||
case MarkerRepresentation::Diamond:
|
||||
case MarkerRepresentation::Plus:
|
||||
case MarkerRepresentation::X:
|
||||
case MarkerRepresentation::Square:
|
||||
case MarkerRepresentation::Triangle:
|
||||
case MarkerRepresentation::Circle:
|
||||
solid = false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ShaderProperties shadprop;
|
||||
shadprop.texUsage = ShaderProperties::VertexColors;
|
||||
if (!solid)
|
||||
shadprop.texUsage |= ShaderProperties::LineAsTriangles;
|
||||
shadprop.lightModel = ShaderProperties::UnlitModel;
|
||||
shadprop.fishEyeOverride = ShaderProperties::FisheyeOverrideModeDisabled;
|
||||
auto* prog = shaderManager->getShader(shadprop);
|
||||
if (prog == nullptr)
|
||||
return;
|
||||
|
||||
auto &markerVO = getVertexObject(VOType::Marker, GL_ARRAY_BUFFER, 0, GL_STATIC_DRAW);
|
||||
auto &markerVO = getVertexObject(solid ? VOType::Marker : VOType::MarkerLine, GL_ARRAY_BUFFER, 0, GL_STATIC_DRAW);
|
||||
markerVO.bind();
|
||||
if (!markerVO.initialized())
|
||||
initVO(markerVO);
|
||||
solid ? initVO(markerVO) : initLineVO(markerVO);
|
||||
|
||||
glVertexAttrib(CelestiaGLProgram::ColorAttributeIndex, color);
|
||||
|
||||
prog->use();
|
||||
float s = size / 2.0f;
|
||||
float s = size / 2.0f * getScaleFactor();
|
||||
prog->setMVPMatrices(*m.projection, (*m.modelview) * vecgl::scale(Vector3f(s, s, 0)));
|
||||
if (!solid)
|
||||
{
|
||||
prog->lineWidthX = getLineWidthX();
|
||||
prog->lineWidthY = getLineWidthY();
|
||||
}
|
||||
|
||||
switch (symbol)
|
||||
{
|
||||
case MarkerRepresentation::Diamond:
|
||||
markerVO.draw(GL_LINE_LOOP, DiamondCount, DiamondOffset);
|
||||
markerVO.draw(GL_TRIANGLES, DiamondLineCount, DiamondLineOffset);
|
||||
break;
|
||||
|
||||
case MarkerRepresentation::Plus:
|
||||
markerVO.draw(GL_LINES, PlusCount, PlusOffset);
|
||||
markerVO.draw(GL_TRIANGLES, PlusLineCount, PlusLineOffset);
|
||||
break;
|
||||
|
||||
case MarkerRepresentation::X:
|
||||
markerVO.draw(GL_LINES, XCount, XOffset);
|
||||
markerVO.draw(GL_TRIANGLES, XLineCount, XLineOffset);
|
||||
break;
|
||||
|
||||
case MarkerRepresentation::Square:
|
||||
markerVO.draw(GL_LINE_LOOP, SquareCount, SquareOffset);
|
||||
markerVO.draw(GL_TRIANGLES, SquareLineCount, SquareLineOffset);
|
||||
break;
|
||||
|
||||
case MarkerRepresentation::FilledSquare:
|
||||
|
@ -264,7 +406,7 @@ void Renderer::renderMarker(MarkerRepresentation::Symbol symbol,
|
|||
break;
|
||||
|
||||
case MarkerRepresentation::Triangle:
|
||||
markerVO.draw(GL_LINE_LOOP, TriangleCount, TriangleOffset);
|
||||
markerVO.draw(GL_TRIANGLES, TriangleLineCount, TriangleLineOffset);
|
||||
break;
|
||||
|
||||
case MarkerRepresentation::RightArrow:
|
||||
|
@ -284,14 +426,14 @@ void Renderer::renderMarker(MarkerRepresentation::Symbol symbol,
|
|||
break;
|
||||
|
||||
case MarkerRepresentation::Circle:
|
||||
if (s <= 20)
|
||||
markerVO.draw(GL_LINE_LOOP, SmallCircleCount, SmallCircleOffset);
|
||||
if (size <= 40.0f) // TODO: this should be configurable
|
||||
markerVO.draw(GL_TRIANGLES, SmallCircleLineCount, SmallCircleLineOffset);
|
||||
else
|
||||
markerVO.draw(GL_LINE_LOOP, LargeCircleCount, LargeCircleOffset);
|
||||
markerVO.draw(GL_TRIANGLES, LargeCircleLineCount, LargeCircleLineOffset);
|
||||
break;
|
||||
|
||||
case MarkerRepresentation::Disk:
|
||||
if (s <= 20) // TODO: this should be configurable
|
||||
if (size <= 40.0f) // TODO: this should be configurable
|
||||
markerVO.draw(GL_TRIANGLE_FAN, SmallCircleCount, SmallCircleOffset);
|
||||
else
|
||||
markerVO.draw(GL_TRIANGLE_FAN, LargeCircleCount, LargeCircleOffset);
|
||||
|
@ -365,7 +507,7 @@ void Renderer::renderSelectionPointer(const Observer& observer,
|
|||
const Vector3f ¢er = cameraMatrix.col(2);
|
||||
prog->setMVPMatrices(getProjectionMatrix(), getModelViewMatrix() * vecgl::translate(Vector3f(-center)));
|
||||
prog->vec4Param("color") = Color(SelectionCursorColor, 0.6f).toVector4();
|
||||
prog->floatParam("pixelSize") = pixelSize;
|
||||
prog->floatParam("pixelSize") = pixelSize * getScaleFactor();
|
||||
prog->floatParam("s") = s;
|
||||
prog->floatParam("c") = c;
|
||||
prog->floatParam("x0") = x0;
|
||||
|
@ -390,22 +532,27 @@ void Renderer::renderEclipticLine()
|
|||
if ((renderFlags & ShowEcliptic) == 0)
|
||||
return;
|
||||
|
||||
assert(shaderManager != nullptr);
|
||||
auto* prog = shaderManager->getShader("ecliptic");
|
||||
ShaderProperties shadprop;
|
||||
shadprop.texUsage = ShaderProperties::VertexColors | ShaderProperties::LineAsTriangles;
|
||||
shadprop.lightModel = ShaderProperties::UnlitModel;
|
||||
auto* prog = shaderManager->getShader(shadprop);
|
||||
if (prog == nullptr)
|
||||
return;
|
||||
|
||||
auto &markerVO = getVertexObject(VOType::Marker, GL_ARRAY_BUFFER, 0, GL_STATIC_DRAW);
|
||||
markerVO.bind();
|
||||
if (!markerVO.initialized())
|
||||
initVO(markerVO);
|
||||
auto &eclipticVO = getVertexObject(VOType::Ecliptic, GL_ARRAY_BUFFER, 0, GL_STATIC_DRAW);
|
||||
eclipticVO.bind();
|
||||
if (!eclipticVO.initialized())
|
||||
initEclipticVO(eclipticVO);
|
||||
|
||||
glVertexAttrib(CelestiaGLProgram::ColorAttributeIndex, EclipticColor);
|
||||
|
||||
prog->use();
|
||||
prog->setMVPMatrices(getProjectionMatrix(), getModelViewMatrix());
|
||||
prog->vec4Param("color") = EclipticColor.toVector4();
|
||||
markerVO.draw(GL_LINE_LOOP, EclipticCount, EclipticOffset);
|
||||
prog->lineWidthX = getLineWidthX();
|
||||
prog->lineWidthY = getLineWidthY();
|
||||
eclipticVO.draw(GL_TRIANGLES, EclipticLineCount, 0);
|
||||
|
||||
markerVO.unbind();
|
||||
eclipticVO.unbind();
|
||||
}
|
||||
|
||||
void Renderer::renderCrosshair(float selectionSizeInPixels,
|
||||
|
@ -439,8 +586,9 @@ void Renderer::renderCrosshair(float selectionSizeInPixels,
|
|||
prog->setMVPMatrices(*m.projection, *m.modelview);
|
||||
prog->vec4Param("color") = color.toVector4();
|
||||
prog->floatParam("radius") = cursorRadius;
|
||||
prog->floatParam("width") = minCursorWidth * cursorGrow;
|
||||
prog->floatParam("h") = 2.0f * cursorGrow;
|
||||
float scaleFactor = getScaleFactor();
|
||||
prog->floatParam("width") = minCursorWidth * cursorGrow * scaleFactor;
|
||||
prog->floatParam("h") = 2.0f * cursorGrow * scaleFactor;
|
||||
|
||||
const unsigned int markCount = 4;
|
||||
for (unsigned int i = 0; i < markCount; i++)
|
||||
|
|
|
@ -25,14 +25,14 @@ using namespace celestia;
|
|||
|
||||
|
||||
unsigned int PlanetographicGrid::circleSubdivisions = 100;
|
||||
float* PlanetographicGrid::xyCircle = nullptr;
|
||||
float* PlanetographicGrid::xzCircle = nullptr;
|
||||
std::vector<LineStripEnd> PlanetographicGrid::xyCircle;
|
||||
std::vector<LineStripEnd> PlanetographicGrid::xzCircle;
|
||||
|
||||
|
||||
PlanetographicGrid::PlanetographicGrid(const Body& _body) :
|
||||
body(_body)
|
||||
{
|
||||
if (xyCircle == nullptr)
|
||||
if (xyCircle.empty())
|
||||
InitializeGeometry();
|
||||
setTag("planetographic grid");
|
||||
setIAULongLatConvention();
|
||||
|
@ -93,7 +93,7 @@ PlanetographicGrid::render(Renderer* renderer,
|
|||
const Matrices& m) const
|
||||
{
|
||||
ShaderProperties shadprop;
|
||||
shadprop.texUsage = ShaderProperties::VertexColors;
|
||||
shadprop.texUsage = ShaderProperties::VertexColors | ShaderProperties::LineAsTriangles;
|
||||
shadprop.lightModel = ShaderProperties::UnlitModel;
|
||||
auto *prog = renderer->getShaderManager().getShader(shadprop);
|
||||
if (prog == nullptr)
|
||||
|
@ -129,8 +129,14 @@ PlanetographicGrid::render(Renderer* renderer,
|
|||
Matrix4f modelView = *m.modelview * transform.matrix();
|
||||
|
||||
glEnableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
|
||||
glEnableVertexAttribArray(CelestiaGLProgram::NextVCoordAttributeIndex);
|
||||
glEnableVertexAttribArray(CelestiaGLProgram::ScaleFactorAttributeIndex);
|
||||
glVertexAttribPointer(CelestiaGLProgram::VertexCoordAttributeIndex,
|
||||
3, GL_FLOAT, GL_FALSE, 0, xzCircle);
|
||||
3, GL_FLOAT, GL_FALSE, sizeof(LineStripEnd), &xzCircle[0].point);
|
||||
glVertexAttribPointer(CelestiaGLProgram::NextVCoordAttributeIndex,
|
||||
3, GL_FLOAT, GL_FALSE, sizeof(LineStripEnd), &xzCircle[2].point);
|
||||
glVertexAttribPointer(CelestiaGLProgram::ScaleFactorAttributeIndex,
|
||||
1, GL_FLOAT, GL_FALSE, sizeof(LineStripEnd), &xzCircle[0].scale);
|
||||
|
||||
// Only show the coordinate labels if the body is sufficiently large on screen
|
||||
bool showCoordinateLabels = false;
|
||||
|
@ -146,6 +152,8 @@ PlanetographicGrid::render(Renderer* renderer,
|
|||
}
|
||||
|
||||
prog->use();
|
||||
float lineWidthX = renderer->getLineWidthX();
|
||||
float lineWidthY = renderer->getLineWidthY();
|
||||
|
||||
for (float latitude = -90.0f + latitudeStep; latitude < 90.0f; latitude += latitudeStep)
|
||||
{
|
||||
|
@ -156,17 +164,18 @@ PlanetographicGrid::render(Renderer* renderer,
|
|||
{
|
||||
glVertexAttrib(CelestiaGLProgram::ColorAttributeIndex,
|
||||
Renderer::PlanetEquatorColor);
|
||||
glLineWidth(2.0f * renderer->getScreenDpi() / 96.0f);
|
||||
prog->lineWidthX = 2.0f * lineWidthX;
|
||||
prog->lineWidthY = 2.0f * lineWidthY;
|
||||
}
|
||||
else
|
||||
{
|
||||
glVertexAttrib(CelestiaGLProgram::ColorAttributeIndex,
|
||||
Renderer::PlanetographicGridColor);
|
||||
prog->lineWidthX = lineWidthX;
|
||||
prog->lineWidthY = lineWidthY;
|
||||
}
|
||||
prog->setMVPMatrices(projection, modelView * vecgl::translate(0.0f, sin(phi), 0.0f) * vecgl::scale(r));
|
||||
glDrawArrays(GL_LINE_LOOP, 0, circleSubdivisions);
|
||||
|
||||
glLineWidth(1.0f * renderer->getScreenDpi() / 96.0f);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, xzCircle.size() - 2);
|
||||
|
||||
if (showCoordinateLabels)
|
||||
{
|
||||
|
@ -186,14 +195,18 @@ PlanetographicGrid::render(Renderer* renderer,
|
|||
}
|
||||
|
||||
glVertexAttribPointer(CelestiaGLProgram::VertexCoordAttributeIndex,
|
||||
3, GL_FLOAT, GL_FALSE, 0, xyCircle);
|
||||
3, GL_FLOAT, GL_FALSE, sizeof(LineStripEnd), &xyCircle[0].point);
|
||||
glVertexAttribPointer(CelestiaGLProgram::NextVCoordAttributeIndex,
|
||||
3, GL_FLOAT, GL_FALSE, sizeof(LineStripEnd), &xyCircle[2].point);
|
||||
glVertexAttribPointer(CelestiaGLProgram::ScaleFactorAttributeIndex,
|
||||
1, GL_FLOAT, GL_FALSE, sizeof(LineStripEnd), &xyCircle[0].scale);
|
||||
|
||||
glVertexAttrib(CelestiaGLProgram::ColorAttributeIndex,
|
||||
Renderer::PlanetographicGridColor);
|
||||
for (float longitude = 0.0f; longitude <= 180.0f; longitude += longitudeStep)
|
||||
{
|
||||
prog->setMVPMatrices(projection, modelView * vecgl::rotate(AngleAxisf(degToRad(longitude), Vector3f::UnitY())));
|
||||
glDrawArrays(GL_LINE_LOOP, 0, circleSubdivisions);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, xyCircle.size() - 2);
|
||||
|
||||
if (showCoordinateLabels)
|
||||
{
|
||||
|
@ -247,6 +260,8 @@ PlanetographicGrid::render(Renderer* renderer,
|
|||
}
|
||||
|
||||
glDisableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
|
||||
glDisableVertexAttribArray(CelestiaGLProgram::NextVCoordAttributeIndex);
|
||||
glDisableVertexAttribArray(CelestiaGLProgram::ScaleFactorAttributeIndex);
|
||||
|
||||
renderer->enableBlending();
|
||||
renderer->setBlendingFactors(GL_SRC_ALPHA, GL_ONE);
|
||||
|
@ -291,18 +306,18 @@ PlanetographicGrid::setIAULongLatConvention()
|
|||
void
|
||||
PlanetographicGrid::InitializeGeometry()
|
||||
{
|
||||
xyCircle = new float[circleSubdivisions * 3];
|
||||
xzCircle = new float[circleSubdivisions * 3];
|
||||
for (unsigned int i = 0; i < circleSubdivisions; i++)
|
||||
xyCircle.reserve((circleSubdivisions + 2) * 2);
|
||||
xzCircle.reserve((circleSubdivisions + 2) * 2);
|
||||
for (unsigned int i = 0; i <= circleSubdivisions + 1; i++)
|
||||
{
|
||||
float theta = (float) (2.0 * PI) * (float) i / (float) circleSubdivisions;
|
||||
float s, c;
|
||||
sincos(theta, s, c);
|
||||
xyCircle[i * 3 + 0] = c;
|
||||
xyCircle[i * 3 + 1] = s;
|
||||
xyCircle[i * 3 + 2] = 0.0f;
|
||||
xzCircle[i * 3 + 0] = c;
|
||||
xzCircle[i * 3 + 1] = 0.0f;
|
||||
xzCircle[i * 3 + 2] = s;
|
||||
Vector3f thisPointXY(c, s, 0.0f);
|
||||
Vector3f thisPointXZ(c, 0.0f, s);
|
||||
xyCircle.emplace_back(thisPointXY, -0.5f);
|
||||
xyCircle.emplace_back(thisPointXY, 0.5f);
|
||||
xzCircle.emplace_back(thisPointXZ, -0.5f);
|
||||
xzCircle.emplace_back(thisPointXZ, 0.5f);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include <celengine/referencemark.h>
|
||||
|
||||
class Body;
|
||||
|
||||
struct LineStripEnd;
|
||||
|
||||
class PlanetographicGrid : public ReferenceMark
|
||||
{
|
||||
|
@ -71,8 +71,8 @@ private:
|
|||
NorthDirection northDirection{ NorthNormal };
|
||||
|
||||
static unsigned int circleSubdivisions;
|
||||
static float* xyCircle;
|
||||
static float* xzCircle;
|
||||
static std::vector<LineStripEnd> xyCircle;
|
||||
static std::vector<LineStripEnd> xzCircle;
|
||||
};
|
||||
|
||||
#endif // _CELENGINE_PLANETGRID_H_
|
||||
|
|
|
@ -162,8 +162,11 @@ RenderContext::drawGroup(const Mesh::PrimitiveGroup& group)
|
|||
return;
|
||||
}
|
||||
|
||||
bool drawPoints = false;
|
||||
bool drawLines = false;
|
||||
if (group.prim == Mesh::SpriteList || group.prim == Mesh::PointList)
|
||||
{
|
||||
drawPoints = true;
|
||||
if (group.prim == Mesh::PointList)
|
||||
glVertexAttrib1f(CelestiaGLProgram::PointSizeAttributeIndex, 1.0f);
|
||||
#ifndef GL_ES
|
||||
|
@ -172,17 +175,26 @@ RenderContext::drawGroup(const Mesh::PrimitiveGroup& group)
|
|||
#endif
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
else if (group.prim == Mesh::LineList || group.prim == Mesh::LineStrip)
|
||||
{
|
||||
drawLines = true;
|
||||
renderer->enableSmoothLines();
|
||||
}
|
||||
|
||||
glDrawElements(GLPrimitiveModes[(int) group.prim],
|
||||
group.nIndices,
|
||||
GL_UNSIGNED_INT,
|
||||
group.indices);
|
||||
#ifndef GL_ES
|
||||
if (group.prim == Mesh::SpriteList || group.prim == Mesh::PointList)
|
||||
if (drawPoints)
|
||||
{
|
||||
glDisable(GL_POINT_SPRITE);
|
||||
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
|
||||
}
|
||||
else if (drawLines)
|
||||
{
|
||||
renderer->disableSmoothLines();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -701,6 +701,31 @@ void Renderer::setScreenDpi(int _dpi)
|
|||
screenDpi = _dpi;
|
||||
}
|
||||
|
||||
float Renderer::getScaleFactor() const
|
||||
{
|
||||
return screenDpi / 96.0f;
|
||||
}
|
||||
|
||||
float Renderer::getPointWidth() const
|
||||
{
|
||||
return 2.0f / windowWidth * getScaleFactor();
|
||||
}
|
||||
|
||||
float Renderer::getPointHeight() const
|
||||
{
|
||||
return 2.0f / windowHeight * getScaleFactor();
|
||||
}
|
||||
|
||||
float Renderer::getLineWidthX() const
|
||||
{
|
||||
return ((renderFlags | ShowSmoothLines) ? 1.5f : 1.0f) * getPointWidth();
|
||||
}
|
||||
|
||||
float Renderer::getLineWidthY() const
|
||||
{
|
||||
return ((renderFlags | ShowSmoothLines) ? 1.5f : 1.0f) * getPointHeight();
|
||||
}
|
||||
|
||||
void Renderer::setFaintestAM45deg(float _faintestAutoMag45deg)
|
||||
{
|
||||
faintestAutoMag45deg = _faintestAutoMag45deg;
|
||||
|
@ -1033,7 +1058,7 @@ Renderer::enableSmoothLines()
|
|||
#ifndef GL_ES
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
#endif
|
||||
glLineWidth(1.5f * screenDpi / 96.0f);
|
||||
glLineWidth(1.5f * getScaleFactor());
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1047,7 +1072,7 @@ Renderer::disableSmoothLines()
|
|||
#ifndef GL_ES
|
||||
glDisable(GL_LINE_SMOOTH);
|
||||
#endif
|
||||
glLineWidth(1.0f * screenDpi / 96.0f);
|
||||
glLineWidth(1.0f * getScaleFactor());
|
||||
}
|
||||
|
||||
Vector4f renderOrbitColor(const Body *body, bool selected, float opacity)
|
||||
|
@ -1117,7 +1142,7 @@ void Renderer::renderOrbit(const OrbitPathListEntry& orbitPath,
|
|||
const Matrices& m)
|
||||
{
|
||||
ShaderProperties shadprop;
|
||||
shadprop.texUsage = ShaderProperties::VertexColors;
|
||||
shadprop.texUsage = ShaderProperties::VertexColors | ShaderProperties::LineAsTriangles;
|
||||
shadprop.lightModel = ShaderProperties::UnlitModel;
|
||||
auto *prog = shaderManager->getShader(shadprop);
|
||||
if (prog == nullptr)
|
||||
|
@ -1320,6 +1345,8 @@ void Renderer::renderOrbit(const OrbitPathListEntry& orbitPath,
|
|||
|
||||
prog->use();
|
||||
prog->setMVPMatrices(*m.projection);
|
||||
prog->lineWidthX = getPointWidth();
|
||||
prog->lineWidthY = getPointHeight();
|
||||
if (orbit->isPeriodic())
|
||||
{
|
||||
double period = orbit->getPeriod();
|
||||
|
@ -1722,9 +1749,7 @@ void Renderer::draw(const Observer& observer,
|
|||
disableDepthMask();
|
||||
|
||||
// Render sky grids first--these will always be in the background
|
||||
enableSmoothLines();
|
||||
renderSkyGrids(observer);
|
||||
disableSmoothLines();
|
||||
enableBlending();
|
||||
|
||||
// Render deep sky objects
|
||||
|
@ -3869,9 +3894,7 @@ void Renderer::renderAsterisms(const Universe& universe, float dist, const Matri
|
|||
(MaxAsterismLinesDist - MaxAsterismLinesConstDist) + 1);
|
||||
}
|
||||
|
||||
enableSmoothLines();
|
||||
m_asterismRenderer->render(*this, Color(ConstellationColor, opacity), mvp);
|
||||
disableSmoothLines();
|
||||
}
|
||||
|
||||
|
||||
|
@ -3900,9 +3923,7 @@ void Renderer::renderBoundaries(const Universe& universe, float dist, const Matr
|
|||
(MaxAsterismLabelsDist - MaxAsterismLabelsConstDist) + 1);
|
||||
}
|
||||
|
||||
enableSmoothLines();
|
||||
m_boundariesRenderer->render(*this, Color(BoundaryColor, opacity), mvp);
|
||||
disableSmoothLines();
|
||||
}
|
||||
|
||||
|
||||
|
@ -4689,10 +4710,6 @@ void Renderer::renderDeepSkyObjects(const Universe& universe,
|
|||
openClusterRep = MarkerRepresentation(MarkerRepresentation::Circle, 8.0f, OpenClusterLabelColor);
|
||||
globularRep = MarkerRepresentation(MarkerRepresentation::Circle, 8.0f, GlobularLabelColor);
|
||||
|
||||
// Render any line primitives with smooth lines
|
||||
// (mostly to make graticules look good.)
|
||||
enableSmoothLines();
|
||||
|
||||
setBlendingFactors(GL_SRC_ALPHA, GL_ONE);
|
||||
|
||||
#ifdef OCTREE_DEBUG
|
||||
|
@ -4713,8 +4730,6 @@ void Renderer::renderDeepSkyObjects(const Universe& universe,
|
|||
#endif
|
||||
|
||||
// clog << "DSOs processed: " << dsoRenderer.dsosProcessed << endl;
|
||||
|
||||
disableSmoothLines();
|
||||
}
|
||||
|
||||
|
||||
|
@ -4946,9 +4961,6 @@ void Renderer::renderAnnotations(const vector<Annotation>& annotations,
|
|||
if (font[fs] == nullptr)
|
||||
return;
|
||||
|
||||
// Enable line smoothing for rendering symbols
|
||||
enableSmoothLines();
|
||||
|
||||
#ifdef USE_HDR
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
|
||||
#endif
|
||||
|
@ -5010,7 +5022,6 @@ void Renderer::renderAnnotations(const vector<Annotation>& annotations,
|
|||
#endif
|
||||
|
||||
font[fs]->unbind();
|
||||
disableSmoothLines();
|
||||
}
|
||||
|
||||
|
||||
|
@ -5444,10 +5455,14 @@ void Renderer::drawRectangle(const Rect &r, int fishEyeOverrideMode, const Eigen
|
|||
ShaderProperties shadprop;
|
||||
shadprop.lightModel = ShaderProperties::UnlitModel;
|
||||
|
||||
bool solid = r.type != Rect::Type::BorderOnly;
|
||||
|
||||
if (r.nColors > 0)
|
||||
shadprop.texUsage |= ShaderProperties::VertexColors;
|
||||
if (r.tex != nullptr)
|
||||
shadprop.texUsage |= ShaderProperties::DiffuseTexture;
|
||||
if (!solid)
|
||||
shadprop.texUsage |= ShaderProperties::LineAsTriangles;
|
||||
|
||||
shadprop.fishEyeOverride = fishEyeOverrideMode;
|
||||
|
||||
|
@ -5457,10 +5472,55 @@ void Renderer::drawRectangle(const Rect &r, int fishEyeOverrideMode, const Eigen
|
|||
|
||||
constexpr array<short, 8> texels = {0, 1, 1, 1, 1, 0, 0, 0};
|
||||
array<float, 8> vertices = { r.x, r.y, r.x+r.w, r.y, r.x+r.w, r.y+r.h, r.x, r.y+r.h };
|
||||
array<float, 80> lineAsTriangleVertices = {
|
||||
r.x, r.y, r.x + r.w, r.y, -0.5,
|
||||
r.x, r.y, r.x + r.w, r.y, 0.5,
|
||||
|
||||
r.x + r.w, r.y, r.x, r.y, -0.5,
|
||||
r.x + r.w, r.y, r.x, r.y, 0.5,
|
||||
|
||||
r.x + r.w, r.y, r.x + r.w, r.y + r.h, -0.5,
|
||||
r.x + r.w, r.y, r.x + r.w, r.y + r.h, 0.5,
|
||||
|
||||
r.x + r.w, r.y + r.h, r.x + r.w, r.y, -0.5,
|
||||
r.x + r.w, r.y + r.h, r.x + r.w, r.y, 0.5,
|
||||
|
||||
r.x + r.w, r.y + r.h, r.x, r.y + r.h, -0.5,
|
||||
r.x + r.w, r.y + r.h, r.x, r.y + r.h, 0.5,
|
||||
|
||||
r.x, r.y + r.h, r.x + r.w, r.y + r.h, -0.5,
|
||||
r.x, r.y + r.h, r.x + r.w, r.y + r.h, 0.5,
|
||||
|
||||
r.x, r.y + r.h, r.x, r.y, -0.5,
|
||||
r.x, r.y + r.h, r.x, r.y, 0.5,
|
||||
|
||||
r.x, r.y, r.x, r.y + r.h, -0.5,
|
||||
r.x, r.y, r.x, r.y + r.h, 0.5,
|
||||
};
|
||||
constexpr array<short, 24> lineAsTriangleIndcies = {
|
||||
0, 1, 2, 2, 3, 0,
|
||||
4, 5, 6, 6, 7, 4,
|
||||
8, 9, 10, 10, 11, 8,
|
||||
12, 13, 14, 14, 15, 12
|
||||
};
|
||||
|
||||
glEnableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
|
||||
glVertexAttribPointer(CelestiaGLProgram::VertexCoordAttributeIndex,
|
||||
2, GL_FLOAT, GL_FALSE, 0, vertices.data());
|
||||
if (solid)
|
||||
{
|
||||
glVertexAttribPointer(CelestiaGLProgram::VertexCoordAttributeIndex,
|
||||
2, GL_FLOAT, GL_FALSE, 0, vertices.data());
|
||||
}
|
||||
else
|
||||
{
|
||||
glEnableVertexAttribArray(CelestiaGLProgram::NextVCoordAttributeIndex);
|
||||
glEnableVertexAttribArray(CelestiaGLProgram::ScaleFactorAttributeIndex);
|
||||
glVertexAttribPointer(CelestiaGLProgram::VertexCoordAttributeIndex,
|
||||
2, GL_FLOAT, GL_FALSE, sizeof(float) * 5, lineAsTriangleVertices.data());
|
||||
glVertexAttribPointer(CelestiaGLProgram::NextVCoordAttributeIndex,
|
||||
2, GL_FLOAT, GL_FALSE, sizeof(float) * 5, lineAsTriangleVertices.data() + 2);
|
||||
glVertexAttribPointer(CelestiaGLProgram::ScaleFactorAttributeIndex,
|
||||
1, GL_FLOAT, GL_FALSE, sizeof(float) * 5, lineAsTriangleVertices.data() + 4);
|
||||
}
|
||||
if (r.tex != nullptr)
|
||||
{
|
||||
glEnableVertexAttribArray(CelestiaGLProgram::TextureCoord0AttributeIndex);
|
||||
|
@ -5482,22 +5542,22 @@ void Renderer::drawRectangle(const Rect &r, int fishEyeOverrideMode, const Eigen
|
|||
prog->use();
|
||||
prog->setMVPMatrices(p, m);
|
||||
|
||||
if (r.type != Rect::Type::BorderOnly)
|
||||
if (solid)
|
||||
{
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (r.lw != 1.0f)
|
||||
glLineWidth(r.lw * screenDpi / 96.0f);
|
||||
glDrawArrays(GL_LINE_LOOP, 0, 4);
|
||||
if (r.lw != 1.0f)
|
||||
glLineWidth(1.0f * screenDpi / 96.0f);
|
||||
prog->lineWidthX = getLineWidthX() * r.lw;
|
||||
prog->lineWidthY = getLineWidthY() * r.lw;
|
||||
glDrawElements(GL_TRIANGLES, lineAsTriangleIndcies.size(), GL_UNSIGNED_SHORT, lineAsTriangleIndcies.data());
|
||||
}
|
||||
|
||||
glDisableVertexAttribArray(CelestiaGLProgram::ColorAttributeIndex);
|
||||
glDisableVertexAttribArray(CelestiaGLProgram::TextureCoord0AttributeIndex);
|
||||
glDisableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
|
||||
glDisableVertexAttribArray(CelestiaGLProgram::NextVCoordAttributeIndex);
|
||||
glDisableVertexAttribArray(CelestiaGLProgram::ScaleFactorAttributeIndex);
|
||||
}
|
||||
|
||||
void Renderer::setRenderRegion(int x, int y, int width, int height, bool withScissor)
|
||||
|
@ -5551,13 +5611,18 @@ bool Renderer::getInfo(map<string, string>& info) const
|
|||
#endif
|
||||
|
||||
GLint pointSizeRange[2];
|
||||
GLfloat lineWidthRange[2];
|
||||
#ifdef GL_ES
|
||||
glGetIntegerv(GL_ALIASED_POINT_SIZE_RANGE, pointSizeRange);
|
||||
glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, lineWidthRange);
|
||||
#else
|
||||
glGetIntegerv(GL_SMOOTH_POINT_SIZE_RANGE, pointSizeRange);
|
||||
glGetFloatv(GL_SMOOTH_LINE_WIDTH_RANGE, lineWidthRange);
|
||||
#endif
|
||||
info["PointSizeMin"] = to_string(pointSizeRange[0]);
|
||||
info["PointSizeMax"] = to_string(pointSizeRange[1]);
|
||||
info["LineWidthMin"] = to_string(lineWidthRange[0]);
|
||||
info["LineWidthMax"] = to_string(lineWidthRange[1]);
|
||||
|
||||
#ifndef GL_ES
|
||||
GLfloat pointSizeGran = 0;
|
||||
|
@ -6142,8 +6207,6 @@ Renderer::renderSolarSystemObjects(const Observer &observer,
|
|||
#else
|
||||
setBlendingFactors(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
#endif
|
||||
enableSmoothLines();
|
||||
|
||||
// Scan through the list of orbits and render any that overlap this interval
|
||||
for (const auto& orbit : orbitPathList)
|
||||
{
|
||||
|
@ -6163,8 +6226,6 @@ Renderer::renderSolarSystemObjects(const Observer &observer,
|
|||
m);
|
||||
}
|
||||
}
|
||||
|
||||
disableSmoothLines();
|
||||
}
|
||||
|
||||
// Render transparent objects in the second pass
|
||||
|
@ -6178,13 +6239,11 @@ Renderer::renderSolarSystemObjects(const Observer &observer,
|
|||
}
|
||||
|
||||
// Render annotations in this interval
|
||||
enableSmoothLines();
|
||||
annotation = renderSortedAnnotations(annotation,
|
||||
nearPlaneDistance,
|
||||
farPlaneDistance,
|
||||
FontNormal);
|
||||
endObjectAnnotations();
|
||||
disableSmoothLines();
|
||||
}
|
||||
|
||||
// reset the depth range
|
||||
|
|
|
@ -48,6 +48,21 @@ struct Matrices
|
|||
const Eigen::Matrix4f *modelview;
|
||||
};
|
||||
|
||||
struct LineStripEnd
|
||||
{
|
||||
LineStripEnd(Eigen::Vector3f point, float scale) : point(point), scale(scale) {};
|
||||
Eigen::Vector3f point;
|
||||
float scale;
|
||||
};
|
||||
|
||||
struct LineEnds
|
||||
{
|
||||
LineEnds(Eigen::Vector3f point1, Eigen::Vector3f point2, float scale) : point1(point1), point2(point2), scale(scale) {};
|
||||
Eigen::Vector3f point1;
|
||||
Eigen::Vector3f point2;
|
||||
float scale;
|
||||
};
|
||||
|
||||
struct LightSource
|
||||
{
|
||||
Eigen::Vector3d position;
|
||||
|
@ -73,7 +88,10 @@ enum class VOType
|
|||
Rectangle = 2,
|
||||
Terminator = 3,
|
||||
LargeStar = 4,
|
||||
Count = 5
|
||||
AxisLetter = 5,
|
||||
MarkerLine = 6,
|
||||
Ecliptic = 7,
|
||||
Count = 8,
|
||||
};
|
||||
|
||||
enum class RenderMode
|
||||
|
@ -257,6 +275,12 @@ class Renderer
|
|||
int getWindowWidth() const;
|
||||
int getWindowHeight() const;
|
||||
|
||||
float getScaleFactor() const;
|
||||
float getPointWidth() const;
|
||||
float getPointHeight() const;
|
||||
float getLineWidthX() const;
|
||||
float getLineWidthY() const;
|
||||
|
||||
// GL wrappers
|
||||
void getViewport(int* x, int* y, int* w, int* h) const;
|
||||
void getViewport(std::array<int, 4>& viewport) const;
|
||||
|
@ -279,6 +303,9 @@ class Renderer
|
|||
void enableDepthTest() noexcept;
|
||||
void disableDepthTest() noexcept;
|
||||
|
||||
void enableSmoothLines();
|
||||
void disableSmoothLines();
|
||||
|
||||
void drawRectangle(const Rect& r, int fishEyeOverrideMode, const Eigen::Matrix4f& p, const Eigen::Matrix4f& m = Eigen::Matrix4f::Identity());
|
||||
void setRenderRegion(int x, int y, int width, int height, bool withScissor = true);
|
||||
|
||||
|
@ -718,9 +745,6 @@ class Renderer
|
|||
|
||||
void createShadowFBO();
|
||||
|
||||
void enableSmoothLines();
|
||||
void disableSmoothLines();
|
||||
|
||||
#ifdef USE_HDR
|
||||
private:
|
||||
int sceneTexWidth, sceneTexHeight;
|
||||
|
|
|
@ -74,7 +74,7 @@ invariant gl_Position;
|
|||
|
||||
static const char *VPFunction =
|
||||
"#ifdef FISHEYE\n"
|
||||
"void set_vp(vec4 in_Position) {\n"
|
||||
"vec4 calc_vp(vec4 in_Position) {\n"
|
||||
" float PID2 = 1.570796326794896619231322;\n"
|
||||
" vec4 inPos = ModelViewMatrix * in_Position;\n"
|
||||
" float l = length(inPos.xy);\n"
|
||||
|
@ -83,17 +83,38 @@ static const char *VPFunction =
|
|||
" float lensR = phi / PID2;\n"
|
||||
" inPos.xy *= (lensR / l);\n"
|
||||
" }\n"
|
||||
" gl_Position = ProjectionMatrix * inPos;\n"
|
||||
" return ProjectionMatrix * inPos;\n"
|
||||
"}\n"
|
||||
"#else\n"
|
||||
"void set_vp(vec4 in_Position) {\n"
|
||||
" gl_Position = MVPMatrix * in_Position;\n"
|
||||
"vec4 calc_vp(vec4 in_Position) {\n"
|
||||
" return MVPMatrix * in_Position;\n"
|
||||
"}\n"
|
||||
"#endif\n";
|
||||
"#endif\n"
|
||||
"void set_vp(vec4 in_Position) {\n"
|
||||
" gl_Position = calc_vp(in_Position);\n"
|
||||
"}\n";
|
||||
|
||||
static const char* VertexPosition =
|
||||
static const char* NormalVertexPosition =
|
||||
"set_vp(in_Position);\n";
|
||||
|
||||
static const char* LineVertexPosition =
|
||||
"vec4 thisPos = calc_vp(in_Position);\n"
|
||||
"vec4 nextPos = calc_vp(in_PositionNext);\n"
|
||||
"float w = thisPos.w;\n"
|
||||
"thisPos /= w;\n"
|
||||
"nextPos /= nextPos.w;\n"
|
||||
"vec2 transform = normalize(nextPos.xy - thisPos.xy);\n"
|
||||
"transform = vec2(transform.y * lineWidthX, -transform.x * lineWidthY) * in_ScaleFactor;\n"
|
||||
"gl_Position = thisPos;\n"
|
||||
"gl_Position.xy += transform;\n"
|
||||
"gl_Position *= w;\n";
|
||||
|
||||
|
||||
static string VertexPosition(const ShaderProperties& props)
|
||||
{
|
||||
return (props.texUsage & ShaderProperties::LineAsTriangles) ? LineVertexPosition : NormalVertexPosition;
|
||||
}
|
||||
|
||||
static const char* FragmentHeader = "";
|
||||
|
||||
static const char* CommonAttribs = R"glsl(
|
||||
|
@ -1689,6 +1710,17 @@ StaticPointSize()
|
|||
return source;
|
||||
}
|
||||
|
||||
static string
|
||||
LineDeclaration()
|
||||
{
|
||||
string source;
|
||||
source += DeclareAttribute("in_PositionNext", Shader_Vector4);
|
||||
source += DeclareAttribute("in_ScaleFactor", Shader_Float);
|
||||
source += DeclareUniform("lineWidthX", Shader_Float);
|
||||
source += DeclareUniform("lineWidthY", Shader_Float);
|
||||
return source;
|
||||
}
|
||||
|
||||
static string
|
||||
CalculateShadow()
|
||||
{
|
||||
|
@ -1854,6 +1886,9 @@ ShaderManager::buildVertexShader(const ShaderProperties& props)
|
|||
if (props.hasShadowMap())
|
||||
source += "uniform mat4 ShadowMatrix0;\n";
|
||||
|
||||
if (props.texUsage & ShaderProperties::LineAsTriangles)
|
||||
source += LineDeclaration();
|
||||
|
||||
if (props.fishEyeOverride != ShaderProperties::FisheyeOverrideModeDisabled && fisheyeEnabled)
|
||||
source += "#define FISHEYE\n";
|
||||
|
||||
|
@ -2076,7 +2111,7 @@ ShaderManager::buildVertexShader(const ShaderProperties& props)
|
|||
if (props.hasShadowMap())
|
||||
source += "shadowTexCoord0 = ShadowMatrix0 * vec4(in_Position.xyz, 1.0);\n";
|
||||
|
||||
source += VertexPosition;
|
||||
source += VertexPosition(props);
|
||||
source += "}\n";
|
||||
|
||||
DumpVSSource(source);
|
||||
|
@ -2699,6 +2734,9 @@ ShaderManager::buildRingsVertexShader(const ShaderProperties& props)
|
|||
if (props.texUsage & ShaderProperties::DiffuseTexture)
|
||||
source += "varying vec2 diffTexCoord;\n";
|
||||
|
||||
if (props.texUsage & ShaderProperties::LineAsTriangles)
|
||||
source += LineDeclaration();
|
||||
|
||||
if (props.fishEyeOverride != ShaderProperties::FisheyeOverrideModeDisabled && fisheyeEnabled)
|
||||
source += "#define FISHEYE\n";
|
||||
|
||||
|
@ -2719,7 +2757,7 @@ ShaderManager::buildRingsVertexShader(const ShaderProperties& props)
|
|||
}
|
||||
}
|
||||
|
||||
source += VertexPosition;
|
||||
source += VertexPosition(props);
|
||||
source += "}\n";
|
||||
|
||||
DumpVSSource(source);
|
||||
|
@ -2858,6 +2896,9 @@ ShaderManager::buildAtmosphereVertexShader(const ShaderProperties& props)
|
|||
source += "varying vec3 scatterEx;\n";
|
||||
source += "varying vec3 eyeDir_obj;\n";
|
||||
|
||||
if (props.texUsage & ShaderProperties::LineAsTriangles)
|
||||
source += LineDeclaration();
|
||||
|
||||
if (props.fishEyeOverride != ShaderProperties::FisheyeOverrideModeDisabled && fisheyeEnabled)
|
||||
source += "#define FISHEYE\n";
|
||||
|
||||
|
@ -2872,7 +2913,7 @@ ShaderManager::buildAtmosphereVertexShader(const ShaderProperties& props)
|
|||
source += AtmosphericEffects(props);
|
||||
|
||||
source += "eyeDir_obj = eyeDir;\n";
|
||||
source += VertexPosition;
|
||||
source += VertexPosition(props);
|
||||
source += "}\n";
|
||||
|
||||
DumpVSSource(source);
|
||||
|
@ -2967,6 +3008,9 @@ ShaderManager::buildEmissiveVertexShader(const ShaderProperties& props)
|
|||
source += DeclareVarying("v_Color", Shader_Vector4);
|
||||
source += DeclareVarying("v_TexCoord0", Shader_Vector2);
|
||||
|
||||
if (props.texUsage & ShaderProperties::LineAsTriangles)
|
||||
source += LineDeclaration();
|
||||
|
||||
if (props.fishEyeOverride != ShaderProperties::FisheyeOverrideModeDisabled && fisheyeEnabled)
|
||||
source += "#define FISHEYE\n";
|
||||
|
||||
|
@ -2998,7 +3042,7 @@ ShaderManager::buildEmissiveVertexShader(const ShaderProperties& props)
|
|||
else if (props.texUsage & ShaderProperties::StaticPointSize)
|
||||
source += StaticPointSize();
|
||||
|
||||
source += VertexPosition;
|
||||
source += VertexPosition(props);
|
||||
source += "}\n";
|
||||
// End of main()
|
||||
|
||||
|
@ -3095,6 +3139,9 @@ ShaderManager::buildParticleVertexShader(const ShaderProperties& props)
|
|||
source << "varying vec3 position_obj;\n";
|
||||
}
|
||||
|
||||
if (props.texUsage & ShaderProperties::LineAsTriangles)
|
||||
source << LineDeclaration();
|
||||
|
||||
if (props.fishEyeOverride != ShaderProperties::FisheyeOverrideModeDisabled && fisheyeEnabled)
|
||||
source << "#define FISHEYE\n";
|
||||
|
||||
|
@ -3132,7 +3179,7 @@ ShaderManager::buildParticleVertexShader(const ShaderProperties& props)
|
|||
else if (props.texUsage & ShaderProperties::StaticPointSize)
|
||||
source << StaticPointSize();
|
||||
|
||||
source << VertexPosition;
|
||||
source << VertexPosition(props);
|
||||
source << "}\n";
|
||||
// End of main()
|
||||
|
||||
|
@ -3283,6 +3330,17 @@ ShaderManager::buildProgram(const ShaderProperties& props)
|
|||
CelestiaGLProgram::IntensityAttributeIndex,
|
||||
"in_Intensity");
|
||||
|
||||
if (props.texUsage & ShaderProperties::LineAsTriangles)
|
||||
{
|
||||
glBindAttribLocation(prog->getID(),
|
||||
CelestiaGLProgram::NextVCoordAttributeIndex,
|
||||
"in_PositionNext");
|
||||
|
||||
glBindAttribLocation(prog->getID(),
|
||||
CelestiaGLProgram::ScaleFactorAttributeIndex,
|
||||
"in_ScaleFactor");
|
||||
}
|
||||
|
||||
if (props.texUsage & ShaderProperties::NormalTexture)
|
||||
{
|
||||
glBindAttribLocation(prog->getID(),
|
||||
|
@ -3593,6 +3651,12 @@ CelestiaGLProgram::initParameters()
|
|||
{
|
||||
pointScale = floatParam("pointScale");
|
||||
}
|
||||
|
||||
if (props.texUsage & ShaderProperties::LineAsTriangles)
|
||||
{
|
||||
lineWidthX = floatParam("lineWidthX");
|
||||
lineWidthY = floatParam("lineWidthY");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -67,6 +67,7 @@ class ShaderProperties
|
|||
PointSprite = 0x4000,
|
||||
SharedTextureCoords = 0x8000,
|
||||
StaticPointSize = 0x10000,
|
||||
LineAsTriangles = 0x20000,
|
||||
};
|
||||
|
||||
enum
|
||||
|
@ -194,6 +195,8 @@ class CelestiaGLProgram
|
|||
PointSizeAttributeIndex = 7,
|
||||
ColorAttributeIndex = 8,
|
||||
IntensityAttributeIndex = 9,
|
||||
NextVCoordAttributeIndex = 10,
|
||||
ScaleFactorAttributeIndex = 11,
|
||||
};
|
||||
|
||||
public:
|
||||
|
@ -260,6 +263,10 @@ class CelestiaGLProgram
|
|||
// Scale factor for point sprites
|
||||
FloatShaderParameter pointScale;
|
||||
|
||||
// Used to draw line as triangles
|
||||
FloatShaderParameter lineWidthX;
|
||||
FloatShaderParameter lineWidthY;
|
||||
|
||||
// Color sent as a uniform
|
||||
Vec4ShaderParameter color;
|
||||
|
||||
|
|
|
@ -392,7 +392,7 @@ SkyGrid::render(Renderer& renderer,
|
|||
int windowHeight)
|
||||
{
|
||||
ShaderProperties shadprop;
|
||||
shadprop.texUsage = ShaderProperties::VertexColors;
|
||||
shadprop.texUsage = ShaderProperties::VertexColors | ShaderProperties::LineAsTriangles;
|
||||
shadprop.lightModel = ShaderProperties::UnlitModel;
|
||||
auto *prog = renderer.getShaderManager().getShader(shadprop);
|
||||
if (prog == nullptr)
|
||||
|
@ -556,14 +556,23 @@ SkyGrid::render(Renderer& renderer,
|
|||
vecgl::rotate((xrot90 * m_orientation.conjugate() * xrot90.conjugate()).cast<float>()) *
|
||||
vecgl::scale(1000.0f);
|
||||
prog->setMVPMatrices(renderer.getProjectionMatrix(), m);
|
||||
prog->lineWidthX = renderer.getLineWidthX();
|
||||
prog->lineWidthY = renderer.getLineWidthY();
|
||||
|
||||
double arcStep = (maxTheta - minTheta) / (double) ARC_SUBDIVISIONS;
|
||||
double theta0 = minTheta;
|
||||
|
||||
auto buffer = new Vector3f[ARC_SUBDIVISIONS+1];
|
||||
vector<LineStripEnd> buffer;
|
||||
buffer.reserve(2 * (ARC_SUBDIVISIONS + 2));
|
||||
glEnableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
|
||||
glEnableVertexAttribArray(CelestiaGLProgram::NextVCoordAttributeIndex);
|
||||
glEnableVertexAttribArray(CelestiaGLProgram::ScaleFactorAttributeIndex);
|
||||
glVertexAttribPointer(CelestiaGLProgram::VertexCoordAttributeIndex,
|
||||
3, GL_FLOAT, GL_FALSE, 0, buffer);
|
||||
3, GL_FLOAT, GL_FALSE, sizeof(LineStripEnd), &buffer[0].point);
|
||||
glVertexAttribPointer(CelestiaGLProgram::NextVCoordAttributeIndex,
|
||||
3, GL_FLOAT, GL_FALSE, sizeof(LineStripEnd), &buffer[2].point);
|
||||
glVertexAttribPointer(CelestiaGLProgram::ScaleFactorAttributeIndex,
|
||||
1, GL_FLOAT, GL_FALSE, sizeof(LineStripEnd), &buffer[0].scale);
|
||||
|
||||
for (int dec = startDec; dec <= endDec; dec += decIncrement)
|
||||
{
|
||||
|
@ -571,15 +580,17 @@ SkyGrid::render(Renderer& renderer,
|
|||
double cosPhi = cos(phi);
|
||||
double sinPhi = sin(phi);
|
||||
|
||||
for (int j = 0; j <= ARC_SUBDIVISIONS; j++)
|
||||
for (int j = 0; j <= ARC_SUBDIVISIONS + 1; j++)
|
||||
{
|
||||
double theta = theta0 + j * arcStep;
|
||||
auto x = (float) (cosPhi * std::cos(theta));
|
||||
auto y = (float) (cosPhi * std::sin(theta));
|
||||
auto z = (float) sinPhi;
|
||||
buffer[j] = {x, z, -y}; // convert to Celestia coords
|
||||
Vector3f position = {x, z, -y}; // convert to Celestia coords
|
||||
buffer[2 * j] = {position, -0.5f};
|
||||
buffer[2 * j + 1] = {position, 0.5f};
|
||||
}
|
||||
glDrawArrays(GL_LINE_STRIP, 0, ARC_SUBDIVISIONS+1);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 2 * (ARC_SUBDIVISIONS + 1));
|
||||
|
||||
// Place labels at the intersections of the view frustum planes
|
||||
// and the parallels.
|
||||
|
@ -646,15 +657,17 @@ SkyGrid::render(Renderer& renderer,
|
|||
double cosTheta = cos(theta);
|
||||
double sinTheta = sin(theta);
|
||||
|
||||
for (int j = 0; j <= ARC_SUBDIVISIONS; j++)
|
||||
for (int j = 0; j <= ARC_SUBDIVISIONS + 1; j++)
|
||||
{
|
||||
double phi = phi0 + j * arcStep;
|
||||
auto x = (float) (cos(phi) * cosTheta);
|
||||
auto y = (float) (cos(phi) * sinTheta);
|
||||
auto z = (float) sin(phi);
|
||||
buffer[j] = {x, z, -y}; // convert to Celestia coords
|
||||
Vector3f position = {x, z, -y}; // convert to Celestia coords
|
||||
buffer[2 * j] = {position, -0.5f};
|
||||
buffer[2 * j + 1] = {position, 0.5f};
|
||||
}
|
||||
glDrawArrays(GL_LINE_STRIP, 0, ARC_SUBDIVISIONS+1);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 2 * (ARC_SUBDIVISIONS + 1));
|
||||
|
||||
// Place labels at the intersections of the view frustum planes
|
||||
// and the meridians.
|
||||
|
@ -704,16 +717,47 @@ SkyGrid::render(Renderer& renderer,
|
|||
}
|
||||
|
||||
// Draw crosses indicating the north and south poles
|
||||
buffer[0] = {-polarCrossSize, 1.0f, 0.0f};
|
||||
buffer[1] = { polarCrossSize, 1.0f, 0.0f};
|
||||
buffer[2] = {0.0f, 1.0f, -polarCrossSize};
|
||||
buffer[3] = {0.0f, 1.0f, polarCrossSize};
|
||||
buffer[4] = {-polarCrossSize, -1.0f, 0.0f};
|
||||
buffer[5] = { polarCrossSize, -1.0f, 0.0f};
|
||||
buffer[6] = {0.0f, -1.0f, -polarCrossSize};
|
||||
buffer[7] = {0.0f, -1.0f, polarCrossSize};
|
||||
glDrawArrays(GL_LINES, 0, 8);
|
||||
array<float, 112> lineAsTriangleVertices = {
|
||||
-polarCrossSize, 1.0f, 0.0f, polarCrossSize, 1.0f, 0.0f, -0.5,
|
||||
-polarCrossSize, 1.0f, 0.0f, polarCrossSize, 1.0f, 0.0f, 0.5,
|
||||
|
||||
polarCrossSize, 1.0f, 0.0f, -polarCrossSize, 1.0f, 0.0f, -0.5,
|
||||
polarCrossSize, 1.0f, 0.0f, -polarCrossSize, 1.0f, 0.0f, 0.5,
|
||||
|
||||
0.0f, 1.0f, -polarCrossSize, 0.0f, 1.0f, polarCrossSize, -0.5,
|
||||
0.0f, 1.0f, -polarCrossSize, 0.0f, 1.0f, polarCrossSize, 0.5,
|
||||
|
||||
0.0f, 1.0f, polarCrossSize, 0.0f, 1.0f, -polarCrossSize, -0.5,
|
||||
0.0f, 1.0f, polarCrossSize, 0.0f, 1.0f, -polarCrossSize, 0.5,
|
||||
|
||||
-polarCrossSize, -1.0f, 0.0f, polarCrossSize, -1.0f, 0.0f, -0.5,
|
||||
-polarCrossSize, -1.0f, 0.0f, polarCrossSize, -1.0f, 0.0f, 0.5,
|
||||
|
||||
polarCrossSize, -1.0f, 0.0f, -polarCrossSize, -1.0f, 0.0f, -0.5,
|
||||
polarCrossSize, -1.0f, 0.0f, -polarCrossSize, -1.0f, 0.0f, 0.5,
|
||||
|
||||
0.0f, -1.0f, -polarCrossSize, 0.0f, -1.0f, polarCrossSize, -0.5,
|
||||
0.0f, -1.0f, -polarCrossSize, 0.0f, -1.0f, polarCrossSize, 0.5,
|
||||
|
||||
0.0f, -1.0f, polarCrossSize, 0.0f, -1.0f, -polarCrossSize, -0.5,
|
||||
0.0f, -1.0f, polarCrossSize, 0.0f, -1.0f, -polarCrossSize, 0.5,
|
||||
};
|
||||
constexpr array<short, 24> lineAsTriangleIndcies = {
|
||||
0, 1, 2, 2, 3, 0,
|
||||
4, 5, 6, 6, 7, 4,
|
||||
8, 9, 10, 10, 11, 8,
|
||||
12, 13, 14, 14, 15, 12
|
||||
};
|
||||
|
||||
glVertexAttribPointer(CelestiaGLProgram::VertexCoordAttributeIndex,
|
||||
3, GL_FLOAT, GL_FALSE, sizeof(float) * 7, lineAsTriangleVertices.data());
|
||||
glVertexAttribPointer(CelestiaGLProgram::NextVCoordAttributeIndex,
|
||||
3, GL_FLOAT, GL_FALSE, sizeof(float) * 7, lineAsTriangleVertices.data() + 3);
|
||||
glVertexAttribPointer(CelestiaGLProgram::ScaleFactorAttributeIndex,
|
||||
1, GL_FLOAT, GL_FALSE, sizeof(float) * 7, lineAsTriangleVertices.data() + 6);
|
||||
glDrawElements(GL_TRIANGLES, lineAsTriangleIndcies.size(), GL_UNSIGNED_SHORT, lineAsTriangleIndcies.data());
|
||||
|
||||
glDisableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
|
||||
delete[] buffer;
|
||||
glDisableVertexAttribArray(CelestiaGLProgram::NextVCoordAttributeIndex);
|
||||
glDisableVertexAttribArray(CelestiaGLProgram::ScaleFactorAttributeIndex);
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@ constexpr const unsigned maxSections = 360;
|
|||
|
||||
static void
|
||||
renderTerminator(Renderer* renderer,
|
||||
const vector<Vector3f>& pos,
|
||||
const vector<LineStripEnd>& pos,
|
||||
const Color& color,
|
||||
const Matrices& mvp)
|
||||
{
|
||||
|
@ -94,8 +94,9 @@ renderTerminator(Renderer* renderer,
|
|||
* Because of this we make calculations on a CPU and stream results to GPU.
|
||||
*/
|
||||
|
||||
float lineWidth = renderer->getScreenDpi() / 96.0f;
|
||||
ShaderProperties shadprop;
|
||||
shadprop.texUsage = ShaderProperties::VertexColors;
|
||||
shadprop.texUsage = ShaderProperties::VertexColors | ShaderProperties::LineAsTriangles;
|
||||
shadprop.lightModel = ShaderProperties::UnlitModel;
|
||||
auto *prog = renderer->getShaderManager().getShader(shadprop);
|
||||
if (prog == nullptr)
|
||||
|
@ -106,18 +107,26 @@ renderTerminator(Renderer* renderer,
|
|||
vo.bindWritable();
|
||||
if (!vo.initialized())
|
||||
{
|
||||
vo.setBufferSize(maxSections * sizeof(Vector3f));
|
||||
vo.setBufferSize((maxSections + 2) * 2 * sizeof(LineStripEnd));
|
||||
vo.allocate();
|
||||
vo.setVertices(3, GL_FLOAT);
|
||||
vo.setVertices(3, GL_FLOAT, false, sizeof(LineStripEnd), 0);
|
||||
vo.setVertexAttribArray(CelestiaGLProgram::NextVCoordAttributeIndex,
|
||||
3, GL_FLOAT, false, sizeof(LineStripEnd)
|
||||
, 2 * sizeof(LineStripEnd) + offsetof(LineStripEnd, point));
|
||||
vo.setVertexAttribArray(CelestiaGLProgram::ScaleFactorAttributeIndex,
|
||||
1, GL_FLOAT, false, sizeof(LineStripEnd)
|
||||
, offsetof(LineStripEnd, scale));
|
||||
}
|
||||
|
||||
vo.setBufferData(pos.data(), 0, pos.size() * sizeof(Vector3f));
|
||||
vo.setBufferData(pos.data(), 0, pos.size() * sizeof(LineStripEnd));
|
||||
|
||||
prog->use();
|
||||
prog->lineWidthX = renderer->getLineWidthX();
|
||||
prog->lineWidthY = renderer->getLineWidthY();
|
||||
prog->setMVPMatrices(*mvp.projection, *mvp.modelview);
|
||||
glVertexAttrib(CelestiaGLProgram::ColorAttributeIndex, color);
|
||||
|
||||
vo.draw(GL_LINE_LOOP, pos.size());
|
||||
vo.draw(GL_TRIANGLE_STRIP, pos.size() - 2);
|
||||
|
||||
vo.unbind();
|
||||
}
|
||||
|
@ -198,17 +207,19 @@ VisibleRegion::render(Renderer* renderer,
|
|||
Vector3d e_ = e.cwiseProduct(recipSemiAxes);
|
||||
double ee = e_.squaredNorm();
|
||||
|
||||
vector<Vector3f> pos;
|
||||
pos.reserve(nSections);
|
||||
vector<LineStripEnd> pos;
|
||||
pos.reserve((nSections + 2) * 2);
|
||||
|
||||
for (unsigned i = 0; i < nSections; i++)
|
||||
for (unsigned i = 0; i <= nSections + 1; i++)
|
||||
{
|
||||
double theta = (double) i / (double) (nSections) * 2.0 * PI;
|
||||
Vector3d w = cos(theta) * uAxis + sin(theta) * vAxis;
|
||||
|
||||
Vector3d toCenter = ellipsoidTangent(recipSemiAxes, w, e, e_, ee);
|
||||
toCenter *= maxSemiAxis * scale;
|
||||
pos.push_back(toCenter.cast<float>());
|
||||
Vector3f thisPoint = toCenter.cast<float>();
|
||||
pos.emplace_back(thisPoint, -0.5);
|
||||
pos.emplace_back(thisPoint, 0.5);
|
||||
}
|
||||
|
||||
Affine3f transform = Translation3f(position) * qf.conjugate();
|
||||
|
|
Loading…
Reference in New Issue