// Draw constellations lines void ConstellationMgr::drawLines(StelPainter& sPainter, const StelCore* core) const { sPainter.enableTexture2d(false); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); if (constellationLineThickness>1.f) glLineWidth(constellationLineThickness); // set line thickness // OpenGL ES 2.0 doesn't have GL_LINE_SMOOTH. But it looks much better. #ifdef GL_LINE_SMOOTH if (QOpenGLContext::currentContext()->format().renderableType()==QSurfaceFormat::OpenGL) glEnable(GL_LINE_SMOOTH); #endif const SphericalCap& viewportHalfspace = sPainter.getProjector()->getBoundingCap(); vector < Constellation * >::const_iterator iter; for (iter = asterisms.begin(); iter != asterisms.end(); ++iter) { (*iter)->drawOptim(sPainter, core, viewportHalfspace); } if (constellationLineThickness>1.f) glLineWidth(1.f); // restore line thickness // OpenGL ES 2.0 doesn't have GL_LINE_SMOOTH. But it looks much better. #ifdef GL_LINE_SMOOTH if (QOpenGLContext::currentContext()->format().renderableType()==QSurfaceFormat::OpenGL) glDisable(GL_LINE_SMOOTH); #endif }
void Constellation::drawName(StelPainter& sPainter, ConstellationMgr::ConstellationDisplayStyle style) const { if (!nameFader.getInterstate()) return; if (checkVisibility()) { QString name; switch (style) { case ConstellationMgr::constellationsTranslated: name=nameI18; break; case ConstellationMgr::constellationsNative: name=nativeName; break; case ConstellationMgr::constellationsEnglish: name=englishName; break; case ConstellationMgr::constellationsAbbreviated: name=(abbreviation.startsWith('.') ? "" : abbreviation); break; Q_ASSERT(0); } sPainter.setColor(labelColor[0], labelColor[1], labelColor[2], nameFader.getInterstate()); sPainter.drawText(XYname[0], XYname[1], name, 0., -sPainter.getFontMetrics().width(name)/2, 0, false); } }
void Comet::drawComa(StelCore* core, StelProjector::ModelViewTranformP transfo) { // Find rotation matrix from 0/0/1 to viewdirection! crossproduct for axis (normal vector), dotproduct for angle. Vec3d eclposNrm=eclipticPos - core->getObserverHeliocentricEclipticPos() ; eclposNrm.normalize(); Mat4d comarot=Mat4d::rotation(Vec3d(0.0, 0.0, 1.0)^(eclposNrm), std::acos(Vec3d(0.0, 0.0, 1.0).dot(eclposNrm)) ); StelProjector::ModelViewTranformP transfo2 = transfo->clone(); transfo2->combine(comarot); StelPainter* sPainter = new StelPainter(core->getProjection(transfo2)); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); glDisable(GL_CULL_FACE); // GZ: For the coma, we can use extinction via atmosphere. // In addition, light falloff is a bit reduced for better visibility. Power basis should be 0.4, we use 0.6. float minSkyMag=core->getSkyDrawer()->getLimitMagnitude(); float mag100pct=minSkyMag-6.0f; // should be 5, but let us draw it a bit brighter. float magDrop=getVMagnitudeWithExtinction(core)-mag100pct; float magFactor=std::pow(0.6f , magDrop); magFactor=qMin(magFactor, 2.0f); // Limit excessively bright display. comaTexture->bind(); sPainter->setColor(magFactor,magFactor,0.6f*magFactor); sPainter->setArrays((Vec3d*)comaVertexArr.constData(), (Vec2f*)comaTexCoordArr.constData()); sPainter->drawFromArray(StelPainter::Triangles, comaVertexArr.size()/3); glDisable(GL_BLEND); if (sPainter) delete sPainter; sPainter=NULL; }
void Supernova::draw(StelCore* core, StelPainter& painter) { StelSkyDrawer* sd = core->getSkyDrawer(); Vec3f color = Vec3f(1.f,1.f,1.f); if (StelApp::getInstance().getVisionModeNight()) color = StelUtils::getNightColor(color); float rcMag[2], size, shift; double mag; StelUtils::spheToRect(snra, snde, XYZ); mag = getVMagnitude(core, true); sd->preDrawPointSource(&painter); if (mag <= sd->getLimitMagnitude()) { sd->computeRCMag(mag, rcMag); // sd->drawPointSource(&painter, Vec3f(XYZ[0], XYZ[1], XYZ[2]), rcMag, color, false); sd->drawPointSource(&painter, XYZ, rcMag, color, false); painter.setColor(color[0], color[1], color[2], 1); size = getAngularSize(NULL)*M_PI/180.*painter.getProjector()->getPixelPerRadAtCenter(); shift = 6.f + size/1.8f; if (labelsFader.getInterstate()<=0.f) { painter.drawText(XYZ, designation, 0, shift, shift, false); } } sd->postDrawPointSource(&painter); }
void Nebula::drawLabel(StelPainter& sPainter, float maxMagLabel) { float lim = mag; if (lim > 50) lim = 15.f; // temporary workaround of this bug: https://bugs.launchpad.net/stellarium/+bug/1115035 --AW if (getEnglishName().contains("Pleiades")) lim = 5.f; if (lim>maxMagLabel) return; Vec3f col(labelColor[0], labelColor[1], labelColor[2]); sPainter.setColor(col[0], col[1], col[2], hintsBrightness); float size = getAngularSize(NULL)*M_PI/180.*sPainter.getProjector()->getPixelPerRadAtCenter(); float shift = 4.f + size/1.8f; QString str; if (!nameI18.isEmpty()) str = getNameI18n(); else { if (M_nb > 0) str = QString("M %1").arg(M_nb); else if (C_nb > 0) str = QString("C %1").arg(C_nb); else if (NGC_nb > 0) str = QString("NGC %1").arg(NGC_nb); else if (IC_nb > 0) str = QString("IC %1").arg(IC_nb); } sPainter.drawText(XY[0]+shift, XY[1]+shift, str, 0, 0, 0, false); }
void StarMgr::drawPointer(StelPainter& sPainter, const StelCore* core) { const QList<StelObjectP> newSelected = objectMgr->getSelectedObject("Star"); if (!newSelected.empty()) { const StelObjectP obj = newSelected[0]; Vec3d pos=obj->getJ2000EquatorialPos(core); Vec3d screenpos; // Compute 2D pos and return if outside screen if (!sPainter.getProjector()->project(pos, screenpos)) return; Vec3f c(obj->getInfoColor()); if (StelApp::getInstance().getVisionModeNight()) c = StelUtils::getNightColor(c); sPainter.setColor(c[0], c[1], c[2]); texPointer->bind(); sPainter.enableTexture2d(true); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Normal transparency mode sPainter.drawSprite2dMode(screenpos[0], screenpos[1], 13.f, StelApp::getInstance().getTotalRunTime()*40.); } }
bool ScreenLabel::draw(StelCore*, StelPainter& sPainter) { if (labelFader.getInterstate() <= 0.0) return false; sPainter.setColor(labelColor[0], labelColor[1], labelColor[2], labelFader.getInterstate()); sPainter.setFont(labelFont); sPainter.drawText(screenX, screenY, labelText, 0, 0, 0, false); return true; }
void TleTraj::drawOrbit(StelPainter &painter) { StelVertexArray vertexArray(StelVertexArray::LineStrip); for (QList<Vec3d>::iterator it = trajectory.begin(); it != trajectory.end(); ++it) { vertexArray.vertex.append(*it); } painter.setColor(orbitColor->redF(), orbitColor->greenF(), orbitColor->blueF()); painter.drawGreatCircleArcs(vertexArray, &viewportHalfspace); }
// Draw the art texture void Constellation::drawArt(StelPainter& sPainter) const { glBlendFunc(GL_ONE, GL_ONE); sPainter.enableTexture2d(true); glEnable(GL_BLEND); glEnable(GL_CULL_FACE); SphericalRegionP region = sPainter.getProjector()->getViewportConvexPolygon(); drawArtOptim(sPainter, *region); glDisable(GL_CULL_FACE); }
// Draw constellations lines void ConstellationMgr::drawLines(StelPainter& sPainter, const StelCore* core) const { sPainter.enableTexture2d(false); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); const SphericalCap& viewportHalfspace = sPainter.getProjector()->getBoundingCap(); vector < Constellation * >::const_iterator iter; for (iter = asterisms.begin(); iter != asterisms.end(); ++iter) { (*iter)->drawOptim(sPainter, core, viewportHalfspace); } }
// returns true if visible // Assumes that we are in local frame void MeteorStream::draw(const StelCore* core, StelPainter& sPainter) { if(!alive) return; Vec3d spos = position; Vec3d epos = posTrain; // convert to equ spos.transfo4d(viewMatrix); epos.transfo4d(viewMatrix); // convert to local and correct for earth radius //[since equ and local coordinates in stellarium use same 0 point!] spos = core->j2000ToAltAz(spos); epos = core->j2000ToAltAz(epos); spos[2] -= EARTH_RADIUS; epos[2] -= EARTH_RADIUS; // 1216 is to scale down under 1 for desktop version spos/=1216; epos/=1216; // connect this point with last drawn point double tmag = mag*distMultiplier; QVector<Vec4f> colorArray; QVector<Vec3d> vertexArray; // last point - dark colorArray.push_back(Vec4f(0,0,0,0)); vertexArray.push_back(epos); // compute intermediate points to curve along projection distortions int segments = 10; for (int i=1; i<segments; i++) { Vec3d posi = posInternal; posi[2] = posTrain[2] + i*(position[2] - posTrain[2])/segments; posi.transfo4d(viewMatrix); posi = core->j2000ToAltAz(posi); posi[2] -= EARTH_RADIUS; posi/=1216; colorArray.push_back(Vec4f(1,1,1,i*tmag/segments)); vertexArray.push_back(posi); } // first point - light colorArray.push_back(Vec4f(1,1,1,tmag)); vertexArray.push_back(spos); sPainter.setColorPointer(4, GL_FLOAT, colorArray.constData()); sPainter.setVertexPointer(3, GL_DOUBLE, vertexArray.constData()); sPainter.enableClientStates(true, false, true); sPainter.drawFromArray(StelPainter::LineStrip, vertexArray.size(), 0, true); sPainter.enableClientStates(false); }
// Draw the names of all the constellations void ConstellationMgr::drawNames(StelPainter& sPainter) const { glEnable(GL_BLEND); sPainter.enableTexture2d(true); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); vector < Constellation * >::const_iterator iter; for (iter = asterisms.begin(); iter != asterisms.end(); iter++) { // Check if in the field of view if (sPainter.getProjector()->projectCheck((*iter)->XYZname, (*iter)->XYname)) (*iter)->drawName(sPainter); } }
// Draw constellations art textures void ConstellationMgr::drawArt(StelPainter& sPainter) const { glBlendFunc(GL_ONE, GL_ONE); sPainter.enableTexture2d(true); glEnable(GL_BLEND); glEnable(GL_CULL_FACE); vector < Constellation * >::const_iterator iter; SphericalRegionP region = sPainter.getProjector()->getViewportConvexPolygon(); for (iter = asterisms.begin(); iter != asterisms.end(); ++iter) { (*iter)->drawArtOptim(sPainter, *region); } glDisable(GL_CULL_FACE); }
void TleTraj::draw(const StelCore *core, StelPainter& painter) { Vec3d pos; satd2StelCoord(curData, pos); XYZ = core->altAzToJ2000(pos); Vec3d xy; if (painter.getProjector()->project(pos, xy)) { glEnable(GL_TEXTURE_2D); glColor3f(orbitColor->redF(), orbitColor->greenF(), orbitColor->blueF()); hintTexture->bind(); painter.drawSprite2dMode(xy[0], xy[1], 16); glDisable(GL_TEXTURE_2D); drawOrbit(painter); } }
void Constellation::drawArtOptim(StelPainter& sPainter, const SphericalRegion& region) const { if (checkVisibility()) { const float intensity = artFader.getInterstate(); if (artTexture && intensity && region.intersects(boundingCap)) { sPainter.setColor(intensity,intensity,intensity); // The texture is not fully loaded if (artTexture->bind()==false) return; sPainter.drawStelVertexArray(artPolygon); } } }
void NebulaMgr::drawPointer(const StelCore* core, StelPainter& sPainter) { const StelProjectorP prj = core->getProjection(StelCore::FrameJ2000); const QList<StelObjectP> newSelected = GETSTELMODULE(StelObjectMgr)->getSelectedObject("Nebula"); if (!newSelected.empty()) { const StelObjectP obj = newSelected[0]; Vec3d pos=obj->getJ2000EquatorialPos(core); // Compute 2D pos and return if outside screen if (!prj->projectInPlace(pos)) return; if (StelApp::getInstance().getVisionModeNight()) sPainter.setColor(0.8f,0.0f,0.0f); else sPainter.setColor(0.4f,0.5f,0.8f); texPointer->bind(); sPainter.enableTexture2d(true); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Normal transparency mode // Size on screen float size = obj->getAngularSize(core)*M_PI/180.*prj->getPixelPerRadAtCenter(); size+=20.f + 10.f*std::sin(2.f * StelApp::getInstance().getTotalRunTime()); sPainter.drawSprite2dMode(pos[0]-size/2, pos[1]-size/2, 10, 90); sPainter.drawSprite2dMode(pos[0]-size/2, pos[1]+size/2, 10, 0); sPainter.drawSprite2dMode(pos[0]+size/2, pos[1]+size/2, 10, -90); sPainter.drawSprite2dMode(pos[0]+size/2, pos[1]-size/2, 10, -180); } }
void Nebula::drawHints(StelPainter& sPainter, float maxMagHints) { float lim = mag; if (lim > 50) lim = 15.f; // temporary workaround of this bug: https://bugs.launchpad.net/stellarium/+bug/1115035 --AW if (getEnglishName().contains("Pleiades")) lim = 5.f; if (lim>maxMagHints) return; glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); float lum = 1.f;//qMin(1,4.f/getOnScreenSize(core))*0.8; Vec3f col(circleColor[0]*lum*hintsBrightness, circleColor[1]*lum*hintsBrightness, circleColor[2]*lum*hintsBrightness); sPainter.setColor(col[0], col[1], col[2], 1); switch (nType) { case NebGx: Nebula::texGalaxy->bind(); break; case NebOc: Nebula::texOpenCluster->bind(); break; case NebGc: Nebula::texGlobularCluster->bind(); break; case NebN: Nebula::texDiffuseNebula->bind(); break; case NebPn: Nebula::texPlanetaryNebula->bind(); break; case NebCn: Nebula::texOpenClusterWithNebulosity->bind(); break; default: Nebula::texCircle->bind(); } sPainter.drawSprite2dMode(XY[0], XY[1], 6); }
void ConstellationMgr::drawBoundaries(StelPainter& sPainter) const { sPainter.enableTexture2d(false); glDisable(GL_BLEND); vector < Constellation * >::const_iterator iter; for (iter = asterisms.begin(); iter != asterisms.end(); ++iter) { (*iter)->drawBoundaryOptim(sPainter); } }
void Constellation::drawOptim(StelPainter& sPainter, const StelCore* core, const SphericalCap& viewportHalfspace) const { if (lineFader.getInterstate()<=0.0001f) return; if (checkVisibility()) { sPainter.setColor(lineColor[0], lineColor[1], lineColor[2], lineFader.getInterstate()); Vec3d star1; Vec3d star2; for (unsigned int i=0;i<numberOfSegments;++i) { star1=asterism[2*i]->getJ2000EquatorialPos(core); star2=asterism[2*i+1]->getJ2000EquatorialPos(core); star1.normalize(); star2.normalize(); sPainter.drawGreatCircleArc(star1, star2, &viewportHalfspace); } } }
void Galaxy::draw(StelCore* core, StelPainter& painter, float) { StelSkyDrawer* sd = core->getSkyDrawer(); Vec3f color = Vec3f(0.4f,0.5f,1.2f); if (StelApp::getInstance().getVisionModeNight()) color = StelUtils::getNightColor(color); double mag = getVMagnitude(core, true); StelUtils::spheToRect(RA, DE, XYZ); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glEnable(GL_TEXTURE_2D); painter.setColor(color[0], color[1], color[2], Galaxy::galaxyBrightness); glColor4f(color[0],color[1],color[2], Galaxy::galaxyBrightness); if (mag <= sd->getLimitMagnitude()) { Galaxy::markerTexture->bind(); float size = getAngularSize(NULL)*M_PI/180.*painter.getProjector()->getPixelPerRadAtCenter(); float shift = 5.f + size/1.6f; if (GETSTELMODULE(POGS)->getDisplayMode()) { painter.drawSprite2dMode(XYZ, 6); painter.drawText(XYZ, " ", 0, shift, shift, false); } else { painter.drawSprite2dMode(XYZ, 6); painter.drawText(XYZ, designation, 0, shift, shift, false); } } }
void Pulsars::drawPointer(StelCore* core, StelPainter& painter) { const StelProjectorP prj = core->getProjection(StelCore::FrameJ2000); const QList<StelObjectP> newSelected = GETSTELMODULE(StelObjectMgr)->getSelectedObject("Pulsar"); if (!newSelected.empty()) { const StelObjectP obj = newSelected[0]; Vec3d pos=obj->getJ2000EquatorialPos(core); Vec3d screenpos; // Compute 2D pos and return if outside screen if (!painter.getProjector()->project(pos, screenpos)) return; const Vec3f& c(obj->getInfoColor()); painter.setColor(c[0],c[1],c[2]); texPointer->bind(); painter.setBlending(true); painter.drawSprite2dMode(screenpos[0], screenpos[1], 13.f, StelApp::getInstance().getTotalRunTime()*40.); } }
void Novae::drawPointer(StelCore* core, StelPainter &painter) { const QList<StelObjectP> newSelected = GETSTELMODULE(StelObjectMgr)->getSelectedObject("Nova"); if (!newSelected.empty()) { const StelObjectP obj = newSelected[0]; Vec3d pos=obj->getJ2000EquatorialPos(core); Vec3d screenpos; // Compute 2D pos and return if outside screen if (!painter.getProjector()->project(pos, screenpos)) return; const Vec3f& c(obj->getInfoColor()); painter.setColor(c[0],c[1],c[2]); texPointer->bind(); painter.enableTexture2d(true); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Normal transparency mode painter.drawSprite2dMode(screenpos[0], screenpos[1], 13.f, StelApp::getInstance().getTotalRunTime()*40.); } }
void Constellation::drawBoundaryOptim(StelPainter& sPainter) const { if (!boundaryFader.getInterstate()) return; sPainter.enableTexture2d(false); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Normal transparency mode sPainter.setColor(boundaryColor[0], boundaryColor[1], boundaryColor[2], boundaryFader.getInterstate()); unsigned int i, j; size_t size; Vec3f pt1, pt2; Vec3d ptd1, ptd2; std::vector<Vec3f> *points; if (singleSelected) size = isolatedBoundarySegments.size(); else size = sharedBoundarySegments.size(); const SphericalCap& viewportHalfspace = sPainter.getProjector()->getBoundingCap(); for (i=0;i<size;i++) { if (singleSelected) points = isolatedBoundarySegments[i]; else points = sharedBoundarySegments[i]; for (j=0;j<points->size()-1;j++) { pt1 = points->at(j); pt2 = points->at(j+1); if (pt1*pt2>0.9999999f) continue; ptd1.set(pt1[0], pt1[1], pt1[2]); ptd2.set(pt2[0], pt2[1], pt2[2]); sPainter.drawGreatCircleArc(ptd1, ptd2, &viewportHalfspace); } } }
void Quasar::draw(StelCore* core, StelPainter& painter) { StelSkyDrawer* sd = core->getSkyDrawer(); Vec3f color = sd->indexToColor(BvToColorIndex(bV))*0.75f; Vec3f dcolor = Vec3f(1.2f,0.5f,0.4f); if (StelApp::getInstance().getVisionModeNight()) dcolor = StelUtils::getNightColor(dcolor); float rcMag[2], size, shift; double mag; StelUtils::spheToRect(qRA, qDE, XYZ); mag = getVMagnitude(core, true); if (GETSTELMODULE(Quasars)->getDisplayMode()) { glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); painter.setColor(dcolor[0], dcolor[1], dcolor[2], 1); Quasar::markerTexture->bind(); size = getAngularSize(NULL)*M_PI/180.*painter.getProjector()->getPixelPerRadAtCenter(); shift = 5.f + size/1.6f; if (labelsFader.getInterstate()<=0.f) { painter.drawSprite2dMode(XYZ, 4); painter.drawText(XYZ, " ", 0, shift, shift, false); } } else { sd->preDrawPointSource(&painter); if (mag <= sd->getLimitMagnitude()) { sd->computeRCMag(mag, rcMag); //sd->drawPointSource(&painter, Vec3f(XYZ[0], XYZ[1], XYZ[2]), rcMag, sd->indexToColor(BvToColorIndex(bV)), false); sd->drawPointSource(&painter, XYZ, rcMag, sd->indexToColor(BvToColorIndex(bV)), false); painter.setColor(color[0], color[1], color[2], 1); size = getAngularSize(NULL)*M_PI/180.*painter.getProjector()->getPixelPerRadAtCenter(); shift = 6.f + size/1.8f; if (labelsFader.getInterstate()<=0.f) { painter.drawText(XYZ, designation, 0, shift, shift, false); } } sd->postDrawPointSource(&painter); } }
void ConstellationMgr::drawBoundaries(StelPainter& sPainter) const { sPainter.enableTexture2d(false); glDisable(GL_BLEND); #ifndef USE_OPENGL_ES2 glLineStipple(2, 0x3333); glEnable(GL_LINE_STIPPLE); #endif vector < Constellation * >::const_iterator iter; for (iter = asterisms.begin(); iter != asterisms.end(); ++iter) { (*iter)->drawBoundaryOptim(sPainter); } #ifndef USE_OPENGL_ES2 glDisable(GL_LINE_STIPPLE); #endif }
void Comet::drawTail(StelCore* core, StelProjector::ModelViewTranformP transfo, bool gas) { // Find rotation matrix from 0/0/1 to eclipticPosition: crossproduct for axis (normal vector), dotproduct for angle. Vec3d eclposNrm=eclipticPos; eclposNrm.normalize(); Mat4d tailrot=Mat4d::rotation(Vec3d(0.0, 0.0, 1.0)^(eclposNrm), std::acos(Vec3d(0.0, 0.0, 1.0).dot(eclposNrm)) ); StelProjector::ModelViewTranformP transfo2 = transfo->clone(); transfo2->combine(tailrot); if (!gas) { CometOrbit* orbit=(CometOrbit*)userDataPtr; Vec3d velocity=orbit->getVelocity(); // [AU/d] // This was a try to rotate a straight parabola somewhat away from the antisolar direction. //Mat4d dustTailRot=Mat4d::rotation(eclposNrm^(-velocity), 0.15f*std::acos(eclposNrm.dot(-velocity))); // GZ: This scale factor of 0.15 is empirical from photos of Halley and Hale-Bopp. // The curved tail is curved towards positive X. We first rotate around the Z axis into a direction opposite of the motion vector, then again the antisolar rotation applies. Mat4d dustTailRot=Mat4d::zrotation(atan2(velocity[1], velocity[0]) + M_PI); transfo2->combine(dustTailRot); // In addition, we let the dust tail already start with a light tilt. Mat4d dustTailYrot=Mat4d::yrotation(5.0f*velocity.length()); // again, this is pretty ad-hoc, feel free to improve! transfo2->combine(dustTailYrot); } StelPainter* sPainter = new StelPainter(core->getProjection(transfo2)); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); glDisable(GL_CULL_FACE); // GZ: If we use getVMagnitudeWithExtinction(), a head extincted in the horizon mist can completely hide an otherwise frighteningly long tail. // we must use unextincted mag, but mix/dim with atmosphere/sky brightness. // In addition, light falloff is a bit reduced for better visibility. Power basis should be 0.4, we use 0.6. //float magfactor=std::pow(0.4f , getVMagnitudeWithExtinction(core)); float magFactor=std::pow(0.6f , getVMagnitude(core)); if (core->getSkyDrawer()->getFlagHasAtmosphere()) { // Mix with sky brightness and light pollution: This is very ad-hoc, if someone finds a better solution, please go ahead! // Light pollution: float bortleIndexFactor=0.1f * (11 - core->getSkyDrawer()->getBortleScaleIndex()); magFactor*= bortleIndexFactor*bortleIndexFactor; // GZ-Guesstimate for light pollution influence // sky brightness: This is about 10 for twilight where bright comet tails should already be visible. Dark night is close to 0. float avgAtmLum=GETSTELMODULE(LandscapeMgr)->getAtmosphereAverageLuminance(); float atmLumFactor=(15.0f-avgAtmLum)/15.0f; if (atmLumFactor<0.05f) atmLumFactor=0.05f; //atmLumFactor=std::sqrt(atmLumFactor); magFactor*=atmLumFactor*atmLumFactor; } magFactor*=(gas? 0.9 : dustTailBrightnessFactor); // TBD: empirical adjustment for texture brightness. magFactor=qMin(magFactor, 1.05f); // Limit excessively bright display. gasTailTexture->bind(); if (gas) { //gasTailTexture->bind(); sPainter->setColor(0.15f*magFactor,0.15f*magFactor,0.6f*magFactor); sPainter->setArrays((Vec3d*)gastailVertexArr.constData(), (Vec2f*)gastailTexCoordArr.constData()); sPainter->drawFromArray(StelPainter::Triangles, gastailIndices.size(), 0, true, gastailIndices.constData()); } else { //dustTailTexture->bind(); sPainter->setColor(magFactor, magFactor,0.6f*magFactor); //sPainter->setArrays((Vec3d*)dusttailVertexArr.constData(), (Vec2f*)dusttailTexCoordArr.constData()); //sPainter->drawFromArray(StelPainter::Triangles, dusttailIndices.size(), 0, true, dusttailIndices.constData()); sPainter->setArrays((Vec3d*)dusttailVertexArr.constData(), (Vec2f*)gastailTexCoordArr.constData()); sPainter->drawFromArray(StelPainter::Triangles, gastailIndices.size(), 0, true, gastailIndices.constData()); } glDisable(GL_BLEND); if (sPainter) delete sPainter; sPainter=NULL; }
bool SkyLabel::draw(StelCore* core, StelPainter& sPainter) { if(labelFader.getInterstate() <= 0.0) return false; Vec3d objectPos = labelObject->getJ2000EquatorialPos(core); Vec3d labelXY; sPainter.getProjector()->project(objectPos,labelXY); sPainter.setFont(labelFont); double xOffset(0.); double yOffset(0.); char hJustify = 'c'; char vJustify = 'c'; if (labelSide.toUpper().contains("N")) { yOffset = 1.0; vJustify = 'b'; // bottom justify text } else if (labelSide.toUpper().contains("S")) { yOffset = -1.0; vJustify = 't'; // top justufy text } if (labelSide.toUpper().contains("E")) { xOffset = 1.0; hJustify = 'l'; // right justify text } else if (labelSide.toUpper().contains("W")) { xOffset = -1.0; hJustify = 'r'; // left justify text } if (labelDistance >= 0.0) { xOffset *= labelDistance; yOffset *= labelDistance; } else { float shift = 4.f + labelObject->getAngularSize(core)*M_PI/180.*sPainter.getProjector()->getPixelPerRadAtCenter()/1.8f; // use the object size xOffset *= shift; yOffset *= shift; } double jxOffset(0.); double jyOffset(0.); if (hJustify == 'r') jxOffset = sPainter.getFontMetrics().width(labelText); else if (hJustify == 'c') jxOffset = sPainter.getFontMetrics().width(labelText) / 2.; if (vJustify == 't') jyOffset = sPainter.getFontMetrics().height(); else if (vJustify == 'c') jyOffset = sPainter.getFontMetrics().height() / 2.; sPainter.setColor(labelColor[0], labelColor[1], labelColor[2], labelFader.getInterstate()); sPainter.drawText(labelXY[0]+xOffset-jxOffset, labelXY[1]+yOffset-jyOffset, labelText, 0, 0, 0, false); if (labelStyle == SkyLabel::Line) { sPainter.enableTexture2d(false); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // screen coordinates of object Vec3d objXY; sPainter.getProjector()->project(objectPos,objXY); double lineEndX = labelXY[0]+xOffset; double lineEndY = labelXY[1]+yOffset; if (vJustify == 'b') lineEndY -= 5; else if (vJustify == 't') lineEndY += 5; if (hJustify == 'l') lineEndX -= 5; else if (hJustify == 'r') lineEndX += 5; sPainter.setColor(labelColor[0], labelColor[1], labelColor[2], labelFader.getInterstate()); sPainter.drawLine2d(lineEndX,lineEndY,objXY[0], objXY[1]); } return true; }
void Nebula::drawLabel(StelPainter& sPainter, float maxMagLabel) { float lim = mag; if (lim > 50) lim = 15.f; // temporary workaround of this bug: https://bugs.launchpad.net/stellarium/+bug/1115035 --AW if (getEnglishName().contains("Pleiades")) lim = 5.f; // Dark nebulae. Not sure how to assess visibility from opacity? --GZ if (nType==NebDn) { // GZ: ad-hoc visibility formula: assuming good visibility if objects of mag9 are visible, "usual" opacity 5 and size 30', better visibility (discernability) comes with higher opacity and larger size, // 9-(opac-5)-2*(angularSize-0.5) if (angularSize>0 && mag<50) lim = 15.0f - mag - 2.0f*angularSize; else lim = 9.0f; } else if (nType==NebHII || nType==NebHa) lim=9.0f; if (lim>maxMagLabel) return; Vec3d win; // Check visibility of DSO labels if (!(sPainter.getProjector()->projectCheck(XYZ, win))) return; Vec3f col(labelColor[0], labelColor[1], labelColor[2]); sPainter.setColor(col[0], col[1], col[2], hintsBrightness); float size = getAngularSize(NULL)*M_PI/180.*sPainter.getProjector()->getPixelPerRadAtCenter(); float shift = 4.f + (drawHintProportional ? size : size/1.8f); QString str; if (!nameI18.isEmpty()) str = getNameI18n(); else { // On screen label: one only, priority as given here. NGC should win over Sharpless. (GZ) if (M_nb > 0) str = QString("M %1").arg(M_nb); else if (C_nb > 0) str = QString("C %1").arg(C_nb); else if (NGC_nb > 0) str = QString("NGC %1").arg(NGC_nb); else if (IC_nb > 0) str = QString("IC %1").arg(IC_nb); else if (B_nb > 0) str = QString("B %1").arg(B_nb); else if (Sh2_nb > 0) str = QString("Sh 2-%1").arg(Sh2_nb); else if (VdB_nb > 0) str = QString("VdB %1").arg(VdB_nb); else if (RCW_nb > 0) str = QString("RCW %1").arg(RCW_nb); else if (LDN_nb > 0) str = QString("LDN %1").arg(LDN_nb); else if (LBN_nb > 0) str = QString("LBN %1").arg(LBN_nb); else if (Cr_nb > 0) str = QString("Cr %1").arg(Cr_nb); else if (Mel_nb > 0) str = QString("Mel %1").arg(Mel_nb); } sPainter.drawText(XY[0]+shift, XY[1]+shift, str, 0, 0, 0, false); }
// returns true if visible // Assumes that we are in local frame void Meteor::draw(const StelCore* core, StelPainter& sPainter) { if (!alive) return; const StelProjectorP proj = sPainter.getProjector(); Vec3d spos = position; Vec3d epos = posTrain; // convert to equ spos.transfo4d(mmat); epos.transfo4d(mmat); // convert to local and correct for earth radius [since equ and local coordinates in stellarium use same 0 point!] spos = core->equinoxEquToAltAz( spos ); epos = core->equinoxEquToAltAz( epos ); spos[2] -= EARTH_RADIUS; epos[2] -= EARTH_RADIUS; // 1216 is to scale down under 1 for desktop version spos/=1216; epos/=1216; // qDebug("[%f %f %f] (%d, %d) (%d, %d)\n", position[0], position[1], position[2], (int)start[0], (int)start[1], (int)end[0], (int)end[1]); if (train) { // connect this point with last drawn point double tmag = mag*distMultiplier; // compute an intermediate point so can curve slightly along projection distortions Vec3d posi = posInternal; posi[2] = position[2] + (posTrain[2] - position[2])/2; posi.transfo4d(mmat); posi = core->equinoxEquToAltAz( posi ); posi[2] -= EARTH_RADIUS; posi/=1216; // draw dark to light Vec4f colorArray[3]; colorArray[0].set(0,0,0,0); colorArray[1].set(1,1,1,tmag*0.5); colorArray[2].set(1,1,1,tmag); Vec3d vertexArray[3]; vertexArray[0]=epos; vertexArray[1]=posi; vertexArray[2]=spos; sPainter.setColorPointer(4, GL_FLOAT, colorArray); sPainter.setVertexPointer(3, GL_DOUBLE, vertexArray); // TODO the crash doesn't appear when the last true is set to false sPainter.enableClientStates(true, false, true); sPainter.drawFromArray(StelPainter::LineStrip, 3, 0, true); sPainter.enableClientStates(false); } else { sPainter.setPointSize(1.f); Vec3d start; proj->project(spos, start); sPainter.drawPoint2d(start[0],start[1]); } train = 1; }
void Nebula::drawHints(StelPainter& sPainter, float maxMagHints) { float lim = mag; if (lim > 50) lim = 15.f; // temporary workaround of this bug: https://bugs.launchpad.net/stellarium/+bug/1115035 --AW if (getEnglishName().contains("Pleiades")) lim = 5.f; // Dark nebulae. Not sure how to assess visibility from opacity? --GZ if (nType==NebDn) { // GZ: ad-hoc visibility formula: assuming good visibility if objects of mag9 are visible, "usual" opacity 5 and size 30', better visibility (discernability) comes with higher opacity and larger size, // 9-(opac-5)-2*(angularSize-0.5) if (angularSize>0 && mag<50) lim = 15.0f - mag - 2.0f*angularSize; else lim = 9.0f; } else if (nType==NebHII || nType==NebHa) { // artificially increase visibility of (most) Sharpless objects? No magnitude recorded:-( lim=9.0f; } if (lim>maxMagHints) return; Vec3d win; // Check visibility of DSO hints if (!(sPainter.getProjector()->projectCheck(XYZ, win))) return; glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); float lum = 1.f;//qMin(1,4.f/getOnScreenSize(core))*0.8; Vec3f col(circleColor[0]*lum*hintsBrightness, circleColor[1]*lum*hintsBrightness, circleColor[2]*lum*hintsBrightness); sPainter.setColor(col[0], col[1], col[2], 1); switch (nType) { case NebGx: Nebula::texGalaxy->bind(); break; case NebOc: Nebula::texOpenCluster->bind(); break; case NebGc: Nebula::texGlobularCluster->bind(); break; case NebN: case NebHII: case NebRn: Nebula::texDiffuseNebula->bind(); break; case NebPn: Nebula::texPlanetaryNebula->bind(); break; case NebDn: Nebula::texDarkNebula->bind(); break; case NebCn: Nebula::texOpenClusterWithNebulosity->bind(); break; default: Nebula::texCircle->bind(); } if (drawHintProportional) { float size = getAngularSize(NULL)*M_PI/180.*sPainter.getProjector()->getPixelPerRadAtCenter(); sPainter.drawSprite2dMode(XY[0], XY[1], qMax(6.0f,size)); } else sPainter.drawSprite2dMode(XY[0], XY[1], 6.0f); }