StelSkyDrawer.cpp   StelSkyDrawer.cpp 
skipping to change at line 20 skipping to change at line 20
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
*/ */
#ifndef GL_POINT_SPRITE
#define GL_POINT_SPRITE 0x8861
#endif
#ifndef GL_VERTEX_PROGRAM_POINT_SIZE
#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642
#endif
#include "StelSkyDrawer.hpp" #include "StelSkyDrawer.hpp"
#include "StelProjector.hpp" #include "StelProjector.hpp"
#include "StelFileMgr.hpp"
#include "StelToneReproducer.hpp" #include "StelToneReproducer.hpp"
#include "renderer/StelTextureNew.hpp" #include "StelTextureMgr.hpp"
#include "renderer/StelRenderer.hpp"
#include "StelApp.hpp" #include "StelApp.hpp"
#include "StelCore.hpp" #include "StelCore.hpp"
#include "StelUtils.hpp" #include "StelUtils.hpp"
#include "StelMovementMgr.hpp" #include "StelMovementMgr.hpp"
#include "StelPainter.hpp"
#include <QOpenGLContext>
#include <QOpenGLShaderProgram>
#include <QStringList> #include <QStringList>
#include <QSettings> #include <QSettings>
#include <QDebug> #include <QDebug>
#include <QtGlobal> #include <QtGlobal>
// The 0.025 corresponds to the maximum eye resolution in degree // The 0.025 corresponds to the maximum eye resolution in degree
#define EYE_RESOLUTION (0.25f) #define EYE_RESOLUTION (0.25f)
#define MAX_LINEAR_RADIUS (8.f) #define MAX_LINEAR_RADIUS 8.f
StelSkyDrawer::StelSkyDrawer(StelCore* acore, StelRenderer* renderer)
: core(acore)
, renderer(renderer)
, texHalo(NULL)
, starPointBuffer(NULL)
, starSpriteBuffer(NULL)
, drawing(false)
, texBigHalo(NULL)
, texSunHalo(NULL)
, texCorona(NULL)
, statisticsInitialized(false)
, bigHaloStatID(-1)
, sunHaloStatID(-1)
, starStatID(-1)
{
eye = core->getToneReproducer();
inScale = 1.f;
bortleScaleIndex = 3;
limitMagnitude = -100.f;
limitLuminance = 0;
oldLum=-1.f;
maxLum = 0.f;
setMaxAdaptFov(180.f);
setMinAdaptFov(0.1f);
starAbsoluteScaleF = 1.f;
starRelativeScale = 1.f;
starLinearScale = 19.569f;
big3dModelHaloRadius = 150.f;
StelSkyDrawer::StelSkyDrawer(StelCore* acore) :
core(acore),
eye(acore->getToneReproducer()),
maxAdaptFov(180.f),
minAdaptFov(0.1f),
lnfovFactor(0.f),
starRelativeScale(1.f),
starAbsoluteScaleF(1.f),
starLinearScale(19.569f),
limitMagnitude(-100.f),
limitLuminance(0.f),
bortleScaleIndex(3),
inScale(1.f),
starShaderProgram(NULL),
starShaderVars(StarShaderVars()),
maxLum(0.f),
oldLum(-1.f),
big3dModelHaloRadius(150.f)
{
QSettings* conf = StelApp::getInstance().getSettings(); QSettings* conf = StelApp::getInstance().getSettings();
initColorTableFromConfigFile(conf); initColorTableFromConfigFile(conf);
setFlagHasAtmosphere(conf->value("landscape/flag_atmosphere", true). toBool()); setFlagHasAtmosphere(conf->value("landscape/flag_atmosphere", true). toBool());
setTwinkleAmount(conf->value("stars/star_twinkle_amount",0.3).toFloa t()); setTwinkleAmount(conf->value("stars/star_twinkle_amount",0.3).toFloa t());
setFlagTwinkle(conf->value("stars/flag_star_twinkle",true).toBool()) ; setFlagTwinkle(conf->value("stars/flag_star_twinkle",true).toBool()) ;
setDrawStarsAsPoints(conf->value("stars/flag_point_star",false).toBo ol());
setMaxAdaptFov(conf->value("stars/mag_converter_max_fov",70.0).toFlo at()); setMaxAdaptFov(conf->value("stars/mag_converter_max_fov",70.0).toFlo at());
setMinAdaptFov(conf->value("stars/mag_converter_min_fov",0.1).toFloa t()); setMinAdaptFov(conf->value("stars/mag_converter_min_fov",0.1).toFloa t());
setFlagLuminanceAdaptation(conf->value("viewing/use_luminance_adapta tion",true).toBool()); setFlagLuminanceAdaptation(conf->value("viewing/use_luminance_adapta tion",true).toBool());
setFlagStarMagnitudeLimit((conf->value("astro/flag_star_magnitude_li mit", false).toBool())); setFlagStarMagnitudeLimit((conf->value("astro/flag_star_magnitude_li mit", false).toBool()));
setCustomStarMagnitudeLimit(conf->value("astro/star_magnitude_limit" , 6.5).toFloat()); setCustomStarMagnitudeLimit(conf->value("astro/star_magnitude_limit" , 6.5).toFloat());
setFlagNebulaMagnitudeLimit((conf->value("astro/flag_nebula_magnitud e_limit", false).toBool())); setFlagNebulaMagnitudeLimit((conf->value("astro/flag_nebula_magnitud e_limit", false).toBool()));
setCustomNebulaMagnitudeLimit(conf->value("astro/nebula_magnitude_li mit", 8.5).toFloat()); setCustomNebulaMagnitudeLimit(conf->value("astro/nebula_magnitude_li mit", 8.5).toFloat());
// qDebug() << "drawer: clampStellarMag: " << clampStellarMagnitude << " , clampDSOmagnitude: " << clampDSOMagnitude; // qDebug() << "drawer: clampStellarMag: " << clampStellarMagnitude << " , clampDSOmagnitude: " << clampDSOMagnitude;
bool ok=true; bool ok=true;
setBortleScale(conf->value("stars/init_bortle_scale",3).toInt(&ok)); setBortleScaleIndex(conf->value("stars/init_bortle_scale",2).toInt(& ok));
if (!ok) if (!ok)
{ setBortleScaleIndex(2);
conf->setValue("stars/init_bortle_scale",3);
setBortleScale(3);
ok = true;
}
setRelativeStarScale(conf->value("stars/relative_scale",1.0).toFloat (&ok)); setRelativeStarScale(conf->value("stars/relative_scale",1.0).toFloat (&ok));
if (!ok) if (!ok)
{
conf->setValue("stars/relative_scale",1.0);
setRelativeStarScale(1.0); setRelativeStarScale(1.0);
ok = true;
}
setAbsoluteStarScale(conf->value("stars/absolute_scale",1.0).toFloat (&ok)); setAbsoluteStarScale(conf->value("stars/absolute_scale",1.0).toFloat (&ok));
if (!ok) if (!ok)
{
conf->setValue("stars/absolute_scale",1.0);
setAbsoluteStarScale(1.0); setAbsoluteStarScale(1.0);
ok = true;
}
//GZ: load 3 values from config. setExtinctionCoefficient(conf->value("landscape/atmospheric_extincti
setExtinctionCoefficient(conf->value("landscape/atmospheric_extincti on_coefficient",0.13).toDouble(&ok));
on_coefficient",0.2).toDouble(&ok));
if (!ok) if (!ok)
{
conf->setValue("landscape/atmospheric_extinction_coefficient
",0.2);
setExtinctionCoefficient(0.2); setExtinctionCoefficient(0.2);
ok = true;
} const QString extinctionMode = conf->value("astro/extinction_mode_be
low_horizon", "zero").toString();
// zero by default
if (extinctionMode=="mirror")
extinction.setUndergroundExtinctionMode(Extinction::Undergro
undExtinctionMirror);
else if (extinctionMode=="max")
extinction.setUndergroundExtinctionMode(Extinction::Undergro
undExtinctionMax);
setAtmosphereTemperature(conf->value("landscape/temperature_C",15.0) .toDouble(&ok)); setAtmosphereTemperature(conf->value("landscape/temperature_C",15.0) .toDouble(&ok));
if (!ok) if (!ok)
{
conf->setValue("landscape/temperature_C",15);
setAtmosphereTemperature(15.0); setAtmosphereTemperature(15.0);
ok = true;
}
setAtmospherePressure(conf->value("landscape/pressure_mbar",1013.0). toDouble(&ok)); setAtmospherePressure(conf->value("landscape/pressure_mbar",1013.0). toDouble(&ok));
if (!ok) if (!ok)
{
conf->setValue("landscape/pressure_mbar",1013.0);
setAtmospherePressure(1013.0); setAtmospherePressure(1013.0);
ok = true;
}
starPointBuffer = renderer->createVertexBuffer<ColoredVertex>(Prim // Initialize buffers for use by gl vertex array
itiveType_Points); nbPointSources = 0;
starSpriteBuffer = renderer->createVertexBuffer<ColoredTexturedVert maxPointSources = 1000;
ex>(PrimitiveType_Triangles);
bigHaloBuffer = renderer->createVertexBuffer<ColoredTexturedVert vertexArray = new StarVertex[maxPointSources*6];
ex>(PrimitiveType_Triangles);
sunHaloBuffer = renderer->createVertexBuffer<ColoredTexturedVert textureCoordArray = new unsigned char[maxPointSources*6*2];
ex>(PrimitiveType_Triangles); for (unsigned int i=0;i<maxPointSources; ++i)
coronaBuffer = renderer->createVertexBuffer<ColoredTexturedVert {
ex>(PrimitiveType_Triangles); static const unsigned char texElems[] = {0, 0, 255, 0, 255,
255, 0, 0, 255, 255, 0, 255};
unsigned char* elem = &textureCoordArray[i*6*2];
memcpy(elem, texElems, 12);
}
} }
StelSkyDrawer::~StelSkyDrawer() StelSkyDrawer::~StelSkyDrawer()
{ {
if(NULL != starPointBuffer) {delete starPointBuffer;} delete[] vertexArray;
if(NULL != starSpriteBuffer) {delete starSpriteBuffer;} vertexArray = NULL;
if(NULL != bigHaloBuffer) {delete bigHaloBuffer;} delete[] textureCoordArray;
if(NULL != sunHaloBuffer) {delete sunHaloBuffer;} textureCoordArray = NULL;
if(NULL != coronaBuffer) {delete coronaBuffer;}
if(NULL != texBigHalo) {delete texBigHalo;} delete starShaderProgram;
if(NULL != texSunHalo) {delete texSunHalo;} starShaderProgram = NULL;
if(NULL != texHalo) {delete texHalo;}
if(NULL != texCorona) {delete texCorona;}
} }
// Init parameters from config file // Init parameters from config file
void StelSkyDrawer::init() void StelSkyDrawer::init()
{ {
// Load star texture no mipmap: // Load star texture no mipmap:
texHalo = renderer->createTexture("textures/star16x16.png"); texHalo = StelApp::getInstance().getTextureManager().createTexture(S
texBigHalo = renderer->createTexture("textures/haloLune.png"); telFileMgr::getInstallationDir()+"/textures/star16x16.png");
texSunHalo = renderer->createTexture("textures/halo.png"); texBigHalo = StelApp::getInstance().getTextureManager().createTextur
texCorona = renderer->createTexture("textures/corona.png"); e(StelFileMgr::getInstallationDir()+"/textures/haloLune.png");
texSunHalo = StelApp::getInstance().getTextureManager().createTextur
e(StelFileMgr::getInstallationDir()+"/textures/halo.png");
// Create shader program
QOpenGLShader vshader(QOpenGLShader::Vertex);
const char *vsrc =
"attribute mediump vec2 pos;\n"
"attribute mediump vec2 texCoord;\n"
"attribute mediump vec3 color;\n"
"uniform mediump mat4 projectionMatrix;\n"
"varying mediump vec2 texc;\n"
"varying mediump vec3 outColor;\n"
"void main(void)\n"
"{\n"
" gl_Position = projectionMatrix * vec4(pos.x, pos.y, 0,
1);\n"
" texc = texCoord;\n"
" outColor = color;\n"
"}\n";
vshader.compileSourceCode(vsrc);
if (!vshader.log().isEmpty()) { qWarning() << "StelSkyDrawer::init()
: Warnings while compiling vshader: " << vshader.log(); }
QOpenGLShader fshader(QOpenGLShader::Fragment);
const char *fsrc =
"varying mediump vec2 texc;\n"
"varying mediump vec3 outColor;\n"
"uniform sampler2D tex;\n"
"void main(void)\n"
"{\n"
" gl_FragColor = texture2D(tex, texc)*vec4(outColor, 1.);
\n"
"}\n";
fshader.compileSourceCode(fsrc);
if (!fshader.log().isEmpty()) { qWarning() << "StelSkyDrawer::init()
: Warnings while compiling fshader: " << fshader.log(); }
starShaderProgram = new QOpenGLShaderProgram(QOpenGLContext::current
Context());
starShaderProgram->addShader(&vshader);
starShaderProgram->addShader(&fshader);
StelPainter::linkProg(starShaderProgram, "starShader");
starShaderVars.projectionMatrix = starShaderProgram->uniformLocation
("projectionMatrix");
starShaderVars.texCoord = starShaderProgram->attributeLocation("texC
oord");
starShaderVars.pos = starShaderProgram->attributeLocation("pos");
starShaderVars.color = starShaderProgram->attributeLocation("color")
;
starShaderVars.texture = starShaderProgram->uniformLocation("tex");
update(0); update(0);
} }
void StelSkyDrawer::update(double) void StelSkyDrawer::update(double)
{ {
float fov = core->getMovementMgr()->getCurrentFov(); float fov = core->getMovementMgr()->getCurrentFov();
if (fov > maxAdaptFov) if (fov > maxAdaptFov)
{ {
fov = maxAdaptFov; fov = maxAdaptFov;
skipping to change at line 217 skipping to change at line 242
// update limit luminance // update limit luminance
limitLuminance = computeLimitLuminance(); limitLuminance = computeLimitLuminance();
} }
// Compute the current limit magnitude by dichotomy // Compute the current limit magnitude by dichotomy
float StelSkyDrawer::computeLimitMagnitude() const float StelSkyDrawer::computeLimitMagnitude() const
{ {
float a=-26.f; float a=-26.f;
float b=30.f; float b=30.f;
float rcmag[2]; RCMag rcmag;
float lim = 0.f; float lim = 0.f;
int safety=0; int safety=0;
while (std::fabs(lim-a)>0.05) while (std::fabs(lim-a)>0.05f)
{ {
computeRCMag(lim, rcmag); computeRCMag(lim, &rcmag);
if (rcmag[0]<=0.f) if (rcmag.radius<=0.f)
{ {
float tmp = lim; float tmp = lim;
lim=(a+lim)*0.5; lim=(a+lim)*0.5;
b=tmp; b=tmp;
} }
else else
{ {
float tmp = lim; float tmp = lim;
lim=(b+lim)*0.5; lim=(b+lim)*0.5;
a=tmp; a=tmp;
skipping to change at line 292 skipping to change at line 317
} }
float StelSkyDrawer::pointSourceLuminanceToMag(float lum) float StelSkyDrawer::pointSourceLuminanceToMag(float lum)
{ {
return (std::log(lum) - lnfovFactor)/-0.92103f - 12.12331f; return (std::log(lum) - lnfovFactor)/-0.92103f - 12.12331f;
} }
// Compute the luminance for an extended source with the given surface brig htness in Vmag/arcmin^2 // Compute the luminance for an extended source with the given surface brig htness in Vmag/arcmin^2
float StelSkyDrawer::surfacebrightnessToLuminance(float sb) float StelSkyDrawer::surfacebrightnessToLuminance(float sb)
{ {
return 2.*2025000.f*std::exp(-0.92103f*(sb + 12.12331f))/(1./60.*1./ 60.); return 2.f*2025000.f*std::exp(-0.92103f*(sb + 12.12331f))/(1.f/60.f* 1.f/60.f);
} }
// Compute the surface brightness from the luminance of an extended source // Compute the surface brightness from the luminance of an extended source
float StelSkyDrawer::luminanceToSurfacebrightness(float lum) float StelSkyDrawer::luminanceToSurfacebrightness(float lum)
{ {
return std::log(lum*(1./60.*1./60.)/(2.*2025000.f))/-0.92103f - 12.1 2331f; return std::log(lum*(1.f/60.f*1.f/60.f)/(2.f*2025000.f))/-0.92103f - 12.12331f;
} }
// Compute RMag and CMag from magnitude for a point source. // Compute RMag and CMag from magnitude for a point source.
bool StelSkyDrawer::computeRCMag(float mag, float rcMag[2]) const bool StelSkyDrawer::computeRCMag(float mag, RCMag* rcMag) const
{ {
rcMag[0] = eye->adaptLuminanceScaledLn(pointSourceMagToLnLuminance(m rcMag->radius = eye->adaptLuminanceScaledLn(pointSourceMagToLnLumina
ag), starRelativeScale*1.40f/2.f); nce(mag), starRelativeScale*1.40f/2.f);
rcMag[0]*=starLinearScale; rcMag->radius *=starLinearScale;
// Use now statically min_rmag = 0.5, because higher and too small v alues look bad // Use now statically min_rmag = 0.5, because higher and too small v alues look bad
if (rcMag[0] < 0.5f) if (rcMag->radius < 0.3f)
{ {
rcMag[0] = rcMag[1] = 0.f; rcMag->radius = 0.f;
rcMag->luminance = 0.f;
return false; return false;
} }
// if size of star is too small (blink) we put its size to 1.2 --> n o more blink // if size of star is too small (blink) we put its size to 1.2 --> n o more blink
// And we compensate the difference of brighteness with cmag // And we compensate the difference of brighteness with cmag
if (rcMag[0]<1.2f) if (rcMag->radius<1.2f)
{ {
rcMag[1] = rcMag[0] * rcMag[0] / 1.44f; rcMag->luminance= rcMag->radius * rcMag->radius * rcMag->rad
if (rcMag[1] < 0.07f) ius / 1.728f;
if (rcMag->luminance < 0.05f)
{ {
rcMag[0] = rcMag[1] = 0.f; rcMag->radius = rcMag->luminance = 0.f;
return false; return false;
} }
rcMag[0] = 1.2f; rcMag->radius = 1.2f;
} }
else else
{ {
// cmag: // cmag:
rcMag[1] = 1.0f; rcMag->luminance = 1.0f;
if (rcMag[0]>MAX_LINEAR_RADIUS) if (rcMag->radius>MAX_LINEAR_RADIUS)
{ {
rcMag[0]=MAX_LINEAR_RADIUS+std::sqrt(1.f+rcMag[0]-MA X_LINEAR_RADIUS)-1.f; rcMag->radius=MAX_LINEAR_RADIUS+std::sqrt(1.f+rcMag- >radius-MAX_LINEAR_RADIUS)-1.f;
} }
} }
return true; return true;
} }
void StelSkyDrawer::preDrawPointSource() void StelSkyDrawer::preDrawPointSource(StelPainter* p)
{ {
Q_ASSERT_X(!drawing, Q_FUNC_INFO, Q_ASSERT(p);
"Attempting to start drawing point sources when it is alr Q_ASSERT(nbPointSources==0);
eady started");
drawing = true; // Blending is really important. Otherwise faint stars in the vicini
} ty of
// bright star will cause tiny black squares on the bright star, e.g
// Helper function that sets Add blend mode, then draws and clears a vertex . see Procyon.
buffer. glEnable(GL_BLEND);
// glBlendFunc(GL_ONE, GL_ONE);
// The buffer is cleared since we re-add the stars on each frame. p->enableTexture2d(true);
template<class VB>
void drawStars(StelTextureNew* texture, VB* vertices, StelRenderer* rendere
r, StelProjectorP projector)
{
if(NULL != texture){texture->bind();}
renderer->setBlendMode(BlendMode_Add);
vertices->lock();
// Vertices are already projected, so we use the dontProject
// argument of drawVertexBuffer.
//
// This is a hack - it would be better to refactor StelSkyDrawer,
// ZoneArray, etc, so projection gets done by the projector
// during drawing like elsewhere.
renderer->drawVertexBuffer(vertices, NULL, projector, true);
vertices->unlock();
vertices->clear();
} }
// Finalize the drawing of point sources // Finalize the drawing of point sources
void StelSkyDrawer::postDrawPointSource(StelProjectorP projector) void StelSkyDrawer::postDrawPointSource(StelPainter* sPainter)
{ {
StelRendererStatistics& stats = renderer->getStatistics(); Q_ASSERT(sPainter);
if(!statisticsInitialized)
{
bigHaloStatID = stats.addStatistic("big_halo_draws", Statist
icSwapMode_SetToZero);
sunHaloStatID = stats.addStatistic("sun_halo_draws", Statist
icSwapMode_SetToZero);
starStatID = stats.addStatistic("star_draws", Statist
icSwapMode_SetToZero);
statisticsInitialized = true;
}
if(bigHaloBuffer->length() > 0)
{
drawStars(texBigHalo, bigHaloBuffer, renderer, projector);
stats[bigHaloStatID] += 1.0;
}
if(sunHaloBuffer->length() > 0)
{
drawStars(texSunHalo, sunHaloBuffer, renderer, projector);
stats[sunHaloStatID] += 1.0;
}
if(drawStarsAsPoints && starPointBuffer->length() > 0)
{
stats[starStatID] += 1.0;
drawStars(NULL, starPointBuffer, renderer, projector);
}
else if(starSpriteBuffer->length() > 0)
{
stats[starStatID] += 1.0;
drawStars(texHalo, starSpriteBuffer, renderer, projector);
}
drawing = false;
}
//Helper function that adds the halo of a star/other point source to given
vertex buffer.
//
//The template parameter is only used so we don't need to write ColoredText
uredVertex
//every time, this function is only meant to be used from drawPointSource.
template<class V>
static void addStar(StelVertexBuffer<V>* vertices,
const float x, const float y,
const float radius, const Vec3f& color)
{
// 1 triangle around the star sprite. We use the fact
// that edges of the halo textures are transparent and
// the clamp to edge draw mode. With that, we can draw 1
// larger triangle around the sprite quad instead of drawing
// the quad as 2 triangles.
const float yBase = y - radius; if (nbPointSources==0)
const float yTop = y + radius * 2.6666666; return;
const float xLeft = x - radius * 2.3333333; texHalo->bind();
const float xRight = x + radius * 2.3333333; sPainter->enableTexture2d(true);
glBlendFunc(GL_ONE, GL_ONE);
glEnable(GL_BLEND);
const Mat4f& m = sPainter->getProjector()->getProjectionMatrix();
const QMatrix4x4 qMat(m[0], m[4], m[8], m[12], m[1], m[5], m[9], m[1
3], m[2], m[6], m[10], m[14], m[3], m[7], m[11], m[15]);
Q_ASSERT(sizeof(StarVertex)==12);
starShaderProgram->bind();
starShaderProgram->setAttributeArray(starShaderVars.pos, GL_FLOAT, (
GLfloat*)vertexArray, 2, 12);
starShaderProgram->enableAttributeArray(starShaderVars.pos);
starShaderProgram->setAttributeArray(starShaderVars.color, GL_UNSIGN
ED_BYTE, (GLubyte*)&(vertexArray[0].color), 3, 12);
starShaderProgram->enableAttributeArray(starShaderVars.color);
starShaderProgram->setUniformValue(starShaderVars.projectionMatrix,
qMat);
starShaderProgram->setAttributeArray(starShaderVars.texCoord, GL_UNS
IGNED_BYTE, (GLubyte*)textureCoordArray, 2, 0);
starShaderProgram->enableAttributeArray(starShaderVars.texCoord);
glDrawArrays(GL_TRIANGLES, 0, nbPointSources*6);
starShaderProgram->disableAttributeArray(starShaderVars.pos);
starShaderProgram->disableAttributeArray(starShaderVars.color);
starShaderProgram->disableAttributeArray(starShaderVars.texCoord);
starShaderProgram->release();
vertices->addVertex(V(Vec2f(xLeft, yBase), color, Vec2f(-0.6666666f nbPointSources = 0;
, 0.0f)));
vertices->addVertex(V(Vec2f(xRight, yBase), color, Vec2f(1.6666666f,
0.0f)));
vertices->addVertex(V(Vec2f(x, yTop), color, Vec2f(0.5f,
1.83333333f)));
} }
// Draw a point source halo. // Draw a point source halo.
void StelSkyDrawer::drawPointSource bool StelSkyDrawer::drawPointSource(StelPainter* sPainter, const Vec3f& v,
(const Vec3f& win, const float rcMag[2], const Vec3f& bcolor) const RCMag& rcMag, const Vec3f& color, bool checkInScreen)
{ {
Q_ASSERT_X(drawing, Q_FUNC_INFO, Q_ASSERT(sPainter);
"Attempting to draw a point source without calling preDra
wPointSource first.");
const float radius = rcMag[0];
const float luminance = rcMag[1];
const Vec3f color = StelApp::getInstance().getVisionModeNight() if (rcMag.radius<=0.f)
? Vec3f(bcolor[0], 0, 0) : bcolor; return false;
// Random coef for star twinkling
const float tw = (flagStarTwinkle && flagHasAtmosphere)
? (1.0f - twinkleAmount * rand() / RAND_MAX) * lumi
nance
: luminance;
const float x = win[0]; Vec3f win;
const float y = win[1]; if (!(checkInScreen ? sPainter->getProjector()->projectCheck(v, win)
: sPainter->getProjector()->project(v, win)))
return false;
const float radius = rcMag.radius;
// Random coef for star twinkling
const float tw = (flagStarTwinkle && flagHasAtmosphere) ? (1.f-twink
leAmount*rand()/RAND_MAX)*rcMag.luminance : rcMag.luminance;
// If the rmag is big, draw a big halo // If the rmag is big, draw a big halo
if (radius > MAX_LINEAR_RADIUS + 5.0f) if (radius>MAX_LINEAR_RADIUS+5.f)
{ {
const float cmag = qMin(1.0f, qMin(luminance, (radius - MAX_ float cmag = qMin(rcMag.luminance,(float)(radius-(MAX_LINEAR
LINEAR_RADIUS + 5.0f) / 30.f)); _RADIUS+5.f))/30.f);
addStar(bigHaloBuffer, x, y, 150.0f, color * cmag); float rmag = 150.f;
} if (cmag>1.f)
cmag = 1.f;
texBigHalo->bind();
sPainter->enableTexture2d(true);
glBlendFunc(GL_ONE, GL_ONE);
glEnable(GL_BLEND);
sPainter->setColor(color[0]*cmag, color[1]*cmag, color[2]*cm
ag);
sPainter->drawSprite2dModeNoDeviceScale(win[0], win[1], rmag
);
}
unsigned char starColor[3] = {0, 0, 0};
starColor[0] = (unsigned char)std::min((int)(color[0]*tw*255+0.5f),
255);
starColor[1] = (unsigned char)std::min((int)(color[1]*tw*255+0.5f),
255);
starColor[2] = (unsigned char)std::min((int)(color[2]*tw*255+0.5f),
255);
// Store the drawing instructions in the vertex arrays
StarVertex* vx = &(vertexArray[nbPointSources*6]);
vx->pos.set(win[0]-radius,win[1]-radius); memcpy(vx->color, starColo
r, 3); ++vx;
vx->pos.set(win[0]+radius,win[1]-radius); memcpy(vx->color, starColo
r, 3); ++vx;
vx->pos.set(win[0]+radius,win[1]+radius); memcpy(vx->color, starColo
r, 3); ++vx;
vx->pos.set(win[0]-radius,win[1]-radius); memcpy(vx->color, starColo
r, 3); ++vx;
vx->pos.set(win[0]+radius,win[1]+radius); memcpy(vx->color, starColo
r, 3); ++vx;
vx->pos.set(win[0]-radius,win[1]+radius); memcpy(vx->color, starColo
r, 3); ++vx;
if (drawStarsAsPoints) ++nbPointSources;
if (nbPointSources>=maxPointSources)
{ {
starPointBuffer->addVertex(ColoredVertex(Vec2f(x, y), color // Flush the buffer (draw all buffered stars)
* tw)); postDrawPointSource(sPainter);
} }
else return true;
{
addStar(starSpriteBuffer, x, y, radius, color * tw);
}
}
// Draw's the sun's corona during a solar eclipse on earth.
void StelSkyDrawer::drawSunCorona(StelProjectorP projector, const Vec3d &v,
float radius, float alpha)
{
Vec3d win;
projector->project(v, win);
addStar(coronaBuffer, win[0], win[1], radius * 2, Vec3f(alpha, alpha
, alpha));
drawStars(texCorona, coronaBuffer, renderer, projector);
} }
// Terminate drawing of a 3D model, draw the halo // Terminate drawing of a 3D model, draw the halo
void StelSkyDrawer::postDrawSky3dModel void StelSkyDrawer::postDrawSky3dModel(StelPainter* painter, const Vec3f& v
(StelProjectorP projector, const Vec3d& v, float illuminatedArea, , float illuminatedArea, float mag, const Vec3f& color)
float mag, const Vec3f& color)
{ {
// GZ: Only draw if we did not clamp this object away. const float pixPerRad = painter->getProjector()->getPixelPerRadAtCen
if (flagStarMagnitudeLimit && (mag > customStarMagLimit)) return; ter();
const float pixPerRad = projector->getPixelPerRadAtCenter();
// Assume a disk shape // Assume a disk shape
float pixRadius = std::sqrt(illuminatedArea/(60.*60.)*M_PI/180.*M_PI /180.*(pixPerRad*pixPerRad))/M_PI; float pixRadius = std::sqrt(illuminatedArea/(60.*60.)*M_PI/180.*M_PI /180.*(pixPerRad*pixPerRad))/M_PI;
bool noStarHalo = false; bool noStarHalo = false;
if (mag<-15.f) if (mag<-15.f)
{ {
const float rmag = big3dModelHaloRadius*(mag+15.f)/-11.f; // Sun, halo size varies in function of the magnitude becaus
e sun as seen from pluto should look dimmer
// as the sun as seen from earth
texSunHalo->bind();
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
painter->enableTexture2d(true);
float rmag = big3dModelHaloRadius*(mag+15.f)/-11.f;
float cmag = 1.f; float cmag = 1.f;
if (rmag<pixRadius*3.f+100.0f) if (rmag<pixRadius*3.f+100.)
{
cmag = qMax(0.f, 1.f-(pixRadius*3.f+100-rmag)/100); cmag = qMax(0.f, 1.f-(pixRadius*3.f+100-rmag)/100);
} Vec3f win;
Vec3d win; painter->getProjector()->project(v, win);
projector->project(v, win); painter->setColor(color[0]*cmag, color[1]*cmag, color[2]*cma
Vec3f c = color; g);
if (StelApp::getInstance().getVisionModeNight()) painter->drawSprite2dModeNoDeviceScale(win[0], win[1], rmag)
c = StelUtils::getNightColor(c); ;
addStar(sunHaloBuffer, win[0], win[1], rmag, c * cmag);
noStarHalo = true; noStarHalo = true;
} }
// Now draw the halo according the object brightness // Now draw the halo according the object brightness
bool save = flagStarTwinkle; bool save = flagStarTwinkle;
flagStarTwinkle = false; flagStarTwinkle = false;
float rcm[2]; RCMag rcm;
computeRCMag(mag, rcm); computeRCMag(mag, &rcm);
// We now have the radius and luminosity of the small halo // We now have the radius and luminosity of the small halo
// If the disk of the planet is big enough to be visible, we should adjust the eye adaptation luminance // If the disk of the planet is big enough to be visible, we should adjust the eye adaptation luminance
// so that the radius of the halo is small enough to be not visible (so that we see the disk) // so that the radius of the halo is small enough to be not visible (so that we see the disk)
float tStart = 2.f; float tStart = 2.f;
float tStop = 6.f; float tStop = 6.f;
bool truncated=false; bool truncated=false;
float maxHaloRadius = qMax(tStart*3., pixRadius*3.); float maxHaloRadius = qMax(tStart*3., pixRadius*3.);
if (rcm[0]>maxHaloRadius) if (rcm.radius>maxHaloRadius)
{ {
truncated = true; truncated = true;
rcm[0]=maxHaloRadius+std::sqrt(rcm[0]-maxHaloRadius); rcm.radius=maxHaloRadius+std::sqrt(rcm.radius-maxHaloRadius) ;
} }
// Fade the halo away when the disk is too big // Fade the halo away when the disk is too big
if (pixRadius>=tStop) if (pixRadius>=tStop)
{ {
rcm[1]=0.f; rcm.luminance=0.f;
} }
if (pixRadius>tStart && pixRadius<tStop) if (pixRadius>tStart && pixRadius<tStop)
{ {
rcm[1]=(tStop-pixRadius)/(tStop-tStart); rcm.luminance=(tStop-pixRadius)/(tStop-tStart);
} }
if (truncated && flagLuminanceAdaptation) if (truncated && flagLuminanceAdaptation)
{ {
float wl = findWorldLumForMag(mag, rcm[0]); float wl = findWorldLumForMag(mag, rcm.radius);
if (wl>0) if (wl>0)
{ {
const float f = core->getMovementMgr()->getCurrentFo v(); const float f = core->getMovementMgr()->getCurrentFo v();
reportLuminanceInFov(qMin(700.f, qMin(wl/50, (60.f*6 0.f)/(f*f)*6.f))); reportLuminanceInFov(qMin(700.f, qMin(wl/50, (60.f*6 0.f)/(f*f)*6.f)));
} }
} }
if (!noStarHalo) if (!noStarHalo)
{ {
preDrawPointSource(); preDrawPointSource(painter);
const Vec3f vf(v[0], v[1], v[2]); drawPointSource(painter, v, rcm, color);
Vec3f win; postDrawPointSource(painter);
if(pointSourceVisible(&(*projector), vf, rcm, false, win))
{
drawPointSource(win, rcm, color);
}
postDrawPointSource(projector);
} }
flagStarTwinkle=save; flagStarTwinkle=save;
} }
float StelSkyDrawer::findWorldLumForMag(float mag, float targetRadius) float StelSkyDrawer::findWorldLumForMag(float mag, float targetRadius)
{ {
const float saveLum = eye->getWorldAdaptationLuminance(); // s ave const float saveLum = eye->getWorldAdaptationLuminance(); // s ave
// Compute the luminance by dichotomy // Compute the luminance by dichotomy
float a=0.001f; float a=0.001f;
float b=500000.f; float b=500000.f;
float rcmag[2]; RCMag rcmag;
rcmag[0]=-99; rcmag.radius=-99;
float curLum = 500.f; float curLum = 500.f;
int safety=0; int safety=0;
while (std::fabs(rcmag[0]-targetRadius)>0.1) while (std::fabs(rcmag.radius-targetRadius)>0.1)
{ {
eye->setWorldAdaptationLuminance(curLum); eye->setWorldAdaptationLuminance(curLum);
computeRCMag(mag, rcmag); computeRCMag(mag, &rcmag);
if (rcmag[0]<=targetRadius) if (rcmag.radius<=targetRadius)
{ {
float tmp = curLum; float tmp = curLum;
curLum=(a+curLum)/2; curLum=(a+curLum)/2;
b=tmp; b=tmp;
} }
else else
{ {
float tmp = curLum; float tmp = curLum;
curLum=(b+curLum)/2; curLum=(b+curLum)/2;
a=tmp; a=tmp;
skipping to change at line 636 skipping to change at line 621
} }
void StelSkyDrawer::preDraw() void StelSkyDrawer::preDraw()
{ {
eye->setWorldAdaptationLuminance(maxLum); eye->setWorldAdaptationLuminance(maxLum);
// Re-initialize for next stage // Re-initialize for next stage
oldLum = maxLum; oldLum = maxLum;
maxLum = 0; maxLum = 0;
} }
// Set the parameters so that the stars disapear at about the limit given b y the bortle scale // Set the parameters so that the stars disappear at about the limit given by the bortle scale
// See http://en.wikipedia.org/wiki/Bortle_Dark-Sky_Scale // See http://en.wikipedia.org/wiki/Bortle_Dark-Sky_Scale
void StelSkyDrawer::setBortleScale(int bIndex) void StelSkyDrawer::setBortleScaleIndex(int bIndex)
{ {
// Associate the Bortle index (1 to 9) to inScale value // Associate the Bortle index (1 to 9) to inScale value
if (bIndex<1) if (bIndex<1)
{ {
qWarning() << "WARING: Bortle scale index range is [1;9], gi ven" << bIndex; qWarning() << "WARNING: Bortle scale index range is [1;9], g iven" << bIndex;
bIndex = 1; bIndex = 1;
} }
if (bIndex>9) if (bIndex>9)
{ {
qWarning() << "WARING: Bortle scale index range is [1;9], gi ven" << bIndex; qWarning() << "WARNING: Bortle scale index range is [1;9], g iven" << bIndex;
bIndex = 9; bIndex = 9;
} }
bortleScaleIndex = bIndex; bortleScaleIndex = bIndex;
// GZ: I moved this block to update() // GZ: I moved this block to update()
// These value have been calibrated by hand, looking at the faintest star in stellarium at around 40 deg FOV // These value have been calibrated by hand, looking at the faintest star in stellarium at around 40 deg FOV
// They should roughly match the scale described at http://en.wikipe dia.org/wiki/Bortle_Dark-Sky_Scale // They should roughly match the scale described at http://en.wikipe dia.org/wiki/Bortle_Dark-Sky_Scale
// static const float bortleToInScale[9] = {2.45, 1.55, 1.0, 0.63, 0 .40, 0.24, 0.23, 0.145, 0.09}; // static const float bortleToInScale[9] = {2.45, 1.55, 1.0, 0.63, 0 .40, 0.24, 0.23, 0.145, 0.09};
// setInputScale(bortleToInScale[bIndex-1]); // setInputScale(bortleToInScale[bIndex-1]);
} }
 End of changes. 74 change blocks. 
281 lines changed or deleted 286 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/