Commit 7c03f272 authored by Jan Möbius's avatar Jan Möbius
Browse files

Added imagestore to reuse already active textures



git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@11730 383ad7c9-94d9-4d36-a494-682f7c89f535
parent d75c0e9b
/*===========================================================================*\
* *
* OpenFlipper *
* Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen *
* www.openflipper.org *
* *
*--------------------------------------------------------------------------- *
* This file is part of OpenFlipper. *
* *
* OpenFlipper is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of *
* the License, or (at your option) any later version with the *
* following exceptions: *
* *
* If other files instantiate templates or use macros *
* or inline functions from this file, or you compile this file and *
* link it with other files to produce an executable, this file does *
* not by itself cause the resulting executable to be covered by the *
* GNU Lesser General Public License. This exception does not however *
* invalidate any other reasons why the executable file might be *
* covered by the GNU Lesser General Public License. *
* *
* OpenFlipper 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 *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU LesserGeneral Public *
* License along with OpenFlipper. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision$ *
* $LastChangedBy$ *
* $Date$ *
* *
\*===========================================================================*/
#include "ImageStorage.hh"
#include <iostream>
#include <OpenFlipper/common/GlobalOptions.hh>
static ImageStore store;
ImageStore& imageStore() {
return store;
}
// ---------------------------------------------------------------------------
ImageStore::ImageStore():
nextId_(1)
{
}
// ---------------------------------------------------------------------------
int ImageStore::addImageFile( QString _fileName ) {
// Clean error string
errorString_ = "No error";
QString loadFilename;
// Construct complete filename
// if it starts with "/" or "." or contains a ":" it is a global filename and we don't touch it
// otherwise we take a relative path from our texture dir
if ( _fileName.startsWith("/") || _fileName.startsWith(".") || _fileName.contains(":") )
loadFilename = _fileName;
else
loadFilename = OpenFlipper::Options::textureDirStr() + QDir::separator() + _fileName;
// Check if it already exists and return the existing one rather than recreating a new one
if ( filenameMap_.count(loadFilename) > 0 ) {
// Get id of the existing image
int existingId = filenameMap_[loadFilename];
// Update refcount
refCount_[existingId] = refCount_[existingId] + 1;
// Return existing ones id
return existingId;
}
QFile file(loadFilename);
if ( !file.exists() ) {
errorString_ = "addedEmptyObject: Cannot load global texture '"+ loadFilename +"'. File not found!" ;
return -1;
}
QImage image;
//QImage cannot handle tga directly
if ( QFileInfo(loadFilename).suffix().toLower() == "tga" ){
QPixmap pic(loadFilename);
image = pic.toImage();
} else {
//load the image
if ( !image.load( loadFilename ) ){
errorString_ = "Unable to load Image from file " + loadFilename;
return -1;
}
}
// Store the mapping from filename to id
filenameMap_[loadFilename]= nextId_;
reverseFilenameMap_[nextId_] = loadFilename;
// Initialize refcount
refCount_[nextId_] = 1;
// Store image
imageMap_[nextId_] = image;
// Increment for next image
nextId_++;
// return the id of the added one
return (nextId_ - 1);
}
// ---------------------------------------------------------------------------
int ImageStore::addImage( QImage _image ) {
// No filename mapping as it does not have a filename
// Initialize refcount
refCount_[nextId_] = 1;
// Store image
imageMap_[nextId_] = _image;
// Increment for next image
nextId_++;
// return the id of the added one
return (nextId_ - 1);
}
// ---------------------------------------------------------------------------
int ImageStore::getImageID(QString _filename) {
// Check if it already exists and return the existing one rather than recreating a new one
if ( filenameMap_.count(_filename) > 0 ) {
return filenameMap_[_filename];
}
// Clean error string
errorString_ = "getImageID failed. No such image :" + _filename;
return -1;
}
// ---------------------------------------------------------------------------
QImage& ImageStore::getImage(int _id, bool* _ok) {
if ( imageMap_.count(_id) > 0 ) {
if ( _ok)
*_ok = true;
return imageMap_[_id];
} else {
if ( _ok)
*_ok = false;
errorString_ = "getImage: Unknown image id : " + QString::number(_id);
return dummy_;
}
}
// ---------------------------------------------------------------------------
void ImageStore::removeImage(int _id) {
// Check if it exists
if ( refCount_.count(_id) > 0 ) {
if ( refCount_[_id] > 1 ) {
refCount_[_id] = refCount_[_id] - 1;
return;
} else {
// Remove from refCount
refCount_.remove(_id);
imageMap_.remove(_id);
// This image is from a file and not directly added
if ( reverseFilenameMap_.count(_id) > 0 ) {
// Get the filename
QString fileName = reverseFilenameMap_[_id];
reverseFilenameMap_.remove(_id);
filenameMap_.remove(fileName);
}
}
}
}
/*===========================================================================*\
* *
* OpenFlipper *
* Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen *
* www.openflipper.org *
* *
*--------------------------------------------------------------------------- *
* This file is part of OpenFlipper. *
* *
* OpenFlipper is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of *
* the License, or (at your option) any later version with the *
* following exceptions: *
* *
* If other files instantiate templates or use macros *
* or inline functions from this file, or you compile this file and *
* link it with other files to produce an executable, this file does *
* not by itself cause the resulting executable to be covered by the *
* GNU Lesser General Public License. This exception does not however *
* invalidate any other reasons why the executable file might be *
* covered by the GNU Lesser General Public License. *
* *
* OpenFlipper 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 *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU LesserGeneral Public *
* License along with OpenFlipper. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision$ *
* $LastChangedBy$ *
* $Date$ *
* *
\*===========================================================================*/
#ifndef TEXTUREIMAGESTORAGE_HH
#define TEXTUREIMAGESTORAGE_HH
#include <QMap>
#include <QImage>
// ---------------------------------------------------------------------------
class ImageStore {
public :
ImageStore();
int addImageFile( QString _filename);
int addImage( QImage _image );
int getImageID(QString _filename);
QImage& getImage(int _id, bool* _ok);
QString error() {return errorString_; };
void removeImage(int _id);
private:
QMap<int,QImage> imageMap_;
QMap<QString,int> filenameMap_;
QMap<int,QString> reverseFilenameMap_;
QMap<int,unsigned int> refCount_;
QString errorString_;
QImage dummy_;
int nextId_;
};
ImageStore& imageStore();
#endif //TEXTUREIMAGESTORAGE_HH
......@@ -54,6 +54,7 @@
#include "OpenFlipper/BasePlugin/PluginFunctions.hh"
#include "OpenFlipper/BasePlugin/PluginFunctionsViewControls.hh"
#include "OpenFlipper/common/GlobalOptions.hh"
#include "ImageStorage.hh"
#include <math.h>
......@@ -85,12 +86,13 @@ void TextureControlPlugin::slotTextureAdded( QString _textureName , QString _fil
// Get the image file
// ================================================================================
QImage textureImage;
if ( !getImage(_filename,textureImage) )
emit log(LOGERR, "slotTextureAdded : Cannot load texture '" + _textureName + "'. File not found '" + _filename + "'");
// Add Image to the image store and set the index in the texture description
int newId = imageStore().addImageFile(_filename);
if ( newId == -1 ) {
emit log(LOGERR,imageStore().error());
return;
}
// ================================================================================
// Add the texture to the texture node and get the corresponding id
......@@ -99,10 +101,10 @@ void TextureControlPlugin::slotTextureAdded( QString _textureName , QString _fil
//inform textureNode about the new texture
if( obj->dataType( DATA_TRIANGLE_MESH ) )
glName = PluginFunctions::triMeshObject(obj)->textureNode()->add_texture(textureImage);
glName = PluginFunctions::triMeshObject(obj)->textureNode()->add_texture(imageStore().getImage(newId,0));
if ( obj->dataType( DATA_POLY_MESH ) )
glName = PluginFunctions::polyMeshObject(obj)->textureNode()->add_texture(textureImage);
glName = PluginFunctions::polyMeshObject(obj)->textureNode()->add_texture(imageStore().getImage(newId,0));
// ================================================================================
// Store texture information in objects metadata
......@@ -114,7 +116,10 @@ void TextureControlPlugin::slotTextureAdded( QString _textureName , QString _fil
}
texData->addTexture(_textureName,_filename,_dimension,glName);
texData->setImage(_textureName,textureImage);
// Remember id in texture descriptor
texData->setImage(_textureName,newId);
texData->texture(_textureName).disable();
}
......@@ -125,12 +130,14 @@ void TextureControlPlugin::slotTextureAdded( QString _textureName , QString _fil
globalTextures_.addTexture(_textureName,_filename,_dimension,0);
globalTextures_.texture(_textureName).disable();
QImage textureImage;
int newImageId = imageStore().addImageFile(_filename);
if ( !getImage(_filename,textureImage) )
emit log(LOGERR, "slotTextureAdded: Cannot load texture '" + _textureName + "'. File not found '" + _filename + "'");
if ( newImageId == -1 ) {
emit log(LOGERR,imageStore().error());
return;
}
globalTextures_.texture(_textureName).textureImage = textureImage;
globalTextures_.texture(_textureName).textureImageId(newImageId);
} else {
emit log(LOGERR,"slotTextureAdded: Trying to add already existing global texture " + _textureName );
......@@ -181,12 +188,16 @@ void TextureControlPlugin::slotMultiTextureAdded( QString _textureGroup , QStrin
//hide the texture (its accessible through the multiTexture)
texData->texture(_name).hidden( true );
QImage textureImage;
// Add to image store
int newImageId = imageStore().addImageFile(_name);
if ( !getImage(_filename,textureImage) )
emit log(LOGERR, "slotMultiTextureAdded: Cannot load multiTexture '" + _textureGroup + "'. File not found '" + _filename + "'");
if ( newImageId == -1 ) {
emit log(LOGERR,imageStore().error());
return;
}
texData->texture(_name).textureImage = textureImage;
// Add to texture description
texData->texture(_name).textureImageId(newImageId);
// Store the new texture in the list of this textureGroup
if ( _textureId != -1 ) {
......@@ -197,31 +208,6 @@ void TextureControlPlugin::slotMultiTextureAdded( QString _textureGroup , QStrin
}
bool TextureControlPlugin::getImage( QString _fileName, QImage& _image ) {
QString loadFilename;
if ( _fileName.startsWith("/") || _fileName.startsWith(".") || _fileName.contains(":") )
loadFilename = _fileName;
else
loadFilename = OpenFlipper::Options::textureDirStr() + QDir::separator() + _fileName;
//qimage cannot handle tga directly
if ( QFileInfo(loadFilename).suffix().toLower() == "tga" ){
QPixmap pic(loadFilename);
_image = pic.toImage();
} else {
//load the image
if ( !_image.load( loadFilename ) ){
_image.load(OpenFlipper::Options::textureDirStr() + QDir::separator() + "unknown.png");
return false;
}
}
return true;
}
void TextureControlPlugin::addedEmptyObject( int _id ) {
// Get the new object
......@@ -245,17 +231,15 @@ void TextureControlPlugin::addedEmptyObject( int _id ) {
// Iterate over all available global textures and add them to the object
for ( uint i = 0 ; i < globalTextures_.textures().size() ; ++i) {
// ================================================================================
// Get the image file
// ================================================================================
QImage textureImage;
if ( !getImage(globalTextures_.textures()[i].filename(),textureImage) )
emit log(LOGERR, "addedEmptyObject: Cannot load global texture '" + globalTextures_.textures()[i].name() +
"'. File not found '" + globalTextures_.textures()[i].filename() + "'");
// Add to image store
int newImageId = imageStore().addImageFile(globalTextures_.textures()[i].filename());
if ( newImageId == -1 ) {
emit log(LOGERR,imageStore().error());
continue;
}
// ================================================================================
// Add the texture to the texture node and get the corresponding id
// ================================================================================
......@@ -263,19 +247,22 @@ void TextureControlPlugin::addedEmptyObject( int _id ) {
//inform textureNode about the new texture
if( obj->dataType( DATA_TRIANGLE_MESH ) )
glName = PluginFunctions::triMeshObject(obj)->textureNode()->add_texture(textureImage);
glName = PluginFunctions::triMeshObject(obj)->textureNode()->add_texture(imageStore().getImage(newImageId,0));
if ( obj->dataType( DATA_POLY_MESH ) )
glName = PluginFunctions::polyMeshObject(obj)->textureNode()->add_texture(textureImage);
glName = PluginFunctions::polyMeshObject(obj)->textureNode()->add_texture(imageStore().getImage(newImageId,0));
// ================================================================================
// Store texture information in objects metadata
// ================================================================================
if (glName != 0) {
texData->addTexture(globalTextures_.textures()[i], glName);
texData->setImage(globalTextures_.textures()[i].name(),textureImage);
// Add to texture description
texData->setImage(globalTextures_.textures()[i].name(),newImageId);
}
else {
imageStore().removeImage(newImageId);
emit log(LOGERR,"addedEmptyObject: Unable to bind Texture");
continue;
}
......@@ -399,7 +386,12 @@ void TextureControlPlugin::slotTextureChangeImage( QString _textureName , QImage
// Update the image
// ================================================================================
Texture& texture = texData->texture(_textureName);
texture.textureImage = _image;
// Add to image store
int newImageId = imageStore().addImage(_image);
// Add to texture description
texture.textureImageId(newImageId);
// ================================================================================
// Flag dirty or update
......@@ -429,7 +421,12 @@ void TextureControlPlugin::slotTextureChangeImage( QString _textureName , QImage
// Update the image in the global texture
// ================================================================================
Texture& texture = globalTextures_.texture(_textureName);
texture.textureImage = _image;
// Add to image store
int newImageId = imageStore().addImage(_image);
// Add to texture description
texture.textureImageId(newImageId);
// ================================================================================
// check if the local textures need to be updated
......@@ -440,7 +437,7 @@ void TextureControlPlugin::slotTextureChangeImage( QString _textureName , QImage
if (texData != 0)
if ( texData->textureExists(_textureName) ){
Texture& localTex = texData->texture(_textureName);
localTex.textureImage = _image;
localTex.textureImageId(newImageId);
if( o_it->dataType( DATA_TRIANGLE_MESH ) ) {
PluginFunctions::triMeshObject(o_it)->textureNode()->set_texture( _image , texData->texture(_textureName).glName());
......@@ -482,7 +479,7 @@ void TextureControlPlugin::slotTextureGetImage( QString _textureName, QImage& _i
if ( texData->texture(_textureName).type() == MULTITEXTURE )
_image = QImage();
else
_image = texData->texture(_textureName).textureImage;
_image = imageStore().getImage(texData->texture(_textureName).textureImageId(),0 );
}
......@@ -496,7 +493,7 @@ void TextureControlPlugin::slotTextureGetImage( QString _textureName, QImage& _i
if ( globalTextures_.texture(_textureName).type() == MULTITEXTURE )
_image = QImage();
else
_image = globalTextures_.texture(_textureName).textureImage;
_image = imageStore().getImage(globalTextures_.texture(_textureName).textureImageId(),0);
}
void TextureControlPlugin::slotTextureIndex( QString _textureName, int _id, int& _index){
......@@ -1257,9 +1254,9 @@ void TextureControlPlugin::applyDialogSettings(TextureData* _texData, QString _t
Texture& texture = _texData->texture(_textureName );
if( obj->dataType( DATA_TRIANGLE_MESH ) ){
PluginFunctions::triMeshObject(obj)->textureNode()->set_texture(texture.textureImage , texture.glName() );
PluginFunctions::triMeshObject(obj)->textureNode()->set_texture(imageStore().getImage(texture.textureImageId(),0) , texture.glName() );
} else if ( obj->dataType( DATA_POLY_MESH ) ) {
PluginFunctions::polyMeshObject(obj)->textureNode()->set_texture(texture.textureImage , texture.glName() );
PluginFunctions::polyMeshObject(obj)->textureNode()->set_texture(imageStore().getImage(texture.textureImageId(),0) , texture.glName() );
}
// Always mark texture as dirty
......
......@@ -83,6 +83,7 @@ class TextureControlPlugin : public QObject, BaseInterface, BackupInterface, Tex
// BaseInterface
void updateView();
void updatedObject(int _identifier, const UpdateType _type);
// TextureInterface
void updateTexture( QString , int);
......@@ -158,9 +159,6 @@ class TextureControlPlugin : public QObject, BaseInterface, BackupInterface, Tex
bool StringToBool(QString _value);
/// Load an Image from disk ( if filename contains leading "/ " its consedered global otherwise in texturedir)
bool getImage( QString _fileName, QImage& _image );
/// Checks for a correct drawmode and changes if necessary
void switchDrawMode( TextureType _type );
......
......@@ -209,17 +209,17 @@ bool TextureData::addMultiTexture( QString _textureName ) {
}
/// Stores the given image in the texture information
bool TextureData::setImage( QString _textureName , QImage& _image ) {
bool TextureData::setImage( QString _textureName , int _id ) {
int textureid = -1;
textureid = getTextureIndex(_textureName);
if ( textureid == -1) {
std::cerr << "setImage: Unknown Texture!" << std::endl;
return true;
return false;
}
textures_[textureid].textureImage = _image;
return false;
textures_[textureid].textureImageId(_id);
return true;
}
//-----------------------------------------------------------------------------------
......
......@@ -47,7 +47,6 @@
#include <QString>
#include <QStringList>
#include <QImage>
#include <ACG/GL/gl.hh>
#include <vector>
#include <map>
......@@ -103,6 +102,7 @@ class Texture {
: parameters(_tex.parameters),
multiTextureList(_tex.multiTextureList),
name_(_tex.name_),
textureImageId_(_tex.textureImageId_),
visibleName_(_tex.visibleName_),
filename_(_tex.filename_),
id_(_tex.id_),
......@@ -114,8 +114,6 @@ class Texture {
type_(_tex.type_),
indexMappingProperty_(_tex.indexMappingProperty_)
{
// copy QImage ( we need a deep copy! )
textureImage = _tex.textureImage.copy(_tex.textureImage.rect());
}
......@@ -156,6 +154,9 @@ class Texture {
void clean() { dirty_ = false; };
void setDirty() { dirty_ = true; };
void textureImageId( int _id) {textureImageId_ = _id;};
int textureImageId() {return textureImageId_; };
void type( TextureType _type ) { type_ = _type; };
TextureType type( ) { return type_; };
......@@ -168,8 +169,6 @@ class Texture {
/// Parameters of the texture
TexParameters parameters;
/// The image used as the texture
QImage textureImage;