Implemented depth sorting for markers, with option to specify non-occludable

markers.
ver1_6_1
Chris Laurel 2008-02-13 21:49:53 +00:00
parent a5321d18e9
commit ed9b33dab0
6 changed files with 287 additions and 190 deletions

View File

@ -20,7 +20,8 @@ Marker::Marker(const Selection& s) :
color(Color::White),
priority(0),
symbol(Diamond),
label("")
label(""),
occludable(true)
{
}
@ -100,6 +101,17 @@ void Marker::setLabel(string _label)
}
bool Marker::isOccludable() const
{
return occludable;
}
void Marker::setOccludable(bool _occludable)
{
occludable = _occludable;
}
void Marker::render() const
{
float s = getSize() / 2.0f;

View File

@ -33,6 +33,8 @@ class Marker
void setSize(float);
int getPriority() const;
void setPriority(int);
bool isOccludable() const;
void setOccludable(bool);
enum Symbol
{
@ -65,6 +67,7 @@ class Marker
int priority;
Symbol symbol;
string label;
bool occludable;
};
typedef std::vector<Marker> MarkerList;

View File

@ -602,10 +602,10 @@ bool operator<(const RenderListEntry& a, const RenderListEntry& b)
// function of Renderer::Label; if it's not a class member, C++'s
// argument dependent lookup will not find the operator when it's
// used as a predicate for STL algorithms.
bool Renderer::Label::operator<(const Label& l) const
bool Renderer::Annotation::operator<(const Annotation& a) const
{
// Operation is reversed because -z axis points into the screen
return position.z > l.position.z;
return position.z > a.position.z;
}
// Depth comparison for orbit paths
@ -1055,10 +1055,12 @@ bool Renderer::vertexShaderSupported() const
}
void Renderer::addLabel(const char* text,
Color color,
const Point3f& pos,
float depth)
void Renderer::addAnnotation(vector<Annotation>& annotations,
const Marker* marker,
const char* labelText,
Color color,
const Point3f& pos,
float depth)
{
double winX, winY, winZ;
int view[4] = { 0, 0, 0, 0 };
@ -1075,28 +1077,53 @@ void Renderer::addLabel(const char* text,
(const GLint*) view,
&winX, &winY, &winZ) != GL_FALSE)
{
Label l;
ReplaceGreekLetterAbbr(l.text, MaxLabelLength, text, strlen(text));
// Might be nice to use abbreviations instead of Greek letters
// strncpy(l.text, text, MaxLabelLength);
l.text[MaxLabelLength - 1] = '\0';
l.color = color;
l.position = Point3f((float) winX, (float) winY, -depth);
labels.insert(labels.end(), l);
Annotation a;
if (marker == NULL)
{
ReplaceGreekLetterAbbr(a.labelText, MaxLabelLength, labelText, strlen(labelText));
// Might be nice to use abbreviations instead of Greek letters
// strncpy(l.text, text, MaxLabelLength);
a.labelText[MaxLabelLength - 1] = '\0';
}
a.marker = marker;
a.color = color;
a.position = Point3f((float) winX, (float) winY, -depth);
annotations.push_back(a);
}
}
void Renderer::addLabel(const string& text,
Color color,
const Point3f& pos,
float depth)
void Renderer::addForegroundAnnotation(const Marker* marker,
const char* labelText,
Color color,
const Point3f& pos,
float depth)
{
addLabel(text.c_str(), color, pos, depth);
addAnnotation(foregroundAnnotations, marker, labelText, color, pos, depth);
}
void Renderer::addSortedLabel(const string& text, Color color, const Point3f& pos)
void Renderer::addBackgroundAnnotation(const Marker* marker,
const char* labelText,
Color color,
const Point3f& pos,
float depth)
{
addAnnotation(backgroundAnnotations, marker, labelText, color, pos, depth);
}
void Renderer::addBackgroundAnnotation(const string& labelText,
Color color,
const Point3f& pos,
float depth)
{
addAnnotation(backgroundAnnotations, NULL, labelText.c_str(), color, pos, depth);
}
void Renderer::addSortedAnnotation(const Marker* marker, const string& labelText, Color color, const Point3f& pos)
{
double winX, winY, winZ;
int view[4] = { 0, 0, 0, 0 };
@ -1113,26 +1140,31 @@ void Renderer::addSortedLabel(const string& text, Color color, const Point3f& po
(const GLint*) view,
&winX, &winY, &winZ) != GL_FALSE)
{
Label l;
//l.text = ReplaceGreekLetterAbbr(_(text.c_str()));
strncpy(l.text, text.c_str(), MaxLabelLength);
l.text[MaxLabelLength - 1] = '\0';
l.color = color;
l.position = Point3f((float) winX, (float) winY, -depth);
depthSortedLabels.insert(depthSortedLabels.end(), l);
Annotation a;
if (marker == NULL)
{
//l.text = ReplaceGreekLetterAbbr(_(text.c_str()));
strncpy(a.labelText, labelText.c_str(), MaxLabelLength);
a.labelText[MaxLabelLength - 1] = '\0';
}
a.marker = marker;
a.color = color;
a.position = Point3f((float) winX, (float) winY, -depth);
depthSortedAnnotations.push_back(a);
}
}
void Renderer::clearLabels()
void Renderer::clearAnnotations(vector<Annotation>& annotations)
{
labels.clear();
annotations.clear();
}
void Renderer::clearSortedLabels()
void Renderer::clearSortedAnnotations()
{
depthSortedLabels.clear();
depthSortedAnnotations.clear();
}
@ -2179,8 +2211,7 @@ void Renderer::render(const Observer& observer,
glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
clearLabels();
clearSortedLabels();
clearSortedAnnotations();
// Put all solar system bodies into the render list. Stars close and
// large enough to have discernible surface detail are also placed in
@ -2327,7 +2358,8 @@ void Renderer::render(const Observer& observer,
glDepthMask(GL_FALSE);
glEnable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
// Render sky grids first--these will always be in the background
if ((renderFlags & ShowCelestialSphere) != 0)
{
glColor(EquatorialGridColor);
@ -2341,6 +2373,7 @@ void Renderer::render(const Observer& observer,
glEnable(GL_TEXTURE_2D);
}
// Render deep sky objects
if ((renderFlags & (ShowGalaxies |
ShowNebulae |
ShowOpenClusters)) != 0 &&
@ -2424,19 +2457,28 @@ void Renderer::render(const Observer& observer,
disableSmoothLines();
}
renderLabels(FontNormal, AlignLeft);
clearLabels();
// Render star and deep sky object labels
renderBackgroundAnnotations(FontNormal, AlignLeft);
// Render constellations labels
if ((labelMode & ConstellationLabels) != 0 && universe.getAsterisms() != NULL)
{
labelConstellations(*universe.getAsterisms(), observer);
renderLabels(FontLarge, AlignCenter);
clearLabels();
renderBackgroundAnnotations(FontLarge, AlignCenter);
}
glPopMatrix();
renderLabels(FontNormal, AlignLeft);
if ((renderFlags & ShowMarkers) != 0)
{
renderMarkers(*universe.getMarkers(),
observer.getPosition(),
now);
// Render background markers; rendering of other markers is deferred until
// solar system objects are rendered.
renderBackgroundAnnotations(FontNormal, AlignLeft);
}
glPolygonMode(GL_FRONT, (GLenum) renderMode);
glPolygonMode(GL_BACK, (GLenum) renderMode);
@ -2575,8 +2617,8 @@ void Renderer::render(const Observer& observer,
// amount of overdraw in Celestia is typically low.)
sort(renderList.begin(), renderList.end());
// Sort the labels
sort(depthSortedLabels.begin(), depthSortedLabels.end());
// Sort the annotations
sort(depthSortedAnnotations.begin(), depthSortedAnnotations.end());
// Sort the orbit paths
sort(orbitPathList.begin(), orbitPathList.end());
@ -2711,7 +2753,7 @@ void Renderer::render(const Observer& observer,
// partitions that have small spans in the depth buffer.
// TODO: Implement this step!
vector<Label>::iterator label = depthSortedLabels.begin();
vector<Annotation>::iterator annotation = depthSortedAnnotations.begin();
// Render everything that wasn't culled.
float intervalSize = 1.0f / (float) max(1, nIntervals);
@ -2860,8 +2902,12 @@ void Renderer::render(const Observer& observer,
i--;
}
// Render labels in this interval
label = renderSortedLabels(label, -depthPartitions[interval].nearZ, -depthPartitions[interval].farZ, FontNormal);
// Render annotations in this interval
if ((renderFlags & ShowSmoothLines) != 0)
enableSmoothLines();
annotation = renderSortedAnnotations(annotation, -depthPartitions[interval].nearZ, -depthPartitions[interval].farZ, FontNormal);
if ((renderFlags & ShowSmoothLines) != 0)
disableSmoothLines();
glDisable(GL_DEPTH_TEST);
}
#if 0
@ -2880,6 +2926,8 @@ void Renderer::render(const Observer& observer,
// reset the depth range
glDepthRange(0, 1);
}
renderForegroundAnnotations(FontNormal, AlignLeft);
// Pop camera orientation matrix
glPopMatrix();
@ -2890,21 +2938,7 @@ void Renderer::render(const Observer& observer,
glPolygonMode(GL_FRONT, GL_FILL);
glPolygonMode(GL_BACK, GL_FILL);
if ((renderFlags & ShowMarkers) != 0)
{
if ((renderFlags & ShowSmoothLines) != 0)
enableSmoothLines();
renderMarkers(*universe.getMarkers(),
observer.getPosition(),
observer.getOrientationf(),
now);
if ((renderFlags & ShowSmoothLines) != 0)
disableSmoothLines();
}
glDisable(GL_BLEND);
glDepthMask(GL_TRUE);
glEnable(GL_LIGHTING);
@ -5544,7 +5578,7 @@ void Renderer::renderLocations(const vector<Location*>& locations,
{
if ((*iter)->getFeatureType() & locationFilter)
{
// Get the position of the label with respect to the planet center
// Get the position of the annotation with respect to the planet center
Vec3f ppos = (*iter)->getPosition();
// Compute the body-centric position of the location
@ -7147,7 +7181,7 @@ void Renderer::renderVelocityVector(Body& body,
}
// Add solar system bodies, orbits, and labels to the render list. Stars
// Add solar system bodies, orbits, and annotations to the render list. Stars
// are handled by other methods.
void Renderer::buildRenderLists(const Star& sun,
const PlanetarySystem* solSystem,
@ -7415,7 +7449,7 @@ void Renderer::buildRenderLists(const Star& sun,
// This only handles the problem of partial label occlusion
// for low orbiting and surface positioned objects, but that
// case is *much* more common than other possibilities.
if (primary != NULL && primary->getModel() == InvalidResource)
if (primary != NULL && primary->isEllipsoid())
{
// In the typical case, we're rendering labels for many
// objects that orbit the same primary. Avoid repeatedly
@ -7466,8 +7500,8 @@ void Renderer::buildRenderLists(const Star& sun,
}
}
addSortedLabel(body->getName(true), labelColor,
Point3f(pos.x, pos.y, pos.z));
addSortedAnnotation(NULL, body->getName(true), labelColor,
Point3f(pos.x, pos.y, pos.z));
}
}
}
@ -7748,9 +7782,9 @@ void StarRenderer::process(const Star& star, float distance, float appMag)
float distr = 3.5f * (labelThresholdMag - appMag)/labelThresholdMag;
if (distr > 1.0f)
distr = 1.0f;
renderer->addLabel(nameBuffer,
Color(Renderer::StarLabelColor, distr * Renderer::StarLabelColor.alpha()),
Point3f(relPos.x, relPos.y, relPos.z));
renderer->addBackgroundAnnotation(NULL, nameBuffer,
Color(Renderer::StarLabelColor, distr * Renderer::StarLabelColor.alpha()),
Point3f(relPos.x, relPos.y, relPos.z));
nLabelled++;
}
}
@ -7969,9 +8003,9 @@ void PointStarRenderer::process(const Star& star, float distance, float appMag)
float distr = 3.5f * (labelThresholdMag - appMag)/labelThresholdMag;
if (distr > 1.0f)
distr = 1.0f;
renderer->addLabel(nameBuffer,
Color(Renderer::StarLabelColor, distr * Renderer::StarLabelColor.alpha()),
Point3f(relPos.x, relPos.y, relPos.z));
renderer->addBackgroundAnnotation(NULL, nameBuffer,
Color(Renderer::StarLabelColor, distr * Renderer::StarLabelColor.alpha()),
Point3f(relPos.x, relPos.y, relPos.z));
nLabelled++;
}
}
@ -8395,9 +8429,9 @@ void DSORenderer::process(DeepSkyObject* const & dso,
if (distr > 1.0f)
distr = 1.0f;
renderer->addLabel(dsoDB->getDSOName(dso),
Color(labelColor, distr * labelColor.alpha()),
Point3f(relPos.x, relPos.y, relPos.z));
renderer->addBackgroundAnnotation(dsoDB->getDSOName(dso),
Color(labelColor, distr * labelColor.alpha()),
Point3f(relPos.x, relPos.y, relPos.z));
}
}
}
@ -8526,7 +8560,7 @@ void Renderer::renderCelestialSphere(const Observer& observer)
{
Point3f pos = astro::equatorialToCelestialCart(ra, dec, radius);
if ((pos * m).z < 0)
addLabel(DecCoordLabels[i], EquatorialGridLabelColor, pos);
addBackgroundAnnotation(DecCoordLabels[i], EquatorialGridLabelColor, pos);
}
}
}
@ -8537,7 +8571,7 @@ void Renderer::renderCelestialSphere(const Observer& observer)
float ra = i * RALabelSpacing;
Point3f pos = astro::equatorialToCelestialCart(ra, 0.0f, radius);
if ((pos * m).z < 0)
addLabel(RACoordLabels[i], EquatorialGridLabelColor, pos);
addBackgroundAnnotation(RACoordLabels[i], EquatorialGridLabelColor, pos);
}
}
@ -8585,9 +8619,9 @@ void Renderer::labelConstellations(const AsterismList& asterisms,
(MaxAsterismLabelsDist - MaxAsterismLabelsConstDist) + 1);
}
addLabel(ast->getName((labelMode & I18nConstellationLabels) != 0),
Color(ConstellationLabelColor, opacity),
Point3f(rpos.x, rpos.y, rpos.z));
addBackgroundAnnotation(ast->getName((labelMode & I18nConstellationLabels) != 0),
Color(ConstellationLabelColor, opacity),
Point3f(rpos.x, rpos.y, rpos.z));
}
}
}
@ -8628,12 +8662,15 @@ void Renderer::renderParticles(const vector<Particle>& particles,
}
void Renderer::renderLabels(FontStyle fs, LabelAlignment la)
void Renderer::renderAnnotations(const vector<Annotation>& annotations, FontStyle fs, LabelAlignment la)
{
if (font[fs] == NULL)
return;
//glEnable(GL_DEPTH_TEST);
// Enable line smoothing for rendering symbols
if ((renderFlags & ShowSmoothLines) != 0)
enableSmoothLines();
glEnable(GL_TEXTURE_2D);
font[fs]->bind();
glEnable(GL_BLEND);
@ -8649,27 +8686,49 @@ void Renderer::renderLabels(FontStyle fs, LabelAlignment la)
glTranslatef(GLfloat((int) (windowWidth / 2)),
GLfloat((int) (windowHeight / 2)), 0);
for (int i = 0; i < (int) labels.size(); i++)
for (int i = 0; i < (int) annotations.size(); i++)
{
glColor(labels[i].color);
glPushMatrix();
int labelOffset = 2;
if (la == AlignCenter)
if (annotations[i].marker != NULL)
{
int labelwidth = (font[fs]->getWidth(labels[i].text));
labelOffset = (int) -labelwidth/2;
}
else if (la == AlignRight)
{
int labelwidth = (font[fs]->getWidth(labels[i].text));
labelOffset = (int) -(labelwidth + 2);
}
const Marker& marker = *annotations[i].marker;
glTranslatef((int) labels[i].position.x + GLfloat((int) labelOffset) + PixelOffset,
(int) labels[i].position.y + PixelOffset, 0.0f);
// EK TODO: Check where to replace (see '_(' above)
font[fs]->render(labels[i].text);
glColor(marker.getColor());
glTranslatef((GLfloat) (int) annotations[i].position.x,
(GLfloat) (int) annotations[i].position.y, 0.0f);
glDisable(GL_TEXTURE_2D);
marker.render();
glEnable(GL_TEXTURE_2D);
if (!marker.getLabel().empty())
{
int labelOffset = (int) marker.getSize() / 2;
glTranslatef(labelOffset + PixelOffset, -labelOffset - font[fs]->getHeight() + PixelOffset, 0.0f);
font[fs]->render(marker.getLabel());
}
}
else
{
int labelOffset = 2;
if (la == AlignCenter)
{
int labelwidth = (font[fs]->getWidth(annotations[i].labelText));
labelOffset = (int) -labelwidth/2;
}
else if (la == AlignRight)
{
int labelwidth = (font[fs]->getWidth(annotations[i].labelText));
labelOffset = (int) -(labelwidth + 2);
}
glColor(annotations[i].color);
glTranslatef((int) annotations[i].position.x + GLfloat((int) labelOffset) + PixelOffset,
(int) annotations[i].position.y + PixelOffset, 0.0f);
// EK TODO: Check where to replace (see '_(' above)
font[fs]->render(annotations[i].labelText);
}
glPopMatrix();
}
@ -8677,12 +8736,38 @@ void Renderer::renderLabels(FontStyle fs, LabelAlignment la)
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glDisable(GL_DEPTH_TEST);
if ((renderFlags & ShowSmoothLines) != 0)
disableSmoothLines();
}
vector<Renderer::Label>::iterator
Renderer::renderSortedLabels(vector<Label>::iterator iter, float nearDist, float farDist, FontStyle fs)
void
Renderer::renderBackgroundAnnotations(FontStyle fs, LabelAlignment la)
{
glEnable(GL_DEPTH_TEST);
renderAnnotations(backgroundAnnotations, fs, la);
glDisable(GL_DEPTH_TEST);
clearAnnotations(backgroundAnnotations);
}
void
Renderer::renderForegroundAnnotations(FontStyle fs, LabelAlignment la)
{
glDisable(GL_DEPTH_TEST);
renderAnnotations(foregroundAnnotations, fs, la);
clearAnnotations(foregroundAnnotations);
}
vector<Renderer::Annotation>::iterator
Renderer::renderSortedAnnotations(vector<Annotation>::iterator iter,
float nearDist,
float farDist,
FontStyle fs)
{
if (font[fs] == NULL)
return iter;
@ -8710,7 +8795,7 @@ Renderer::renderSortedLabels(vector<Label>::iterator iter, float nearDist, float
float d1 = -(farDist + nearDist) / (farDist - nearDist);
float d2 = -2.0f * nearDist * farDist / (farDist - nearDist);
for (; iter != depthSortedLabels.end() && iter->position.z > nearDist; iter++)
for (; iter != depthSortedAnnotations.end() && iter->position.z > nearDist; iter++)
{
// Compute normalized device z
float ndc_z = d1 + d2 / -iter->position.z;
@ -8720,12 +8805,33 @@ Renderer::renderSortedLabels(vector<Label>::iterator iter, float nearDist, float
int labelHOffset = 0;
int labelVOffset = 0;
glColor(iter->color);
glPushMatrix();
glTranslatef((int) iter->position.x + PixelOffset + labelHOffset,
(int) iter->position.y + PixelOffset + labelVOffset,
ndc_z);
font[fs]->render(iter->text);
if (iter->marker != NULL)
{
const Marker& marker = *iter->marker;
glTranslatef((GLfloat) (int) iter->position.x, (GLfloat) (int) iter->position.y, ndc_z);
glColor(marker.getColor());
glDisable(GL_TEXTURE_2D);
marker.render();
glEnable(GL_TEXTURE_2D);
if (!marker.getLabel().empty())
{
int labelOffset = (int) marker.getSize() / 2;
glTranslatef(labelOffset + PixelOffset, -labelOffset - font[fs]->getHeight() + PixelOffset, 0.0f);
font[fs]->render(marker.getLabel());
}
}
else
{
glTranslatef((int) iter->position.x + PixelOffset + labelHOffset,
(int) iter->position.y + PixelOffset + labelVOffset,
ndc_z);
glColor(iter->color);
font[fs]->render(iter->labelText);
}
glPopMatrix();
}
@ -8741,81 +8847,45 @@ Renderer::renderSortedLabels(vector<Label>::iterator iter, float nearDist, float
void Renderer::renderMarkers(const MarkerList& markers,
const UniversalCoord& position,
const Quatf& orientation,
double jd)
{
double identity4x4[16] = { 1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0
};
int view[4] = { 0, 0, 0, 0 };
view[0] = -windowWidth / 2;
view[1] = -windowHeight / 2;
view[2] = windowWidth;
view[3] = windowHeight;
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glDisable(GL_LIGHTING);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_TEXTURE_2D);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0, windowWidth, 0, windowHeight);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glTranslatef(GLfloat((int) (windowWidth / 2)),
GLfloat((int) (windowHeight / 2)), 0);
Mat3f rot = conjugate(orientation).toMatrix3();
for (MarkerList::const_iterator iter = markers.begin();
iter != markers.end(); iter++)
string emptyLabel;
for (MarkerList::const_iterator iter = markers.begin(); iter != markers.end(); iter++)
{
UniversalCoord uc = iter->getPosition(jd);
Vec3d offset = uc - position;
Vec3f eyepos = Vec3f((float) offset.x, (float) offset.y, (float) offset.z) * rot;
eyepos.normalize();
eyepos *= 1000.0f;
double winX, winY, winZ;
if (gluProject(eyepos.x, eyepos.y, eyepos.z,
identity4x4,
projMatrix,
(const GLint*) view,
&winX, &winY, &winZ) != GL_FALSE)
Vec3d offset = (uc - position) * astro::microLightYearsToKilometers(1.0);
if (iter->isOccludable())
{
if (eyepos.z < 0.0f)
// If the marker is occludable, add it to the sorted annotation list if it's relatively
// nearby, and to the background list if it's very distant.
if (offset.length() < astro::lightYearsToKilometers(1.0))
{
glPushMatrix();
glTranslatef((GLfloat) (int) winX, (GLfloat) (int) winY, 0.0f);
glColor(iter->getColor());
iter->render();
if (!iter->getLabel().empty())
{
glEnable(GL_TEXTURE_2D);
int labelOffset = (int) iter->getSize() / 2;
glTranslatef(labelOffset + PixelOffset, -labelOffset - font[FontNormal]->getHeight() + PixelOffset, 0.0f);
font[FontNormal]->bind();
font[FontNormal]->render(iter->getLabel());
glDisable(GL_TEXTURE_2D);
}
glPopMatrix();
// Modify the marker position so that it is always in front of the marked object.
double boundingRadius;
if (iter->getObject().body() != NULL)
boundingRadius = iter->getObject().body()->getBoundingRadius();
else
boundingRadius = iter->getObject().radius();
offset *= (1.0 - boundingRadius * 1.01 / offset.length());
addSortedAnnotation(&(*iter), emptyLabel, iter->getColor(),
Point3f((float) offset.x, (float) offset.y, (float) offset.z));
}
else
{
addAnnotation(backgroundAnnotations,
&(*iter), NULL, iter->getColor(),
Point3f((float) offset.x, (float) offset.y, (float) offset.z));
}
}
else
{
addAnnotation(foregroundAnnotations,
&(*iter), NULL, iter->getColor(),
Point3f((float) offset.x, (float) offset.y, (float) offset.z));
}
}
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glDisable(GL_DEPTH_TEST);
}

View File

@ -198,20 +198,23 @@ class Renderer
// Label related methods
static const int MaxLabelLength = 32;
struct Label
struct Annotation
{
char text[MaxLabelLength];
char labelText[MaxLabelLength];
const Marker* marker;
Color color;
Point3f position;
bool operator<(const Label&) const;
bool operator<(const Annotation&) const;
};
void addForegroundAnnotation(const Marker*, const char* labelText, Color, const Point3f&, float depth = -1);
void addBackgroundAnnotation(const Marker*, const char* labelText, Color, const Point3f&, float depth = -1);
void addBackgroundAnnotation(const std::string&, Color, const Point3f&, float depth = -1);
void addSortedAnnotation(const Marker* marker, const std::string&, Color, const Point3f&);
void addLabel(const char* text, Color, const Point3f&, float depth = -1);
void addLabel(const std::string&, Color, const Point3f&, float depth = -1);
void addSortedLabel(const std::string&, Color, const Point3f&);
void clearLabels();
void clearSortedLabels();
void clearAnnotations(std::vector<Annotation>&);
void clearSortedAnnotations();
void invalidateOrbitCache();
@ -517,14 +520,19 @@ class Renderer
const Observer& observer);
void renderParticles(const std::vector<Particle>& particles,
Quatf orientation);
void renderLabels(FontStyle fs, LabelAlignment la);
std::vector<Label>::iterator renderSortedLabels(std::vector<Label>::iterator,
float nearDist,
float farDist,
FontStyle fs);
void addAnnotation(std::vector<Annotation>&,
const Marker*, const char* labelText, Color, const Point3f&, float depth = -1);
void renderAnnotations(const std::vector<Annotation>&, FontStyle fs, LabelAlignment la);
void renderBackgroundAnnotations(FontStyle fs, LabelAlignment la);
void renderForegroundAnnotations(FontStyle fs, LabelAlignment la);
std::vector<Annotation>::iterator renderSortedAnnotations(std::vector<Annotation>::iterator,
float nearDist,
float farDist,
FontStyle fs);
void renderMarkers(const MarkerList&,
const UniversalCoord& position,
const Quatf& orientation,
double jd);
void renderOrbit(const OrbitPathListEntry&,
@ -571,8 +579,9 @@ class Renderer
std::vector<RenderListEntry> renderList;
std::vector<DepthBufferPartition> depthPartitions;
std::vector<Particle> glareParticles;
std::vector<Label> labels;
std::vector<Label> depthSortedLabels;
std::vector<Annotation> backgroundAnnotations;
std::vector<Annotation> foregroundAnnotations;
std::vector<Annotation> depthSortedAnnotations;
std::vector<OrbitPathListEntry> orbitPathList;
std::vector<EclipseShadow> eclipseShadows[MaxLights];
std::vector<const Star*> nearStars;

View File

@ -170,7 +170,8 @@ void Universe::markObject(const Selection& sel,
Color color,
Marker::Symbol symbol,
int priority,
string label)
string label,
bool occludable)
{
for (MarkerList::iterator iter = markers->begin();
iter != markers->end(); iter++)
@ -198,6 +199,7 @@ void Universe::markObject(const Selection& sel,
marker.setSize(size);
marker.setPriority(priority);
marker.setLabel(label);
marker.setOccludable(occludable);
markers->insert(markers->end(), marker);
}

View File

@ -103,7 +103,8 @@ class Universe
Color color,
Marker::Symbol symbol,
int priority,
string label);
string label,
bool occludable = true);
void unmarkObject(const Selection&, int priority);
void unmarkAll();
bool isMarked(const Selection&, int priority) const;