|
Shinya Kitaoka |
e5734a |
#include <memory></memory>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzCore includes
|
|
Toshihiro Shimizu |
890ddd |
#include "tgl.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzExt includes
|
|
Toshihiro Shimizu |
890ddd |
#include "ext/meshtexturizer.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// tcg includes
|
|
Toshihiro Shimizu |
890ddd |
#include "tcg/tcg_list.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Qt includes
|
|
Toshihiro Shimizu |
890ddd |
#include <qstring></qstring>
|
|
Toshihiro Shimizu |
890ddd |
#include <qcache></qcache>
|
|
Toshihiro Shimizu |
890ddd |
#include <qmutex></qmutex>
|
|
Toshihiro Shimizu |
890ddd |
#include <qmutexlocker></qmutexlocker>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "ext/ttexturesstorage.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//***************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// Local namespace - structures
|
|
Toshihiro Shimizu |
890ddd |
//***************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
struct TexturesContainer {
|
|
Shinya Kitaoka |
120a6e |
MeshTexturizer
|
|
Shinya Kitaoka |
120a6e |
m_texturizer; //!< The mesh texturizer - actual textures container
|
|
Shinya Kitaoka |
120a6e |
tcg::list<qstring> m_keys; //!< Keys in the storage</qstring>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
TexturesContainer() {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
TexturesContainer(const TexturesContainer &);
|
|
Shinya Kitaoka |
120a6e |
TexturesContainer &operator=(const TexturesContainer &);
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//***************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// Local namespace - variables
|
|
Toshihiro Shimizu |
890ddd |
//***************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QMutex l_mutex(QMutex::Recursive); // A mutex is needed to synchronize access
|
|
Shinya Kitaoka |
120a6e |
// to the following objects
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
std::map<int, *="" texturescontainer=""></int,>
|
|
Shinya Kitaoka |
120a6e |
l_texturesContainers; // Texture Containers by display lists space id
|
|
Shinya Kitaoka |
120a6e |
QCache<qstring, drawabletexturedatap=""> l_objects(500 * 1024); // 500 MB cache</qstring,>
|
|
Shinya Kitaoka |
120a6e |
// for now - NOTE:
|
|
Shinya Kitaoka |
120a6e |
// MUST be
|
|
Shinya Kitaoka |
120a6e |
// allocated
|
|
Shinya Kitaoka |
120a6e |
// before the
|
|
Shinya Kitaoka |
120a6e |
// following
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
} // namespace
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//***************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// Local namespace - global functions
|
|
Toshihiro Shimizu |
890ddd |
//***************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline QString textureString(int dlSpaceId, const std::string &texId) {
|
|
Shinya Kitaoka |
120a6e |
return QString::number(dlSpaceId) + "_" + QString::fromStdString(texId);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline void deleteTexturesContainer(
|
|
Shinya Kitaoka |
120a6e |
const std::pair<int, *="" texturescontainer=""> &pair) {</int,>
|
|
Shinya Kitaoka |
120a6e |
delete pair.second;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//***************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// DrawableTextureData implementation
|
|
Toshihiro Shimizu |
890ddd |
//***************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
DrawableTextureData::~DrawableTextureData() {
|
|
Shinya Kitaoka |
120a6e |
QMutexLocker locker(&l_mutex);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TexturesContainer *texContainer = l_texturesContainers[m_dlSpaceId];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (m_dlSpaceId >= 0) {
|
|
Shinya Kitaoka |
120a6e |
// Load the container's display lists space (remember current OpenGL
|
|
Shinya Kitaoka |
120a6e |
// context, too)
|
|
Shinya Kitaoka |
120a6e |
TGLDisplayListsProxy *proxy =
|
|
Shinya Kitaoka |
120a6e |
TGLDisplayListsManager::instance()->dlProxy(m_dlSpaceId);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TGlContext currentContext = tglGetCurrentContext();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Unbind the textures
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
QMutexLocker locker(proxy->mutex());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
proxy->makeCurrent();
|
|
Shinya Kitaoka |
120a6e |
texContainer->m_texturizer.unbindTexture(m_texId);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Restore OpenGL context - equivalent to tglDoneCurrent if currentContext
|
|
Shinya Kitaoka |
120a6e |
// == TGlContext()
|
|
Shinya Kitaoka |
120a6e |
tglMakeCurrent(currentContext);
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
// Temporary - use current OpenGL context directly
|
|
Shinya Kitaoka |
120a6e |
texContainer->m_texturizer.unbindTexture(m_texId);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
texContainer->m_keys.erase(m_objIdx);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//***************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// TTexturesStorage implementation
|
|
Toshihiro Shimizu |
890ddd |
//***************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TTexturesStorage::TTexturesStorage() {
|
|
Shinya Kitaoka |
120a6e |
// This singleton is dependent on TGLDisplayListsManager
|
|
Shinya Kitaoka |
120a6e |
TGLDisplayListsManager::instance()->addObserver(this);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TTexturesStorage::~TTexturesStorage() {
|
|
Shinya Kitaoka |
120a6e |
l_objects.clear();
|
|
Shinya Kitaoka |
120a6e |
std::for_each(l_texturesContainers.begin(), l_texturesContainers.end(),
|
|
Shinya Kitaoka |
120a6e |
deleteTexturesContainer);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TTexturesStorage *TTexturesStorage::instance() {
|
|
Shinya Kitaoka |
120a6e |
static TTexturesStorage theInstance;
|
|
Shinya Kitaoka |
120a6e |
return &theInstance;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
DrawableTextureDataP TTexturesStorage::loadTexture(const std::string &textureId,
|
|
Shinya Kitaoka |
120a6e |
const TRaster32P &ras,
|
|
Shinya Kitaoka |
120a6e |
const TRectD &geometry) {
|
|
Shinya Kitaoka |
120a6e |
// Try to retrieve the proxy associated to current OpenGL context
|
|
Shinya Kitaoka |
120a6e |
TGlContext currentContext = tglGetCurrentContext();
|
|
Shinya Kitaoka |
120a6e |
int dlSpaceId =
|
|
Shinya Kitaoka |
120a6e |
TGLDisplayListsManager::instance()->displayListsSpaceId(currentContext);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QString texString(::textureString(dlSpaceId, textureId));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Deal with containers
|
|
Shinya Kitaoka |
120a6e |
QMutexLocker locker(&l_mutex);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// If necessary, allocate a textures container
|
|
Shinya Kitaoka |
120a6e |
std::map<int, *="" texturescontainer="">::iterator it =</int,>
|
|
Shinya Kitaoka |
120a6e |
l_texturesContainers.find(dlSpaceId);
|
|
Shinya Kitaoka |
120a6e |
if (it == l_texturesContainers.end())
|
|
Shinya Kitaoka |
120a6e |
it = l_texturesContainers
|
|
Shinya Kitaoka |
120a6e |
.insert(std::make_pair(dlSpaceId, new TexturesContainer))
|
|
Shinya Kitaoka |
120a6e |
.first;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
MeshTexturizer &texturizer = it->second->m_texturizer;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
DrawableTextureDataP dataPtr = std::make_shared<drawabletexturedata>();</drawabletexturedata>
|
|
Shinya Kitaoka |
120a6e |
DrawableTextureData *data = dataPtr.get();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
data->m_dlSpaceId = dlSpaceId;
|
|
Shinya Kitaoka |
120a6e |
data->m_texId = texturizer.bindTexture(ras, geometry);
|
|
Shinya Kitaoka |
120a6e |
data->m_objIdx = it->second->m_keys.push_back(texString);
|
|
Shinya Kitaoka |
120a6e |
data->m_textureData = texturizer.getTextureData(data->m_texId);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
l_objects.insert(texString, new DrawableTextureDataP(dataPtr),
|
|
Shinya Kitaoka |
120a6e |
(ras->getLx() * ras->getLy() * ras->getPixelSize()) >> 10);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (dlSpaceId < 0) {
|
|
Shinya Kitaoka |
120a6e |
// obj is a temporary. It was pushed in the cache to make space for it -
|
|
Shinya Kitaoka |
120a6e |
// however, it must not be
|
|
Shinya Kitaoka |
120a6e |
// stored. Remove it now.
|
|
Shinya Kitaoka |
120a6e |
l_objects.remove(texString);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return dataPtr;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TTexturesStorage::unloadTexture(const std::string &textureId) {
|
|
Shinya Kitaoka |
120a6e |
QMutexLocker locker(&l_mutex);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Remove the specified texture from ALL the display lists spaces
|
|
Shinya Kitaoka |
120a6e |
std::map<int, *="" texturescontainer="">::iterator it,</int,>
|
|
Shinya Kitaoka |
120a6e |
iEnd(l_texturesContainers.end());
|
|
Shinya Kitaoka |
120a6e |
for (it = l_texturesContainers.begin(); it != iEnd; ++it)
|
|
Shinya Kitaoka |
120a6e |
l_objects.remove(::textureString(it->first, textureId));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TTexturesStorage::onDisplayListDestroyed(int dlSpaceId) {
|
|
Shinya Kitaoka |
120a6e |
QMutexLocker locker(&l_mutex);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Remove the textures container associated with dlSpaceId
|
|
Shinya Kitaoka |
120a6e |
std::map<int, *="" texturescontainer="">::iterator it =</int,>
|
|
Shinya Kitaoka |
120a6e |
l_texturesContainers.find(dlSpaceId);
|
|
Shinya Kitaoka |
120a6e |
if (it == l_texturesContainers.end()) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
tcg::list<qstring>::iterator st, sEnd(it->second->m_keys.end());</qstring>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (st = it->second->m_keys.begin(); st != sEnd;) // Note that the increment
|
|
Shinya Kitaoka |
120a6e |
// is performed BEFORE the
|
|
Shinya Kitaoka |
120a6e |
// texture is removed.
|
|
Shinya Kitaoka |
120a6e |
l_objects.remove(*st++); // This is because texture removal may destroy the
|
|
Shinya Kitaoka |
120a6e |
// key being addressed,
|
|
Shinya Kitaoka |
120a6e |
// whose iterator would then be invalidated.
|
|
Shinya Kitaoka |
120a6e |
delete it->second;
|
|
Shinya Kitaoka |
120a6e |
l_texturesContainers.erase(it);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
DrawableTextureDataP TTexturesStorage::getTextureData(
|
|
Shinya Kitaoka |
120a6e |
const std::string &textureId) {
|
|
Shinya Kitaoka |
120a6e |
// Get current display lists space
|
|
Shinya Kitaoka |
120a6e |
TGlContext currentContext = tglGetCurrentContext();
|
|
Shinya Kitaoka |
120a6e |
int dlSpaceId =
|
|
Shinya Kitaoka |
120a6e |
TGLDisplayListsManager::instance()->displayListsSpaceId(currentContext);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// If there is no known associated display lists space, the texture cannot be
|
|
Shinya Kitaoka |
120a6e |
// stored.
|
|
Shinya Kitaoka |
120a6e |
if (dlSpaceId < 0) return DrawableTextureDataP();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QMutexLocker locker(&l_mutex);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Search the texture object
|
|
Shinya Kitaoka |
120a6e |
QString texString(::textureString(dlSpaceId, textureId));
|
|
Shinya Kitaoka |
120a6e |
if (!l_objects.contains(texString)) return DrawableTextureDataP();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return *l_objects.object(texString);
|
|
Toshihiro Shimizu |
890ddd |
}
|