17
17
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
20
#include "STexture.hpp"
23
/*************************************************************************
24
Constructor for the STexture class
25
*************************************************************************/
26
STexture::STexture() : texels(NULL), type(GL_UNSIGNED_BYTE)
21
#include "StelTextureMgr.hpp"
22
#include "StelFileMgr.hpp"
23
#include "StelApp.hpp"
26
#include <QMutexLocker>
28
#include <QImageReader>
31
#include <QTemporaryFile>
37
#if defined(__APPLE__) && defined(__MACH__)
38
#include <OpenGL/glu.h> /* Header File For The GLU Library */
40
#include <GL/glu.h> /* Header File For The GLU Library */
44
QSemaphore* STexture::maxLoadThreadSemaphore = new QSemaphore(20);
46
STexture::STexture() : downloaded(false), downloadId(0), isLoadingImage(false), imageFile(NULL),
47
errorOccured(false), id(0), avgLuminance(-1.f), texels(NULL), type(GL_UNSIGNED_BYTE)
28
51
texCoordinates[0].set(1., 0.);
29
52
texCoordinates[1].set(0., 0.);
30
53
texCoordinates[2].set(1., 1.);
31
54
texCoordinates[3].set(0., 1.);
34
/*************************************************************************
35
Destructor for the STexture class
36
*************************************************************************/
37
60
STexture::~STexture()
42
glDeleteTextures(1, &id);
46
/*************************************************************************
47
Return the average texture luminance : 0 is black, 1 is white
48
*************************************************************************/
49
float STexture::getAverageLuminance(void)
51
int size = width*height;
52
glBindTexture(GL_TEXTURE_2D, id);
53
GLfloat* p = (GLfloat*)calloc(size, sizeof(GLfloat));
56
glGetTexImage(GL_TEXTURE_2D, 0, GL_LUMINANCE, GL_FLOAT, p);
58
for (int i=0;i<size;++i)
65
if (glIsTexture(id)==GL_FALSE)
67
// std::cerr << "Warning: in STexture::~STexture() tried to delete invalid texture with ID=" << id << " Current GL ERROR status is " << glGetError() << std::endl;
71
glDeleteTextures(1, &id);
72
// std::cerr << "Delete texture with ID=" << id << std::endl;
79
/*************************************************************************
80
This method should be called if the texture loading failed for any reasons
81
*************************************************************************/
82
void STexture::reportError(const QString& aerrorMessage)
85
errorMessage = aerrorMessage;
86
// Report failure of texture loading
87
emit(loadingProcessFinished(this, true));
90
/*************************************************************************
91
Class used to load an image and set the texture parameters in a thread
92
*************************************************************************/
93
class ImageLoadThread : public QThread
96
ImageLoadThread(STexture* tex) : QThread((QObject*)tex), texture(tex) {;}
102
void ImageLoadThread::run()
104
STexture::maxLoadThreadSemaphore->acquire(1);
105
texture->imageLoad();
106
STexture::maxLoadThreadSemaphore->release(1);
109
/*************************************************************************
110
Bind the texture so that it can be used for openGL drawing (calls glBindTexture)
111
*************************************************************************/
112
bool STexture::bind()
116
// The texture is already fully loaded, just bind and return true;
117
glBindTexture(GL_TEXTURE_2D, id);
123
// The texture is not yet fully loaded
124
if (downloaded==false && downloadId==0 && fullPath.startsWith("http://"))
126
// We need to start download
127
imageFile = new QTemporaryFile(QDir::tempPath() + "XXXXXX." + fileExtension, this);
128
if (!imageFile->open(QIODevice::ReadWrite))
130
qWarning() << "STexture::bind(): can't create temporary file " << QDir::tempPath() + "XXXXXX." + fileExtension;
134
QHttp* http = StelApp::getInstance().getTextureManager().getDownloader();
135
connect(http, SIGNAL(requestFinished(int, bool)), this, SLOT(downloadFinished(int, bool)));
137
http->setHost(url.host(), url.port(80));
138
downloadId = http->get(fullPath, imageFile);
139
fullPath = imageFile->fileName();
143
// From this point we assume that fullPath is valid
144
// Start loading the image in a thread and return imediately
147
isLoadingImage = true;
148
ImageLoadThread* thread = new ImageLoadThread(this);
149
connect(thread, SIGNAL(finished()), this, SLOT(fileLoadFinished()));
156
/*************************************************************************
157
Called when the download for the texture file terminated
158
*************************************************************************/
159
void STexture::downloadFinished(int did, bool error)
168
qWarning() << "Texture download failed for " + imageFile->fileName()+ ": " + StelApp::getInstance().getTextureManager().getDownloader()->errorString();
171
QHttp* http = StelApp::getInstance().getTextureManager().getDownloader();
172
disconnect(http, SIGNAL(requestFinished(int, bool)), this, SLOT(downloadFinished(int, bool)));
174
// Call bind to activate data loading
178
/*************************************************************************
179
Called when the file loading thread has terminated
180
*************************************************************************/
181
void STexture::fileLoadFinished()
186
/*************************************************************************
187
Actually load the texture already in the RAM to openGL memory
188
*************************************************************************/
189
bool STexture::glLoad()
198
glGenTextures (1, &id);
199
glBindTexture (GL_TEXTURE_2D, id);
201
// setup some parameters for texture filters and mipmapping
202
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
203
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
204
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode);
205
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode);
207
glTexImage2D (GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, type, texels);
208
if (mipmapsMode==true)
209
gluBuild2DMipmaps (GL_TEXTURE_2D, internalFormat, width, height, format, type, texels);
211
// OpenGL has its own copy of texture data
215
// Report success of texture loading
216
emit(loadingProcessFinished(this, false));
221
/*************************************************************************
222
Return the average texture luminance, 0 is black, 1 is white
223
*************************************************************************/
224
bool STexture::getAverageLuminance(float& lum)
229
QMutexLocker lock(mutex);
232
int size = width*height;
233
glBindTexture(GL_TEXTURE_2D, id);
234
GLfloat* p = (GLfloat*)calloc(size, sizeof(GLfloat));
237
glGetTexImage(GL_TEXTURE_2D, 0, GL_LUMINANCE, GL_FLOAT, p);
239
for (int i=0;i<size;++i)
245
avgLuminance = sum/size;
67
252
/*************************************************************************
68
253
Return the width and heigth of the texture in pixels
69
254
*************************************************************************/
70
void STexture::getDimensions(int &awidth, int &aheight) const
255
bool STexture::getDimensions(int &awidth, int &aheight)
257
QMutexLocker lock(mutex);
258
if (width<0 || height<0)
260
// Try to get the size from the file without loading data
261
QImageReader im(fullPath);
266
QSize size = im.size();
267
width = size.width();
268
height = size.height();
275
/*************************************************************************
277
*************************************************************************/
278
bool STexture::imageLoad()
280
QMutexLocker lock(mutex);
281
return StelApp::getInstance().getTextureManager().loadImage(this);