3
3
* Copyright (C) 2006 Fabien Chereau
5
5
* This program is free software; you can redistribute it and/or
6
6
* modify it under the terms of the GNU General Public License
7
7
* as published by the Free Software Foundation; either version 2
8
8
* of the License, or (at your option) any later version.
10
10
* This program is distributed in the hope that it will be useful,
11
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
13
* GNU General Public License for more details.
15
15
* You should have received a copy of the GNU General Public License
16
16
* along with this program; if not, write to the Free Software
17
17
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
#include "StelTextureMgr.hpp"
21
22
#include "StelTexture.hpp"
22
#include "StelTextureMgr.hpp"
23
24
#include "StelFileMgr.hpp"
24
25
#include "StelApp.hpp"
26
#include "StelUtils.hpp"
27
#include "StelMainGraphicsView.hpp"
27
30
#include <QMutexLocker>
66
62
StelTexture::maxLoadThreadSemaphore->release(1);
69
/*************************************************************************
71
*************************************************************************/
72
65
StelTexture::StelTexture() : httpReply(NULL), loadThread(NULL), downloaded(false), isLoadingImage(false),
73
errorOccured(false), id(0), avgLuminance(-1.f), texels(NULL), type(GL_UNSIGNED_BYTE)
66
errorOccured(false), id(0), avgLuminance(-1.f)
75
68
mutex = new QMutex();
77
texCoordinates[0].set(1., 0.);
78
texCoordinates[1].set(0., 0.);
79
texCoordinates[2].set(1., 1.);
80
texCoordinates[3].set(0., 1.);
205
191
/*************************************************************************
206
Return the average texture luminance, 0 is black, 1 is white
207
*************************************************************************/
208
bool StelTexture::getAverageLuminance(float& lum)
213
QMutexLocker lock(mutex);
216
int size = width*height;
217
glBindTexture(GL_TEXTURE_2D, id);
218
GLfloat* p = (GLfloat*)calloc(size, sizeof(GLfloat));
221
glGetTexImage(GL_TEXTURE_2D, 0, GL_LUMINANCE, GL_FLOAT, p);
223
for (int i=0;i<size;++i)
229
avgLuminance = sum/size;
236
/*************************************************************************
237
192
Return the width and heigth of the texture in pixels
238
193
*************************************************************************/
239
194
bool StelTexture::getDimensions(int &awidth, int &aheight)
241
QMutexLocker lock(mutex);
242
196
if (width<0 || height<0)
244
198
// Try to get the size from the file without loading data
259
/*************************************************************************
261
*************************************************************************/
213
// Load the image data
262
214
bool StelTexture::imageLoad()
265
216
if (downloadedData.isEmpty())
267
218
// Load the data from the file
268
219
QMutexLocker lock(mutex);
269
res = StelApp::getInstance().getTextureManager().loadImage(this);
220
qImage = QImage(fullPath);
273
// Load the image from the buffer, not from a file
274
if (fullPath.endsWith(".jpg", Qt::CaseInsensitive) || fullPath.endsWith(".jpeg", Qt::CaseInsensitive))
276
// Special case optimized for loading jpeg
277
// Could be even more optimized by re-using the texels buffers instead of allocating one for each textures
278
ImageLoader::TexInfo texInfo;
279
res = JpgLoader::loadFromMemory(downloadedData, texInfo);
284
QMutexLocker lock(mutex);
285
format = texInfo.format;
286
width = texInfo.width;
287
height = texInfo.height;
288
type = GL_UNSIGNED_BYTE;
289
internalFormat = texInfo.internalFormat;
290
texels = texInfo.texels;
295
// Use Qt QImage which is slower but works for many formats
296
// This is quite slow because Qt allocates twice the memory and needs to swap from ARGB to RGBA
297
qImage = QGLWidget::convertToGLFormat(QImage::fromData(downloadedData));
299
// Update texture parameters from loaded image
301
QMutexLocker lock(mutex);
303
width = qImage.width();
304
height = qImage.height();
305
type = GL_UNSIGNED_BYTE;
224
qImage = QImage::fromData(downloadedData);
309
225
// Release the memory
310
226
downloadedData = QByteArray();
228
return !qImage.isNull();
315
/*************************************************************************
316
Actually load the texture already in the RAM to openGL memory
317
*************************************************************************/
231
// Actually load the texture to openGL memory
318
232
bool StelTexture::glLoad()
320
if (qImage.isNull() && !texels)
322
236
errorOccured = true;
323
237
reportError("Unknown error");
328
glGenTextures (1, &id);
329
glBindTexture (GL_TEXTURE_2D, id);
331
// setup some parameters for texture filters and mipmapping
332
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
333
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
334
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode);
335
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode);
337
if (!qImage.isNull())
340
if (mipmapsMode==true)
341
gluBuild2DMipmaps(GL_TEXTURE_2D, internalFormat, width, height, format, type, qImage.bits());
343
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, type, qImage.bits());
345
// Release shared memory
241
#ifdef USE_OPENGL_ES2
242
glActiveTexture(GL_TEXTURE0);
245
QGLContext::BindOptions opt = QGLContext::InvertedYBindOption;
246
if (loadParams.filtering==GL_LINEAR)
247
opt |= QGLContext::LinearFilteringBindOption;
249
// Mipmap seems to be pretty buggy on windows..
251
if (loadParams.generateMipmaps==true)
252
opt |= QGLContext::MipmapBindOption;
256
if (qImage.isGrayscale())
258
glformat = qImage.hasAlphaChannel() ? GL_LUMINANCE_ALPHA : GL_LUMINANCE;
260
else if (qImage.hasAlphaChannel())
350
// Fixed the bug which caused shifted loading for LUMINANCE images with non multiple of 4 widths!
351
glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
352
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
354
// Load from texels buffer
355
if (mipmapsMode==true)
356
gluBuild2DMipmaps(GL_TEXTURE_2D, internalFormat, width, height, format, type, texels);
358
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, type, texels);
362
// OpenGL has its own copy of texture data
363
TexMalloc::free (texels);
266
id = StelMainGraphicsView::getInstance().getOpenGLWin()->bindTexture(qImage, GL_TEXTURE_2D, glformat, opt);
267
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, loadParams.wrapMode);
268
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, loadParams.wrapMode);
270
StelApp::makeMainGLContextCurrent();
272
// Release shared memory
367
275
// Report success of texture loading
368
276
emit(loadingProcessFinished(false));