[Kstars-devel] [kstars] kstars: It required rewrite of TextureManager. Now its API became much simpler

Khudyakov Alexey alexey.skladnoy at gmail.com
Tue May 3 23:29:06 CEST 2011


Git commit 4bb749b5842f0fd7838dc5a5f068dd39a0296bb1 by Khudyakov Alexey.
Committed on 03/05/2011 at 23:14.
Pushed by khudyakov into branch 'master'.

It required rewrite of TextureManager. Now its API became much simpler
there are just 3(+1) static functions. One to obtain image and two
to bind texture.

Most important changes:

* Texture IDs are cached by Qt so there no point cache them twice
* Texture manager do not own GL context any more. Instead it is
  passed as parameter of QGLWidget* type.
* Texture class is not used anywhere but is still here.
* All Q_ASSERTS on QGLContext are gone
* Planet and deep-skyes store their images as QImage not as
  textures. Also they are loaded at construction time.

Unfortunately this is rather large changeset but there is no
obvious way to implement these changes incrementally.

CCMAIL: kstars-devel at kde.org
BUG: 266933

M  +58   -80   kstars/skyglpainter.cpp     
M  +2    -2    kstars/skyglpainter.h     
M  +0    -7    kstars/skymap.cpp     
M  +4    -6    kstars/skymapgldraw.cpp     
M  +9    -12   kstars/skyobjects/deepskyobject.cpp     
M  +5    -11   kstars/skyobjects/deepskyobject.h     
M  +1    -1    kstars/skyobjects/ksmoon.cpp     
M  +2    -3    kstars/skyobjects/ksplanetbase.cpp     
M  +2    -4    kstars/skyobjects/ksplanetbase.h     
M  +4    -8    kstars/skyqpainter.cpp     
M  +10   -10   kstars/texture.cpp     
M  +57   -44   kstars/texturemanager.cpp     
M  +32   -33   kstars/texturemanager.h     

http://commits.kde.org/kstars/4bb749b5842f0fd7838dc5a5f068dd39a0296bb1

diff --git a/kstars/skyglpainter.cpp b/kstars/skyglpainter.cpp
index 668e76e..f4c5358 100644
--- a/kstars/skyglpainter.cpp
+++ b/kstars/skyglpainter.cpp
@@ -32,7 +32,6 @@ using Eigen::Rotation2Df;
 #include "Options.h"
 
 #include "texturemanager.h"
-#include "texture.h"
 
 #include "skycomponents/linelist.h"
 #include "skycomponents/skiplist.h"
@@ -53,7 +52,7 @@ Vector3f SkyGLPainter::m_color[NUMTYPES][6*BUFSIZE];
 int      SkyGLPainter::m_idx[NUMTYPES];
 bool     SkyGLPainter::m_init = false;
 
-SkyGLPainter::SkyGLPainter( const QGLWidget *widget ) : SkyPainter()
+SkyGLPainter::SkyGLPainter( QGLWidget *widget ) : SkyPainter()
 {
     m_widget = widget;
     if( !m_init ) {
@@ -70,7 +69,6 @@ SkyGLPainter::SkyGLPainter( const QGLWidget *widget ) : SkyPainter()
             }
         }
         //Generate textures that were loaded before the SkyMap was
-        TextureManager::genTextures();
         m_init = true;
     }
 }
@@ -81,17 +79,15 @@ void SkyGLPainter::drawBuffer(int type)
     if( m_idx[type] == 0 ) return;
 
     glEnable(GL_TEXTURE_2D);
-    const Texture *tex = 0;
     switch( type ) {
-        case 3: case 13:          tex = TextureManager::getTexture("open-cluster"); break;
-        case 4:                   tex = TextureManager::getTexture("globular-cluster"); break;
-        case 6:                   tex = TextureManager::getTexture("planetary-nebula"); break;
-        case 5: case 7: case 15:  tex = TextureManager::getTexture("gaseous-nebula"); break;
-        case 8: case 16:          tex = TextureManager::getTexture("galaxy"); break;
-        case 14:                  tex = TextureManager::getTexture("galaxy-cluster"); break;
-        case 0: case 1: default:  tex = TextureManager::getTexture("star"); break;
+        case 3: case 13:          TextureManager::bindTexture("open-cluster",     m_widget); break;
+        case 4:                   TextureManager::bindTexture("globular-cluster", m_widget); break;
+        case 6:                   TextureManager::bindTexture("planetary-nebula", m_widget); break;
+        case 5: case 7: case 15:  TextureManager::bindTexture("gaseous-nebula",   m_widget); break;
+        case 8: case 16:          TextureManager::bindTexture("galaxy",           m_widget); break;
+        case 14:                  TextureManager::bindTexture("galaxy-cluster",   m_widget); break;
+        case 0: case 1: default:  TextureManager::bindTexture("star",             m_widget); break;
     }
-    tex->bind();
 
     glBlendFunc(GL_ONE, GL_ONE);
     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
@@ -168,7 +164,7 @@ bool SkyGLPainter::drawPlanet(KSPlanetBase* planet)
     if( planet->name() == "Sun" || planet->name() == "Moon" )
         sizemin = 8.0;
     
-    if( size < fakeStarSize || !planet->texture()->isReady() )
+    if( size < fakeStarSize || planet->image().isNull() )
     {
         // Draw them as bright stars of appropriate color instead of images
         char spType;
@@ -184,11 +180,11 @@ bool SkyGLPainter::drawPlanet(KSPlanetBase* planet)
         }
         return addItem(planet, planet->type(), qMin(fakeStarSize,(float)20.),spType);
     } else {
-        //Draw images
-        Q_ASSERT(planet->texture()->isReady());
+        // Draw them as textures
         bool visible = false;
         Vector2f pos = m_proj->toScreenVec(planet,true,&visible);
-        if( !visible ) return false;
+        if( !visible )
+            return false;
         
         //Because Saturn has rings, we inflate its image size by a factor 2.5
         if( planet->name() == "Saturn" )
@@ -202,9 +198,7 @@ bool SkyGLPainter::drawPlanet(KSPlanetBase* planet)
         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
         glEnable(GL_TEXTURE_2D);
 
-        bool bound = planet->texture()->bind();
-        if( !bound ) return false;
-        
+        TextureManager::bindFromImage( planet->image(), m_widget );
         glBegin(GL_QUADS);
             vec = pos + rot*Vector2f(-s,-s);
             glTexCoord2f(0.,0.);
@@ -248,16 +242,12 @@ bool SkyGLPainter::drawDeepSkyObject(DeepSkyObject* obj, bool drawImage)
     float h = w * obj->e();
 
     //Init texture if it doesn't exist and we would be drawing it anyways
-    if( drawImage && !obj->texture() )
-        obj->loadTexture();
-    const Texture *tex = obj->texture();
-
-    if( drawImage && tex && tex->isReady() ) {
+    if( drawImage  &&  !obj->image().isNull() ) {
         glEnable(GL_TEXTURE_2D);
         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
         Vector2f vertex;
-        tex->bind();
+        TextureManager::bindFromImage( obj->image(), m_widget );
         glBegin(GL_QUADS);
             vertex = vec + r*Vector2f(-w,-h);
             glTexCoord2f(0.,0.);
@@ -493,8 +483,7 @@ void SkyGLPainter::drawObservingList(const QList< SkyObject* >& obs)
         ++i;
     }
 
-    const Texture *tex = TextureManager::getTexture("obslistsymbol");
-    tex->bind();
+    TextureManager::bindTexture("obslistsymbol", m_widget);
 
     glBlendFunc(GL_ONE, GL_ONE);
     glEnableClientState(GL_VERTEX_ARRAY);
@@ -514,7 +503,6 @@ void SkyGLPainter::drawFlags()
     KStarsData *data = KStarsData::Instance();
     SkyPoint* point;
     QImage image;
-    const Texture *tex;
     const QString label;
     bool visible = false;
     Vector2f vec;
@@ -535,33 +523,28 @@ void SkyGLPainter::drawFlags()
 
         // Get texture from TextureManager
         if ( data->skyComposite()->flags()->imageName( i ) == "Default" )
-            tex = TextureManager::getTexture("defaultflag");
-        else
-            tex = TextureManager::createTexture( image );
-        
-        tex->bind();
-
-        // Draw image
-        if( tex->isReady() ) {
-            glEnable(GL_TEXTURE_2D);
-            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-            glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-            Vector2f vertex;
-            glBegin(GL_QUADS);
-                vertex = vec + Vector2f( image.width()/2 * -1, image.height()/2 );
-                glTexCoord2f(0.,0.);
-                glVertex2fv(vertex.data());
-                vertex = vec + Vector2f( image.width()/2, image.height()/2 );
-                glTexCoord2f(1.,0.);
-                glVertex2fv(vertex.data());
-                vertex = vec + Vector2f( image.width()/2, image.height()/2 * -1  );
-                glTexCoord2f(1.,1.);
-                glVertex2fv(vertex.data());
-                vertex = vec + Vector2f( image.width()/2 * -1, image.height()/2 * -1 );
-                glTexCoord2f(0.,1.);
-                glVertex2fv(vertex.data());
-            glEnd();
-        }
+            TextureManager::bindTexture("defaultflag", m_widget);
+        else 
+            TextureManager::bindFromImage( image, m_widget );
+
+        glEnable(GL_TEXTURE_2D);
+        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+        Vector2f vertex;
+        glBegin(GL_QUADS);
+        vertex = vec + Vector2f( image.width()/2 * -1, image.height()/2 );
+        glTexCoord2f(0.,0.);
+            glVertex2fv(vertex.data());
+            vertex = vec + Vector2f( image.width()/2, image.height()/2 );
+            glTexCoord2f(1.,0.);
+            glVertex2fv(vertex.data());
+            vertex = vec + Vector2f( image.width()/2, image.height()/2 * -1  );
+            glTexCoord2f(1.,1.);
+            glVertex2fv(vertex.data());
+            vertex = vec + Vector2f( image.width()/2 * -1, image.height()/2 * -1 );
+            glTexCoord2f(0.,1.);
+            glVertex2fv(vertex.data());
+        glEnd();
 
         // Draw label
         drawText( vec.x(), vec.y(), data->skyComposite()->flags()->label( i ), QFont( "Courier New", 10, QFont::Bold ), data->skyComposite()->flags()->labelColor( i ) );
@@ -600,31 +583,26 @@ void SkyGLPainter::drawText( int x, int y, const QString text, QFont font, QColo
     p.end();
 
     // Create texture
-    Texture *texture = TextureManager::createTexture( text_image );
-    texture->bind();
-
-    // Render image
-    if( texture->isReady() ) {
-        glEnable(GL_TEXTURE_2D);
-        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-        Vector2f vec( x, y );
-        Vector2f vertex;
-        glBegin(GL_QUADS);
-            vertex = vec + Vector2f( 10, text_image.height()/2 -10 );
-            glTexCoord2f(0.,0.);
-            glVertex2fv(vertex.data());
-            vertex = vec + Vector2f( text_image.width() + 10, text_image.height()/2 -10 );
-            glTexCoord2f(1.,0.);
-            glVertex2fv(vertex.data());
-            vertex = vec + Vector2f( text_image.width() + 10, text_image.height()/2*(-1) - 10 );
-            glTexCoord2f(1.,1.);
-            glVertex2fv(vertex.data());
-            vertex = vec + Vector2f( 10, text_image.height()/2*(-1) - 10 );;
-            glTexCoord2f(0.,1.);
-            glVertex2fv(vertex.data());
-        glEnd();
-    }
+    TextureManager::bindFromImage( text_image, m_widget );
+    glEnable(GL_TEXTURE_2D);
+    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+    Vector2f vec( x, y );
+    Vector2f vertex;
+    glBegin(GL_QUADS);
+        vertex = vec + Vector2f( 10, text_image.height()/2 -10 );
+        glTexCoord2f(0.,0.);
+        glVertex2fv(vertex.data());
+        vertex = vec + Vector2f( text_image.width() + 10, text_image.height()/2 -10 );
+        glTexCoord2f(1.,0.);
+        glVertex2fv(vertex.data());
+        vertex = vec + Vector2f( text_image.width() + 10, text_image.height()/2*(-1) - 10 );
+        glTexCoord2f(1.,1.);
+        glVertex2fv(vertex.data());
+        vertex = vec + Vector2f( 10, text_image.height()/2*(-1) - 10 );;
+        glTexCoord2f(0.,1.);
+        glVertex2fv(vertex.data());
+    glEnd();
 }
 
 void SkyGLPainter::drawSkyLine(SkyPoint* a, SkyPoint* b)
diff --git a/kstars/skyglpainter.h b/kstars/skyglpainter.h
index 78a0785..73ac82c 100644
--- a/kstars/skyglpainter.h
+++ b/kstars/skyglpainter.h
@@ -32,7 +32,7 @@ class QGLWidget;
 class SkyGLPainter : public SkyPainter
 {
 public:
-    SkyGLPainter( const QGLWidget *widget );
+    SkyGLPainter( QGLWidget *widget );
     virtual bool drawPlanet(KSPlanetBase* planet);
     virtual bool drawDeepSkyObject(DeepSkyObject* obj, bool drawImage = false);
     virtual bool drawPointSource(SkyPoint* loc, float mag, char sp = 'A');
@@ -65,7 +65,7 @@ private:
     static Vector3f m_color[NUMTYPES][6*BUFSIZE];
     static int m_idx[NUMTYPES];
     static bool m_init; ///< keep track of whether we have filled the texcoord array
-    const QGLWidget* m_widget; // Pointer to (GL) widget on which we are painting
+    QGLWidget* m_widget; // Pointer to (GL) widget on which we are painting
 };
 
 #endif // SKYGLPAINTER_H
diff --git a/kstars/skymap.cpp b/kstars/skymap.cpp
index 2471a5e..afbf19b 100644
--- a/kstars/skymap.cpp
+++ b/kstars/skymap.cpp
@@ -207,9 +207,6 @@ SkyMap::SkyMap() :
             m_objBox, SLOT(   slotPointChanged(SkyPoint*) ) );
 
 #ifdef HAVE_OPENGL
-
-    Q_ASSERT( TextureManager::getContext() ); // Should not fail, because TextureManager should be already created.
-    
     m_SkyMapQDraw  = new SkyMapQDraw( this );
     m_SkyMapQDraw->setMouseTracking( true );
     m_SkyMapGLDraw = new SkyMapGLDraw( this );
@@ -221,9 +218,7 @@ SkyMap::SkyMap() :
         m_SkyMapDraw = m_SkyMapGLDraw;
     else
         m_SkyMapDraw = m_SkyMapQDraw;
-
 #else
-
     m_SkyMapDraw = new SkyMapQDraw( this );
     m_SkyMapDraw->setMouseTracking( true );
 #endif
@@ -1088,8 +1083,6 @@ void SkyMap::slotToggleGL() {
 
             Options::setUseGL( true );
 
-            Q_ASSERT( TextureManager::getContext() ); // Should not fail, because TextureManager should be already created.
-
             m_SkyMapDraw = m_SkyMapGLDraw;
             KStars::Instance()->actionCollection()->action( "opengl" )->setText(i18n("Switch to QPainter backend"));
         }
diff --git a/kstars/skymapgldraw.cpp b/kstars/skymapgldraw.cpp
index a16a40e..aecc429 100644
--- a/kstars/skymapgldraw.cpp
+++ b/kstars/skymapgldraw.cpp
@@ -21,12 +21,10 @@
 #include "skymap.h"
 
 
-SkyMapGLDraw::SkyMapGLDraw( SkyMap *sm ) : QGLWidget( TextureManager::getContext(), sm ),SkyMapDrawAbstract( sm ) {
-
-    // We must have the context ready before we create our
-    // GLWidget. This is a check on that.
-    Q_ASSERT( TextureManager::getContext() );
-
+SkyMapGLDraw::SkyMapGLDraw( SkyMap *sm ) :
+    QGLWidget( sm ),
+    SkyMapDrawAbstract( sm )
+{
     if( !format().testOption( QGL::SampleBuffers ) )
         qWarning() << "No sample buffer; can't use multisampling (antialiasing)";
     if( !format().testOption( QGL::StencilBuffer ) )
diff --git a/kstars/skyobjects/deepskyobject.cpp b/kstars/skyobjects/deepskyobject.cpp
index 7be12dc..f650abe 100644
--- a/kstars/skyobjects/deepskyobject.cpp
+++ b/kstars/skyobjects/deepskyobject.cpp
@@ -44,7 +44,7 @@ DeepSkyObject::DeepSkyObject( const DeepSkyObject &o ) :
     PGC( o.PGC ),
     MajorAxis( o.MajorAxis ),
     MinorAxis( o.MinorAxis ),
-    m_texture( o.texture() )
+    m_image( o.m_image )
 {
     customCat = NULL;
     Flux = 0;
@@ -57,7 +57,8 @@ DeepSkyObject::DeepSkyObject( int t, dms r, dms d, float m,
                               const QString &n, const QString &n2,
                               const QString &lname, const QString &cat,
                               float a, float b, double pa, int pgc, int ugc )
-        : SkyObject( t, r, d, m, n, n2, lname ) {
+        : SkyObject( t, r, d, m, n, n2, lname )
+{
     MajorAxis = a;
     MinorAxis = b;
     PositionAngle = pa;
@@ -65,16 +66,17 @@ DeepSkyObject::DeepSkyObject( int t, dms r, dms d, float m,
     UGC = ugc;
     setCatalog( cat );
     updateID = updateNumID = 0;
-    m_texture = 0;
     customCat = NULL;
     Flux = 0;
+    loadImage();
 }
 
 DeepSkyObject::DeepSkyObject( int t, double r, double d, float m,
                               const QString &n, const QString &n2,
                               const QString &lname, const QString &cat,
                               float a, float b, double pa, int pgc, int ugc )
-        : SkyObject( t, r, d, m, n, n2, lname ) {
+        : SkyObject( t, r, d, m, n, n2, lname )
+{
     MajorAxis = a;
     MinorAxis = b;
     PositionAngle = pa;
@@ -82,9 +84,9 @@ DeepSkyObject::DeepSkyObject( int t, double r, double d, float m,
     UGC = ugc;
     setCatalog( cat );
     updateID = updateNumID = 0;
-    m_texture = 0;
     customCat = NULL;
     Flux = 0;
+    loadImage();
 }
 
 DeepSkyObject* DeepSkyObject::clone() const
@@ -116,15 +118,10 @@ void DeepSkyObject::setCatalog( const QString &cat ) {
     else Catalog = (unsigned char)CAT_UNKNOWN;
 }   
 
-void DeepSkyObject::loadTexture()
+void DeepSkyObject::loadImage()
 {
     QString tname = name().toLower().remove(' ');
-    m_texture = TextureManager::getTexture( tname );
-}
-
-const Texture* DeepSkyObject::texture() const
-{
-    return m_texture;
+    m_image = TextureManager::getImage( tname );
 }
 
 double DeepSkyObject::labelOffset() const {
diff --git a/kstars/skyobjects/deepskyobject.h b/kstars/skyobjects/deepskyobject.h
index 7b17fa6..93c65f1 100644
--- a/kstars/skyobjects/deepskyobject.h
+++ b/kstars/skyobjects/deepskyobject.h
@@ -27,7 +27,6 @@
 class QImage;
 class QString;
 class KSPopupMenu;
-class Texture;
 class CustomCatalogComponent;
 
 /**
@@ -180,16 +179,11 @@ public:
     	*/
     inline int pgc() const { return PGC; }
 
-    /**
-     * @return a pointer to the object's texture.
-     * @note do check for null pointers...
-     */
-    const Texture* texture() const;
+    /** @return an object's image */
+    const QImage& image() const { return m_image; }
 
-    /**
-     * Try to load the object's texture
-     */
-    void loadTexture();
+    /** Try to load the object's image */
+    void loadImage();
 
     /**
       *@return true if the object is in the Messier catalog
@@ -226,7 +220,7 @@ private:
     double PositionAngle;
     int UGC, PGC;
     float MajorAxis, MinorAxis, Flux;
-    const Texture *m_texture;
+    QImage m_image;
     CustomCatalogComponent *customCat;
 };
 
diff --git a/kstars/skyobjects/ksmoon.cpp b/kstars/skyobjects/ksmoon.cpp
index a1a5fa1..ef25e5c 100644
--- a/kstars/skyobjects/ksmoon.cpp
+++ b/kstars/skyobjects/ksmoon.cpp
@@ -238,7 +238,7 @@ void KSMoon::findPhase() {
     double DegPhase = dms( Phase ).reduce().Degrees();
     iPhase = int( 0.1*DegPhase+0.5 ) % 36; // iPhase must be in [0,36) range
 
-    m_tex = TextureManager::getTexture(
+    m_image = TextureManager::getImage(
         QString("moon%1").arg(iPhase,2,10,QChar('0')));
 }
 
diff --git a/kstars/skyobjects/ksplanetbase.cpp b/kstars/skyobjects/ksplanetbase.cpp
index 21c3580..0b340a4 100644
--- a/kstars/skyobjects/ksplanetbase.cpp
+++ b/kstars/skyobjects/ksplanetbase.cpp
@@ -56,14 +56,13 @@ const SkyObject::UID KSPlanetBase::UID_SOL_COMET    = 2;
 
 KSPlanetBase::KSPlanetBase( const QString &s, const QString &image_file, const QColor &c, double pSize ) :
     TrailObject( 2, 0.0, 0.0, 0.0, s ),
-    Rearth(0.0),
-    m_tex(0)
+    Rearth(0.0)
 {
     init( s, image_file, c, pSize );
 }
 
 void KSPlanetBase::init( const QString &s, const QString &image_file, const QColor &c, double pSize ) {
-    m_tex = TextureManager::getTexture(image_file);
+    m_image = TextureManager::getImage( image_file );
     PositionAngle = 0.0;
     PhysicalSize = pSize;
     m_Color = c;
diff --git a/kstars/skyobjects/ksplanetbase.h b/kstars/skyobjects/ksplanetbase.h
index 08efe0d..4b663a4 100644
--- a/kstars/skyobjects/ksplanetbase.h
+++ b/kstars/skyobjects/ksplanetbase.h
@@ -28,7 +28,6 @@
 
 #include "trailobject.h"
 
-class Texture;
 class KSNumbers;
 class KSPopupMenu;
 
@@ -121,7 +120,7 @@ public:
     void EquatorialToEcliptic( const dms *Obliquity );
 
     /** @return pointer to this planet's texture */
-    const Texture* texture() { return m_tex; }
+    const QImage& image() { return m_image; }
 
     /**@return distance from Sun, in Astronomical Units (1 AU is Earth-Sun distance) */
     double rsun() const { return ep.radius; }
@@ -243,8 +242,7 @@ protected:
     EclipticPosition helEcPos;
     double  Rearth;
     double Phase;
-
-    const Texture *m_tex;
+    QImage m_image;
 
 private:
     /**
diff --git a/kstars/skyqpainter.cpp b/kstars/skyqpainter.cpp
index 91257fc..87719b2 100644
--- a/kstars/skyqpainter.cpp
+++ b/kstars/skyqpainter.cpp
@@ -24,7 +24,6 @@
 #include "kstarsdata.h"
 #include "Options.h"
 #include "skymap.h"
-#include "texture.h"
 
 #include "skycomponents/linelist.h"
 #include "skycomponents/skiplist.h"
@@ -322,9 +321,9 @@ bool SkyQPainter::drawPlanet(KSPlanetBase* planet)
             sizemin = 8.0;
 
         float size = planet->angSize() * dms::PI * Options::zoomFactor()/10800.0;
-        if ( size < sizemin )
+        if( size < sizemin )
             size = sizemin;
-        if ( Options::showPlanetImages() && planet->texture()->isReady() ) {
+        if( Options::showPlanetImages() && !planet->image().isNull() ) {
             //Because Saturn has rings, we inflate its image size by a factor 2.5
             if( planet->name() == "Saturn" )
                 size = int(2.5*size);
@@ -333,7 +332,7 @@ bool SkyQPainter::drawPlanet(KSPlanetBase* planet)
             translate(pos);
             rotate( m_proj->findPA( planet, pos.x(), pos.y() ) );
             drawImage( QRect(-0.5*size, -0.5*size, size, size),
-                       planet->texture()->image() );
+                       planet->image() );
             restore();
         } else { //Otherwise, draw a simple circle.
             drawEllipse( pos, size, size );
@@ -387,9 +386,6 @@ bool SkyQPainter::drawDeepSkyObject(DeepSkyObject* obj, bool drawImage)
 
 bool SkyQPainter::drawDeepSkyImage(const QPointF& pos, DeepSkyObject* obj, float positionAngle)
 {
-    if ( !obj->texture() ) obj->loadTexture();
-    if ( !obj->texture()->isReady() ) return false;
-    
     double zoom = Options::zoomFactor();
     double w = obj->a() * dms::PI * zoom/10800.0;
     double h = obj->e() * w;
@@ -397,7 +393,7 @@ bool SkyQPainter::drawDeepSkyImage(const QPointF& pos, DeepSkyObject* obj, float
     save();
     translate(pos);
     rotate( positionAngle );
-    drawImage( QRect(-0.5*w, -0.5*h, w, h), obj->texture()->image() );
+    drawImage( QRect(-0.5*w, -0.5*h, w, h), obj->image() );
     restore();
 
     return true;
diff --git a/kstars/texture.cpp b/kstars/texture.cpp
index 5d2dffb..7a88de3 100644
--- a/kstars/texture.cpp
+++ b/kstars/texture.cpp
@@ -67,16 +67,16 @@ void Texture::setImage(const QImage& img)
 #ifdef HAVE_OPENGL
 void Texture::genTexture()
 {
-    //FIXME do proper mipmapping
-    if( Options::useGL() ) {
-        if( !m_image.isNull() ) {
-            Q_ASSERT( TextureManager::getContext() );
-            m_tid = TextureManager::getContext()->bindTexture(m_image, GL_TEXTURE_2D, GL_RGBA, QGLContext::DefaultBindOption);
-            m_ready = (m_tid != 0);
-            Q_ASSERT( m_ready );
-        } else
-            m_ready = false;
-    }
+    // //FIXME do proper mipmapping
+    // if( Options::useGL() ) {
+    //     if( !m_image.isNull() ) {
+    //         Q_ASSERT( TextureManager::getContext() );
+    //         m_tid = TextureManager::getContext()->bindTexture(m_image, GL_TEXTURE_2D, GL_RGBA, QGLContext::DefaultBindOption);
+    //         m_ready = (m_tid != 0);
+    //         Q_ASSERT( m_ready );
+    //     } else
+    //         m_ready = false;
+    // }
 }
 #endif
 
diff --git a/kstars/texturemanager.cpp b/kstars/texturemanager.cpp
index fe8ff9d..eedeeca 100644
--- a/kstars/texturemanager.cpp
+++ b/kstars/texturemanager.cpp
@@ -8,7 +8,8 @@
 
     This program is distributed in the hope that it will be useful,
     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.
 
     You should have received a copy of the GNU General Public License along
@@ -24,62 +25,74 @@
 #include <kstandarddirs.h>
 
 #ifdef HAVE_OPENGL
-#include <QGLWidget>
-QGLContext* TextureManager::m_context = 0;
+# include <QGLWidget>
 #endif
 
+// We returning reference to image. We refer to this image when search
+// for image fails
+const static QImage emptyImage;
+
 TextureManager* TextureManager::m_p;
 
-const Texture* TextureManager::getTexture(const QString& name)
-{
 
+TextureManager *TextureManager::Create() {
+    if( !m_p )
+        m_p = new TextureManager();
+    return m_p;
+}
+
+const QImage& TextureManager::getImage(const QString& name)
+{
     Create();
+    CacheIter it = findTexture( name );
+    if( it != m_p->m_textures.end() ) {
+        return *it;
+    } else {
+        return emptyImage;
+    }
+}
 
-    Texture *tex = m_p->m_textures.value(name,0);
-    if( !tex ) {
+TextureManager::CacheIter TextureManager::findTexture(const QString& name)
+{
+    Create();
+    // Lookup in cache first
+    CacheIter it = m_p->m_textures.find( name );
+    if( it != m_p->m_textures.end() ) {
+        return it;
+    } else {
+        // Try to load from file
         QString filename = KStandardDirs::locate("appdata",QString("textures/%1.png").arg(name));
-        tex = new Texture(m_p);
         if( !filename.isNull() ) {
-            QImage img(filename);
-            tex->setImage(img);
+            return m_p->m_textures.insert( name, QImage(filename) );
         } else {
-            qWarning() << "Could not find texture" << name;
+            qWarning() << "Could not find texture: " << name;
+            return m_p->m_textures.end();
         }
-        m_p->m_textures.insert(name,tex);
     }
-    return tex;
 }
 
 #ifdef HAVE_OPENGL
-void TextureManager::genTextures()
+static void bindImage(const QImage& img, QGLWidget* cxt)
 {
-    //If there's no instance, there are no textures to bind!
-    if(!m_p) return;
-    
-    for( QHash<QString, Texture*>::const_iterator it = m_p->m_textures.constBegin();
-         it != m_p->m_textures.constEnd();
-         ++it )
-    {
-        if( !(*it)->isReady() )
-            (*it)->genTexture();
-    }
+    GLuint tid = cxt->bindTexture(img, GL_TEXTURE_2D, GL_RGBA, QGLContext::DefaultBindOption);
+    glBindTexture(GL_TEXTURE_2D, tid);
 }
-#endif
 
-TextureManager *TextureManager::Create() {
-    if( !m_p )
-        m_p = new TextureManager( KStars::Instance() );
-#ifdef HAVE_OPENGL
-    if( !m_context )
-        m_context = new QGLContext( QGLFormat(QGL::SampleBuffers) );
-#endif
-    return m_p;
+void TextureManager::bindTexture(const QString& name, QGLWidget* cxt)
+{
+    Create();
+    Q_ASSERT( "Must be called only with valid GL context" && cxt );
+
+    CacheIter it = findTexture( name );
+    if( it != m_p->m_textures.end() )
+        bindImage( *it, cxt );
 }
 
-Texture* TextureManager::createTexture( QImage image )
+void TextureManager::bindFromImage(const QImage& image, QGLWidget* cxt)
 {
-    Texture *texture = new Texture( m_p );
-    // Resize image if necessary and create texture
+    Create();
+    Q_ASSERT( "Must be called only with valid GL context" && cxt );
+
     if ( image.width() != image.height() || ( image.width() & ( image.width() - 1 ) ) ) {
         // Compute texture size
         int longest  = qMax( image.width(), image.height() );
@@ -88,14 +101,14 @@ Texture* TextureManager::createTexture( QImage image )
             tex_size *= 2;
         }
         // FIXME: Check if Qt does this for us already. [Note that it does scale to the nearest power of two]
-        texture->setImage( image.scaled( tex_size, tex_size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation ) );
-    } else
-        texture->setImage( image );
-
-    return texture;
+        bindImage( 
+            image.scaled( tex_size, tex_size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation ),
+            cxt );
+    } else {
+        bindImage( image, cxt );
+    }
 }
+#endif
 
 TextureManager::TextureManager(QObject* parent): QObject(parent)
-{
-
-}
+{}
diff --git a/kstars/texturemanager.h b/kstars/texturemanager.h
index 8a59128..e8c2288 100644
--- a/kstars/texturemanager.h
+++ b/kstars/texturemanager.h
@@ -23,54 +23,53 @@
 #include <QObject>
 #include <QHash>
 
-#include "texture.h"
-
 #include <config-kstars.h>
 
-class QGLContext;
+class QGLWidget;
+class QImage;
 
-/** @brief a singleton class to manage texture loading/retrieval */
+/** @brief a singleton class to manage texture loading/retrieval
+ */
 class TextureManager : public QObject
 {
     Q_OBJECT
 public:
-    /** Gets and/or loads a texture
-        @param name the name of the texture
-        @return a pointer to the texture
-        */
-    static const Texture* getTexture(const QString& name);
+    /** @short Create the instance of TextureManager */
+    static TextureManager* Create();
+
+    /** Return texture image. If image is not found in cache tries to
+     *  load it from disk if that fails too returns reference to empty
+     *  image. */
+    static const QImage& getImage(const QString& name);
 
 #ifdef HAVE_OPENGL
-    /** If there exist textures that have a QImage loaded
-        but which have not yet been set up for use with GL,
-        this function will set them up. */
-    static void genTextures();
-
-    /**
-     *@return the QGLContext that is used for the textures
-     */
-    static inline QGLContext* getContext() { return (m_p ? m_p->m_context : 0); }
+    /** Bind OpenGL texture. Acts similarily to getImage but does
+     *  nothing if image is not found in the end */
+    static void bindTexture(const QString& name, QGLWidget* cxt);
+
+    /** Bind OpenGL texture using QImage as source */
+    static void bindFromImage(const QImage& image, QGLWidget* cxt);
 #endif
 
-    /**
-     *@short Create the instance of TextureManager
-     */
-    static TextureManager *Create();
+private:
+    /** Shorthand for iterator to hashtable */
+    typedef QHash<QString,QImage>::const_iterator CacheIter;
 
-    /**
-     *@short Create a texture from image
-     */
-    static Texture* createTexture( QImage image );
+    /** Private constructor */
+    TextureManager(QObject* paretn = 0);
+    /** Try find image in the cache and then to load it from disk if
+     *  it's not found */
+    static CacheIter findTexture(const QString& name);
 
-protected:
-    TextureManager(QObject* parent = 0);
-    static TextureManager* m_p;
-    QHash<QString,Texture*> m_textures;
 
-#ifdef HAVE_OPENGL
-    static QGLContext *m_context; // GL Context to bind textures to.
-#endif
+    // Pointer to singleton instance
+    static TextureManager* m_p;
+    // List of named textures
+    QHash<QString,QImage> m_textures;
 
+    // Prohibit copying
+    TextureManager(const TextureManager&);
+    TextureManager& operator = (const TextureManager&);
 };
 
 #endif // TEXTUREMANAGER_H



More information about the Kstars-devel mailing list