Refactor code to draw objects as points
* provide common routine to calculate point size * precalculate saturation magnitude * remove unused variablespull/1337/head
parent
29a2e1ec1c
commit
20a4d13328
|
@ -25,30 +25,14 @@ template <class OBJ, class PREC> class ObjectRenderer : public OctreeProcessor<O
|
|||
const Observer* observer { nullptr };
|
||||
Renderer* renderer { nullptr };
|
||||
|
||||
Eigen::Vector3f viewNormal;
|
||||
|
||||
float fov { 0.0f };
|
||||
float size { 0.0f };
|
||||
float pixelSize { 0.0f };
|
||||
float faintestMag { 0.0f };
|
||||
float faintestMagNight { 0.0f };
|
||||
float saturationMag { 0.0f };
|
||||
float brightnessScale { 0.0f };
|
||||
float brightnessBias { 0.0f };
|
||||
float distanceLimit { 0.0f };
|
||||
|
||||
// Objects brighter than labelThresholdMag will be labeled
|
||||
float labelThresholdMag { 0.0f };
|
||||
|
||||
// These are not fully used by this template's descendants
|
||||
// but we place them here just in case a more sophisticated
|
||||
// rendering scheme is implemented:
|
||||
int nRendered { 0 };
|
||||
int nClose { 0 };
|
||||
int nBright { 0 };
|
||||
int nProcessed { 0 };
|
||||
int nLabelled { 0 };
|
||||
|
||||
uint64_t renderFlags { 0 };
|
||||
int labelMode { 0 };
|
||||
};
|
||||
|
|
|
@ -34,7 +34,8 @@ PointStarRenderer::PointStarRenderer() :
|
|||
|
||||
void PointStarRenderer::process(const Star& star, float distance, float appMag)
|
||||
{
|
||||
nProcessed++;
|
||||
if (distance > distanceLimit)
|
||||
return;
|
||||
|
||||
Vector3f starPos = star.getPosition();
|
||||
|
||||
|
@ -44,9 +45,6 @@ void PointStarRenderer::process(const Star& star, float distance, float appMag)
|
|||
float orbitalRadius = star.getOrbitalRadius();
|
||||
bool hasOrbit = orbitalRadius > 0.0f;
|
||||
|
||||
if (distance > distanceLimit)
|
||||
return;
|
||||
|
||||
// A very rough check to see if the star may be visible: is the star in
|
||||
// front of the viewer? If the star might be close (relPos.x^2 < 0.1) or
|
||||
// is moving in an orbit, we'll always regard it as potentially visible.
|
||||
|
@ -69,10 +67,10 @@ void PointStarRenderer::process(const Star& star, float distance, float appMag)
|
|||
// * It may be large enough that we should render it as a mesh
|
||||
// instead of a particle
|
||||
// It's possible that the second condition might apply for stars
|
||||
// further than one light year away if the star is huge, the fov is
|
||||
// further than a solar system size if the star is huge, the fov is
|
||||
// very small and the resolution is high. We'll ignore this for now
|
||||
// and use the most inexpensive test possible . . .
|
||||
if (distance < 1.0f || orbitSizeInPixels > 1.0f)
|
||||
if (distance < SolarSystemMaxDistance || orbitSizeInPixels > 1.0f)
|
||||
{
|
||||
// Compute the position of the observer relative to the star.
|
||||
// This is a much more accurate (and expensive) distance
|
||||
|
@ -85,10 +83,9 @@ void PointStarRenderer::process(const Star& star, float distance, float appMag)
|
|||
distance = relPos.norm();
|
||||
|
||||
// Recompute apparent magnitude using new distance computation
|
||||
appMag = star.getApparentMagnitude((float)distance);
|
||||
appMag = star.getApparentMagnitude(distance);
|
||||
|
||||
discSizeInPixels = star.getRadius() / astro::lightYearsToKilometers(distance) / pixelSize;
|
||||
++nClose;
|
||||
}
|
||||
|
||||
// Stars closer than the maximum solar system size are actually
|
||||
|
@ -96,44 +93,19 @@ void PointStarRenderer::process(const Star& star, float distance, float appMag)
|
|||
// planets.
|
||||
if (distance > SolarSystemMaxDistance)
|
||||
{
|
||||
float satPoint = faintestMag - (1.0f - brightnessBias) / brightnessScale; // TODO: precompute this value
|
||||
float alpha = (faintestMag - appMag) * brightnessScale + brightnessBias;
|
||||
float pointSize, alpha, glareSize, glareAlpha;
|
||||
float size = BaseStarDiscSize * static_cast<float>(renderer->getScreenDpi()) / 96.0f;
|
||||
renderer->calculatePointSize(appMag,
|
||||
size,
|
||||
pointSize,
|
||||
alpha,
|
||||
glareSize,
|
||||
glareAlpha);
|
||||
|
||||
if (useScaledDiscs)
|
||||
{
|
||||
float discSize = size;
|
||||
if (alpha < 0.0f)
|
||||
{
|
||||
alpha = 0.0f;
|
||||
}
|
||||
else if (alpha > 1.0f)
|
||||
{
|
||||
float discScale = min(MaxScaledDiscStarSize, (float) pow(2.0f, 0.3f * (satPoint - appMag)));
|
||||
discSize *= discScale;
|
||||
|
||||
float glareAlpha = min(0.5f, discScale / 4.0f);
|
||||
glareVertexBuffer->addStar(relPos, Color(starColor, glareAlpha), discSize * 3.0f);
|
||||
|
||||
alpha = 1.0f;
|
||||
}
|
||||
starVertexBuffer->addStar(relPos, Color(starColor, alpha), discSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (alpha < 0.0f)
|
||||
{
|
||||
alpha = 0.0f;
|
||||
}
|
||||
else if (alpha > 1.0f)
|
||||
{
|
||||
float discScale = min(100.0f, satPoint - appMag + 2.0f);
|
||||
float glareAlpha = min(GlareOpacity, (discScale - 2.0f) / 4.0f);
|
||||
glareVertexBuffer->addStar(relPos, Color(starColor, glareAlpha), 2.0f * discScale * size);
|
||||
}
|
||||
starVertexBuffer->addStar(relPos, Color(starColor, alpha), size);
|
||||
}
|
||||
|
||||
++nRendered;
|
||||
if (glareSize != 0.0f)
|
||||
glareVertexBuffer->addStar(relPos, Color(starColor, glareAlpha), glareSize);
|
||||
if (pointSize != 0.0f)
|
||||
starVertexBuffer->addStar(relPos, Color(starColor, alpha), pointSize);
|
||||
|
||||
// Place labels for stars brighter than the specified label threshold brightness
|
||||
if (((labelMode & Renderer::StarLabels) != 0) && appMag < labelThresholdMag)
|
||||
|
@ -147,7 +119,6 @@ void PointStarRenderer::process(const Star& star, float distance, float appMag)
|
|||
starDB->getStarName(star, true),
|
||||
color,
|
||||
relPos);
|
||||
nLabelled++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,13 +43,12 @@ class PointStarRenderer : public ObjectRenderer<Star, float>
|
|||
void process(const Star &star, float distance, float appMag);
|
||||
|
||||
Eigen::Vector3d obsPos;
|
||||
Eigen::Vector3f viewNormal;
|
||||
std::vector<RenderListEntry>* renderList { nullptr };
|
||||
PointStarVertexBuffer* starVertexBuffer { nullptr };
|
||||
PointStarVertexBuffer* glareVertexBuffer { nullptr };
|
||||
const StarDatabase* starDB { nullptr };
|
||||
const ColorTemperatureTable* colorTemp { nullptr };
|
||||
float SolarSystemMaxDistance { 1.0f };
|
||||
float maxDiscSize { 1.0f };
|
||||
float cosFOV { 1.0f };
|
||||
bool useScaledDiscs { false };
|
||||
};
|
||||
|
|
|
@ -1560,6 +1560,13 @@ void Renderer::draw(const Observer& observer,
|
|||
else
|
||||
brightnessScale = 0.1667f;
|
||||
|
||||
brightnessScale *= corrFac;
|
||||
if (starStyle == ScaledDiscStars)
|
||||
brightnessScale *= 2.0f;
|
||||
|
||||
// Calculate saturation magnitude
|
||||
satPoint = faintestMag - (1.0f - brightnessBias) / brightnessScale;
|
||||
|
||||
ambientColor = Color(ambientLightLevel, ambientLightLevel, ambientLightLevel);
|
||||
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
@ -1742,6 +1749,50 @@ void renderLargePoint(Renderer &renderer,
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
Renderer::calculatePointSize(float appMag,
|
||||
float size,
|
||||
float &discSize,
|
||||
float &alpha,
|
||||
float &glareSize,
|
||||
float &glareAlpha) const
|
||||
{
|
||||
alpha = std::max(0.0f, (faintestMag - appMag) * brightnessScale + brightnessBias);
|
||||
|
||||
discSize = size;
|
||||
if (starStyle == ScaledDiscStars)
|
||||
{
|
||||
if (alpha > 1.0f)
|
||||
{
|
||||
float discScale = std::min(MaxScaledDiscStarSize, pow(2.0f, 0.3f * (satPoint - appMag)));
|
||||
discSize *= std::max(1.0f, discScale);
|
||||
|
||||
glareAlpha = std::min(0.5f, discScale / 4.0f);
|
||||
glareSize = discSize * 3.0f;
|
||||
|
||||
alpha = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
glareSize = glareAlpha = 0.0f;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (alpha > 1.0f)
|
||||
{
|
||||
float discScale = std::min(100.0f, satPoint - appMag + 2.0f);
|
||||
glareAlpha = std::min(GlareOpacity, (discScale - 2.0f) / 4.0f);
|
||||
glareSize = 2.0f * discScale * size;
|
||||
alpha = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
glareSize = glareAlpha = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the an object occupies a pixel or less of screen space, we don't
|
||||
// render its mesh at all and just display a starlike point instead.
|
||||
// Switching between the particle and mesh renderings of an object is
|
||||
|
@ -1751,74 +1802,38 @@ void renderLargePoint(Renderer &renderer,
|
|||
void Renderer::renderObjectAsPoint(const Vector3f& position,
|
||||
float radius,
|
||||
float appMag,
|
||||
float _faintestMag,
|
||||
float discSizeInPixels,
|
||||
const Color &color,
|
||||
bool useHalos,
|
||||
bool emissive,
|
||||
const Matrices &mvp)
|
||||
{
|
||||
const float maxSize = MaxScaledDiscStarSize;
|
||||
float maxDiscSize = (starStyle == ScaledDiscStars) ? maxSize : 1.0f;
|
||||
const bool useScaledDiscs = starStyle == ScaledDiscStars;
|
||||
float maxDiscSize = useScaledDiscs ? MaxScaledDiscStarSize : 1.0f;
|
||||
float maxBlendDiscSize = maxDiscSize + 3.0f;
|
||||
|
||||
bool useScaledDiscs = starStyle == ScaledDiscStars;
|
||||
|
||||
if (discSizeInPixels < maxBlendDiscSize || useHalos)
|
||||
{
|
||||
float alpha = 1.0f;
|
||||
float fade = 1.0f;
|
||||
float size = BaseStarDiscSize * screenDpi / 96.0f;
|
||||
float satPoint = _faintestMag - (1.0f - brightnessBias) / brightnessScale;
|
||||
|
||||
if (discSizeInPixels > maxDiscSize)
|
||||
{
|
||||
fade = (maxBlendDiscSize - discSizeInPixels) /
|
||||
(maxBlendDiscSize - maxDiscSize);
|
||||
if (fade > 1)
|
||||
fade = 1;
|
||||
fade = std::min(1.0f, (maxBlendDiscSize - discSizeInPixels) /
|
||||
(maxBlendDiscSize - maxDiscSize));
|
||||
}
|
||||
|
||||
alpha = (_faintestMag - appMag) * brightnessScale * 2.0f + brightnessBias;
|
||||
if (alpha < 0.0f)
|
||||
alpha = 0.0f;
|
||||
float scale = static_cast<float>(screenDpi) / 96.0f;
|
||||
float pointSize, alpha, glareSize, glareAlpha;
|
||||
calculatePointSize(appMag, BaseStarDiscSize * scale, pointSize, alpha, glareSize, glareAlpha);
|
||||
|
||||
float pointSize = size;
|
||||
float glareSize = 0.0f;
|
||||
float glareAlpha = 0.0f;
|
||||
if (useScaledDiscs)
|
||||
{
|
||||
if (alpha > 1.0f)
|
||||
{
|
||||
float discScale = min(maxSize, (float) pow(2.0f, 0.3f * (satPoint - appMag)));
|
||||
pointSize *= max(1.0f, discScale);
|
||||
|
||||
glareAlpha = min(0.5f, discScale / 4.0f);
|
||||
if (discSizeInPixels > maxSize)
|
||||
glareAlpha = min(glareAlpha, (maxSize - discSizeInPixels) / maxSize + 1.0f);
|
||||
glareSize = pointSize * 3.0f;
|
||||
|
||||
alpha = 1.0f;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (alpha > 1.0f)
|
||||
{
|
||||
float discScale = min(100.0f, satPoint - appMag + 2.0f);
|
||||
glareAlpha = min(GlareOpacity, (discScale - 2.0f) / 4.0f);
|
||||
glareSize = pointSize * discScale * 2.0f ;
|
||||
if (emissive)
|
||||
glareSize = max(glareSize, pointSize * discSizeInPixels / (screenDpi / 96.0f) * 3.0f);
|
||||
}
|
||||
}
|
||||
if (useScaledDiscs && discSizeInPixels > MaxScaledDiscStarSize)
|
||||
glareAlpha = std::min(glareAlpha, (MaxScaledDiscStarSize - discSizeInPixels) / MaxScaledDiscStarSize + 1.0f);
|
||||
|
||||
alpha *= fade;
|
||||
if (!emissive)
|
||||
{
|
||||
glareSize = max(glareSize, pointSize * discSizeInPixels / (screenDpi / 96.0f) * 3.0f);
|
||||
glareAlpha *= fade;
|
||||
}
|
||||
|
||||
if (glareSize != 0.0f)
|
||||
glareSize = std::max(glareSize, pointSize * discSizeInPixels / scale * 3.0f);
|
||||
|
||||
Matrix3f m = m_cameraOrientation.conjugate().toRotationMatrix();
|
||||
Vector3f center = position;
|
||||
|
@ -1833,7 +1848,8 @@ void Renderer::renderObjectAsPoint(const Vector3f& position,
|
|||
enableDepthTest();
|
||||
disableDepthMask();
|
||||
|
||||
bool useSprites = starStyle != PointStars;
|
||||
const bool useSprites = starStyle != PointStars;
|
||||
|
||||
if (useSprites)
|
||||
gaussianDiscTex->bind();
|
||||
if (pointSize > gl::maxPointSize)
|
||||
|
@ -3317,7 +3333,6 @@ void Renderer::renderPlanet(Body& body,
|
|||
renderObjectAsPoint(pos,
|
||||
body.getRadius(),
|
||||
appMag,
|
||||
faintestMag,
|
||||
discSizeInPixels,
|
||||
body.getSurface().color,
|
||||
false, false, m);
|
||||
|
@ -3396,7 +3411,6 @@ void Renderer::renderStar(const Star& star,
|
|||
renderObjectAsPoint(pos,
|
||||
star.getRadius(),
|
||||
appMag,
|
||||
faintestMag,
|
||||
discSizeInPixels,
|
||||
color,
|
||||
star.hasCorona(), true,
|
||||
|
@ -4371,11 +4385,7 @@ void Renderer::renderPointStars(const StarDatabase& starDB,
|
|||
starRenderer.cosFOV = (float) cos(degToRad(calcMaxFOV(fov, getAspectRatio())) / 2.0f);
|
||||
|
||||
starRenderer.pixelSize = pixelSize;
|
||||
starRenderer.brightnessScale = brightnessScale * corrFac;
|
||||
starRenderer.brightnessBias = brightnessBias;
|
||||
starRenderer.faintestMag = faintestMag;
|
||||
starRenderer.faintestMagNight = faintestMagNight;
|
||||
starRenderer.saturationMag = saturationMag;
|
||||
starRenderer.distanceLimit = distanceLimit;
|
||||
starRenderer.labelMode = labelMode;
|
||||
starRenderer.SolarSystemMaxDistance = SolarSystemMaxDistance;
|
||||
|
@ -4384,18 +4394,6 @@ void Renderer::renderPointStars(const StarDatabase& starDB,
|
|||
float effDistanceToScreen = mmToInches((float) REF_DISTANCE_TO_SCREEN) * pixelSize * getScreenDpi();
|
||||
starRenderer.labelThresholdMag = 1.2f * max(1.0f, (faintestMag - 4.0f) * (1.0f - 0.5f * (float) log10(effDistanceToScreen)));
|
||||
|
||||
starRenderer.size = BaseStarDiscSize * screenDpi / 96.0f;
|
||||
if (starStyle == ScaledDiscStars)
|
||||
{
|
||||
starRenderer.useScaledDiscs = true;
|
||||
starRenderer.brightnessScale *= 2.0f;
|
||||
starRenderer.maxDiscSize = starRenderer.size * MaxScaledDiscStarSize;
|
||||
}
|
||||
else if (starStyle == FuzzyPointStars)
|
||||
{
|
||||
starRenderer.brightnessScale *= 1.0f;
|
||||
}
|
||||
|
||||
starRenderer.colorTemp = colorTemp;
|
||||
|
||||
gaussianDiscTex->bind();
|
||||
|
@ -4455,17 +4453,11 @@ void Renderer::renderDeepSkyObjects(const Universe& universe,
|
|||
dsoRenderer.orientationMatrix= observer.getOrientationf().conjugate().toRotationMatrix();
|
||||
dsoRenderer.observer = &observer;
|
||||
dsoRenderer.obsPos = obsPos;
|
||||
dsoRenderer.viewNormal = observer.getOrientationf().conjugate() * -Vector3f::UnitZ();
|
||||
dsoRenderer.fov = fov;
|
||||
// size/pixelSize =0.86 at 120deg, 1.43 at 45deg and 1.6 at 0deg.
|
||||
dsoRenderer.size = pixelSize * 1.6f / corrFac;
|
||||
dsoRenderer.pixelSize = pixelSize;
|
||||
dsoRenderer.brightnessScale = brightnessScale * corrFac;
|
||||
dsoRenderer.brightnessBias = brightnessBias;
|
||||
dsoRenderer.avgAbsMag = dsoDB->getAverageAbsoluteMagnitude();
|
||||
dsoRenderer.faintestMag = faintestMag;
|
||||
dsoRenderer.faintestMagNight = faintestMagNight;
|
||||
dsoRenderer.saturationMag = saturationMag;
|
||||
dsoRenderer.renderFlags = renderFlags;
|
||||
dsoRenderer.labelMode = labelMode;
|
||||
dsoRenderer.wWidth = windowWidth;
|
||||
|
|
|
@ -618,10 +618,16 @@ class Renderer
|
|||
float discSizeInPixels,
|
||||
const Matrices&);
|
||||
|
||||
void calculatePointSize(float appMag,
|
||||
float size,
|
||||
float &discSize,
|
||||
float &alpha,
|
||||
float &glareSize,
|
||||
float &glareAlpha) const;
|
||||
|
||||
void renderObjectAsPoint(const Eigen::Vector3f& center,
|
||||
float radius,
|
||||
float appMag,
|
||||
float _faintestMag,
|
||||
float discSizeInPixels,
|
||||
const Color& color,
|
||||
bool useHalos,
|
||||
|
@ -840,6 +846,9 @@ class Renderer
|
|||
|
||||
std::array<celgl::VertexObject*, static_cast<size_t>(VOType::Count)> m_VertexObjects;
|
||||
|
||||
// Saturation magnitude used to calculate a point star size
|
||||
float satPoint;
|
||||
|
||||
// Location markers
|
||||
public:
|
||||
celestia::MarkerRepresentation mountainRep;
|
||||
|
@ -897,6 +906,8 @@ class Renderer
|
|||
static Color EclipticColor;
|
||||
|
||||
static Color SelectionCursorColor;
|
||||
|
||||
friend class PointStarRenderer;
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue