StelSkyImageTile.cpp   StelSkyImageTile.cpp 
skipping to change at line 19 skipping to change at line 19
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, U SA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, U SA.
*/ */
#include "StelTextureMgr.hpp"
#include "StelSkyImageTile.hpp" #include "StelSkyImageTile.hpp"
#include "StelApp.hpp" #include "StelApp.hpp"
#include "StelFileMgr.hpp" #include "StelFileMgr.hpp"
#include "StelUtils.hpp" #include "StelUtils.hpp"
#include "StelTexture.hpp" #include "StelTexture.hpp"
#include "StelProjector.hpp" #include "StelProjector.hpp"
#include "StelToneReproducer.hpp" #include "StelToneReproducer.hpp"
#include "StelCore.hpp" #include "StelCore.hpp"
#include "StelTextureMgr.hpp"
#include "StelSkyDrawer.hpp" #include "StelSkyDrawer.hpp"
#include "StelPainter.hpp" #include "StelPainter.hpp"
#include <QDebug> #include <QDebug>
#ifdef DEBUG_STELSKYIMAGE_TILE StelSkyImageTile::StelSkyImageTile()
#include "StelFont.hpp" {
#include "StelFontMgr.hpp" initCtor();
#include "StelLocaleMgr.hpp" }
StelFont* StelSkyImageTile::debugFont = NULL;
#endif
void StelSkyImageTile::initCtor() void StelSkyImageTile::initCtor()
{ {
minResolution = -1; minResolution = -1;
luminance = -1; luminance = -1;
alphaBlend = false; alphaBlend = false;
noTexture = false; noTexture = false;
texFader = NULL; texFader = NULL;
} }
skipping to change at line 78 skipping to change at line 76
alphaBlend = parent->alphaBlend; alphaBlend = parent->alphaBlend;
} }
initFromQVariantMap(map); initFromQVariantMap(map);
} }
// Destructor // Destructor
StelSkyImageTile::~StelSkyImageTile() StelSkyImageTile::~StelSkyImageTile()
{ {
} }
void StelSkyImageTile::draw(StelCore* core, const StelPainter& sPainter) void StelSkyImageTile::draw(StelCore* core, StelPainter& sPainter, float op acity)
{ {
const StelProjectorP prj = core->getProjection(StelCore::FrameJ2000) ; const StelProjectorP prj = core->getProjection(StelCore::FrameJ2000) ;
const float limitLuminance = core->getSkyDrawer()->getLimitLuminance (); const float limitLuminance = core->getSkyDrawer()->getLimitLuminance ();
QMultiMap<double, StelSkyImageTile*> result; QMultiMap<double, StelSkyImageTile*> result;
getTilesToDraw(result, core, prj->getViewportConvexPolygon(0, 0), li mitLuminance, true); getTilesToDraw(result, core, prj->getViewportConvexPolygon(0, 0), li mitLuminance, true);
int numToBeLoaded=0; int numToBeLoaded=0;
foreach (StelSkyImageTile* t, result) foreach (StelSkyImageTile* t, result)
if (t->isReadyToDisplay()==false) if (t->isReadyToDisplay()==false)
++numToBeLoaded; ++numToBeLoaded;
updatePercent(result.size(), numToBeLoaded); updatePercent(result.size(), numToBeLoaded);
// Draw in the good order // Draw in the good order
glEnable(GL_TEXTURE_2D); sPainter.enableTexture2d(true);
glBlendFunc(GL_ONE, GL_ONE); glBlendFunc(GL_ONE, GL_ONE);
QMap<double, StelSkyImageTile*>::Iterator i = result.end(); QMap<double, StelSkyImageTile*>::Iterator i = result.end();
while (i!=result.begin()) while (i!=result.begin())
{ {
--i; --i;
i.value()->drawTile(core, sPainter); i.value()->drawTile(core, sPainter);
} }
deleteUnusedSubTiles(); deleteUnusedSubTiles();
} }
// Return the list of tiles which should be drawn. // Return the list of tiles which should be drawn.
void StelSkyImageTile::getTilesToDraw(QMultiMap<double, StelSkyImageTile*>& result, StelCore* core, const StelGeom::ConvexPolygon& viewPortPoly, float limitLuminance, bool recheckIntersect) void StelSkyImageTile::getTilesToDraw(QMultiMap<double, StelSkyImageTile*>& result, StelCore* core, const SphericalRegionP& viewPortPoly, float limitL uminance, bool recheckIntersect)
{ {
#ifndef NDEBUG #ifndef NDEBUG
// When this method is called, we can assume that: // When this method is called, we can assume that:
// - the parent tile min resolution was reached // - the parent tile min resolution was reached
// - the parent tile is intersecting FOV // - the parent tile is intersecting FOV
// - the parent tile is not scheduled for deletion // - the parent tile is not scheduled for deletion
const StelSkyImageTile* parent = qobject_cast<StelSkyImageTile*>(QOb ject::parent()); const StelSkyImageTile* parent = qobject_cast<StelSkyImageTile*>(QOb ject::parent());
if (parent!=NULL) if (parent!=NULL)
{ {
skipping to change at line 156 skipping to change at line 154
if (recheckIntersect) if (recheckIntersect)
{ {
if (skyConvexPolygons.isEmpty()) if (skyConvexPolygons.isEmpty())
{ {
// If no polygon is defined, we assume that the tile covers the whole sky // If no polygon is defined, we assume that the tile covers the whole sky
fullInScreen=false; fullInScreen=false;
intersectScreen=true; intersectScreen=true;
} }
else else
{ {
foreach (const StelGeom::ConvexPolygon poly, skyConv exPolygons) foreach (const SphericalRegionP& poly, skyConvexPoly gons)
{ {
if (contains(viewPortPoly, poly)) if (viewPortPoly->contains(poly))
{ {
intersectScreen = true; intersectScreen = true;
} }
else else
{ {
fullInScreen = false; fullInScreen = false;
if (intersect(viewPortPoly, poly)) if (viewPortPoly->intersects(poly))
intersectScreen = true; intersectScreen = true;
} }
} }
} }
} }
// The tile is outside screen // The tile is outside screen
if (fullInScreen==false && intersectScreen==false) if (fullInScreen==false && intersectScreen==false)
{ {
// Schedule a deletion // Schedule a deletion
scheduleChildsDeletion(); scheduleChildsDeletion();
skipping to change at line 189 skipping to change at line 187
// The tile is in screen, and it is a precondition that its resoluti on is higher than the limit // The tile is in screen, and it is a precondition that its resoluti on is higher than the limit
// make sure that it's not going to be deleted // make sure that it's not going to be deleted
cancelDeletion(); cancelDeletion();
if (noTexture==false) if (noTexture==false)
{ {
if (!tex) if (!tex)
{ {
// The tile has an associated texture, but it is not yet loaded: load it now // The tile has an associated texture, but it is not yet loaded: load it now
StelTextureMgr& texMgr=StelApp::getInstance().getTex tureManager(); StelTextureMgr& texMgr=StelApp::getInstance().getTex tureManager();
texMgr.setDefaultParams(); tex = texMgr.createTextureThread(absoluteImageURI, S
texMgr.setMipmapsMode(true); telTexture::StelTextureParams(true));
texMgr.setMinFilter(GL_LINEAR);
texMgr.setMagFilter(GL_LINEAR);
texMgr.setWrapMode(GL_CLAMP_TO_EDGE);
tex = texMgr.createTextureThread(absoluteImageURI);
if (!tex) if (!tex)
{ {
qWarning() << "WARNING : Can't create tile: " << absoluteImageURI; qWarning() << "WARNING : Can't create tile: " << absoluteImageURI;
errorOccured = true; errorOccured = true;
return; return;
} }
} }
// The tile is in screen and has a texture: every test passe d :) The tile will be displayed // The tile is in screen and has a texture: every test passe d :) The tile will be displayed
result.insert(minResolution, this); result.insert(minResolution, this);
skipping to change at line 242 skipping to change at line 235
} }
else else
{ {
// The subtiles should not be displayed because their resolu tion is too high // The subtiles should not be displayed because their resolu tion is too high
scheduleChildsDeletion(); scheduleChildsDeletion();
} }
} }
// Draw the image on the screen. // Draw the image on the screen.
// Assume GL_TEXTURE_2D is enabled // Assume GL_TEXTURE_2D is enabled
bool StelSkyImageTile::drawTile(StelCore* core, const StelPainter& sPainter ) bool StelSkyImageTile::drawTile(StelCore* core, StelPainter& sPainter)
{ {
if (!tex->bind()) if (!tex->bind())
{
return false; return false;
}
if (!texFader) if (!texFader)
{ {
texFader = new QTimeLine(1000, this); texFader = new QTimeLine(1000, this);
texFader->start(); texFader->start();
} }
const StelProjectorP prj = core->getProjection(StelCore::FrameJ2000)
;
const float factorX = tex->getCoordinates()[2][0];
const float factorY = tex->getCoordinates()[2][1];
// Draw the real texture for this image // Draw the real texture for this image
const float ad_lum = (luminance>0) ? core->getToneReproducer()->adap tLuminanceScaled(luminance) : 1.f; const float ad_lum = (luminance>0) ? core->getToneReproducer()->adap tLuminanceScaled(luminance) : 1.f;
Vec4f color;
if (alphaBlend==true || texFader->state()==QTimeLine::Running) if (alphaBlend==true || texFader->state()==QTimeLine::Running)
{ {
if (!alphaBlend) if (!alphaBlend)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); / / Normal transparency mode glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); / / Normal transparency mode
glEnable(GL_BLEND); glEnable(GL_BLEND);
glColor4f(ad_lum,ad_lum,ad_lum, texFader->currentValue()); color.set(ad_lum,ad_lum,ad_lum, texFader->currentValue());
} }
else else
{ {
glDisable(GL_BLEND); glDisable(GL_BLEND);
glColor3f(ad_lum,ad_lum,ad_lum); color.set(ad_lum,ad_lum,ad_lum, 1.);
} }
for (int p=0;p<skyConvexPolygons.size();++p) sPainter.setColor(color[0], color[1], color[2], color[3]);
sPainter.enableTexture2d(true);
foreach (const SphericalRegionP& poly, skyConvexPolygons)
{ {
const StelGeom::Polygon& poly = skyConvexPolygons.at(p).asPo sPainter.drawSphericalRegion(poly.data(), StelPainter::Spher
lygon(); icalPolygonDrawModeTextureFill);
const QList<Vec2f>& texCoords = textureCoords.at(p);
Q_ASSERT((int)poly.size()==texCoords.size());
Vec3d win;
const int N=poly.size()-1;
int idx=N;
int diff = 0;
// Using TRIANGLE STRIP requires to use the following vertex
order N-0,0,N-1,1,N-2,2 etc..
glBegin(GL_TRIANGLE_STRIP);
for (int i=0;i<=N;++i)
{
idx = (diff==0 ? N-i/2 : i/2);
++diff;
if (diff>1) diff=0;
glTexCoord2d(texCoords[idx][0]*factorX, texCoords[id
x][1]*factorY);
prj->project(poly[idx],win);
glVertex3dv(win);
}
glEnd();
} }
#ifdef DEBUG_STELSKYIMAGE_TILE #ifdef DEBUG_STELSKYIMAGE_TILE
if (debugFont==NULL) if (debugFont==NULL)
{ {
debugFont = &StelApp::getInstance().getFontManager().getStan dardFont(StelApp::getInstance().getLocaleMgr().getSkyLanguage(), 12); debugFont = &StelApp::getInstance().getFontManager().getStan dardFont(StelApp::getInstance().getLocaleMgr().getSkyLanguage(), 12);
} }
glColor3f(1.0,0.5,0.5); color.set(1.0,0.5,0.5,1.0);
foreach (const StelGeom::ConvexPolygon& poly, skyConvexPolygons) foreach (const SphericalRegionP& poly, skyConvexPolygons)
{ {
Vec3d win; Vec3d win;
Vec3d bary = poly.getBarycenter(); Vec3d bary = poly->getPointInside();
prj->project(bary,win); sPainter.getProjector()->project(bary,win);
sPainter.drawText(debugFont, win[0], win[1], getAbsoluteImag eURI()); sPainter.drawText(debugFont, win[0], win[1], getAbsoluteImag eURI());
sPainter.enableTexture2d(false);
glDisable(GL_TEXTURE_2D); sPainter.drawSphericalRegion(poly.get(), StelPainter::Spheri
sPainter.drawPolygon(poly); calPolygonDrawModeBoundary, &color);
glEnable(GL_TEXTURE_2D); sPainter.enableTexture2d(true);
} }
#endif #endif
if (!alphaBlend) if (!alphaBlend)
glBlendFunc(GL_ONE, GL_ONE); // Revert glBlendFunc(GL_ONE, GL_ONE); // Revert
return true; return true;
} }
// Return true if the tile is fully loaded and can be displayed // Return true if the tile is fully loaded and can be displayed
bool StelSkyImageTile::isReadyToDisplay() const bool StelSkyImageTile::isReadyToDisplay() const
skipping to change at line 346 skipping to change at line 315
dataSetCredits.fullCredits = dsCredits.value("full").toStrin g(); dataSetCredits.fullCredits = dsCredits.value("full").toStrin g();
dataSetCredits.infoURL = dsCredits.value("infoUrl").toString (); dataSetCredits.infoURL = dsCredits.value("infoUrl").toString ();
} }
if (map.contains("serverCredits")) if (map.contains("serverCredits"))
{ {
QVariantMap sCredits = map.value("serverCredits").toMap(); QVariantMap sCredits = map.value("serverCredits").toMap();
serverCredits.shortCredits = sCredits.value("short").toStrin g(); serverCredits.shortCredits = sCredits.value("short").toStrin g();
serverCredits.fullCredits = sCredits.value("full").toString( ); serverCredits.fullCredits = sCredits.value("full").toString( );
serverCredits.infoURL = sCredits.value("infoUrl").toString() ; serverCredits.infoURL = sCredits.value("infoUrl").toString() ;
} }
if (map.contains("description"))
{
htmlDescription = map.value("description").toString();
if (parent()==NULL)
{
htmlDescription+= "<h3>URL: "+contructorUrl+"</h3>";
}
}
else
{
if (parent()==NULL)
{
htmlDescription= "<h3>URL: "+contructorUrl+"</h3>";
}
}
shortName = map.value("shortName").toString(); shortName = map.value("shortName").toString();
if (shortName.isEmpty())
shortName = "no name";
bool ok=false; bool ok=false;
if (!map.contains("minResolution"))
throw std::runtime_error(qPrintable(QString("minResolution i
s mandatory")));
minResolution = map.value("minResolution").toDouble(&ok); minResolution = map.value("minResolution").toDouble(&ok);
if (!ok) if (!ok)
throw std::runtime_error("minResolution expect a double valu {
e"); throw std::runtime_error(qPrintable(QString("minResolution e
xpect a double value, found: \"%1\"").arg(map.value("minResolution").toStri
ng())));
}
if (map.contains("luminance")) if (map.contains("luminance"))
{ {
luminance = map.value("luminance").toDouble(&ok); luminance = map.value("luminance").toDouble(&ok);
if (!ok) if (!ok)
throw std::runtime_error("luminance expect a float v alue"); throw std::runtime_error("luminance expect a float v alue");
qWarning() << "luminance in preview JSON files is deprecated . Replace with maxBrightness."; qWarning() << "luminance in preview JSON files is deprecated . Replace with maxBrightness.";
} }
if (map.contains("maxBrightness")) if (map.contains("maxBrightness"))
skipping to change at line 380 skipping to change at line 370
{ {
alphaBlend = map.value("alphaBlend").toBool(); alphaBlend = map.value("alphaBlend").toBool();
} }
// Load the convex polygons (if any) // Load the convex polygons (if any)
QVariantList polyList = map.value("skyConvexPolygons").toList(); QVariantList polyList = map.value("skyConvexPolygons").toList();
if (polyList.empty()) if (polyList.empty())
polyList = map.value("worldCoords").toList(); polyList = map.value("worldCoords").toList();
else else
qWarning() << "skyConvexPolygons in preview JSON files is de precated. Replace with worldCoords."; qWarning() << "skyConvexPolygons in preview JSON files is de precated. Replace with worldCoords.";
foreach (const QVariant& polyRaDec, polyList)
// Load the matching textures positions (if any)
QVariantList texCoordList = map.value("textureCoords").toList();
if (!texCoordList.isEmpty() && polyList.size()!=texCoordList.size())
throw std::runtime_error("the number of convex polyg
ons does not match the number of texture space polygon");
for (int i=0;i<polyList.size();++i)
{ {
QList<Vec3d> vertices; const QVariant& polyRaDec = polyList.at(i);
foreach (QVariant vRaDec, polyRaDec.toList()) QVector<Vec3d> vertices;
foreach (const QVariant& vRaDec, polyRaDec.toList())
{ {
const QVariantList vl = vRaDec.toList(); const QVariantList vl = vRaDec.toList();
Vec3d v; Vec3d v;
StelUtils::spheToRect(vl.at(0).toDouble(&ok)*M_PI/18 0., vl.at(1).toDouble(&ok)*M_PI/180., v); StelUtils::spheToRect(vl.at(0).toDouble(&ok)*M_PI/18 0., vl.at(1).toDouble(&ok)*M_PI/180., v);
if (!ok) if (!ok)
throw std::runtime_error("wrong Ra and Dec, expect a double value"); throw std::runtime_error("wrong Ra and Dec, expect a double value");
vertices.append(v); vertices.append(v);
} }
Q_ASSERT(vertices.size()==4); Q_ASSERT(vertices.size()==4);
skyConvexPolygons.append(StelGeom::ConvexPolygon(vertices[0]
, vertices[1], vertices[2], vertices[3]));
}
// Load the matching textures positions (if any) if (!texCoordList.isEmpty())
polyList = map.value("textureCoords").toList();
foreach (const QVariant& polyXY, polyList)
{
QList<Vec2f> vertices;
foreach (QVariant vXY, polyXY.toList())
{ {
const QVariantList vl = vXY.toList(); const QVariant& polyXY = texCoordList.at(i);
vertices.append(Vec2f(vl.at(0).toDouble(&ok), vl.at( QVector<Vec2f> texCoords;
1).toDouble(&ok))); foreach (const QVariant& vXY, polyXY.toList())
if (!ok) {
throw std::runtime_error("wrong X and Y, exp const QVariantList vl = vXY.toList();
ect a double value"); texCoords.append(Vec2f(vl.at(0).toDouble(&ok
), vl.at(1).toDouble(&ok)));
if (!ok)
throw std::runtime_error("wrong X an
d Y, expect a double value");
}
Q_ASSERT(texCoords.size()==4);
SphericalTexturedConvexPolygon* pol = new SphericalT
exturedConvexPolygon(vertices, texCoords);
Q_ASSERT(pol->checkValid());
skyConvexPolygons.append(SphericalRegionP(pol));
}
else
{
SphericalConvexPolygon* pol = new SphericalConvexPol
ygon(vertices);
Q_ASSERT(pol->checkValid());
skyConvexPolygons.append(SphericalRegionP(pol));
} }
Q_ASSERT(vertices.size()==4);
textureCoords.append(vertices);
} }
if (map.contains("imageUrl")) if (map.contains("imageUrl"))
{ {
QString imageUrl = map.value("imageUrl").toString(); QString imageUrl = map.value("imageUrl").toString();
if (baseUrl.startsWith("http://")) if (baseUrl.startsWith("http://"))
{ {
absoluteImageURI = baseUrl+imageUrl; absoluteImageURI = baseUrl+imageUrl;
} }
else else
{ {
try try
{ {
absoluteImageURI = StelApp::getInstance().ge tFileMgr().findFile(baseUrl+imageUrl); absoluteImageURI = StelFileMgr::findFile(bas eUrl+imageUrl);
} }
catch (std::runtime_error& er) catch (std::runtime_error& er)
{ {
// Maybe the user meant a file in stellarium local files // Maybe the user meant a file in stellarium local files
absoluteImageURI = imageUrl; absoluteImageURI = imageUrl;
} }
} }
if (skyConvexPolygons.size()!=textureCoords.size())
throw std::runtime_error("the number of convex polyg
ons does not match the number of texture space polygon");
} }
else else
noTexture = true; noTexture = true;
// This is a list of URLs to the child tiles or a list of already lo aded map containing child information // This is a list of URLs to the child tiles or a list of already lo aded map containing child information
// (in this later case, the StelSkyImageTile objects will be created later) // (in this later case, the StelSkyImageTile objects will be created later)
subTilesUrls = map.value("subTiles").toList(); subTilesUrls = map.value("subTiles").toList();
for (QVariantList::Iterator i=subTilesUrls.begin(); i!=subTilesUrls. end();++i) for (QVariantList::Iterator i=subTilesUrls.begin(); i!=subTilesUrls. end();++i)
{ {
if (i->type()==QVariant::Map) if (i->type()==QVariant::Map)
skipping to change at line 498 skipping to change at line 500
if (minResolution>0) if (minResolution>0)
res["minResolution"]=minResolution; res["minResolution"]=minResolution;
if (luminance>0) if (luminance>0)
res["maxBrightness"]=StelApp::getInstance().getCore()->getSk yDrawer()->luminanceToSurfacebrightness(luminance); res["maxBrightness"]=StelApp::getInstance().getCore()->getSk yDrawer()->luminanceToSurfacebrightness(luminance);
if (alphaBlend) if (alphaBlend)
res["alphaBlend"]=true; res["alphaBlend"]=true;
if (noTexture==false) if (noTexture==false)
res["imageUrl"]=absoluteImageURI; res["imageUrl"]=absoluteImageURI;
// Polygons // Polygons
if (!skyConvexPolygons.isEmpty()) // TODO
{
QVariantList polygsL;
foreach (const StelGeom::ConvexPolygon& poly, skyConvexPolyg
ons)
{
QVariantList polyL;
for (size_t i=0;i<poly.asPolygon().size();++i)
{
double ra, dec;
StelUtils::rectToSphe(&ra, &dec, poly[i]);
QVariantList vL;
vL.append(ra);
vL.append(dec);
polyL.append(vL);
}
polygsL.append(polyL);
}
res["worldCoords"]=polygsL;
}
// textures positions // textures positions
if (!textureCoords.empty()) // TODO
{
QVariantList polygsL;
foreach (const QList<Vec2f>& poly, textureCoords)
{
QVariantList polyL;
foreach (Vec2f v, poly)
{
QVariantList vL;
vL.append(v[0]);
vL.append(v[1]);
polyL.append(vL);
}
polygsL.append(polyL);
}
res["textureCoords"]=polygsL;
}
if (!subTilesUrls.empty()) if (!subTilesUrls.empty())
{ {
res["subTiles"] = subTilesUrls; res["subTiles"] = subTilesUrls;
} }
return res; return res;
} }
 End of changes. 37 change blocks. 
126 lines changed or deleted 95 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/