mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-26 09:35:28 +00:00
Merge remote-tracking branch 'scrawl/memory'
This commit is contained in:
commit
4894b3ec30
@ -14,6 +14,7 @@
|
|||||||
#include <OgreCompositionPass.h>
|
#include <OgreCompositionPass.h>
|
||||||
#include <OgreHardwarePixelBuffer.h>
|
#include <OgreHardwarePixelBuffer.h>
|
||||||
#include <OgreControllerManager.h>
|
#include <OgreControllerManager.h>
|
||||||
|
#include <OgreMeshManager.h>
|
||||||
|
|
||||||
#include <extern/shiny/Main/Factory.hpp>
|
#include <extern/shiny/Main/Factory.hpp>
|
||||||
#include <extern/shiny/Platforms/Ogre/OgrePlatform.hpp>
|
#include <extern/shiny/Platforms/Ogre/OgrePlatform.hpp>
|
||||||
@ -120,13 +121,11 @@ RenderingManager::RenderingManager(OEngine::Render::OgreRenderer& _rend, const b
|
|||||||
MaterialManager::getSingleton().setDefaultTextureFiltering(tfo);
|
MaterialManager::getSingleton().setDefaultTextureFiltering(tfo);
|
||||||
MaterialManager::getSingleton().setDefaultAnisotropy( (filter == "anisotropic") ? Settings::Manager::getInt("anisotropy", "General") : 1 );
|
MaterialManager::getSingleton().setDefaultAnisotropy( (filter == "anisotropic") ? Settings::Manager::getInt("anisotropy", "General") : 1 );
|
||||||
|
|
||||||
//ResourceGroupManager::getSingleton ().declareResource ("GlobalMap.png", "Texture", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
|
Ogre::TextureManager::getSingleton().setMemoryBudget(126*1024*1024);
|
||||||
|
Ogre::MeshManager::getSingleton().setMemoryBudget(64*1024*1024);
|
||||||
|
|
||||||
ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
|
ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
|
||||||
|
|
||||||
// causes light flicker in opengl when moving..
|
|
||||||
//mRendering.getScene()->setCameraRelativeRendering(true);
|
|
||||||
|
|
||||||
// disable unsupported effects
|
// disable unsupported effects
|
||||||
if (!Settings::Manager::getBool("shaders", "Objects"))
|
if (!Settings::Manager::getBool("shaders", "Objects"))
|
||||||
Settings::Manager::setBool("enabled", "Shadows", false);
|
Settings::Manager::setBool("enabled", "Shadows", false);
|
||||||
@ -236,6 +235,7 @@ void RenderingManager::toggleWater()
|
|||||||
|
|
||||||
void RenderingManager::cellAdded (MWWorld::Ptr::CellStore *store)
|
void RenderingManager::cellAdded (MWWorld::Ptr::CellStore *store)
|
||||||
{
|
{
|
||||||
|
sh::Factory::getInstance().unloadUnreferencedMaterials();
|
||||||
mObjects.buildStaticGeometry (*store);
|
mObjects.buildStaticGeometry (*store);
|
||||||
mDebugging->cellAdded(store);
|
mDebugging->cellAdded(store);
|
||||||
if (store->mCell->isExterior())
|
if (store->mCell->isExterior())
|
||||||
@ -306,7 +306,6 @@ void RenderingManager::update (float duration, bool paused)
|
|||||||
|
|
||||||
int blind = MWWorld::Class::get(player).getCreatureStats(player).getMagicEffects().get(MWMechanics::EffectKey(ESM::MagicEffect::Blind)).mMagnitude;
|
int blind = MWWorld::Class::get(player).getCreatureStats(player).getMagicEffects().get(MWMechanics::EffectKey(ESM::MagicEffect::Blind)).mMagnitude;
|
||||||
mRendering.getFader()->setFactor(1.f-(blind / 100.f));
|
mRendering.getFader()->setFactor(1.f-(blind / 100.f));
|
||||||
|
|
||||||
setAmbientMode();
|
setAmbientMode();
|
||||||
|
|
||||||
// player position
|
// player position
|
||||||
|
16
extern/shiny/CMakeLists.txt
vendored
16
extern/shiny/CMakeLists.txt
vendored
@ -9,8 +9,6 @@ set(SHINY_LIBRARY "shiny")
|
|||||||
set(SHINY_OGREPLATFORM_LIBRARY "shiny.OgrePlatform")
|
set(SHINY_OGREPLATFORM_LIBRARY "shiny.OgrePlatform")
|
||||||
|
|
||||||
# Sources
|
# Sources
|
||||||
file(GLOB SOURCE_FILES Main/*.cpp )
|
|
||||||
|
|
||||||
set(SOURCE_FILES
|
set(SOURCE_FILES
|
||||||
Main/Factory.cpp
|
Main/Factory.cpp
|
||||||
Main/MaterialInstance.cpp
|
Main/MaterialInstance.cpp
|
||||||
@ -57,12 +55,20 @@ file(GLOB OGRE_PLATFORM_SOURCE_FILES Platforms/Ogre/*.cpp)
|
|||||||
|
|
||||||
add_library(${SHINY_LIBRARY} STATIC ${SOURCE_FILES})
|
add_library(${SHINY_LIBRARY} STATIC ${SOURCE_FILES})
|
||||||
|
|
||||||
|
set(SHINY_LIBRARIES ${SHINY_LIBRARY})
|
||||||
|
|
||||||
if (SHINY_BUILD_OGRE_PLATFORM)
|
if (SHINY_BUILD_OGRE_PLATFORM)
|
||||||
add_library(${SHINY_OGREPLATFORM_LIBRARY} STATIC ${OGRE_PLATFORM_SOURCE_FILES})
|
add_library(${SHINY_OGREPLATFORM_LIBRARY} STATIC ${OGRE_PLATFORM_SOURCE_FILES})
|
||||||
|
set(SHINY_LIBRARIES ${SHINY_LIBRARIES} ${SHINY_OGREPLATFORM_LIBRARY})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
set(SHINY_LIBRARY ${SHINY_LIBRARY} PARENT_SCOPE)
|
||||||
|
|
||||||
|
if (DEFINED SHINY_BUILD_MATERIAL_EDITOR)
|
||||||
|
add_subdirectory(Editor)
|
||||||
|
|
||||||
|
set(SHINY_BUILD_EDITOR_FLAG ${SHINY_BUILD_EDITOR_FLAG} PARENT_SCOPE)
|
||||||
|
endif()
|
||||||
|
|
||||||
link_directories(${CMAKE_CURRENT_BINARY_DIR})
|
link_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
set(SHINY_LIBRARIES ${SHINY_LIBRARIES} PARENT_SCOPE)
|
||||||
set(SHINY_LIBRARY ${SHINY_LIBRARY} PARENT_SCOPE)
|
|
||||||
set(SHINY_OGREPLATFORM_LIBRARY ${SHINY_OGREPLATFORM_LIBRARY} PARENT_SCOPE)
|
|
||||||
|
2
extern/shiny/Docs/Configurations.dox
vendored
2
extern/shiny/Docs/Configurations.dox
vendored
@ -21,7 +21,7 @@
|
|||||||
}
|
}
|
||||||
\endcode
|
\endcode
|
||||||
|
|
||||||
\note You may also create configurations using sh::Factory::registerConfiguration.
|
\note You may also create configurations using sh::Factory::createConfiguration.
|
||||||
|
|
||||||
The active Configuration is controlled by the active material scheme in Ogre. So, in order to use the configuration "reflection_targets" for your reflection renders, simply call
|
The active Configuration is controlled by the active material scheme in Ogre. So, in order to use the configuration "reflection_targets" for your reflection renders, simply call
|
||||||
\code
|
\code
|
||||||
|
195
extern/shiny/Editor/Actions.cpp
vendored
Normal file
195
extern/shiny/Editor/Actions.cpp
vendored
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
#include "Actions.hpp"
|
||||||
|
|
||||||
|
#include "../Main/Factory.hpp"
|
||||||
|
|
||||||
|
namespace sh
|
||||||
|
{
|
||||||
|
|
||||||
|
void ActionDeleteMaterial::execute()
|
||||||
|
{
|
||||||
|
sh::Factory::getInstance().destroyMaterialInstance(mName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActionCloneMaterial::execute()
|
||||||
|
{
|
||||||
|
sh::MaterialInstance* sourceMaterial = sh::Factory::getInstance().getMaterialInstance(mSourceName);
|
||||||
|
std::string sourceMaterialParent = static_cast<sh::MaterialInstance*>(sourceMaterial->getParent())->getName();
|
||||||
|
sh::MaterialInstance* material = sh::Factory::getInstance().createMaterialInstance(
|
||||||
|
mDestName, sourceMaterialParent);
|
||||||
|
sourceMaterial->copyAll(material, sourceMaterial, false);
|
||||||
|
|
||||||
|
material->setSourceFile(sourceMaterial->getSourceFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActionSaveAll::execute()
|
||||||
|
{
|
||||||
|
sh::Factory::getInstance().saveAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActionChangeGlobalSetting::execute()
|
||||||
|
{
|
||||||
|
sh::Factory::getInstance().setGlobalSetting(mName, mNewValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActionCreateConfiguration::execute()
|
||||||
|
{
|
||||||
|
sh::Configuration newConfiguration;
|
||||||
|
sh::Factory::getInstance().createConfiguration(mName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActionDeleteConfiguration::execute()
|
||||||
|
{
|
||||||
|
sh::Factory::getInstance().destroyConfiguration(mName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActionChangeConfiguration::execute()
|
||||||
|
{
|
||||||
|
sh::Configuration* c = sh::Factory::getInstance().getConfiguration(mName);
|
||||||
|
c->setProperty(mKey, sh::makeProperty(new sh::StringValue(mValue)));
|
||||||
|
sh::Factory::getInstance().notifyConfigurationChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActionDeleteConfigurationProperty::execute()
|
||||||
|
{
|
||||||
|
sh::Configuration* c = sh::Factory::getInstance().getConfiguration(mName);
|
||||||
|
c->deleteProperty(mKey);
|
||||||
|
sh::Factory::getInstance().notifyConfigurationChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActionSetMaterialProperty::execute()
|
||||||
|
{
|
||||||
|
sh::MaterialInstance* m = sh::Factory::getInstance().getMaterialInstance(mName);
|
||||||
|
m->setProperty(mKey, sh::makeProperty(mValue));
|
||||||
|
|
||||||
|
sh::Factory::getInstance().notifyConfigurationChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActionDeleteMaterialProperty::execute()
|
||||||
|
{
|
||||||
|
sh::MaterialInstance* m = sh::Factory::getInstance().getMaterialInstance(mName);
|
||||||
|
m->deleteProperty(mKey);
|
||||||
|
|
||||||
|
sh::Factory::getInstance().notifyConfigurationChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActionCreatePass::execute()
|
||||||
|
{
|
||||||
|
sh::MaterialInstance* m = sh::Factory::getInstance().getMaterialInstance(mName);
|
||||||
|
m->createPass();
|
||||||
|
|
||||||
|
sh::Factory::getInstance().notifyConfigurationChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActionDeletePass::execute()
|
||||||
|
{
|
||||||
|
sh::MaterialInstance* m = sh::Factory::getInstance().getMaterialInstance(mName);
|
||||||
|
m->deletePass(mPassIndex);
|
||||||
|
|
||||||
|
sh::Factory::getInstance().notifyConfigurationChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActionSetPassProperty::execute()
|
||||||
|
{
|
||||||
|
sh::MaterialInstance* m = sh::Factory::getInstance().getMaterialInstance(mName);
|
||||||
|
assert (m->getPasses()->size() > mPassIndex);
|
||||||
|
m->getPasses()->at(mPassIndex).setProperty (mKey, sh::makeProperty(mValue));
|
||||||
|
|
||||||
|
sh::Factory::getInstance().notifyConfigurationChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActionDeletePassProperty::execute()
|
||||||
|
{
|
||||||
|
sh::MaterialInstance* m = sh::Factory::getInstance().getMaterialInstance(mName);
|
||||||
|
assert (m->getPasses()->size() > mPassIndex);
|
||||||
|
m->getPasses()->at(mPassIndex).deleteProperty(mKey);
|
||||||
|
|
||||||
|
sh::Factory::getInstance().notifyConfigurationChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActionSetShaderProperty::execute()
|
||||||
|
{
|
||||||
|
sh::MaterialInstance* m = sh::Factory::getInstance().getMaterialInstance(mName);
|
||||||
|
assert (m->getPasses()->size() > mPassIndex);
|
||||||
|
m->getPasses()->at(mPassIndex).mShaderProperties.setProperty (mKey, sh::makeProperty(mValue));
|
||||||
|
|
||||||
|
sh::Factory::getInstance().notifyConfigurationChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActionDeleteShaderProperty::execute()
|
||||||
|
{
|
||||||
|
sh::MaterialInstance* m = sh::Factory::getInstance().getMaterialInstance(mName);
|
||||||
|
assert (m->getPasses()->size() > mPassIndex);
|
||||||
|
m->getPasses()->at(mPassIndex).mShaderProperties.deleteProperty (mKey);
|
||||||
|
|
||||||
|
sh::Factory::getInstance().notifyConfigurationChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActionSetTextureProperty::execute()
|
||||||
|
{
|
||||||
|
sh::MaterialInstance* m = sh::Factory::getInstance().getMaterialInstance(mName);
|
||||||
|
assert (m->getPasses()->size() > mPassIndex);
|
||||||
|
assert (m->getPasses()->at(mPassIndex).mTexUnits.size() > mTextureIndex);
|
||||||
|
m->getPasses()->at(mPassIndex).mTexUnits.at(mTextureIndex).setProperty(mKey, sh::makeProperty(mValue));
|
||||||
|
|
||||||
|
sh::Factory::getInstance().notifyConfigurationChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActionDeleteTextureProperty::execute()
|
||||||
|
{
|
||||||
|
sh::MaterialInstance* m = sh::Factory::getInstance().getMaterialInstance(mName);
|
||||||
|
assert (m->getPasses()->size() > mPassIndex);
|
||||||
|
assert (m->getPasses()->at(mPassIndex).mTexUnits.size() > mTextureIndex);
|
||||||
|
m->getPasses()->at(mPassIndex).mTexUnits.at(mTextureIndex).deleteProperty(mKey);
|
||||||
|
|
||||||
|
sh::Factory::getInstance().notifyConfigurationChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActionCreateTextureUnit::execute()
|
||||||
|
{
|
||||||
|
sh::MaterialInstance* m = sh::Factory::getInstance().getMaterialInstance(mName);
|
||||||
|
assert (m->getPasses()->size() > mPassIndex);
|
||||||
|
m->getPasses()->at(mPassIndex).createTextureUnit(mTexUnitName);
|
||||||
|
|
||||||
|
sh::Factory::getInstance().notifyConfigurationChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActionDeleteTextureUnit::execute()
|
||||||
|
{
|
||||||
|
sh::MaterialInstance* m = sh::Factory::getInstance().getMaterialInstance(mName);
|
||||||
|
assert (m->getPasses()->size() > mPassIndex);
|
||||||
|
assert (m->getPasses()->at(mPassIndex).mTexUnits.size() > mTextureIndex);
|
||||||
|
|
||||||
|
m->getPasses()->at(mPassIndex).mTexUnits.erase(m->getPasses()->at(mPassIndex).mTexUnits.begin() + mTextureIndex);
|
||||||
|
|
||||||
|
sh::Factory::getInstance().notifyConfigurationChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActionMoveTextureUnit::execute()
|
||||||
|
{
|
||||||
|
sh::MaterialInstance* m = sh::Factory::getInstance().getMaterialInstance(mName);
|
||||||
|
assert (m->getPasses()->size() > mPassIndex);
|
||||||
|
assert (m->getPasses()->at(mPassIndex).mTexUnits.size() > mTextureIndex);
|
||||||
|
if (!mMoveUp)
|
||||||
|
assert (m->getPasses()->at(mPassIndex).mTexUnits.size() > mTextureIndex+1);
|
||||||
|
|
||||||
|
std::vector<MaterialInstanceTextureUnit> textures = m->getPasses()->at(mPassIndex).mTexUnits;
|
||||||
|
if (mMoveUp)
|
||||||
|
std::swap(textures[mTextureIndex-1], textures[mTextureIndex]);
|
||||||
|
else
|
||||||
|
std::swap(textures[mTextureIndex+1], textures[mTextureIndex]);
|
||||||
|
m->getPasses()->at(mPassIndex).mTexUnits = textures;
|
||||||
|
|
||||||
|
sh::Factory::getInstance().notifyConfigurationChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActionChangeTextureUnitName::execute()
|
||||||
|
{
|
||||||
|
sh::MaterialInstance* m = sh::Factory::getInstance().getMaterialInstance(mName);
|
||||||
|
assert (m->getPasses()->size() > mPassIndex);
|
||||||
|
assert (m->getPasses()->at(mPassIndex).mTexUnits.size() > mTextureIndex);
|
||||||
|
|
||||||
|
m->getPasses()->at(mPassIndex).mTexUnits[mTextureIndex].setName(mTexUnitName);
|
||||||
|
|
||||||
|
sh::Factory::getInstance().notifyConfigurationChanged();
|
||||||
|
}
|
||||||
|
}
|
307
extern/shiny/Editor/Actions.hpp
vendored
Normal file
307
extern/shiny/Editor/Actions.hpp
vendored
Normal file
@ -0,0 +1,307 @@
|
|||||||
|
#ifndef SH_ACTIONS_H
|
||||||
|
#define SH_ACTIONS_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace sh
|
||||||
|
{
|
||||||
|
|
||||||
|
class Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void execute() = 0;
|
||||||
|
virtual ~Action();
|
||||||
|
};
|
||||||
|
|
||||||
|
class ActionDeleteMaterial : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ActionDeleteMaterial(const std::string& name)
|
||||||
|
: mName(name) {}
|
||||||
|
|
||||||
|
virtual void execute();
|
||||||
|
private:
|
||||||
|
std::string mName;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ActionCloneMaterial : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ActionCloneMaterial(const std::string& sourceName, const std::string& destName)
|
||||||
|
: mSourceName(sourceName), mDestName(destName) {}
|
||||||
|
|
||||||
|
virtual void execute();
|
||||||
|
private:
|
||||||
|
std::string mSourceName;
|
||||||
|
std::string mDestName;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ActionSaveAll : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void execute();
|
||||||
|
};
|
||||||
|
|
||||||
|
class ActionChangeGlobalSetting : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ActionChangeGlobalSetting(const std::string& name, const std::string& newValue)
|
||||||
|
: mName(name), mNewValue(newValue) {}
|
||||||
|
|
||||||
|
virtual void execute();
|
||||||
|
private:
|
||||||
|
std::string mName;
|
||||||
|
std::string mNewValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
// configuration
|
||||||
|
|
||||||
|
class ActionCreateConfiguration : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ActionCreateConfiguration(const std::string& name)
|
||||||
|
: mName(name) {}
|
||||||
|
|
||||||
|
virtual void execute();
|
||||||
|
private:
|
||||||
|
std::string mName;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class ActionDeleteConfiguration : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ActionDeleteConfiguration(const std::string& name)
|
||||||
|
: mName(name) {}
|
||||||
|
|
||||||
|
virtual void execute();
|
||||||
|
private:
|
||||||
|
std::string mName;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class ActionChangeConfiguration : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ActionChangeConfiguration (const std::string& name, const std::string& key, const std::string& value)
|
||||||
|
: mName(name), mKey(key), mValue(value) {}
|
||||||
|
|
||||||
|
virtual void execute();
|
||||||
|
private:
|
||||||
|
std::string mName;
|
||||||
|
std::string mKey;
|
||||||
|
std::string mValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ActionDeleteConfigurationProperty : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ActionDeleteConfigurationProperty (const std::string& name, const std::string& key)
|
||||||
|
: mName(name), mKey(key) {}
|
||||||
|
|
||||||
|
virtual void execute();
|
||||||
|
private:
|
||||||
|
std::string mName;
|
||||||
|
std::string mKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
// material
|
||||||
|
|
||||||
|
class ActionSetMaterialProperty : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ActionSetMaterialProperty (const std::string& name, const std::string& key, const std::string& value)
|
||||||
|
: mName(name), mKey(key), mValue(value) {}
|
||||||
|
|
||||||
|
virtual void execute();
|
||||||
|
private:
|
||||||
|
std::string mName;
|
||||||
|
std::string mKey;
|
||||||
|
std::string mValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ActionDeleteMaterialProperty : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ActionDeleteMaterialProperty (const std::string& name, const std::string& key)
|
||||||
|
: mName(name), mKey(key) {}
|
||||||
|
|
||||||
|
virtual void execute();
|
||||||
|
private:
|
||||||
|
std::string mName;
|
||||||
|
std::string mKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
// pass
|
||||||
|
|
||||||
|
class ActionCreatePass : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ActionCreatePass (const std::string& name)
|
||||||
|
: mName(name) {}
|
||||||
|
|
||||||
|
virtual void execute();
|
||||||
|
private:
|
||||||
|
std::string mName;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ActionDeletePass : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ActionDeletePass (const std::string& name, int passIndex)
|
||||||
|
: mName(name), mPassIndex(passIndex) {}
|
||||||
|
|
||||||
|
virtual void execute();
|
||||||
|
private:
|
||||||
|
std::string mName;
|
||||||
|
int mPassIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ActionSetPassProperty : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ActionSetPassProperty (const std::string& name, int passIndex, const std::string& key, const std::string& value)
|
||||||
|
: mName(name), mPassIndex(passIndex), mKey(key), mValue(value) {}
|
||||||
|
|
||||||
|
virtual void execute();
|
||||||
|
private:
|
||||||
|
std::string mName;
|
||||||
|
int mPassIndex;
|
||||||
|
std::string mKey;
|
||||||
|
std::string mValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ActionDeletePassProperty : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ActionDeletePassProperty (const std::string& name, int passIndex, const std::string& key)
|
||||||
|
: mName(name), mPassIndex(passIndex), mKey(key) {}
|
||||||
|
|
||||||
|
virtual void execute();
|
||||||
|
private:
|
||||||
|
std::string mName;
|
||||||
|
int mPassIndex;
|
||||||
|
std::string mKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
// shader
|
||||||
|
|
||||||
|
class ActionSetShaderProperty : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ActionSetShaderProperty (const std::string& name, int passIndex, const std::string& key, const std::string& value)
|
||||||
|
: mName(name), mPassIndex(passIndex), mKey(key), mValue(value) {}
|
||||||
|
|
||||||
|
virtual void execute();
|
||||||
|
private:
|
||||||
|
std::string mName;
|
||||||
|
int mPassIndex;
|
||||||
|
std::string mKey;
|
||||||
|
std::string mValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ActionDeleteShaderProperty : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ActionDeleteShaderProperty (const std::string& name, int passIndex, const std::string& key)
|
||||||
|
: mName(name), mPassIndex(passIndex), mKey(key) {}
|
||||||
|
|
||||||
|
virtual void execute();
|
||||||
|
private:
|
||||||
|
std::string mName;
|
||||||
|
int mPassIndex;
|
||||||
|
std::string mKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
// texture unit
|
||||||
|
|
||||||
|
class ActionChangeTextureUnitName : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ActionChangeTextureUnitName (const std::string& name, int passIndex, int textureIndex, const std::string& texUnitName)
|
||||||
|
: mName(name), mPassIndex(passIndex), mTextureIndex(textureIndex), mTexUnitName(texUnitName) {}
|
||||||
|
|
||||||
|
virtual void execute();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string mName;
|
||||||
|
int mPassIndex;
|
||||||
|
int mTextureIndex;
|
||||||
|
std::string mTexUnitName;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ActionCreateTextureUnit : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ActionCreateTextureUnit (const std::string& name, int passIndex, const std::string& texUnitName)
|
||||||
|
: mName(name), mPassIndex(passIndex), mTexUnitName(texUnitName) {}
|
||||||
|
|
||||||
|
virtual void execute();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string mName;
|
||||||
|
int mPassIndex;
|
||||||
|
std::string mTexUnitName;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ActionDeleteTextureUnit : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ActionDeleteTextureUnit (const std::string& name, int passIndex, int textureIndex)
|
||||||
|
: mName(name), mPassIndex(passIndex), mTextureIndex(textureIndex) {}
|
||||||
|
|
||||||
|
virtual void execute();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string mName;
|
||||||
|
int mPassIndex;
|
||||||
|
int mTextureIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ActionMoveTextureUnit : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ActionMoveTextureUnit (const std::string& name, int passIndex, int textureIndex, bool moveUp)
|
||||||
|
: mName(name), mPassIndex(passIndex), mTextureIndex(textureIndex), mMoveUp(moveUp) {}
|
||||||
|
|
||||||
|
virtual void execute();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string mName;
|
||||||
|
int mPassIndex;
|
||||||
|
int mTextureIndex;
|
||||||
|
bool mMoveUp;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ActionSetTextureProperty : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ActionSetTextureProperty (const std::string& name, int passIndex, int textureIndex, const std::string& key, const std::string& value)
|
||||||
|
: mName(name), mPassIndex(passIndex), mTextureIndex(textureIndex), mKey(key), mValue(value) {}
|
||||||
|
|
||||||
|
virtual void execute();
|
||||||
|
private:
|
||||||
|
std::string mName;
|
||||||
|
int mPassIndex;
|
||||||
|
int mTextureIndex;
|
||||||
|
std::string mKey;
|
||||||
|
std::string mValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ActionDeleteTextureProperty : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ActionDeleteTextureProperty (const std::string& name, int passIndex, int textureIndex, const std::string& key)
|
||||||
|
: mName(name), mPassIndex(passIndex), mTextureIndex(textureIndex), mKey(key) {}
|
||||||
|
|
||||||
|
virtual void execute();
|
||||||
|
private:
|
||||||
|
std::string mName;
|
||||||
|
int mPassIndex;
|
||||||
|
int mTextureIndex;
|
||||||
|
std::string mKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
31
extern/shiny/Editor/AddPropertyDialog.cpp
vendored
Normal file
31
extern/shiny/Editor/AddPropertyDialog.cpp
vendored
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#include "AddPropertyDialog.hpp"
|
||||||
|
#include "ui_addpropertydialog.h"
|
||||||
|
|
||||||
|
AddPropertyDialog::AddPropertyDialog(QWidget *parent)
|
||||||
|
: QDialog(parent)
|
||||||
|
, ui(new Ui::AddPropertyDialog)
|
||||||
|
, mType(0)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
connect(ui->buttonBox, SIGNAL(accepted()),
|
||||||
|
this, SLOT(accepted()));
|
||||||
|
connect(ui->buttonBox, SIGNAL(rejected()),
|
||||||
|
this, SLOT(rejected()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddPropertyDialog::accepted()
|
||||||
|
{
|
||||||
|
mName = ui->lineEdit->text();
|
||||||
|
mType = ui->comboBox->currentIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddPropertyDialog::rejected()
|
||||||
|
{
|
||||||
|
mName = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
AddPropertyDialog::~AddPropertyDialog()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
22
extern/shiny/Editor/AddPropertyDialog.h
vendored
Normal file
22
extern/shiny/Editor/AddPropertyDialog.h
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#ifndef ADDPROPERTYDIALOG_H
|
||||||
|
#define ADDPROPERTYDIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class AddPropertyDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
class AddPropertyDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit AddPropertyDialog(QWidget *parent = 0);
|
||||||
|
~AddPropertyDialog();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::AddPropertyDialog *ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ADDPROPERTYDIALOG_H
|
29
extern/shiny/Editor/AddPropertyDialog.hpp
vendored
Normal file
29
extern/shiny/Editor/AddPropertyDialog.hpp
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#ifndef ADDPROPERTYDIALOG_H
|
||||||
|
#define ADDPROPERTYDIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class AddPropertyDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
class AddPropertyDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit AddPropertyDialog(QWidget *parent = 0);
|
||||||
|
~AddPropertyDialog();
|
||||||
|
|
||||||
|
int mType;
|
||||||
|
QString mName;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void accepted();
|
||||||
|
void rejected();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::AddPropertyDialog *ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ADDPROPERTYDIALOG_H
|
61
extern/shiny/Editor/CMakeLists.txt
vendored
Normal file
61
extern/shiny/Editor/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
set(SHINY_EDITOR_LIBRARY "shiny.Editor")
|
||||||
|
|
||||||
|
find_package(Qt4)
|
||||||
|
|
||||||
|
if (QT_FOUND)
|
||||||
|
|
||||||
|
add_definitions(-DSHINY_BUILD_MATERIAL_EDITOR=1)
|
||||||
|
set (SHINY_BUILD_EDITOR_FLAG -DSHINY_BUILD_MATERIAL_EDITOR=1 PARENT_SCOPE)
|
||||||
|
|
||||||
|
set(QT_USE_QTGUI 1)
|
||||||
|
|
||||||
|
# Headers that must be preprocessed
|
||||||
|
set(SHINY_EDITOR_HEADER_MOC
|
||||||
|
MainWindow.hpp
|
||||||
|
NewMaterialDialog.hpp
|
||||||
|
AddPropertyDialog.hpp
|
||||||
|
PropertySortModel.hpp
|
||||||
|
)
|
||||||
|
|
||||||
|
set(SHINY_EDITOR_UI
|
||||||
|
mainwindow.ui
|
||||||
|
newmaterialdialog.ui
|
||||||
|
addpropertydialog.ui
|
||||||
|
)
|
||||||
|
|
||||||
|
QT4_WRAP_CPP(MOC_SRCS ${SHINY_EDITOR_HEADER_MOC})
|
||||||
|
QT4_WRAP_UI(UI_HDRS ${SHINY_EDITOR_UI})
|
||||||
|
|
||||||
|
set(SOURCE_FILES
|
||||||
|
NewMaterialDialog.cpp
|
||||||
|
AddPropertyDialog.cpp
|
||||||
|
ColoredTabWidget.hpp
|
||||||
|
MainWindow.cpp
|
||||||
|
Editor.cpp
|
||||||
|
Actions.cpp
|
||||||
|
Query.cpp
|
||||||
|
PropertySortModel.cpp
|
||||||
|
${SHINY_EDITOR_UI} # Just to have them in the IDE's file explorer
|
||||||
|
)
|
||||||
|
|
||||||
|
include(${QT_USE_FILE})
|
||||||
|
|
||||||
|
set (CMAKE_INCLUDE_CURRENT_DIR "true")
|
||||||
|
|
||||||
|
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|
||||||
|
add_library(${SHINY_EDITOR_LIBRARY} STATIC ${SOURCE_FILES} ${MOC_SRCS} ${UI_HDRS})
|
||||||
|
|
||||||
|
set(SHINY_LIBRARIES ${SHINY_LIBRARIES}
|
||||||
|
${SHINY_EDITOR_LIBRARY}
|
||||||
|
${QT_LIBRARIES}
|
||||||
|
)
|
||||||
|
set(SHINY_LIBRARIES ${SHINY_LIBRARIES} PARENT_SCOPE)
|
||||||
|
|
||||||
|
else (QT_FOUND)
|
||||||
|
|
||||||
|
add_definitions(-DSHINY_BUILD_MATERIAL_EDITOR=0)
|
||||||
|
set (SHINY_BUILD_EDITOR_FLAG -DSHINY_BUILD_MATERIAL_EDITOR=0 PARENT_SCOPE)
|
||||||
|
message(STATUS "QT4 was not found. You will not be able to use the material editor.")
|
||||||
|
|
||||||
|
endif(QT_FOUND)
|
24
extern/shiny/Editor/ColoredTabWidget.hpp
vendored
Normal file
24
extern/shiny/Editor/ColoredTabWidget.hpp
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#ifndef SHINY_EDITOR_COLOREDTABWIDGET_H
|
||||||
|
#define SHINY_EDITOR_COLOREDTABWIDGET_H
|
||||||
|
|
||||||
|
#include <QTabWidget>
|
||||||
|
|
||||||
|
namespace sh
|
||||||
|
{
|
||||||
|
|
||||||
|
/// Makes tabBar() public to allow changing tab title colors.
|
||||||
|
class ColoredTabWidget : public QTabWidget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ColoredTabWidget(QWidget* parent = 0)
|
||||||
|
: QTabWidget(parent) {}
|
||||||
|
|
||||||
|
QTabBar* tabBar()
|
||||||
|
{
|
||||||
|
return QTabWidget::tabBar();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
117
extern/shiny/Editor/Editor.cpp
vendored
Normal file
117
extern/shiny/Editor/Editor.cpp
vendored
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
#include "Editor.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
#include <boost/thread.hpp>
|
||||||
|
|
||||||
|
#include "../Main/Factory.hpp"
|
||||||
|
|
||||||
|
#include "MainWindow.hpp"
|
||||||
|
|
||||||
|
namespace sh
|
||||||
|
{
|
||||||
|
|
||||||
|
Editor::Editor()
|
||||||
|
: mMainWindow(NULL)
|
||||||
|
, mApplication(NULL)
|
||||||
|
, mInitialized(false)
|
||||||
|
, mThread(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Editor::~Editor()
|
||||||
|
{
|
||||||
|
if (mMainWindow)
|
||||||
|
mMainWindow->mRequestExit = true;
|
||||||
|
|
||||||
|
if (mThread)
|
||||||
|
mThread->join();
|
||||||
|
delete mThread;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Editor::show()
|
||||||
|
{
|
||||||
|
if (!mInitialized)
|
||||||
|
{
|
||||||
|
mInitialized = true;
|
||||||
|
|
||||||
|
mThread = new boost::thread(boost::bind(&Editor::runThread, this));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (mMainWindow)
|
||||||
|
mMainWindow->mRequestShowWindow = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Editor::runThread()
|
||||||
|
{
|
||||||
|
int argc = 0;
|
||||||
|
char** argv = NULL;
|
||||||
|
mApplication = new QApplication(argc, argv);
|
||||||
|
mApplication->setQuitOnLastWindowClosed(false);
|
||||||
|
mMainWindow = new MainWindow();
|
||||||
|
mMainWindow->mSync = &mSync;
|
||||||
|
mMainWindow->show();
|
||||||
|
|
||||||
|
mApplication->exec();
|
||||||
|
|
||||||
|
delete mApplication;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Editor::update()
|
||||||
|
{
|
||||||
|
sh::Factory::getInstance().doMonitorShaderFiles();
|
||||||
|
|
||||||
|
if (!mMainWindow)
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::mutex::scoped_lock lock(mSync.mActionMutex);
|
||||||
|
|
||||||
|
// execute pending actions
|
||||||
|
while (mMainWindow->mActionQueue.size())
|
||||||
|
{
|
||||||
|
Action* action = mMainWindow->mActionQueue.front();
|
||||||
|
action->execute();
|
||||||
|
delete action;
|
||||||
|
mMainWindow->mActionQueue.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
boost::mutex::scoped_lock lock(mSync.mQueryMutex);
|
||||||
|
|
||||||
|
// execute pending queries
|
||||||
|
for (std::vector<Query*>::iterator it = mMainWindow->mQueries.begin(); it != mMainWindow->mQueries.end(); ++it)
|
||||||
|
{
|
||||||
|
Query* query = *it;
|
||||||
|
if (!query->mDone)
|
||||||
|
query->execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::mutex::scoped_lock lock2(mSync.mUpdateMutex);
|
||||||
|
|
||||||
|
// update the list of materials
|
||||||
|
mMainWindow->mState.mMaterialList.clear();
|
||||||
|
sh::Factory::getInstance().listMaterials(mMainWindow->mState.mMaterialList);
|
||||||
|
|
||||||
|
// update global settings
|
||||||
|
mMainWindow->mState.mGlobalSettingsMap.clear();
|
||||||
|
sh::Factory::getInstance().listGlobalSettings(mMainWindow->mState.mGlobalSettingsMap);
|
||||||
|
|
||||||
|
// update configuration list
|
||||||
|
mMainWindow->mState.mConfigurationList.clear();
|
||||||
|
sh::Factory::getInstance().listConfigurationNames(mMainWindow->mState.mConfigurationList);
|
||||||
|
|
||||||
|
// update shader list
|
||||||
|
mMainWindow->mState.mShaderSets.clear();
|
||||||
|
sh::Factory::getInstance().listShaderSets(mMainWindow->mState.mShaderSets);
|
||||||
|
|
||||||
|
mMainWindow->mState.mErrors += sh::Factory::getInstance().getErrorLog();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
73
extern/shiny/Editor/Editor.hpp
vendored
Normal file
73
extern/shiny/Editor/Editor.hpp
vendored
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
#ifndef SH_EDITOR_H
|
||||||
|
#define SH_EDITOR_H
|
||||||
|
|
||||||
|
#if SHINY_BUILD_MATERIAL_EDITOR
|
||||||
|
class QApplication;
|
||||||
|
|
||||||
|
#include <boost/thread/condition_variable.hpp>
|
||||||
|
#include <boost/thread/mutex.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
class thread;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace sh
|
||||||
|
{
|
||||||
|
class MainWindow;
|
||||||
|
|
||||||
|
struct SynchronizationState
|
||||||
|
{
|
||||||
|
boost::mutex mUpdateMutex;
|
||||||
|
boost::mutex mActionMutex;
|
||||||
|
boost::mutex mQueryMutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Editor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
Editor();
|
||||||
|
~Editor();
|
||||||
|
|
||||||
|
void show();
|
||||||
|
void update();
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool mInitialized;
|
||||||
|
|
||||||
|
MainWindow* mMainWindow;
|
||||||
|
QApplication* mApplication;
|
||||||
|
|
||||||
|
SynchronizationState mSync;
|
||||||
|
|
||||||
|
boost::thread* mThread;
|
||||||
|
|
||||||
|
void runThread();
|
||||||
|
|
||||||
|
void processShowWindow();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// Dummy implementation, so that the user's code does not have to be polluted with #ifdefs
|
||||||
|
namespace sh
|
||||||
|
{
|
||||||
|
|
||||||
|
class Editor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Editor() {}
|
||||||
|
~Editor() {}
|
||||||
|
void show() {}
|
||||||
|
void update() {}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
950
extern/shiny/Editor/MainWindow.cpp
vendored
Normal file
950
extern/shiny/Editor/MainWindow.cpp
vendored
Normal file
@ -0,0 +1,950 @@
|
|||||||
|
#include "MainWindow.hpp"
|
||||||
|
#include "ui_mainwindow.h"
|
||||||
|
|
||||||
|
#include <QCloseEvent>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
#include <QInputDialog>
|
||||||
|
#include <QMessageBox>
|
||||||
|
|
||||||
|
#include "Editor.hpp"
|
||||||
|
#include "ColoredTabWidget.hpp"
|
||||||
|
#include "AddPropertyDialog.hpp"
|
||||||
|
|
||||||
|
sh::MainWindow::MainWindow(QWidget *parent)
|
||||||
|
: QMainWindow(parent)
|
||||||
|
, ui(new Ui::MainWindow)
|
||||||
|
, mRequestShowWindow(false)
|
||||||
|
, mRequestExit(false)
|
||||||
|
, mIgnoreGlobalSettingChange(false)
|
||||||
|
, mIgnoreConfigurationChange(false)
|
||||||
|
, mIgnoreMaterialChange(false)
|
||||||
|
, mIgnoreMaterialPropertyChange(false)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
QTimer *timer = new QTimer(this);
|
||||||
|
connect(timer, SIGNAL(timeout()), this, SLOT(onIdle()));
|
||||||
|
timer->start(50);
|
||||||
|
|
||||||
|
QList<int> sizes;
|
||||||
|
sizes << 250;
|
||||||
|
sizes << 550;
|
||||||
|
ui->splitter->setSizes(sizes);
|
||||||
|
|
||||||
|
mMaterialModel = new QStringListModel(this);
|
||||||
|
|
||||||
|
mMaterialProxyModel = new QSortFilterProxyModel(this);
|
||||||
|
mMaterialProxyModel->setSourceModel(mMaterialModel);
|
||||||
|
mMaterialProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
|
||||||
|
mMaterialProxyModel->setDynamicSortFilter(true);
|
||||||
|
mMaterialProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
|
||||||
|
|
||||||
|
ui->materialList->setModel(mMaterialProxyModel);
|
||||||
|
ui->materialList->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||||
|
ui->materialList->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||||
|
ui->materialList->setAlternatingRowColors(true);
|
||||||
|
|
||||||
|
connect(ui->materialList->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
|
||||||
|
this, SLOT(onMaterialSelectionChanged(QModelIndex,QModelIndex)));
|
||||||
|
|
||||||
|
mMaterialPropertyModel = new QStandardItemModel(0, 2, this);
|
||||||
|
mMaterialPropertyModel->setHorizontalHeaderItem(0, new QStandardItem(QString("Name")));
|
||||||
|
mMaterialPropertyModel->setHorizontalHeaderItem(1, new QStandardItem(QString("Value")));
|
||||||
|
connect(mMaterialPropertyModel, SIGNAL(itemChanged(QStandardItem*)),
|
||||||
|
this, SLOT(onMaterialPropertyChanged(QStandardItem*)));
|
||||||
|
|
||||||
|
mMaterialSortModel = new PropertySortModel(this);
|
||||||
|
mMaterialSortModel->setSourceModel(mMaterialPropertyModel);
|
||||||
|
mMaterialSortModel->setDynamicSortFilter(true);
|
||||||
|
mMaterialSortModel->setSortCaseSensitivity(Qt::CaseInsensitive);
|
||||||
|
|
||||||
|
ui->materialView->setModel(mMaterialSortModel);
|
||||||
|
ui->materialView->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
ui->materialView->setAlternatingRowColors(true);
|
||||||
|
ui->materialView->setSortingEnabled(true);
|
||||||
|
connect(ui->materialView, SIGNAL(customContextMenuRequested(QPoint)),
|
||||||
|
this, SLOT(onContextMenuRequested(QPoint)));
|
||||||
|
|
||||||
|
mGlobalSettingsModel = new QStandardItemModel(0, 2, this);
|
||||||
|
mGlobalSettingsModel->setHorizontalHeaderItem(0, new QStandardItem(QString("Name")));
|
||||||
|
mGlobalSettingsModel->setHorizontalHeaderItem(1, new QStandardItem(QString("Value")));
|
||||||
|
connect(mGlobalSettingsModel, SIGNAL(itemChanged(QStandardItem*)),
|
||||||
|
this, SLOT(onGlobalSettingChanged(QStandardItem*)));
|
||||||
|
|
||||||
|
ui->globalSettingsView->setModel(mGlobalSettingsModel);
|
||||||
|
ui->globalSettingsView->verticalHeader()->setResizeMode(QHeaderView::ResizeToContents);
|
||||||
|
ui->globalSettingsView->verticalHeader()->hide();
|
||||||
|
ui->globalSettingsView->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
|
||||||
|
ui->globalSettingsView->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||||
|
|
||||||
|
ui->configurationList->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||||
|
ui->configurationList->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||||
|
connect(ui->configurationList, SIGNAL(currentTextChanged(QString)),
|
||||||
|
this, SLOT(onConfigurationSelectionChanged(QString)));
|
||||||
|
|
||||||
|
mConfigurationModel = new QStandardItemModel(0, 2, this);
|
||||||
|
mConfigurationModel->setHorizontalHeaderItem(0, new QStandardItem(QString("Name")));
|
||||||
|
mConfigurationModel->setHorizontalHeaderItem(1, new QStandardItem(QString("Value")));
|
||||||
|
connect(mConfigurationModel, SIGNAL(itemChanged(QStandardItem*)),
|
||||||
|
this, SLOT(onConfigurationChanged(QStandardItem*)));
|
||||||
|
|
||||||
|
ui->configurationView->setModel(mConfigurationModel);
|
||||||
|
ui->configurationView->verticalHeader()->setResizeMode(QHeaderView::ResizeToContents);
|
||||||
|
ui->configurationView->verticalHeader()->hide();
|
||||||
|
ui->configurationView->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
|
||||||
|
ui->configurationView->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||||
|
}
|
||||||
|
|
||||||
|
sh::MainWindow::~MainWindow()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sh::MainWindow::closeEvent(QCloseEvent *event)
|
||||||
|
{
|
||||||
|
this->hide();
|
||||||
|
event->ignore();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sh::MainWindow::onIdle()
|
||||||
|
{
|
||||||
|
if (mRequestShowWindow)
|
||||||
|
{
|
||||||
|
mRequestShowWindow = false;
|
||||||
|
show();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mRequestExit)
|
||||||
|
{
|
||||||
|
QApplication::exit();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::mutex::scoped_lock lock(mSync->mUpdateMutex);
|
||||||
|
|
||||||
|
|
||||||
|
mIgnoreMaterialChange = true;
|
||||||
|
QString selected;
|
||||||
|
|
||||||
|
QModelIndex selectedIndex = ui->materialList->selectionModel()->currentIndex();
|
||||||
|
if (selectedIndex.isValid())
|
||||||
|
selected = mMaterialModel->data(selectedIndex, Qt::DisplayRole).toString();
|
||||||
|
|
||||||
|
QStringList list;
|
||||||
|
|
||||||
|
for (std::vector<std::string>::const_iterator it = mState.mMaterialList.begin(); it != mState.mMaterialList.end(); ++it)
|
||||||
|
{
|
||||||
|
list.push_back(QString::fromStdString(*it));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mMaterialModel->stringList() != list)
|
||||||
|
{
|
||||||
|
mMaterialModel->setStringList(list);
|
||||||
|
|
||||||
|
// quick hack to keep our selection when the model has changed
|
||||||
|
if (!selected.isEmpty())
|
||||||
|
for (int i=0; i<mMaterialModel->rowCount(); ++i)
|
||||||
|
{
|
||||||
|
const QModelIndex& index = mMaterialModel->index(i,0);
|
||||||
|
if (mMaterialModel->data(index, Qt::DisplayRole).toString() == selected)
|
||||||
|
{
|
||||||
|
ui->materialList->setCurrentIndex(index);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mIgnoreMaterialChange = false;
|
||||||
|
|
||||||
|
mIgnoreGlobalSettingChange = true;
|
||||||
|
for (std::map<std::string, std::string>::const_iterator it = mState.mGlobalSettingsMap.begin();
|
||||||
|
it != mState.mGlobalSettingsMap.end(); ++it)
|
||||||
|
{
|
||||||
|
QList<QStandardItem *> list = mGlobalSettingsModel->findItems(QString::fromStdString(it->first));
|
||||||
|
if (!list.empty()) // item was already there
|
||||||
|
{
|
||||||
|
// if it changed, set the value column
|
||||||
|
if (mGlobalSettingsModel->data(mGlobalSettingsModel->index(list.front()->row(), 1)).toString()
|
||||||
|
!= QString::fromStdString(it->second))
|
||||||
|
{
|
||||||
|
mGlobalSettingsModel->setItem(list.front()->row(), 1, new QStandardItem(QString::fromStdString(it->second)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // item wasn't there; insert new row
|
||||||
|
{
|
||||||
|
QList<QStandardItem*> toAdd;
|
||||||
|
QStandardItem* name = new QStandardItem(QString::fromStdString(it->first));
|
||||||
|
name->setFlags(name->flags() &= ~Qt::ItemIsEditable);
|
||||||
|
QStandardItem* value = new QStandardItem(QString::fromStdString(it->second));
|
||||||
|
toAdd.push_back(name);
|
||||||
|
toAdd.push_back(value);
|
||||||
|
mGlobalSettingsModel->appendRow(toAdd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mIgnoreGlobalSettingChange = false;
|
||||||
|
|
||||||
|
|
||||||
|
mIgnoreConfigurationChange = true;
|
||||||
|
QList<QListWidgetItem*> selected_ = ui->configurationList->selectedItems();
|
||||||
|
QString selectedStr;
|
||||||
|
if (selected_.size())
|
||||||
|
selectedStr = selected_.front()->text();
|
||||||
|
|
||||||
|
ui->configurationList->clear();
|
||||||
|
|
||||||
|
for (std::vector<std::string>::const_iterator it = mState.mConfigurationList.begin(); it != mState.mConfigurationList.end(); ++it)
|
||||||
|
ui->configurationList->addItem(QString::fromStdString(*it));
|
||||||
|
|
||||||
|
if (!selectedStr.isEmpty())
|
||||||
|
for (int i=0; i<ui->configurationList->count(); ++i)
|
||||||
|
{
|
||||||
|
if (ui->configurationList->item(i)->text() == selectedStr)
|
||||||
|
{
|
||||||
|
ui->configurationList->setCurrentItem(ui->configurationList->item(i), QItemSelectionModel::ClearAndSelect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mIgnoreConfigurationChange = false;
|
||||||
|
|
||||||
|
if (!mState.mErrors.empty())
|
||||||
|
{
|
||||||
|
ui->errorLog->append(QString::fromStdString(mState.mErrors));
|
||||||
|
mState.mErrors = "";
|
||||||
|
QColor color = ui->tabWidget->palette().color(QPalette::Normal, QPalette::Link);
|
||||||
|
ui->tabWidget->tabBar()->setTabTextColor(3, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// process query results
|
||||||
|
boost::mutex::scoped_lock lock2(mSync->mQueryMutex);
|
||||||
|
for (std::vector<Query*>::iterator it = mQueries.begin(); it != mQueries.end();)
|
||||||
|
{
|
||||||
|
if ((*it)->mDone)
|
||||||
|
{
|
||||||
|
if (typeid(**it) == typeid(ConfigurationQuery))
|
||||||
|
buildConfigurationModel(static_cast<ConfigurationQuery*>(*it));
|
||||||
|
else if (typeid(**it) == typeid(MaterialQuery))
|
||||||
|
buildMaterialModel(static_cast<MaterialQuery*>(*it));
|
||||||
|
else if (typeid(**it) == typeid(MaterialPropertyQuery))
|
||||||
|
{
|
||||||
|
MaterialPropertyQuery* q = static_cast<MaterialPropertyQuery*>(*it);
|
||||||
|
mIgnoreMaterialPropertyChange = true;
|
||||||
|
if (getSelectedMaterial().toStdString() == q->mName)
|
||||||
|
{
|
||||||
|
for (int i=0; i<mMaterialPropertyModel->rowCount(); ++i)
|
||||||
|
{
|
||||||
|
if (mMaterialPropertyModel->item(i,0)->text() == QString::fromStdString(q->mPropertyName))
|
||||||
|
{
|
||||||
|
mMaterialPropertyModel->item(i,1)->setText(QString::fromStdString(q->mValue));
|
||||||
|
if (mMaterialPropertyModel->item(i,1)->isCheckable())
|
||||||
|
mMaterialPropertyModel->item(i,1)->setCheckState ((q->mValue == "true")
|
||||||
|
? Qt::Checked : Qt::Unchecked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mIgnoreMaterialPropertyChange = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete *it;
|
||||||
|
it = mQueries.erase(it);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sh::MainWindow::onMaterialSelectionChanged (const QModelIndex & current, const QModelIndex & previous)
|
||||||
|
{
|
||||||
|
if (mIgnoreMaterialChange)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QString name = getSelectedMaterial();
|
||||||
|
if (!name.isEmpty())
|
||||||
|
requestQuery(new sh::MaterialQuery(name.toStdString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
QString sh::MainWindow::getSelectedMaterial()
|
||||||
|
{
|
||||||
|
QModelIndex selectedIndex = ui->materialList->selectionModel()->currentIndex();
|
||||||
|
if (!selectedIndex.isValid())
|
||||||
|
return QString("");
|
||||||
|
|
||||||
|
return mMaterialProxyModel->data(selectedIndex, Qt::DisplayRole).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sh::MainWindow::onConfigurationSelectionChanged (const QString& current)
|
||||||
|
{
|
||||||
|
if (mIgnoreConfigurationChange)
|
||||||
|
return;
|
||||||
|
requestQuery(new sh::ConfigurationQuery(current.toStdString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void sh::MainWindow::onGlobalSettingChanged(QStandardItem *item)
|
||||||
|
{
|
||||||
|
if (mIgnoreGlobalSettingChange)
|
||||||
|
return; // we are only interested in changes by the user, not by the backend.
|
||||||
|
|
||||||
|
std::string name = mGlobalSettingsModel->data(mGlobalSettingsModel->index(item->row(), 0)).toString().toStdString();
|
||||||
|
std::string value = mGlobalSettingsModel->data(mGlobalSettingsModel->index(item->row(), 1)).toString().toStdString();
|
||||||
|
|
||||||
|
queueAction(new sh::ActionChangeGlobalSetting(name, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
void sh::MainWindow::onConfigurationChanged (QStandardItem* item)
|
||||||
|
{
|
||||||
|
QList<QListWidgetItem*> items = ui->configurationList->selectedItems();
|
||||||
|
if (items.size())
|
||||||
|
{
|
||||||
|
std::string name = items.front()->text().toStdString();
|
||||||
|
std::string key = mConfigurationModel->data(mConfigurationModel->index(item->row(), 0)).toString().toStdString();
|
||||||
|
std::string value = mConfigurationModel->data(mConfigurationModel->index(item->row(), 1)).toString().toStdString();
|
||||||
|
|
||||||
|
queueAction(new sh::ActionChangeConfiguration(name, key, value));
|
||||||
|
|
||||||
|
requestQuery(new sh::ConfigurationQuery(name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sh::MainWindow::on_lineEdit_textEdited(const QString &arg1)
|
||||||
|
{
|
||||||
|
mMaterialProxyModel->setFilterFixedString(arg1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sh::MainWindow::on_actionSave_triggered()
|
||||||
|
{
|
||||||
|
queueAction (new sh::ActionSaveAll());
|
||||||
|
}
|
||||||
|
|
||||||
|
void sh::MainWindow::on_actionNewMaterial_triggered()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void sh::MainWindow::on_actionDeleteMaterial_triggered()
|
||||||
|
{
|
||||||
|
QModelIndex selectedIndex = ui->materialList->selectionModel()->currentIndex();
|
||||||
|
QString name = mMaterialProxyModel->data(selectedIndex, Qt::DisplayRole).toString();
|
||||||
|
|
||||||
|
queueAction (new sh::ActionDeleteMaterial(name.toStdString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void sh::MainWindow::queueAction(Action* action)
|
||||||
|
{
|
||||||
|
boost::mutex::scoped_lock lock(mSync->mActionMutex);
|
||||||
|
mActionQueue.push(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sh::MainWindow::requestQuery(Query *query)
|
||||||
|
{
|
||||||
|
boost::mutex::scoped_lock lock(mSync->mActionMutex);
|
||||||
|
mQueries.push_back(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sh::MainWindow::on_actionQuit_triggered()
|
||||||
|
{
|
||||||
|
hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sh::MainWindow::on_actionNewConfiguration_triggered()
|
||||||
|
{
|
||||||
|
QInputDialog dialog(this);
|
||||||
|
|
||||||
|
QString text = QInputDialog::getText(this, tr("New Configuration"),
|
||||||
|
tr("Configuration name:"));
|
||||||
|
|
||||||
|
if (!text.isEmpty())
|
||||||
|
{
|
||||||
|
queueAction(new ActionCreateConfiguration(text.toStdString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sh::MainWindow::on_actionDeleteConfiguration_triggered()
|
||||||
|
{
|
||||||
|
QList<QListWidgetItem*> items = ui->configurationList->selectedItems();
|
||||||
|
if (items.size())
|
||||||
|
queueAction(new ActionDeleteConfiguration(items.front()->text().toStdString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void sh::MainWindow::on_actionDeleteConfigurationProperty_triggered()
|
||||||
|
{
|
||||||
|
QList<QListWidgetItem*> items = ui->configurationList->selectedItems();
|
||||||
|
if (items.empty())
|
||||||
|
return;
|
||||||
|
std::string configurationName = items.front()->text().toStdString();
|
||||||
|
|
||||||
|
QModelIndex current = ui->configurationView->currentIndex();
|
||||||
|
if (!current.isValid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::string propertyName = mConfigurationModel->data(mConfigurationModel->index(current.row(), 0)).toString().toStdString();
|
||||||
|
|
||||||
|
queueAction(new sh::ActionDeleteConfigurationProperty(configurationName, propertyName));
|
||||||
|
requestQuery(new sh::ConfigurationQuery(configurationName));
|
||||||
|
}
|
||||||
|
|
||||||
|
void sh::MainWindow::on_actionCloneMaterial_triggered()
|
||||||
|
{
|
||||||
|
QModelIndex selectedIndex = ui->materialList->selectionModel()->currentIndex();
|
||||||
|
QString name = mMaterialProxyModel->data(selectedIndex, Qt::DisplayRole).toString();
|
||||||
|
if (name.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QInputDialog dialog(this);
|
||||||
|
|
||||||
|
QString text = QInputDialog::getText(this, tr("Clone material"),
|
||||||
|
tr("Name:"));
|
||||||
|
|
||||||
|
if (!text.isEmpty())
|
||||||
|
{
|
||||||
|
queueAction(new ActionCloneMaterial(name.toStdString(), text.toStdString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sh::MainWindow::onContextMenuRequested(const QPoint &point)
|
||||||
|
{
|
||||||
|
QPoint globalPos = ui->materialView->viewport()->mapToGlobal(point);
|
||||||
|
|
||||||
|
QMenu menu;
|
||||||
|
|
||||||
|
QList <QAction*> actions;
|
||||||
|
actions.push_back(ui->actionNewProperty);
|
||||||
|
actions.push_back(ui->actionDeleteProperty);
|
||||||
|
actions.push_back(ui->actionCreatePass);
|
||||||
|
actions.push_back(ui->actionCreateTextureUnit);
|
||||||
|
menu.addActions(actions);
|
||||||
|
|
||||||
|
menu.exec(globalPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sh::MainWindow::getContext(QModelIndex index, int* passIndex, int* textureIndex, bool* isInPass, bool* isInTextureUnit)
|
||||||
|
{
|
||||||
|
if (passIndex)
|
||||||
|
{
|
||||||
|
*passIndex = 0;
|
||||||
|
if (isInPass)
|
||||||
|
*isInPass = false;
|
||||||
|
QModelIndex passModelIndex = index;
|
||||||
|
// go up until we find the pass item.
|
||||||
|
while (getPropertyKey(passModelIndex) != "pass" && passModelIndex.isValid())
|
||||||
|
passModelIndex = passModelIndex.parent();
|
||||||
|
|
||||||
|
if (passModelIndex.isValid())
|
||||||
|
{
|
||||||
|
if (passModelIndex.column() != 0)
|
||||||
|
passModelIndex = passModelIndex.parent().child(passModelIndex.row(), 0);
|
||||||
|
for (int i=0; i<mMaterialPropertyModel->rowCount(); ++i)
|
||||||
|
{
|
||||||
|
if (mMaterialPropertyModel->data(mMaterialPropertyModel->index(i, 0)).toString() == QString("pass"))
|
||||||
|
{
|
||||||
|
if (mMaterialPropertyModel->index(i, 0) == passModelIndex)
|
||||||
|
{
|
||||||
|
if (isInPass)
|
||||||
|
*isInPass = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++(*passIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (textureIndex)
|
||||||
|
{
|
||||||
|
*textureIndex = 0;
|
||||||
|
if (isInTextureUnit)
|
||||||
|
*isInTextureUnit = false;
|
||||||
|
QModelIndex texModelIndex = index;
|
||||||
|
// go up until we find the texture_unit item.
|
||||||
|
while (getPropertyKey(texModelIndex) != "texture_unit" && texModelIndex.isValid())
|
||||||
|
texModelIndex = texModelIndex.parent();
|
||||||
|
if (texModelIndex.isValid())
|
||||||
|
{
|
||||||
|
if (texModelIndex.column() != 0)
|
||||||
|
texModelIndex = texModelIndex.parent().child(texModelIndex.row(), 0);
|
||||||
|
for (int i=0; i<mMaterialPropertyModel->rowCount(texModelIndex.parent()); ++i)
|
||||||
|
{
|
||||||
|
if (texModelIndex.parent().child(i, 0).data().toString() == QString("texture_unit"))
|
||||||
|
{
|
||||||
|
if (texModelIndex.parent().child(i, 0) == texModelIndex)
|
||||||
|
{
|
||||||
|
if (isInTextureUnit)
|
||||||
|
*isInTextureUnit = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++(*textureIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string sh::MainWindow::getPropertyKey(QModelIndex index)
|
||||||
|
{
|
||||||
|
if (!index.parent().isValid())
|
||||||
|
return mMaterialPropertyModel->data(mMaterialPropertyModel->index(index.row(), 0)).toString().toStdString();
|
||||||
|
else
|
||||||
|
return index.parent().child(index.row(), 0).data().toString().toStdString();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string sh::MainWindow::getPropertyValue(QModelIndex index)
|
||||||
|
{
|
||||||
|
if (!index.parent().isValid())
|
||||||
|
return mMaterialPropertyModel->data(mMaterialPropertyModel->index(index.row(), 1)).toString().toStdString();
|
||||||
|
else
|
||||||
|
return index.parent().child(index.row(), 1).data().toString().toStdString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sh::MainWindow::onMaterialPropertyChanged(QStandardItem *item)
|
||||||
|
{
|
||||||
|
if (mIgnoreMaterialPropertyChange)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QString material = getSelectedMaterial();
|
||||||
|
if (material.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// handle checkboxes being checked/unchecked
|
||||||
|
std::string value = getPropertyValue(item->index());
|
||||||
|
if (item->data(Qt::UserRole).toInt() == MaterialProperty::Boolean)
|
||||||
|
{
|
||||||
|
if (item->checkState() == Qt::Checked && value != "true")
|
||||||
|
value = "true";
|
||||||
|
else if (item->checkState() == Qt::Unchecked && value == "true")
|
||||||
|
value = "false";
|
||||||
|
item->setText(QString::fromStdString(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle inherited properties being changed, i.e. overridden by the current (derived) material
|
||||||
|
if (item->data(Qt::UserRole+1).toInt() == MaterialProperty::Inherited_Unchanged)
|
||||||
|
{
|
||||||
|
QColor normalColor = ui->materialView->palette().color(QPalette::Normal, QPalette::WindowText);
|
||||||
|
mIgnoreMaterialPropertyChange = true;
|
||||||
|
mMaterialPropertyModel->item(item->index().row(), 0)
|
||||||
|
->setData(QVariant(MaterialProperty::Inherited_Changed), Qt::UserRole+1);
|
||||||
|
mMaterialPropertyModel->item(item->index().row(), 0)
|
||||||
|
->setData(normalColor, Qt::ForegroundRole);
|
||||||
|
mMaterialPropertyModel->item(item->index().row(), 1)
|
||||||
|
->setData(QVariant(MaterialProperty::Inherited_Changed), Qt::UserRole+1);
|
||||||
|
mMaterialPropertyModel->item(item->index().row(), 1)
|
||||||
|
->setData(normalColor, Qt::ForegroundRole);
|
||||||
|
mIgnoreMaterialPropertyChange = false;
|
||||||
|
|
||||||
|
ui->materialView->scrollTo(mMaterialSortModel->mapFromSource(item->index()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!item->index().parent().isValid())
|
||||||
|
{
|
||||||
|
// top level material property
|
||||||
|
queueAction(new ActionSetMaterialProperty(
|
||||||
|
material.toStdString(), getPropertyKey(item->index()), value));
|
||||||
|
}
|
||||||
|
else if (getPropertyKey(item->index()) == "texture_unit")
|
||||||
|
{
|
||||||
|
// texture unit name changed
|
||||||
|
int passIndex, textureIndex;
|
||||||
|
getContext(item->index(), &passIndex, &textureIndex);
|
||||||
|
std::cout << "passIndex " << passIndex << " " << textureIndex << std::endl;
|
||||||
|
|
||||||
|
queueAction(new ActionChangeTextureUnitName(
|
||||||
|
material.toStdString(), passIndex, textureIndex, value));
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (item->index().parent().data().toString() == "pass")
|
||||||
|
{
|
||||||
|
// pass property
|
||||||
|
int passIndex;
|
||||||
|
getContext(item->index(), &passIndex, NULL);
|
||||||
|
/// \todo if shaders are changed, check that the material provides all properties needed by the shader
|
||||||
|
queueAction(new ActionSetPassProperty(
|
||||||
|
material.toStdString(), passIndex, getPropertyKey(item->index()), value));
|
||||||
|
}
|
||||||
|
else if (item->index().parent().data().toString() == "shader_properties")
|
||||||
|
{
|
||||||
|
// shader property
|
||||||
|
int passIndex;
|
||||||
|
getContext(item->index(), &passIndex, NULL);
|
||||||
|
queueAction(new ActionSetShaderProperty(
|
||||||
|
material.toStdString(), passIndex, getPropertyKey(item->index()), value));
|
||||||
|
}
|
||||||
|
else if (item->index().parent().data().toString() == "texture_unit")
|
||||||
|
{
|
||||||
|
// texture property
|
||||||
|
int passIndex, textureIndex;
|
||||||
|
getContext(item->index(), &passIndex, &textureIndex);
|
||||||
|
queueAction(new ActionSetTextureProperty(
|
||||||
|
material.toStdString(), passIndex, textureIndex, getPropertyKey(item->index()), value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sh::MainWindow::buildMaterialModel(MaterialQuery *data)
|
||||||
|
{
|
||||||
|
mMaterialPropertyModel->clear();
|
||||||
|
|
||||||
|
mMaterialPropertyModel->setHorizontalHeaderItem(0, new QStandardItem(QString("Name")));
|
||||||
|
mMaterialPropertyModel->setHorizontalHeaderItem(1, new QStandardItem(QString("Value")));
|
||||||
|
|
||||||
|
for (std::map<std::string, MaterialProperty>::const_iterator it = data->mProperties.begin();
|
||||||
|
it != data->mProperties.end(); ++it)
|
||||||
|
{
|
||||||
|
addProperty(mMaterialPropertyModel->invisibleRootItem(), it->first, it->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::vector<PassInfo>::iterator it = data->mPasses.begin();
|
||||||
|
it != data->mPasses.end(); ++it)
|
||||||
|
{
|
||||||
|
QStandardItem* passItem = new QStandardItem (QString("pass"));
|
||||||
|
passItem->setFlags(passItem->flags() &= ~Qt::ItemIsEditable);
|
||||||
|
passItem->setData(QVariant(static_cast<int>(MaterialProperty::Object)), Qt::UserRole);
|
||||||
|
|
||||||
|
if (it->mShaderProperties.size())
|
||||||
|
{
|
||||||
|
QStandardItem* shaderPropertiesItem = new QStandardItem (QString("shader_properties"));
|
||||||
|
shaderPropertiesItem->setFlags(shaderPropertiesItem->flags() &= ~Qt::ItemIsEditable);
|
||||||
|
shaderPropertiesItem->setData(QVariant(static_cast<int>(MaterialProperty::Object)), Qt::UserRole);
|
||||||
|
|
||||||
|
for (std::map<std::string, MaterialProperty>::iterator pit = it->mShaderProperties.begin();
|
||||||
|
pit != it->mShaderProperties.end(); ++pit)
|
||||||
|
{
|
||||||
|
addProperty(shaderPropertiesItem, pit->first, pit->second);
|
||||||
|
}
|
||||||
|
passItem->appendRow(shaderPropertiesItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::map<std::string, MaterialProperty>::iterator pit = it->mProperties.begin();
|
||||||
|
pit != it->mProperties.end(); ++pit)
|
||||||
|
{
|
||||||
|
addProperty(passItem, pit->first, pit->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::vector<TextureUnitInfo>::iterator tIt = it->mTextureUnits.begin();
|
||||||
|
tIt != it->mTextureUnits.end(); ++tIt)
|
||||||
|
{
|
||||||
|
QStandardItem* unitItem = new QStandardItem (QString("texture_unit"));
|
||||||
|
unitItem->setFlags(unitItem->flags() &= ~Qt::ItemIsEditable);
|
||||||
|
unitItem->setData(QVariant(static_cast<int>(MaterialProperty::Object)), Qt::UserRole);
|
||||||
|
QStandardItem* nameItem = new QStandardItem (QString::fromStdString(tIt->mName));
|
||||||
|
nameItem->setData(QVariant(static_cast<int>(MaterialProperty::Object)), Qt::UserRole);
|
||||||
|
|
||||||
|
QList<QStandardItem*> texUnit;
|
||||||
|
texUnit << unitItem << nameItem;
|
||||||
|
|
||||||
|
for (std::map<std::string, MaterialProperty>::iterator pit = tIt->mProperties.begin();
|
||||||
|
pit != tIt->mProperties.end(); ++pit)
|
||||||
|
{
|
||||||
|
addProperty(unitItem, pit->first, pit->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
passItem->appendRow(texUnit);
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QStandardItem*> toAdd;
|
||||||
|
toAdd << passItem;
|
||||||
|
toAdd << new QStandardItem(QString(""));
|
||||||
|
mMaterialPropertyModel->appendRow(toAdd);
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->materialView->expandAll();
|
||||||
|
ui->materialView->resizeColumnToContents(0);
|
||||||
|
ui->materialView->resizeColumnToContents(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sh::MainWindow::addProperty(QStandardItem *parent, const std::string &key, MaterialProperty value, bool scrollTo)
|
||||||
|
{
|
||||||
|
QList<QStandardItem*> toAdd;
|
||||||
|
QStandardItem* keyItem = new QStandardItem(QString::fromStdString(key));
|
||||||
|
keyItem->setFlags(keyItem->flags() &= ~Qt::ItemIsEditable);
|
||||||
|
keyItem->setData(QVariant(value.mType), Qt::UserRole);
|
||||||
|
keyItem->setData(QVariant(value.mSource), Qt::UserRole+1);
|
||||||
|
toAdd.push_back(keyItem);
|
||||||
|
|
||||||
|
QStandardItem* valueItem = NULL;
|
||||||
|
if (value.mSource != MaterialProperty::None)
|
||||||
|
{
|
||||||
|
valueItem = new QStandardItem(QString::fromStdString(value.mValue));
|
||||||
|
valueItem->setData(QVariant(value.mType), Qt::UserRole);
|
||||||
|
valueItem->setData(QVariant(value.mSource), Qt::UserRole+1);
|
||||||
|
toAdd.push_back(valueItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (value.mSource == MaterialProperty::Inherited_Unchanged)
|
||||||
|
{
|
||||||
|
QColor color = ui->configurationView->palette().color(QPalette::Disabled, QPalette::WindowText);
|
||||||
|
keyItem->setData(color, Qt::ForegroundRole);
|
||||||
|
if (valueItem)
|
||||||
|
valueItem->setData(color, Qt::ForegroundRole);
|
||||||
|
}
|
||||||
|
if (value.mType == MaterialProperty::Boolean && valueItem)
|
||||||
|
{
|
||||||
|
valueItem->setCheckable(true);
|
||||||
|
valueItem->setCheckState((value.mValue == "true") ? Qt::Checked : Qt::Unchecked);
|
||||||
|
}
|
||||||
|
|
||||||
|
parent->appendRow(toAdd);
|
||||||
|
|
||||||
|
if (scrollTo)
|
||||||
|
ui->materialView->scrollTo(mMaterialSortModel->mapFromSource(keyItem->index()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void sh::MainWindow::buildConfigurationModel(ConfigurationQuery *data)
|
||||||
|
{
|
||||||
|
while (mConfigurationModel->rowCount())
|
||||||
|
mConfigurationModel->removeRow(0);
|
||||||
|
for (std::map<std::string, std::string>::iterator it = data->mProperties.begin();
|
||||||
|
it != data->mProperties.end(); ++it)
|
||||||
|
{
|
||||||
|
QList<QStandardItem*> toAdd;
|
||||||
|
QStandardItem* name = new QStandardItem(QString::fromStdString(it->first));
|
||||||
|
name->setFlags(name->flags() &= ~Qt::ItemIsEditable);
|
||||||
|
QStandardItem* value = new QStandardItem(QString::fromStdString(it->second));
|
||||||
|
toAdd.push_back(name);
|
||||||
|
toAdd.push_back(value);
|
||||||
|
mConfigurationModel->appendRow(toAdd);
|
||||||
|
}
|
||||||
|
|
||||||
|
// add items that are in global settings, but not in this configuration (with a "inactive" color)
|
||||||
|
for (std::map<std::string, std::string>::const_iterator it = mState.mGlobalSettingsMap.begin();
|
||||||
|
it != mState.mGlobalSettingsMap.end(); ++it)
|
||||||
|
{
|
||||||
|
if (data->mProperties.find(it->first) == data->mProperties.end())
|
||||||
|
{
|
||||||
|
QColor color = ui->configurationView->palette().color(QPalette::Disabled, QPalette::WindowText);
|
||||||
|
QList<QStandardItem*> toAdd;
|
||||||
|
QStandardItem* name = new QStandardItem(QString::fromStdString(it->first));
|
||||||
|
name->setFlags(name->flags() &= ~Qt::ItemIsEditable);
|
||||||
|
name->setData(color, Qt::ForegroundRole);
|
||||||
|
QStandardItem* value = new QStandardItem(QString::fromStdString(it->second));
|
||||||
|
value->setData(color, Qt::ForegroundRole);
|
||||||
|
toAdd.push_back(name);
|
||||||
|
toAdd.push_back(value);
|
||||||
|
mConfigurationModel->appendRow(toAdd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sh::MainWindow::on_actionCreatePass_triggered()
|
||||||
|
{
|
||||||
|
QString material = getSelectedMaterial();
|
||||||
|
if (!material.isEmpty())
|
||||||
|
{
|
||||||
|
addProperty(mMaterialPropertyModel->invisibleRootItem(),
|
||||||
|
"pass", MaterialProperty("", MaterialProperty::Object, MaterialProperty::None), true);
|
||||||
|
|
||||||
|
queueAction (new ActionCreatePass(material.toStdString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sh::MainWindow::on_actionDeleteProperty_triggered()
|
||||||
|
{
|
||||||
|
QModelIndex selectedIndex = mMaterialSortModel->mapToSource(ui->materialView->selectionModel()->currentIndex());
|
||||||
|
QString material = getSelectedMaterial();
|
||||||
|
if (material.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
mIgnoreMaterialPropertyChange = true;
|
||||||
|
|
||||||
|
if (getPropertyKey(selectedIndex) == "pass")
|
||||||
|
{
|
||||||
|
// delete whole pass
|
||||||
|
int passIndex;
|
||||||
|
getContext(selectedIndex, &passIndex, NULL);
|
||||||
|
if (passIndex == 0)
|
||||||
|
{
|
||||||
|
QMessageBox msgBox;
|
||||||
|
msgBox.setText("The first pass can not be deleted.");
|
||||||
|
msgBox.exec();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
queueAction(new ActionDeletePass(material.toStdString(), passIndex));
|
||||||
|
mMaterialPropertyModel->removeRow(selectedIndex.row(), selectedIndex.parent());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (getPropertyKey(selectedIndex) == "texture_unit")
|
||||||
|
{
|
||||||
|
// delete whole texture unit
|
||||||
|
int passIndex, textureIndex;
|
||||||
|
getContext(selectedIndex, &passIndex, &textureIndex);
|
||||||
|
queueAction(new ActionDeleteTextureUnit(material.toStdString(), passIndex, textureIndex));
|
||||||
|
mMaterialPropertyModel->removeRow(selectedIndex.row(), selectedIndex.parent());
|
||||||
|
}
|
||||||
|
else if (!selectedIndex.parent().isValid())
|
||||||
|
{
|
||||||
|
// top level material property
|
||||||
|
MaterialProperty::Source source = static_cast<MaterialProperty::Source>(
|
||||||
|
mMaterialPropertyModel->itemFromIndex(selectedIndex)->data(Qt::UserRole+1).toInt());
|
||||||
|
if (source == MaterialProperty::Inherited_Unchanged)
|
||||||
|
{
|
||||||
|
QMessageBox msgBox;
|
||||||
|
msgBox.setText("Inherited properties can not be deleted.");
|
||||||
|
msgBox.exec();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
queueAction(new ActionDeleteMaterialProperty(
|
||||||
|
material.toStdString(), getPropertyKey(selectedIndex)));
|
||||||
|
std::cout << "source is " << source << std::endl;
|
||||||
|
if (source == MaterialProperty::Inherited_Changed)
|
||||||
|
{
|
||||||
|
QColor inactiveColor = ui->materialView->palette().color(QPalette::Disabled, QPalette::WindowText);
|
||||||
|
mMaterialPropertyModel->item(selectedIndex.row(), 0)
|
||||||
|
->setData(QVariant(MaterialProperty::Inherited_Unchanged), Qt::UserRole+1);
|
||||||
|
mMaterialPropertyModel->item(selectedIndex.row(), 0)
|
||||||
|
->setData(inactiveColor, Qt::ForegroundRole);
|
||||||
|
mMaterialPropertyModel->item(selectedIndex.row(), 1)
|
||||||
|
->setData(QVariant(MaterialProperty::Inherited_Unchanged), Qt::UserRole+1);
|
||||||
|
mMaterialPropertyModel->item(selectedIndex.row(), 1)
|
||||||
|
->setData(inactiveColor, Qt::ForegroundRole);
|
||||||
|
|
||||||
|
// make sure to update the property's value
|
||||||
|
requestQuery(new sh::MaterialPropertyQuery(material.toStdString(), getPropertyKey(selectedIndex)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mMaterialPropertyModel->removeRow(selectedIndex.row());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (selectedIndex.parent().data().toString() == "pass")
|
||||||
|
{
|
||||||
|
// pass property
|
||||||
|
int passIndex;
|
||||||
|
getContext(selectedIndex, &passIndex, NULL);
|
||||||
|
queueAction(new ActionDeletePassProperty(
|
||||||
|
material.toStdString(), passIndex, getPropertyKey(selectedIndex)));
|
||||||
|
mMaterialPropertyModel->removeRow(selectedIndex.row(), selectedIndex.parent());
|
||||||
|
}
|
||||||
|
else if (selectedIndex.parent().data().toString() == "shader_properties")
|
||||||
|
{
|
||||||
|
// shader property
|
||||||
|
int passIndex;
|
||||||
|
getContext(selectedIndex, &passIndex, NULL);
|
||||||
|
queueAction(new ActionDeleteShaderProperty(
|
||||||
|
material.toStdString(), passIndex, getPropertyKey(selectedIndex)));
|
||||||
|
mMaterialPropertyModel->removeRow(selectedIndex.row(), selectedIndex.parent());
|
||||||
|
}
|
||||||
|
else if (selectedIndex.parent().data().toString() == "texture_unit")
|
||||||
|
{
|
||||||
|
// texture property
|
||||||
|
int passIndex, textureIndex;
|
||||||
|
getContext(selectedIndex, &passIndex, &textureIndex);
|
||||||
|
queueAction(new ActionDeleteTextureProperty(
|
||||||
|
material.toStdString(), passIndex, textureIndex, getPropertyKey(selectedIndex)));
|
||||||
|
mMaterialPropertyModel->removeRow(selectedIndex.row(), selectedIndex.parent());
|
||||||
|
}
|
||||||
|
mIgnoreMaterialPropertyChange = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sh::MainWindow::on_actionNewProperty_triggered()
|
||||||
|
{
|
||||||
|
QModelIndex selectedIndex = mMaterialSortModel->mapToSource(ui->materialView->selectionModel()->currentIndex());
|
||||||
|
QString material = getSelectedMaterial();
|
||||||
|
if (material.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
AddPropertyDialog* dialog = new AddPropertyDialog(this);
|
||||||
|
dialog->exec();
|
||||||
|
QString propertyName = dialog->mName;
|
||||||
|
QString defaultValue = "";
|
||||||
|
|
||||||
|
/// \todo check if this property name exists already
|
||||||
|
|
||||||
|
if (!propertyName.isEmpty())
|
||||||
|
{
|
||||||
|
int passIndex, textureIndex;
|
||||||
|
bool isInPass, isInTextureUnit;
|
||||||
|
getContext(selectedIndex, &passIndex, &textureIndex, &isInPass, &isInTextureUnit);
|
||||||
|
|
||||||
|
QList<QStandardItem*> items;
|
||||||
|
QStandardItem* keyItem = new QStandardItem(propertyName);
|
||||||
|
keyItem->setFlags(keyItem->flags() &= ~Qt::ItemIsEditable);
|
||||||
|
items << keyItem;
|
||||||
|
items << new QStandardItem(defaultValue);
|
||||||
|
|
||||||
|
// figure out which item the new property should be a child of
|
||||||
|
QModelIndex parentIndex = selectedIndex;
|
||||||
|
if (selectedIndex.data(Qt::UserRole) != MaterialProperty::Object)
|
||||||
|
parentIndex = selectedIndex.parent();
|
||||||
|
QStandardItem* parentItem;
|
||||||
|
if (!parentIndex.isValid())
|
||||||
|
parentItem = mMaterialPropertyModel->invisibleRootItem();
|
||||||
|
else
|
||||||
|
parentItem = mMaterialPropertyModel->itemFromIndex(parentIndex);
|
||||||
|
|
||||||
|
if (isInTextureUnit)
|
||||||
|
{
|
||||||
|
queueAction(new ActionSetTextureProperty(
|
||||||
|
material.toStdString(), passIndex, textureIndex, propertyName.toStdString(), defaultValue.toStdString()));
|
||||||
|
}
|
||||||
|
else if (isInPass)
|
||||||
|
{
|
||||||
|
if (selectedIndex.parent().child(selectedIndex.row(),0).data().toString() == "shader_properties"
|
||||||
|
|| selectedIndex.parent().data().toString() == "shader_properties")
|
||||||
|
{
|
||||||
|
queueAction(new ActionSetShaderProperty(
|
||||||
|
material.toStdString(), passIndex, propertyName.toStdString(), defaultValue.toStdString()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
queueAction(new ActionSetPassProperty(
|
||||||
|
material.toStdString(), passIndex, propertyName.toStdString(), defaultValue.toStdString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
queueAction(new ActionSetMaterialProperty(
|
||||||
|
material.toStdString(), propertyName.toStdString(), defaultValue.toStdString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
addProperty(parentItem, propertyName.toStdString(),
|
||||||
|
MaterialProperty (defaultValue.toStdString(), MaterialProperty::Misc, MaterialProperty::Normal), true);
|
||||||
|
|
||||||
|
/// \todo scroll to newly added property
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sh::MainWindow::on_actionCreateTextureUnit_triggered()
|
||||||
|
{
|
||||||
|
QString material = getSelectedMaterial();
|
||||||
|
if (material.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QInputDialog dialog(this);
|
||||||
|
|
||||||
|
QString text = QInputDialog::getText(this, tr("New texture unit"),
|
||||||
|
tr("Texture unit name (for referencing in shaders):"));
|
||||||
|
if (!text.isEmpty())
|
||||||
|
{
|
||||||
|
QModelIndex selectedIndex = mMaterialSortModel->mapToSource(ui->materialView->selectionModel()->currentIndex());
|
||||||
|
int passIndex;
|
||||||
|
getContext(selectedIndex, &passIndex, NULL);
|
||||||
|
queueAction(new ActionCreateTextureUnit(material.toStdString(), passIndex, text.toStdString()));
|
||||||
|
|
||||||
|
// add to model
|
||||||
|
int index = 0;
|
||||||
|
for (int i=0; i<mMaterialPropertyModel->rowCount(); ++i)
|
||||||
|
{
|
||||||
|
if (mMaterialPropertyModel->data(mMaterialPropertyModel->index(i, 0)).toString() == QString("pass"))
|
||||||
|
{
|
||||||
|
if (index == passIndex)
|
||||||
|
{
|
||||||
|
addProperty(mMaterialPropertyModel->itemFromIndex(mMaterialPropertyModel->index(i, 0)),
|
||||||
|
"texture_unit", MaterialProperty(text.toStdString(), MaterialProperty::Object), true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sh::MainWindow::on_clearButton_clicked()
|
||||||
|
{
|
||||||
|
ui->errorLog->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sh::MainWindow::on_tabWidget_currentChanged(int index)
|
||||||
|
{
|
||||||
|
QColor color = ui->tabWidget->palette().color(QPalette::Normal, QPalette::WindowText);
|
||||||
|
|
||||||
|
if (index == 3)
|
||||||
|
ui->tabWidget->tabBar()->setTabTextColor(3, color);
|
||||||
|
}
|
139
extern/shiny/Editor/MainWindow.hpp
vendored
Normal file
139
extern/shiny/Editor/MainWindow.hpp
vendored
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
#ifndef SHINY_EDITOR_MAINWINDOW_HPP
|
||||||
|
#define SHINY_EDITOR_MAINWINDOW_HPP
|
||||||
|
|
||||||
|
#include <QMainWindow>
|
||||||
|
|
||||||
|
#include <QSortFilterProxyModel>
|
||||||
|
#include <QStandardItemModel>
|
||||||
|
#include <QStringListModel>
|
||||||
|
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
|
#include "Actions.hpp"
|
||||||
|
#include "Query.hpp"
|
||||||
|
|
||||||
|
#include "PropertySortModel.hpp"
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class MainWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace sh
|
||||||
|
{
|
||||||
|
|
||||||
|
struct SynchronizationState;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A snapshot of the material system's state. Lock the mUpdateMutex before accessing.
|
||||||
|
*/
|
||||||
|
struct MaterialSystemState
|
||||||
|
{
|
||||||
|
std::vector<std::string> mMaterialList;
|
||||||
|
|
||||||
|
std::map<std::string, std::string> mGlobalSettingsMap;
|
||||||
|
|
||||||
|
std::vector<std::string> mConfigurationList;
|
||||||
|
|
||||||
|
std::vector<std::string> mMaterialFiles;
|
||||||
|
std::vector<std::string> mConfigurationFiles;
|
||||||
|
|
||||||
|
std::vector<std::string> mShaderSets;
|
||||||
|
|
||||||
|
std::string mErrors;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MainWindow : public QMainWindow
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit MainWindow(QWidget *parent = 0);
|
||||||
|
~MainWindow();
|
||||||
|
|
||||||
|
// really should be an std::atomic
|
||||||
|
volatile bool mRequestShowWindow;
|
||||||
|
// dito
|
||||||
|
volatile bool mRequestExit;
|
||||||
|
|
||||||
|
SynchronizationState* mSync;
|
||||||
|
|
||||||
|
/// \todo Is there a better way to ignore manual model changes?
|
||||||
|
bool mIgnoreGlobalSettingChange;
|
||||||
|
bool mIgnoreConfigurationChange;
|
||||||
|
bool mIgnoreMaterialChange;
|
||||||
|
bool mIgnoreMaterialPropertyChange;
|
||||||
|
|
||||||
|
std::queue<Action*> mActionQueue;
|
||||||
|
std::vector<Query*> mQueries;
|
||||||
|
|
||||||
|
MaterialSystemState mState;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::MainWindow *ui;
|
||||||
|
|
||||||
|
// material tab
|
||||||
|
QStringListModel* mMaterialModel;
|
||||||
|
QSortFilterProxyModel* mMaterialProxyModel;
|
||||||
|
|
||||||
|
QStandardItemModel* mMaterialPropertyModel;
|
||||||
|
PropertySortModel* mMaterialSortModel;
|
||||||
|
|
||||||
|
// global settings tab
|
||||||
|
QStandardItemModel* mGlobalSettingsModel;
|
||||||
|
|
||||||
|
// configuration tab
|
||||||
|
QStandardItemModel* mConfigurationModel;
|
||||||
|
|
||||||
|
void queueAction(Action* action);
|
||||||
|
void requestQuery(Query* query);
|
||||||
|
|
||||||
|
void buildMaterialModel (MaterialQuery* data);
|
||||||
|
void buildConfigurationModel (ConfigurationQuery* data);
|
||||||
|
|
||||||
|
QString getSelectedMaterial();
|
||||||
|
|
||||||
|
/// get the context of an index in the material property model
|
||||||
|
void getContext(QModelIndex index, int* passIndex, int* textureIndex, bool* isInPass=NULL, bool* isInTextureUnit=NULL);
|
||||||
|
|
||||||
|
std::string getPropertyKey(QModelIndex index);
|
||||||
|
std::string getPropertyValue(QModelIndex index);
|
||||||
|
|
||||||
|
void addProperty (QStandardItem* parent, const std::string& key, MaterialProperty value, bool scrollTo=false);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void closeEvent(QCloseEvent *event);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void onIdle();
|
||||||
|
|
||||||
|
void onMaterialSelectionChanged (const QModelIndex & current, const QModelIndex & previous);
|
||||||
|
void onConfigurationSelectionChanged (const QString& current);
|
||||||
|
|
||||||
|
void onGlobalSettingChanged (QStandardItem* item);
|
||||||
|
void onConfigurationChanged (QStandardItem* item);
|
||||||
|
void onMaterialPropertyChanged (QStandardItem* item);
|
||||||
|
|
||||||
|
void onContextMenuRequested(const QPoint& point);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void on_lineEdit_textEdited(const QString &arg1);
|
||||||
|
void on_actionSave_triggered();
|
||||||
|
void on_actionNewMaterial_triggered();
|
||||||
|
void on_actionDeleteMaterial_triggered();
|
||||||
|
void on_actionQuit_triggered();
|
||||||
|
void on_actionNewConfiguration_triggered();
|
||||||
|
void on_actionDeleteConfiguration_triggered();
|
||||||
|
void on_actionDeleteConfigurationProperty_triggered();
|
||||||
|
void on_actionCloneMaterial_triggered();
|
||||||
|
void on_actionCreatePass_triggered();
|
||||||
|
void on_actionDeleteProperty_triggered();
|
||||||
|
void on_actionNewProperty_triggered();
|
||||||
|
void on_actionCreateTextureUnit_triggered();
|
||||||
|
void on_clearButton_clicked();
|
||||||
|
void on_tabWidget_currentChanged(int index);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // MAINWINDOW_HPP
|
14
extern/shiny/Editor/NewMaterialDialog.cpp
vendored
Normal file
14
extern/shiny/Editor/NewMaterialDialog.cpp
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#include "NewMaterialDialog.hpp"
|
||||||
|
#include "ui_newmaterialdialog.h"
|
||||||
|
|
||||||
|
NewMaterialDialog::NewMaterialDialog(QWidget *parent) :
|
||||||
|
QDialog(parent),
|
||||||
|
ui(new Ui::NewMaterialDialog)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
NewMaterialDialog::~NewMaterialDialog()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
22
extern/shiny/Editor/NewMaterialDialog.hpp
vendored
Normal file
22
extern/shiny/Editor/NewMaterialDialog.hpp
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#ifndef NEWMATERIALDIALOG_HPP
|
||||||
|
#define NEWMATERIALDIALOG_HPP
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class NewMaterialDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
class NewMaterialDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit NewMaterialDialog(QWidget *parent = 0);
|
||||||
|
~NewMaterialDialog();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::NewMaterialDialog *ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NEWMATERIALDIALOG_HPP
|
35
extern/shiny/Editor/PropertySortModel.cpp
vendored
Normal file
35
extern/shiny/Editor/PropertySortModel.cpp
vendored
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#include "PropertySortModel.hpp"
|
||||||
|
|
||||||
|
#include "Query.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
sh::PropertySortModel::PropertySortModel(QObject *parent)
|
||||||
|
: QSortFilterProxyModel(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool sh::PropertySortModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
|
||||||
|
{
|
||||||
|
if (left.data(Qt::UserRole+1).toInt() != 0 && right.data(Qt::UserRole+1).toInt() != 0)
|
||||||
|
{
|
||||||
|
int sourceL = left.data(Qt::UserRole+1).toInt();
|
||||||
|
int sourceR = right.data(Qt::UserRole+1).toInt();
|
||||||
|
|
||||||
|
if (sourceL > sourceR)
|
||||||
|
return true;
|
||||||
|
else if (sourceR > sourceL)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int typeL = left.data(Qt::UserRole).toInt();
|
||||||
|
int typeR = right.data(Qt::UserRole).toInt();
|
||||||
|
|
||||||
|
if (typeL > typeR)
|
||||||
|
return true;
|
||||||
|
else if (typeR > typeL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
QString nameL = left.data().toString();
|
||||||
|
QString nameR = right.data().toString();
|
||||||
|
return nameL > nameR;
|
||||||
|
}
|
21
extern/shiny/Editor/PropertySortModel.hpp
vendored
Normal file
21
extern/shiny/Editor/PropertySortModel.hpp
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#ifndef SHINY_EDITOR_PROPERTYSORTMODEL_H
|
||||||
|
#define SHINY_EDITOR_PROPERTYSORTMODEL_H
|
||||||
|
|
||||||
|
#include <QSortFilterProxyModel>
|
||||||
|
|
||||||
|
namespace sh
|
||||||
|
{
|
||||||
|
|
||||||
|
class PropertySortModel : public QSortFilterProxyModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
PropertySortModel(QObject* parent);
|
||||||
|
protected:
|
||||||
|
bool lessThan(const QModelIndex &left, const QModelIndex &right) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
134
extern/shiny/Editor/Query.cpp
vendored
Normal file
134
extern/shiny/Editor/Query.cpp
vendored
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
#include "Query.hpp"
|
||||||
|
|
||||||
|
#include "../Main/Factory.hpp"
|
||||||
|
|
||||||
|
namespace sh
|
||||||
|
{
|
||||||
|
|
||||||
|
void Query::execute()
|
||||||
|
{
|
||||||
|
executeImpl();
|
||||||
|
mDone = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigurationQuery::ConfigurationQuery(const std::string &name)
|
||||||
|
: mName(name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigurationQuery::executeImpl()
|
||||||
|
{
|
||||||
|
sh::Factory::getInstance().listConfigurationSettings(mName, mProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaterialQuery::executeImpl()
|
||||||
|
{
|
||||||
|
sh::MaterialInstance* instance = sh::Factory::getInstance().getMaterialInstance(mName);
|
||||||
|
|
||||||
|
if (instance->getParent())
|
||||||
|
mParent = static_cast<sh::MaterialInstance*>(instance->getParent())->getName();
|
||||||
|
|
||||||
|
// add the inherited properties
|
||||||
|
sh::PropertySetGet* parent = instance;
|
||||||
|
std::vector<std::string> inheritedPropertiesVector;
|
||||||
|
while (parent->getParent())
|
||||||
|
{
|
||||||
|
parent = parent->getParent();
|
||||||
|
const sh::PropertyMap& parentProperties = parent->listProperties();
|
||||||
|
|
||||||
|
for (PropertyMap::const_iterator it = parentProperties.begin(); it != parentProperties.end(); ++it)
|
||||||
|
{
|
||||||
|
MaterialProperty::Source source = MaterialProperty::Inherited_Unchanged;
|
||||||
|
MaterialProperty::Type type = getType(it->first, parent->getProperty(it->first));
|
||||||
|
mProperties[it->first] = MaterialProperty (
|
||||||
|
retrieveValue<sh::StringValue>(parent->getProperty(it->first), NULL).get(),
|
||||||
|
type, source);
|
||||||
|
inheritedPropertiesVector.push_back(it->first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add our properties
|
||||||
|
const sh::PropertyMap& ourProperties = instance->listProperties();
|
||||||
|
for (PropertyMap::const_iterator it = ourProperties.begin(); it != ourProperties.end(); ++it)
|
||||||
|
{
|
||||||
|
MaterialProperty::Source source =
|
||||||
|
(std::find(inheritedPropertiesVector.begin(), inheritedPropertiesVector.end(), it->first)
|
||||||
|
!= inheritedPropertiesVector.end()) ?
|
||||||
|
MaterialProperty::Inherited_Changed : MaterialProperty::Normal;
|
||||||
|
MaterialProperty::Type type = getType(it->first, instance->getProperty(it->first));
|
||||||
|
mProperties[it->first] = MaterialProperty (
|
||||||
|
retrieveValue<sh::StringValue>(instance->getProperty(it->first), NULL).get(),
|
||||||
|
type, source);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<MaterialInstancePass>* passes = instance->getPasses();
|
||||||
|
for (std::vector<MaterialInstancePass>::iterator it = passes->begin(); it != passes->end(); ++it)
|
||||||
|
{
|
||||||
|
mPasses.push_back(PassInfo());
|
||||||
|
|
||||||
|
const sh::PropertyMap& passProperties = it->listProperties();
|
||||||
|
for (PropertyMap::const_iterator pit = passProperties.begin(); pit != passProperties.end(); ++pit)
|
||||||
|
{
|
||||||
|
PropertyValuePtr property = it->getProperty(pit->first);
|
||||||
|
MaterialProperty::Type type = getType(pit->first, property);
|
||||||
|
if (typeid(*property).name() == typeid(sh::LinkedValue).name())
|
||||||
|
mPasses.back().mProperties[pit->first] = MaterialProperty("$" + property->_getStringValue(), type);
|
||||||
|
else
|
||||||
|
mPasses.back().mProperties[pit->first] = MaterialProperty(
|
||||||
|
retrieveValue<sh::StringValue>(property, NULL).get(), type);
|
||||||
|
}
|
||||||
|
|
||||||
|
const sh::PropertyMap& shaderProperties = it->mShaderProperties.listProperties();
|
||||||
|
for (PropertyMap::const_iterator pit = shaderProperties.begin(); pit != shaderProperties.end(); ++pit)
|
||||||
|
{
|
||||||
|
PropertyValuePtr property = it->mShaderProperties.getProperty(pit->first);
|
||||||
|
MaterialProperty::Type type = getType(pit->first, property);
|
||||||
|
if (typeid(*property).name() == typeid(sh::LinkedValue).name())
|
||||||
|
mPasses.back().mShaderProperties[pit->first] = MaterialProperty("$" + property->_getStringValue(), type);
|
||||||
|
else
|
||||||
|
mPasses.back().mShaderProperties[pit->first] = MaterialProperty(
|
||||||
|
retrieveValue<sh::StringValue>(property, NULL).get(), type);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<MaterialInstanceTextureUnit>* texUnits = &it->mTexUnits;
|
||||||
|
for (std::vector<MaterialInstanceTextureUnit>::iterator tIt = texUnits->begin(); tIt != texUnits->end(); ++tIt)
|
||||||
|
{
|
||||||
|
mPasses.back().mTextureUnits.push_back(TextureUnitInfo());
|
||||||
|
mPasses.back().mTextureUnits.back().mName = tIt->getName();
|
||||||
|
const sh::PropertyMap& unitProperties = tIt->listProperties();
|
||||||
|
for (PropertyMap::const_iterator pit = unitProperties.begin(); pit != unitProperties.end(); ++pit)
|
||||||
|
{
|
||||||
|
PropertyValuePtr property = tIt->getProperty(pit->first);
|
||||||
|
MaterialProperty::Type type = getType(pit->first, property);
|
||||||
|
if (typeid(*property).name() == typeid(sh::LinkedValue).name())
|
||||||
|
mPasses.back().mTextureUnits.back().mProperties[pit->first] = MaterialProperty(
|
||||||
|
"$" + property->_getStringValue(), MaterialProperty::Linked);
|
||||||
|
else
|
||||||
|
mPasses.back().mTextureUnits.back().mProperties[pit->first] = MaterialProperty(
|
||||||
|
retrieveValue<sh::StringValue>(property, NULL).get(), type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MaterialProperty::Type MaterialQuery::getType(const std::string &key, PropertyValuePtr value)
|
||||||
|
{
|
||||||
|
if (typeid(*value).name() == typeid(sh::LinkedValue).name())
|
||||||
|
return MaterialProperty::Linked;
|
||||||
|
|
||||||
|
if (key == "vertex_program" || key == "fragment_program")
|
||||||
|
return MaterialProperty::Shader;
|
||||||
|
|
||||||
|
std::string valueStr = retrieveValue<sh::StringValue>(value, NULL).get();
|
||||||
|
|
||||||
|
if (valueStr == "false" || valueStr == "true")
|
||||||
|
return MaterialProperty::Boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaterialPropertyQuery::executeImpl()
|
||||||
|
{
|
||||||
|
sh::MaterialInstance* m = sh::Factory::getInstance().getMaterialInstance(mName);
|
||||||
|
mValue = retrieveValue<sh::StringValue>(m->getProperty(mPropertyName), m).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
121
extern/shiny/Editor/Query.hpp
vendored
Normal file
121
extern/shiny/Editor/Query.hpp
vendored
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
#ifndef SH_QUERY_H
|
||||||
|
#define SH_QUERY_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "../Main/PropertyBase.hpp"
|
||||||
|
|
||||||
|
namespace sh
|
||||||
|
{
|
||||||
|
|
||||||
|
class Query
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Query()
|
||||||
|
: mDone(false) {}
|
||||||
|
virtual ~Query();
|
||||||
|
|
||||||
|
void execute();
|
||||||
|
|
||||||
|
bool mDone;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void executeImpl() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ConfigurationQuery : public Query
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ConfigurationQuery(const std::string& name);
|
||||||
|
|
||||||
|
std::map<std::string, std::string> mProperties;
|
||||||
|
protected:
|
||||||
|
std::string mName;
|
||||||
|
virtual void executeImpl();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct MaterialProperty
|
||||||
|
{
|
||||||
|
|
||||||
|
enum Type
|
||||||
|
{
|
||||||
|
Texture,
|
||||||
|
Color,
|
||||||
|
Boolean,
|
||||||
|
Shader,
|
||||||
|
Misc,
|
||||||
|
Linked,
|
||||||
|
Object // child object, i.e. pass, texture unit, shader properties
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Source
|
||||||
|
{
|
||||||
|
Normal,
|
||||||
|
Inherited_Changed,
|
||||||
|
Inherited_Unchanged,
|
||||||
|
None // there is no property source (e.g. a pass, which does not have a name)
|
||||||
|
};
|
||||||
|
|
||||||
|
MaterialProperty() {}
|
||||||
|
MaterialProperty (const std::string& value, Type type, Source source=Normal)
|
||||||
|
: mValue(value), mType(type), mSource(source) {}
|
||||||
|
|
||||||
|
std::string mValue;
|
||||||
|
Type mType;
|
||||||
|
Source mSource;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct TextureUnitInfo
|
||||||
|
{
|
||||||
|
std::string mName;
|
||||||
|
std::map<std::string, MaterialProperty> mProperties;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PassInfo
|
||||||
|
{
|
||||||
|
std::map<std::string, MaterialProperty> mShaderProperties;
|
||||||
|
|
||||||
|
std::map<std::string, MaterialProperty> mProperties;
|
||||||
|
std::vector<TextureUnitInfo> mTextureUnits;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MaterialQuery : public Query
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MaterialQuery(const std::string& name)
|
||||||
|
: mName(name) {}
|
||||||
|
|
||||||
|
std::string mParent;
|
||||||
|
std::vector<PassInfo> mPasses;
|
||||||
|
std::map<std::string, MaterialProperty> mProperties;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::string mName;
|
||||||
|
virtual void executeImpl();
|
||||||
|
|
||||||
|
MaterialProperty::Type getType (const std::string& key, PropertyValuePtr value);
|
||||||
|
};
|
||||||
|
|
||||||
|
class MaterialPropertyQuery : public Query
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MaterialPropertyQuery(const std::string& name, const std::string& propertyName)
|
||||||
|
: mName(name), mPropertyName(propertyName)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string mValue;
|
||||||
|
|
||||||
|
std::string mName;
|
||||||
|
std::string mPropertyName;
|
||||||
|
protected:
|
||||||
|
virtual void executeImpl();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
118
extern/shiny/Editor/addpropertydialog.ui
vendored
Normal file
118
extern/shiny/Editor/addpropertydialog.ui
vendored
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>AddPropertyDialog</class>
|
||||||
|
<widget class="QDialog" name="AddPropertyDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>257</width>
|
||||||
|
<height>133</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Dialog</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLineEdit" name="lineEdit"/>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Property name</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Editing widget</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QComboBox" name="comboBox">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Checkbox</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Shader</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Color</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Texture</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Other</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>AddPropertyDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>248</x>
|
||||||
|
<y>254</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>AddPropertyDialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>316</x>
|
||||||
|
<y>260</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
420
extern/shiny/Editor/mainwindow.ui
vendored
Normal file
420
extern/shiny/Editor/mainwindow.ui
vendored
Normal file
@ -0,0 +1,420 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>MainWindow</class>
|
||||||
|
<widget class="QMainWindow" name="MainWindow">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>647</width>
|
||||||
|
<height>512</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>MainWindow</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="centralwidget">
|
||||||
|
<layout class="QHBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="sh::ColoredTabWidget" name="tabWidget">
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="tab">
|
||||||
|
<property name="accessibleName">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Materials</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QSplitter" name="splitter">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="verticalLayoutWidget">
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="lineEdit">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="placeholderText">
|
||||||
|
<string>Search</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QListView" name="materialList">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolBar" name="toolBar1">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>16</width>
|
||||||
|
<height>16</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionNewMaterial"/>
|
||||||
|
<addaction name="actionCloneMaterial"/>
|
||||||
|
<addaction name="actionDeleteMaterial"/>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="verticalLayoutWidget2">
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||||
|
<item>
|
||||||
|
<widget class="QTreeView" name="materialView">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>1</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolBar" name="toolBar4">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||||
|
<horstretch>1</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>16</width>
|
||||||
|
<height>16</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="toolButtonStyle">
|
||||||
|
<enum>Qt::ToolButtonIconOnly</enum>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionNewProperty"/>
|
||||||
|
<addaction name="actionDeleteProperty"/>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="tab2">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Global settings</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<item>
|
||||||
|
<widget class="QTableView" name="globalSettingsView"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="tab_2">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Configurations</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QSplitter" name="splitter_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="layoutWidget">
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
|
<item>
|
||||||
|
<widget class="QListWidget" name="configurationList"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolBar" name="toolBar2">
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>16</width>
|
||||||
|
<height>16</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionNewConfiguration"/>
|
||||||
|
<addaction name="actionDeleteConfiguration"/>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="layoutWidget2">
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||||
|
<item>
|
||||||
|
<widget class="QTableView" name="configurationView"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolBar" name="toolBar2_2">
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>16</width>
|
||||||
|
<height>16</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionDeleteConfigurationProperty"/>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="tab_3">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Errors</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||||
|
<item>
|
||||||
|
<widget class="QTextEdit" name="errorLog">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="clearButton">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Clear</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="edit-clear"/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QMenuBar" name="menubar">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>647</width>
|
||||||
|
<height>25</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="defaultUp">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<widget class="QMenu" name="menuFile">
|
||||||
|
<property name="title">
|
||||||
|
<string>File</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionSave"/>
|
||||||
|
<addaction name="actionQuit"/>
|
||||||
|
</widget>
|
||||||
|
<widget class="QMenu" name="menuMaterial">
|
||||||
|
<property name="title">
|
||||||
|
<string>Material</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionNewMaterial"/>
|
||||||
|
<addaction name="actionCloneMaterial"/>
|
||||||
|
<addaction name="actionDeleteMaterial"/>
|
||||||
|
<addaction name="actionChange_parent"/>
|
||||||
|
</widget>
|
||||||
|
<widget class="QMenu" name="menuHistory">
|
||||||
|
<property name="title">
|
||||||
|
<string>History</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<addaction name="menuFile"/>
|
||||||
|
<addaction name="menuMaterial"/>
|
||||||
|
<addaction name="menuHistory"/>
|
||||||
|
</widget>
|
||||||
|
<action name="actionQuit">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="application-exit">
|
||||||
|
<normaloff/>
|
||||||
|
</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Quit</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionSave">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="document-save">
|
||||||
|
<normaloff/>
|
||||||
|
</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Save</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Save all</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionDeleteMaterial">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="edit-delete">
|
||||||
|
<normaloff/>
|
||||||
|
</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Delete</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Delete selected material</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionChange_parent">
|
||||||
|
<property name="text">
|
||||||
|
<string>Change parent...</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionNewMaterial">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="document-new">
|
||||||
|
<normaloff/>
|
||||||
|
</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>New</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Create a new material</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionCloneMaterial">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="edit-copy">
|
||||||
|
<normaloff/>
|
||||||
|
</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Clone</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Clone selected material</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionDeleteConfiguration">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="edit-delete">
|
||||||
|
<normaloff/>
|
||||||
|
</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Delete</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Delete selected configuration</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Del</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionNewConfiguration">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="document-new">
|
||||||
|
<normaloff/>
|
||||||
|
</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>New</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Create a new configuration</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionDeleteConfigurationProperty">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="edit-delete">
|
||||||
|
<normaloff/>
|
||||||
|
</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Delete</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Delete property</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionDeleteProperty">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="remove">
|
||||||
|
<normaloff/>
|
||||||
|
</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Delete</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Delete item</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionNewProperty">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="add">
|
||||||
|
<normaloff/>
|
||||||
|
</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>New property</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionCreatePass">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="edit-add">
|
||||||
|
<normaloff/>
|
||||||
|
</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Create pass</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionCreateTextureUnit">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="edit-add">
|
||||||
|
<normaloff/>
|
||||||
|
</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Create texture unit</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>sh::ColoredTabWidget</class>
|
||||||
|
<extends>QTabWidget</extends>
|
||||||
|
<header>ColoredTabWidget.hpp</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
98
extern/shiny/Editor/newmaterialdialog.ui
vendored
Normal file
98
extern/shiny/Editor/newmaterialdialog.ui
vendored
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>NewMaterialDialog</class>
|
||||||
|
<widget class="QDialog" name="NewMaterialDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>385</width>
|
||||||
|
<height>198</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Dialog</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Name</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Parent material</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLineEdit" name="lineEdit_2"/>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLineEdit" name="lineEdit"/>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="text">
|
||||||
|
<string>File</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QComboBox" name="comboBox"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>NewMaterialDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>248</x>
|
||||||
|
<y>254</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>NewMaterialDialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>316</x>
|
||||||
|
<y>260</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
349
extern/shiny/Main/Factory.cpp
vendored
349
extern/shiny/Main/Factory.cpp
vendored
@ -51,8 +51,6 @@ namespace sh
|
|||||||
{
|
{
|
||||||
assert(mCurrentLanguage != Language_None);
|
assert(mCurrentLanguage != Language_None);
|
||||||
|
|
||||||
bool removeBinaryCache = false;
|
|
||||||
|
|
||||||
if (boost::filesystem::exists (mPlatform->getCacheFolder () + "/lastModified.txt"))
|
if (boost::filesystem::exists (mPlatform->getCacheFolder () + "/lastModified.txt"))
|
||||||
{
|
{
|
||||||
std::ifstream file;
|
std::ifstream file;
|
||||||
@ -86,8 +84,9 @@ namespace sh
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
PropertySetGet newConfiguration;
|
Configuration newConfiguration;
|
||||||
newConfiguration.setParent(&mGlobalSettings);
|
newConfiguration.setParent(&mGlobalSettings);
|
||||||
|
newConfiguration.setSourceFile (it->second->mFileName);
|
||||||
|
|
||||||
std::vector<ScriptNode*> props = it->second->getChildren();
|
std::vector<ScriptNode*> props = it->second->getChildren();
|
||||||
for (std::vector<ScriptNode*>::const_iterator propIt = props.begin(); propIt != props.end(); ++propIt)
|
for (std::vector<ScriptNode*>::const_iterator propIt = props.begin(); propIt != props.end(); ++propIt)
|
||||||
@ -137,82 +136,7 @@ namespace sh
|
|||||||
}
|
}
|
||||||
|
|
||||||
// load shader sets
|
// load shader sets
|
||||||
{
|
bool removeBinaryCache = reloadShaders();
|
||||||
ScriptLoader shaderSetLoader(".shaderset");
|
|
||||||
ScriptLoader::loadAllFiles (&shaderSetLoader, mPlatform->getBasePath());
|
|
||||||
std::map <std::string, ScriptNode*> nodes = shaderSetLoader.getAllConfigScripts();
|
|
||||||
for (std::map <std::string, ScriptNode*>::const_iterator it = nodes.begin();
|
|
||||||
it != nodes.end(); ++it)
|
|
||||||
{
|
|
||||||
if (!(it->second->getName() == "shader_set"))
|
|
||||||
{
|
|
||||||
std::cerr << "sh::Factory: Warning: Unsupported root node type \"" << it->second->getName() << "\" for file type .shaderset" << std::endl;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!it->second->findChild("profiles_cg"))
|
|
||||||
throw std::runtime_error ("missing \"profiles_cg\" field for \"" + it->first + "\"");
|
|
||||||
if (!it->second->findChild("profiles_hlsl"))
|
|
||||||
throw std::runtime_error ("missing \"profiles_hlsl\" field for \"" + it->first + "\"");
|
|
||||||
if (!it->second->findChild("source"))
|
|
||||||
throw std::runtime_error ("missing \"source\" field for \"" + it->first + "\"");
|
|
||||||
if (!it->second->findChild("type"))
|
|
||||||
throw std::runtime_error ("missing \"type\" field for \"" + it->first + "\"");
|
|
||||||
|
|
||||||
std::vector<std::string> profiles_cg;
|
|
||||||
boost::split (profiles_cg, it->second->findChild("profiles_cg")->getValue(), boost::is_any_of(" "));
|
|
||||||
std::string cg_profile;
|
|
||||||
for (std::vector<std::string>::iterator it2 = profiles_cg.begin(); it2 != profiles_cg.end(); ++it2)
|
|
||||||
{
|
|
||||||
if (mPlatform->isProfileSupported(*it2))
|
|
||||||
{
|
|
||||||
cg_profile = *it2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> profiles_hlsl;
|
|
||||||
boost::split (profiles_hlsl, it->second->findChild("profiles_hlsl")->getValue(), boost::is_any_of(" "));
|
|
||||||
std::string hlsl_profile;
|
|
||||||
for (std::vector<std::string>::iterator it2 = profiles_hlsl.begin(); it2 != profiles_hlsl.end(); ++it2)
|
|
||||||
{
|
|
||||||
if (mPlatform->isProfileSupported(*it2))
|
|
||||||
{
|
|
||||||
hlsl_profile = *it2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string sourceAbsolute = mPlatform->getBasePath() + "/" + it->second->findChild("source")->getValue();
|
|
||||||
std::string sourceRelative = it->second->findChild("source")->getValue();
|
|
||||||
|
|
||||||
ShaderSet newSet (it->second->findChild("type")->getValue(), cg_profile, hlsl_profile,
|
|
||||||
sourceAbsolute,
|
|
||||||
mPlatform->getBasePath(),
|
|
||||||
it->first,
|
|
||||||
&mGlobalSettings);
|
|
||||||
|
|
||||||
int lastModified = boost::filesystem::last_write_time (boost::filesystem::path(sourceAbsolute));
|
|
||||||
mShadersLastModifiedNew[sourceRelative] = lastModified;
|
|
||||||
if (mShadersLastModified.find(sourceRelative) != mShadersLastModified.end())
|
|
||||||
{
|
|
||||||
if (mShadersLastModified[sourceRelative] != lastModified)
|
|
||||||
{
|
|
||||||
// delete any outdated shaders based on this shader set
|
|
||||||
if (removeCache (it->first))
|
|
||||||
removeBinaryCache = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// if we get here, this is either the first run or a new shader file was added
|
|
||||||
// in both cases we can safely delete
|
|
||||||
if (removeCache (it->first))
|
|
||||||
removeBinaryCache = true;
|
|
||||||
}
|
|
||||||
mShaderSets.insert(std::make_pair(it->first, newSet));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// load materials
|
// load materials
|
||||||
{
|
{
|
||||||
@ -315,6 +239,8 @@ namespace sh
|
|||||||
|
|
||||||
Factory::~Factory ()
|
Factory::~Factory ()
|
||||||
{
|
{
|
||||||
|
mShaderSets.clear();
|
||||||
|
|
||||||
if (mPlatform->supportsShaderSerialization () && mWriteMicrocodeCache)
|
if (mPlatform->supportsShaderSerialization () && mWriteMicrocodeCache)
|
||||||
{
|
{
|
||||||
std::string file = mPlatform->getCacheFolder () + "/" + mBinaryCacheName;
|
std::string file = mPlatform->getCacheFolder () + "/" + mBinaryCacheName;
|
||||||
@ -367,15 +293,16 @@ namespace sh
|
|||||||
while (i>0)
|
while (i>0)
|
||||||
{
|
{
|
||||||
--i;
|
--i;
|
||||||
m->createForConfiguration (configuration, i);
|
if (m->createForConfiguration (configuration, i) && mListener)
|
||||||
|
|
||||||
if (mListener)
|
|
||||||
mListener->materialCreated (m, configuration, i);
|
mListener->materialCreated (m, configuration, i);
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
m->createForConfiguration (configuration, lodIndex);
|
if (m->createForConfiguration (configuration, lodIndex) && mListener)
|
||||||
if (mListener)
|
|
||||||
mListener->materialCreated (m, configuration, lodIndex);
|
mListener->materialCreated (m, configuration, lodIndex);
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
@ -439,6 +366,12 @@ namespace sh
|
|||||||
|
|
||||||
ShaderSet* Factory::getShaderSet (const std::string& name)
|
ShaderSet* Factory::getShaderSet (const std::string& name)
|
||||||
{
|
{
|
||||||
|
if (mShaderSets.find(name) == mShaderSets.end())
|
||||||
|
{
|
||||||
|
std::stringstream msg;
|
||||||
|
msg << "Shader '" << name << "' not found";
|
||||||
|
throw std::runtime_error(msg.str());
|
||||||
|
}
|
||||||
return &mShaderSets.find(name)->second;
|
return &mShaderSets.find(name)->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -466,6 +399,14 @@ namespace sh
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Factory::notifyConfigurationChanged()
|
||||||
|
{
|
||||||
|
for (MaterialMap::iterator it = mMaterials.begin(); it != mMaterials.end(); ++it)
|
||||||
|
{
|
||||||
|
it->second.destroyAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MaterialInstance* Factory::getMaterialInstance (const std::string& name)
|
MaterialInstance* Factory::getMaterialInstance (const std::string& name)
|
||||||
{
|
{
|
||||||
return findInstance(name);
|
return findInstance(name);
|
||||||
@ -493,17 +434,21 @@ namespace sh
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
PropertySetGet* Factory::getConfiguration (const std::string& name)
|
Configuration* Factory::getConfiguration (const std::string& name)
|
||||||
{
|
{
|
||||||
return &mConfigurations[name];
|
return &mConfigurations[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Factory::registerConfiguration (const std::string& name, PropertySetGet configuration)
|
void Factory::createConfiguration (const std::string& name)
|
||||||
{
|
{
|
||||||
mConfigurations[name] = configuration;
|
|
||||||
mConfigurations[name].setParent (&mGlobalSettings);
|
mConfigurations[name].setParent (&mGlobalSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Factory::destroyConfiguration(const std::string &name)
|
||||||
|
{
|
||||||
|
mConfigurations.erase(name);
|
||||||
|
}
|
||||||
|
|
||||||
void Factory::registerLodConfiguration (int index, PropertySetGet configuration)
|
void Factory::registerLodConfiguration (int index, PropertySetGet configuration)
|
||||||
{
|
{
|
||||||
mLodConfigurations[index] = configuration;
|
mLodConfigurations[index] = configuration;
|
||||||
@ -571,17 +516,93 @@ namespace sh
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Factory::saveMaterials (const std::string& filename)
|
void Factory::saveAll ()
|
||||||
{
|
{
|
||||||
std::ofstream file;
|
std::map<std::string, std::ofstream*> files;
|
||||||
file.open (filename.c_str ());
|
|
||||||
|
|
||||||
for (MaterialMap::iterator it = mMaterials.begin(); it != mMaterials.end(); ++it)
|
for (MaterialMap::iterator it = mMaterials.begin(); it != mMaterials.end(); ++it)
|
||||||
{
|
{
|
||||||
it->second.save(file);
|
if (it->second.getSourceFile().empty())
|
||||||
|
continue;
|
||||||
|
if (files.find(it->second.getSourceFile()) == files.end())
|
||||||
|
{
|
||||||
|
/// \todo check if this is actually the same file, since there can be different paths to the same file
|
||||||
|
std::ofstream* stream = new std::ofstream();
|
||||||
|
stream->open (it->second.getSourceFile().c_str());
|
||||||
|
|
||||||
|
files[it->second.getSourceFile()] = stream;
|
||||||
|
}
|
||||||
|
it->second.save (*files[it->second.getSourceFile()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
file.close();
|
for (std::map<std::string, std::ofstream*>::iterator it = files.begin(); it != files.end(); ++it)
|
||||||
|
{
|
||||||
|
delete it->second;
|
||||||
|
}
|
||||||
|
files.clear();
|
||||||
|
|
||||||
|
for (ConfigurationMap::iterator it = mConfigurations.begin(); it != mConfigurations.end(); ++it)
|
||||||
|
{
|
||||||
|
if (it->second.getSourceFile().empty())
|
||||||
|
continue;
|
||||||
|
if (files.find(it->second.getSourceFile()) == files.end())
|
||||||
|
{
|
||||||
|
/// \todo check if this is actually the same file, since there can be different paths to the same file
|
||||||
|
std::ofstream* stream = new std::ofstream();
|
||||||
|
stream->open (it->second.getSourceFile().c_str());
|
||||||
|
|
||||||
|
files[it->second.getSourceFile()] = stream;
|
||||||
|
}
|
||||||
|
it->second.save (it->first, *files[it->second.getSourceFile()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::map<std::string, std::ofstream*>::iterator it = files.begin(); it != files.end(); ++it)
|
||||||
|
{
|
||||||
|
delete it->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Factory::listMaterials(std::vector<std::string> &out)
|
||||||
|
{
|
||||||
|
for (MaterialMap::iterator it = mMaterials.begin(); it != mMaterials.end(); ++it)
|
||||||
|
{
|
||||||
|
out.push_back(it->first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Factory::listGlobalSettings(std::map<std::string, std::string> &out)
|
||||||
|
{
|
||||||
|
const PropertyMap& properties = mGlobalSettings.listProperties();
|
||||||
|
|
||||||
|
for (PropertyMap::const_iterator it = properties.begin(); it != properties.end(); ++it)
|
||||||
|
{
|
||||||
|
out[it->first] = retrieveValue<StringValue>(mGlobalSettings.getProperty(it->first), NULL).get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Factory::listConfigurationSettings(const std::string& name, std::map<std::string, std::string> &out)
|
||||||
|
{
|
||||||
|
const PropertyMap& properties = mConfigurations[name].listProperties();
|
||||||
|
|
||||||
|
for (PropertyMap::const_iterator it = properties.begin(); it != properties.end(); ++it)
|
||||||
|
{
|
||||||
|
out[it->first] = retrieveValue<StringValue>(mConfigurations[name].getProperty(it->first), NULL).get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Factory::listConfigurationNames(std::vector<std::string> &out)
|
||||||
|
{
|
||||||
|
for (ConfigurationMap::const_iterator it = mConfigurations.begin(); it != mConfigurations.end(); ++it)
|
||||||
|
{
|
||||||
|
out.push_back(it->first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Factory::listShaderSets(std::vector<std::string> &out)
|
||||||
|
{
|
||||||
|
for (ShaderSetMap::const_iterator it = mShaderSets.begin(); it != mShaderSets.end(); ++it)
|
||||||
|
{
|
||||||
|
out.push_back(it->first);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Factory::_ensureMaterial(const std::string& name, const std::string& configuration)
|
void Factory::_ensureMaterial(const std::string& name, const std::string& configuration)
|
||||||
@ -630,4 +651,146 @@ namespace sh
|
|||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Factory::reloadShaders()
|
||||||
|
{
|
||||||
|
mShaderSets.clear();
|
||||||
|
notifyConfigurationChanged();
|
||||||
|
|
||||||
|
bool removeBinaryCache = false;
|
||||||
|
ScriptLoader shaderSetLoader(".shaderset");
|
||||||
|
ScriptLoader::loadAllFiles (&shaderSetLoader, mPlatform->getBasePath());
|
||||||
|
std::map <std::string, ScriptNode*> nodes = shaderSetLoader.getAllConfigScripts();
|
||||||
|
for (std::map <std::string, ScriptNode*>::const_iterator it = nodes.begin();
|
||||||
|
it != nodes.end(); ++it)
|
||||||
|
{
|
||||||
|
if (!(it->second->getName() == "shader_set"))
|
||||||
|
{
|
||||||
|
std::cerr << "sh::Factory: Warning: Unsupported root node type \"" << it->second->getName() << "\" for file type .shaderset" << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!it->second->findChild("profiles_cg"))
|
||||||
|
throw std::runtime_error ("missing \"profiles_cg\" field for \"" + it->first + "\"");
|
||||||
|
if (!it->second->findChild("profiles_hlsl"))
|
||||||
|
throw std::runtime_error ("missing \"profiles_hlsl\" field for \"" + it->first + "\"");
|
||||||
|
if (!it->second->findChild("source"))
|
||||||
|
throw std::runtime_error ("missing \"source\" field for \"" + it->first + "\"");
|
||||||
|
if (!it->second->findChild("type"))
|
||||||
|
throw std::runtime_error ("missing \"type\" field for \"" + it->first + "\"");
|
||||||
|
|
||||||
|
std::vector<std::string> profiles_cg;
|
||||||
|
boost::split (profiles_cg, it->second->findChild("profiles_cg")->getValue(), boost::is_any_of(" "));
|
||||||
|
std::string cg_profile;
|
||||||
|
for (std::vector<std::string>::iterator it2 = profiles_cg.begin(); it2 != profiles_cg.end(); ++it2)
|
||||||
|
{
|
||||||
|
if (mPlatform->isProfileSupported(*it2))
|
||||||
|
{
|
||||||
|
cg_profile = *it2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> profiles_hlsl;
|
||||||
|
boost::split (profiles_hlsl, it->second->findChild("profiles_hlsl")->getValue(), boost::is_any_of(" "));
|
||||||
|
std::string hlsl_profile;
|
||||||
|
for (std::vector<std::string>::iterator it2 = profiles_hlsl.begin(); it2 != profiles_hlsl.end(); ++it2)
|
||||||
|
{
|
||||||
|
if (mPlatform->isProfileSupported(*it2))
|
||||||
|
{
|
||||||
|
hlsl_profile = *it2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string sourceAbsolute = mPlatform->getBasePath() + "/" + it->second->findChild("source")->getValue();
|
||||||
|
std::string sourceRelative = it->second->findChild("source")->getValue();
|
||||||
|
|
||||||
|
ShaderSet newSet (it->second->findChild("type")->getValue(), cg_profile, hlsl_profile,
|
||||||
|
sourceAbsolute,
|
||||||
|
mPlatform->getBasePath(),
|
||||||
|
it->first,
|
||||||
|
&mGlobalSettings);
|
||||||
|
|
||||||
|
int lastModified = boost::filesystem::last_write_time (boost::filesystem::path(sourceAbsolute));
|
||||||
|
mShadersLastModifiedNew[sourceRelative] = lastModified;
|
||||||
|
if (mShadersLastModified.find(sourceRelative) != mShadersLastModified.end())
|
||||||
|
{
|
||||||
|
if (mShadersLastModified[sourceRelative] != lastModified)
|
||||||
|
{
|
||||||
|
// delete any outdated shaders based on this shader set
|
||||||
|
if (removeCache (it->first))
|
||||||
|
removeBinaryCache = true;
|
||||||
|
mShadersLastModified[sourceRelative] = lastModified;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// if we get here, this is either the first run or a new shader file was added
|
||||||
|
// in both cases we can safely delete
|
||||||
|
if (removeCache (it->first))
|
||||||
|
removeBinaryCache = true;
|
||||||
|
mShadersLastModified[sourceRelative] = lastModified;
|
||||||
|
}
|
||||||
|
mShaderSets.insert(std::make_pair(it->first, newSet));
|
||||||
|
}
|
||||||
|
|
||||||
|
return removeBinaryCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Factory::doMonitorShaderFiles()
|
||||||
|
{
|
||||||
|
bool reload=false;
|
||||||
|
ScriptLoader shaderSetLoader(".shaderset");
|
||||||
|
ScriptLoader::loadAllFiles (&shaderSetLoader, mPlatform->getBasePath());
|
||||||
|
std::map <std::string, ScriptNode*> nodes = shaderSetLoader.getAllConfigScripts();
|
||||||
|
for (std::map <std::string, ScriptNode*>::const_iterator it = nodes.begin();
|
||||||
|
it != nodes.end(); ++it)
|
||||||
|
{
|
||||||
|
|
||||||
|
std::string sourceAbsolute = mPlatform->getBasePath() + "/" + it->second->findChild("source")->getValue();
|
||||||
|
std::string sourceRelative = it->second->findChild("source")->getValue();
|
||||||
|
|
||||||
|
int lastModified = boost::filesystem::last_write_time (boost::filesystem::path(sourceAbsolute));
|
||||||
|
if (mShadersLastModified.find(sourceRelative) != mShadersLastModified.end())
|
||||||
|
{
|
||||||
|
if (mShadersLastModified[sourceRelative] != lastModified)
|
||||||
|
{
|
||||||
|
reload=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (reload)
|
||||||
|
reloadShaders();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Factory::logError(const std::string &msg)
|
||||||
|
{
|
||||||
|
mErrorLog << msg << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Factory::getErrorLog()
|
||||||
|
{
|
||||||
|
std::string errors = mErrorLog.str();
|
||||||
|
mErrorLog.str("");
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Factory::unloadUnreferencedMaterials()
|
||||||
|
{
|
||||||
|
for (MaterialMap::iterator it = mMaterials.begin(); it != mMaterials.end(); ++it)
|
||||||
|
{
|
||||||
|
if (it->second.getMaterial()->isUnreferenced())
|
||||||
|
it->second.destroyAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Configuration::save(const std::string& name, std::ofstream &stream)
|
||||||
|
{
|
||||||
|
stream << "configuration " << name << '\n';
|
||||||
|
stream << "{\n";
|
||||||
|
PropertySetGet::save(stream, "\t");
|
||||||
|
stream << "}\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
70
extern/shiny/Main/Factory.hpp
vendored
70
extern/shiny/Main/Factory.hpp
vendored
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
#include "MaterialInstance.hpp"
|
#include "MaterialInstance.hpp"
|
||||||
#include "ShaderSet.hpp"
|
#include "ShaderSet.hpp"
|
||||||
@ -12,9 +13,21 @@ namespace sh
|
|||||||
{
|
{
|
||||||
class Platform;
|
class Platform;
|
||||||
|
|
||||||
|
class Configuration : public PropertySetGet
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void setSourceFile (const std::string& file) { mSourceFile = file ; }
|
||||||
|
std::string getSourceFile () { return mSourceFile; }
|
||||||
|
|
||||||
|
void save(const std::string& name, std::ofstream &stream);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string mSourceFile;
|
||||||
|
};
|
||||||
|
|
||||||
typedef std::map<std::string, MaterialInstance> MaterialMap;
|
typedef std::map<std::string, MaterialInstance> MaterialMap;
|
||||||
typedef std::map<std::string, ShaderSet> ShaderSetMap;
|
typedef std::map<std::string, ShaderSet> ShaderSetMap;
|
||||||
typedef std::map<std::string, PropertySetGet> ConfigurationMap;
|
typedef std::map<std::string, Configuration> ConfigurationMap;
|
||||||
typedef std::map<int, PropertySetGet> LodConfigurationMap;
|
typedef std::map<int, PropertySetGet> LodConfigurationMap;
|
||||||
typedef std::map<std::string, int> LastModifiedMap;
|
typedef std::map<std::string, int> LastModifiedMap;
|
||||||
|
|
||||||
@ -81,8 +94,8 @@ namespace sh
|
|||||||
/// Get a MaterialInstance by name
|
/// Get a MaterialInstance by name
|
||||||
MaterialInstance* getMaterialInstance (const std::string& name);
|
MaterialInstance* getMaterialInstance (const std::string& name);
|
||||||
|
|
||||||
/// Register a configuration, which can then be used by switching the active material scheme
|
/// Create a configuration, which can then be altered by using Factory::getConfiguration
|
||||||
void registerConfiguration (const std::string& name, PropertySetGet configuration);
|
void createConfiguration (const std::string& name);
|
||||||
|
|
||||||
/// Register a lod configuration, which can then be used by setting up lod distance values for the material \n
|
/// Register a lod configuration, which can then be used by setting up lod distance values for the material \n
|
||||||
/// 0 refers to highest lod, so use 1 or higher as index parameter
|
/// 0 refers to highest lod, so use 1 or higher as index parameter
|
||||||
@ -125,8 +138,48 @@ namespace sh
|
|||||||
/// \note The default is off (no cache reading)
|
/// \note The default is off (no cache reading)
|
||||||
void setReadMicrocodeCache(bool read) { mReadMicrocodeCache = read; }
|
void setReadMicrocodeCache(bool read) { mReadMicrocodeCache = read; }
|
||||||
|
|
||||||
/// Saves all the materials that were initially loaded from the file with this name
|
/// Lists all materials currently registered with the factory. Whether they are
|
||||||
void saveMaterials (const std::string& filename);
|
/// loaded or not does not matter.
|
||||||
|
void listMaterials (std::vector<std::string>& out);
|
||||||
|
|
||||||
|
/// Lists current name & value of all global settings.
|
||||||
|
void listGlobalSettings (std::map<std::string, std::string>& out);
|
||||||
|
|
||||||
|
/// Lists configuration names.
|
||||||
|
void listConfigurationNames (std::vector<std::string>& out);
|
||||||
|
|
||||||
|
/// Lists current name & value of settings for a given configuration.
|
||||||
|
void listConfigurationSettings (const std::string& name, std::map<std::string, std::string>& out);
|
||||||
|
|
||||||
|
/// Lists shader sets.
|
||||||
|
void listShaderSets (std::vector<std::string>& out);
|
||||||
|
|
||||||
|
/// \note This only works if microcode caching is disabled, as there is currently no way to remove the cache
|
||||||
|
/// through the Ogre API. Luckily, this is already fixed in Ogre 1.9.
|
||||||
|
bool reloadShaders();
|
||||||
|
|
||||||
|
/// Calls reloadShaders() if shader files have been modified since the last reload.
|
||||||
|
/// \note This only works if microcode caching is disabled, as there is currently no way to remove the cache
|
||||||
|
/// through the Ogre API. Luckily, this is already fixed in Ogre 1.9.
|
||||||
|
void doMonitorShaderFiles();
|
||||||
|
|
||||||
|
/// Unloads all materials that are currently not referenced. This will not unload the textures themselves,
|
||||||
|
/// but it will let go of the SharedPtr's to the textures, so that you may unload them if you so desire. \n
|
||||||
|
/// A good time to call this would be after a new level has been loaded, but just calling it occasionally after a period
|
||||||
|
/// of time should work just fine too.
|
||||||
|
void unloadUnreferencedMaterials();
|
||||||
|
|
||||||
|
void destroyConfiguration (const std::string& name);
|
||||||
|
|
||||||
|
void notifyConfigurationChanged();
|
||||||
|
|
||||||
|
/// Saves all materials and configurations, by default to the file they were loaded from.
|
||||||
|
/// If you wish to save them elsewhere, use setSourceFile first.
|
||||||
|
void saveAll ();
|
||||||
|
|
||||||
|
/// Returns the error log as a string, then clears it.
|
||||||
|
/// Note: Errors are also written to the standard error output, or thrown if they are fatal.
|
||||||
|
std::string getErrorLog ();
|
||||||
|
|
||||||
static Factory& getInstance();
|
static Factory& getInstance();
|
||||||
///< Return instance of this class.
|
///< Return instance of this class.
|
||||||
@ -137,11 +190,13 @@ namespace sh
|
|||||||
/// You will probably never have to use this.
|
/// You will probably never have to use this.
|
||||||
void _ensureMaterial(const std::string& name, const std::string& configuration);
|
void _ensureMaterial(const std::string& name, const std::string& configuration);
|
||||||
|
|
||||||
|
|
||||||
|
Configuration* getConfiguration (const std::string& name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
MaterialInstance* requestMaterial (const std::string& name, const std::string& configuration, unsigned short lodIndex);
|
MaterialInstance* requestMaterial (const std::string& name, const std::string& configuration, unsigned short lodIndex);
|
||||||
ShaderSet* getShaderSet (const std::string& name);
|
ShaderSet* getShaderSet (const std::string& name);
|
||||||
PropertySetGet* getConfiguration (const std::string& name);
|
|
||||||
Platform* getPlatform ();
|
Platform* getPlatform ();
|
||||||
|
|
||||||
PropertySetGet* getCurrentGlobalSettings();
|
PropertySetGet* getCurrentGlobalSettings();
|
||||||
@ -163,6 +218,8 @@ namespace sh
|
|||||||
|
|
||||||
std::map<TextureUnitState*, std::string> mTextureAliasInstances;
|
std::map<TextureUnitState*, std::string> mTextureAliasInstances;
|
||||||
|
|
||||||
|
void logError (const std::string& msg);
|
||||||
|
|
||||||
friend class Platform;
|
friend class Platform;
|
||||||
friend class MaterialInstance;
|
friend class MaterialInstance;
|
||||||
friend class ShaderInstance;
|
friend class ShaderInstance;
|
||||||
@ -179,6 +236,7 @@ namespace sh
|
|||||||
bool mWriteMicrocodeCache;
|
bool mWriteMicrocodeCache;
|
||||||
bool mReadSourceCache;
|
bool mReadSourceCache;
|
||||||
bool mWriteSourceCache;
|
bool mWriteSourceCache;
|
||||||
|
std::stringstream mErrorLog;
|
||||||
|
|
||||||
MaterialMap mMaterials;
|
MaterialMap mMaterials;
|
||||||
ShaderSetMap mShaderSets;
|
ShaderSetMap mShaderSets;
|
||||||
|
228
extern/shiny/Main/MaterialInstance.cpp
vendored
228
extern/shiny/Main/MaterialInstance.cpp
vendored
@ -1,6 +1,7 @@
|
|||||||
#include "MaterialInstance.hpp"
|
#include "MaterialInstance.hpp"
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include "Factory.hpp"
|
#include "Factory.hpp"
|
||||||
#include "ShaderSet.hpp"
|
#include "ShaderSet.hpp"
|
||||||
@ -12,6 +13,7 @@ namespace sh
|
|||||||
, mShadersEnabled(true)
|
, mShadersEnabled(true)
|
||||||
, mFactory(f)
|
, mFactory(f)
|
||||||
, mListener(NULL)
|
, mListener(NULL)
|
||||||
|
, mFailedToCreate(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,6 +48,7 @@ namespace sh
|
|||||||
return;
|
return;
|
||||||
mMaterial->removeAll();
|
mMaterial->removeAll();
|
||||||
mTexUnits.clear();
|
mTexUnits.clear();
|
||||||
|
mFailedToCreate = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaterialInstance::setProperty (const std::string& name, PropertyValuePtr value)
|
void MaterialInstance::setProperty (const std::string& name, PropertyValuePtr value)
|
||||||
@ -54,118 +57,136 @@ namespace sh
|
|||||||
destroyAll(); // trigger updates
|
destroyAll(); // trigger updates
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaterialInstance::createForConfiguration (const std::string& configuration, unsigned short lodIndex)
|
bool MaterialInstance::createForConfiguration (const std::string& configuration, unsigned short lodIndex)
|
||||||
{
|
{
|
||||||
bool res = mMaterial->createConfiguration(configuration, lodIndex);
|
if (mFailedToCreate)
|
||||||
if (!res)
|
return false;
|
||||||
return; // listener was false positive
|
try{
|
||||||
|
mMaterial->ensureLoaded();
|
||||||
|
bool res = mMaterial->createConfiguration(configuration, lodIndex);
|
||||||
|
if (!res)
|
||||||
|
return false; // listener was false positive
|
||||||
|
|
||||||
if (mListener)
|
if (mListener)
|
||||||
mListener->requestedConfiguration (this, configuration);
|
mListener->requestedConfiguration (this, configuration);
|
||||||
|
|
||||||
mFactory->setActiveConfiguration (configuration);
|
mFactory->setActiveConfiguration (configuration);
|
||||||
mFactory->setActiveLodLevel (lodIndex);
|
mFactory->setActiveLodLevel (lodIndex);
|
||||||
|
|
||||||
bool allowFixedFunction = true;
|
bool allowFixedFunction = true;
|
||||||
if (!mShadersEnabled && hasProperty("allow_fixed_function"))
|
if (!mShadersEnabled && hasProperty("allow_fixed_function"))
|
||||||
{
|
|
||||||
allowFixedFunction = retrieveValue<BooleanValue>(getProperty("allow_fixed_function"), NULL).get();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool useShaders = mShadersEnabled || !allowFixedFunction;
|
|
||||||
|
|
||||||
// get passes of the top-most parent
|
|
||||||
PassVector passes = getPasses();
|
|
||||||
if (passes.size() == 0)
|
|
||||||
throw std::runtime_error ("material \"" + mName + "\" does not have any passes");
|
|
||||||
|
|
||||||
for (PassVector::iterator it = passes.begin(); it != passes.end(); ++it)
|
|
||||||
{
|
|
||||||
boost::shared_ptr<Pass> pass = mMaterial->createPass (configuration, lodIndex);
|
|
||||||
it->copyAll (pass.get(), this);
|
|
||||||
|
|
||||||
// texture samplers used in the shaders
|
|
||||||
std::vector<std::string> usedTextureSamplersVertex;
|
|
||||||
std::vector<std::string> usedTextureSamplersFragment;
|
|
||||||
|
|
||||||
PropertySetGet* context = this;
|
|
||||||
|
|
||||||
// create or retrieve shaders
|
|
||||||
bool hasVertex = it->hasProperty("vertex_program");
|
|
||||||
bool hasFragment = it->hasProperty("fragment_program");
|
|
||||||
if (useShaders)
|
|
||||||
{
|
{
|
||||||
it->setContext(context);
|
allowFixedFunction = retrieveValue<BooleanValue>(getProperty("allow_fixed_function"), NULL).get();
|
||||||
it->mShaderProperties.setContext(context);
|
}
|
||||||
if (hasVertex)
|
|
||||||
|
bool useShaders = mShadersEnabled || !allowFixedFunction;
|
||||||
|
|
||||||
|
// get passes of the top-most parent
|
||||||
|
PassVector* passes = getParentPasses();
|
||||||
|
if (passes->empty())
|
||||||
|
throw std::runtime_error ("material \"" + mName + "\" does not have any passes");
|
||||||
|
|
||||||
|
for (PassVector::iterator it = passes->begin(); it != passes->end(); ++it)
|
||||||
|
{
|
||||||
|
boost::shared_ptr<Pass> pass = mMaterial->createPass (configuration, lodIndex);
|
||||||
|
it->copyAll (pass.get(), this);
|
||||||
|
|
||||||
|
// texture samplers used in the shaders
|
||||||
|
std::vector<std::string> usedTextureSamplersVertex;
|
||||||
|
std::vector<std::string> usedTextureSamplersFragment;
|
||||||
|
|
||||||
|
PropertySetGet* context = this;
|
||||||
|
|
||||||
|
// create or retrieve shaders
|
||||||
|
bool hasVertex = it->hasProperty("vertex_program")
|
||||||
|
&& !retrieveValue<StringValue>(it->getProperty("vertex_program"), context).get().empty();
|
||||||
|
bool hasFragment = it->hasProperty("fragment_program")
|
||||||
|
&& !retrieveValue<StringValue>(it->getProperty("fragment_program"), context).get().empty();
|
||||||
|
if (useShaders)
|
||||||
{
|
{
|
||||||
ShaderSet* vertex = mFactory->getShaderSet(retrieveValue<StringValue>(it->getProperty("vertex_program"), context).get());
|
it->setContext(context);
|
||||||
ShaderInstance* v = vertex->getInstance(&it->mShaderProperties);
|
it->mShaderProperties.setContext(context);
|
||||||
if (v)
|
if (hasVertex)
|
||||||
{
|
{
|
||||||
pass->assignProgram (GPT_Vertex, v->getName());
|
ShaderSet* vertex = mFactory->getShaderSet(retrieveValue<StringValue>(it->getProperty("vertex_program"), context).get());
|
||||||
v->setUniformParameters (pass, &it->mShaderProperties);
|
ShaderInstance* v = vertex->getInstance(&it->mShaderProperties);
|
||||||
|
if (v)
|
||||||
std::vector<std::string> sharedParams = v->getSharedParameters ();
|
|
||||||
for (std::vector<std::string>::iterator it = sharedParams.begin(); it != sharedParams.end(); ++it)
|
|
||||||
{
|
{
|
||||||
pass->addSharedParameter (GPT_Vertex, *it);
|
pass->assignProgram (GPT_Vertex, v->getName());
|
||||||
}
|
v->setUniformParameters (pass, &it->mShaderProperties);
|
||||||
|
|
||||||
std::vector<std::string> vector = v->getUsedSamplers ();
|
std::vector<std::string> sharedParams = v->getSharedParameters ();
|
||||||
usedTextureSamplersVertex.insert(usedTextureSamplersVertex.end(), vector.begin(), vector.end());
|
for (std::vector<std::string>::iterator it2 = sharedParams.begin(); it2 != sharedParams.end(); ++it2)
|
||||||
|
{
|
||||||
|
pass->addSharedParameter (GPT_Vertex, *it2);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> vector = v->getUsedSamplers ();
|
||||||
|
usedTextureSamplersVertex.insert(usedTextureSamplersVertex.end(), vector.begin(), vector.end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hasFragment)
|
||||||
|
{
|
||||||
|
ShaderSet* fragment = mFactory->getShaderSet(retrieveValue<StringValue>(it->getProperty("fragment_program"), context).get());
|
||||||
|
ShaderInstance* f = fragment->getInstance(&it->mShaderProperties);
|
||||||
|
if (f)
|
||||||
|
{
|
||||||
|
pass->assignProgram (GPT_Fragment, f->getName());
|
||||||
|
f->setUniformParameters (pass, &it->mShaderProperties);
|
||||||
|
|
||||||
|
std::vector<std::string> sharedParams = f->getSharedParameters ();
|
||||||
|
for (std::vector<std::string>::iterator it2 = sharedParams.begin(); it2 != sharedParams.end(); ++it2)
|
||||||
|
{
|
||||||
|
pass->addSharedParameter (GPT_Fragment, *it2);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> vector = f->getUsedSamplers ();
|
||||||
|
usedTextureSamplersFragment.insert(usedTextureSamplersFragment.end(), vector.begin(), vector.end());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hasFragment)
|
|
||||||
|
// create texture units
|
||||||
|
std::vector<MaterialInstanceTextureUnit>* texUnits = &it->mTexUnits;
|
||||||
|
int i=0;
|
||||||
|
for (std::vector<MaterialInstanceTextureUnit>::iterator texIt = texUnits->begin(); texIt != texUnits->end(); ++texIt )
|
||||||
{
|
{
|
||||||
ShaderSet* fragment = mFactory->getShaderSet(retrieveValue<StringValue>(it->getProperty("fragment_program"), context).get());
|
// only create those that are needed by the shader, OR those marked to be created in fixed function pipeline if shaders are disabled
|
||||||
ShaderInstance* f = fragment->getInstance(&it->mShaderProperties);
|
bool foundVertex = std::find(usedTextureSamplersVertex.begin(), usedTextureSamplersVertex.end(), texIt->getName()) != usedTextureSamplersVertex.end();
|
||||||
if (f)
|
bool foundFragment = std::find(usedTextureSamplersFragment.begin(), usedTextureSamplersFragment.end(), texIt->getName()) != usedTextureSamplersFragment.end();
|
||||||
|
if ( (foundVertex || foundFragment)
|
||||||
|
|| (((!useShaders || (!hasVertex || !hasFragment)) && allowFixedFunction) && texIt->hasProperty("create_in_ffp") && retrieveValue<BooleanValue>(texIt->getProperty("create_in_ffp"), this).get()))
|
||||||
{
|
{
|
||||||
pass->assignProgram (GPT_Fragment, f->getName());
|
boost::shared_ptr<TextureUnitState> texUnit = pass->createTextureUnitState (texIt->getName());
|
||||||
f->setUniformParameters (pass, &it->mShaderProperties);
|
texIt->copyAll (texUnit.get(), context);
|
||||||
|
|
||||||
std::vector<std::string> sharedParams = f->getSharedParameters ();
|
mTexUnits.push_back(texUnit);
|
||||||
for (std::vector<std::string>::iterator it = sharedParams.begin(); it != sharedParams.end(); ++it)
|
|
||||||
|
// set texture unit indices (required by GLSL)
|
||||||
|
if (useShaders && ((hasVertex && foundVertex) || (hasFragment && foundFragment)) && mFactory->getCurrentLanguage () == Language_GLSL)
|
||||||
{
|
{
|
||||||
pass->addSharedParameter (GPT_Fragment, *it);
|
pass->setTextureUnitIndex (foundVertex ? GPT_Vertex : GPT_Fragment, texIt->getName(), i);
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> vector = f->getUsedSamplers ();
|
++i;
|
||||||
usedTextureSamplersFragment.insert(usedTextureSamplersFragment.end(), vector.begin(), vector.end());
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// create texture units
|
if (mListener)
|
||||||
std::vector<MaterialInstanceTextureUnit> texUnits = it->getTexUnits();
|
mListener->createdConfiguration (this, configuration);
|
||||||
int i=0;
|
return true;
|
||||||
for (std::vector<MaterialInstanceTextureUnit>::iterator texIt = texUnits.begin(); texIt != texUnits.end(); ++texIt )
|
|
||||||
{
|
|
||||||
// only create those that are needed by the shader, OR those marked to be created in fixed function pipeline if shaders are disabled
|
|
||||||
bool foundVertex = std::find(usedTextureSamplersVertex.begin(), usedTextureSamplersVertex.end(), texIt->getName()) != usedTextureSamplersVertex.end();
|
|
||||||
bool foundFragment = std::find(usedTextureSamplersFragment.begin(), usedTextureSamplersFragment.end(), texIt->getName()) != usedTextureSamplersFragment.end();
|
|
||||||
if ( (foundVertex || foundFragment)
|
|
||||||
|| (((!useShaders || (!hasVertex || !hasFragment)) && allowFixedFunction) && texIt->hasProperty("create_in_ffp") && retrieveValue<BooleanValue>(texIt->getProperty("create_in_ffp"), this).get()))
|
|
||||||
{
|
|
||||||
boost::shared_ptr<TextureUnitState> texUnit = pass->createTextureUnitState ();
|
|
||||||
texIt->copyAll (texUnit.get(), context);
|
|
||||||
|
|
||||||
mTexUnits.push_back(texUnit);
|
} catch (std::runtime_error& e)
|
||||||
|
{
|
||||||
// set texture unit indices (required by GLSL)
|
destroyAll();
|
||||||
if (useShaders && ((hasVertex && foundVertex) || (hasFragment && foundFragment)) && mFactory->getCurrentLanguage () == Language_GLSL)
|
mFailedToCreate = true;
|
||||||
{
|
std::stringstream msg;
|
||||||
pass->setTextureUnitIndex (foundVertex ? GPT_Vertex : GPT_Fragment, texIt->getName(), i);
|
msg << "Error while creating material " << mName << ": " << e.what();
|
||||||
|
std::cerr << msg.str() << std::endl;
|
||||||
++i;
|
mFactory->logError(msg.str());
|
||||||
}
|
return false;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mListener)
|
|
||||||
mListener->createdConfiguration (this, configuration);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Material* MaterialInstance::getMaterial ()
|
Material* MaterialInstance::getMaterial ()
|
||||||
@ -180,12 +201,23 @@ namespace sh
|
|||||||
return &mPasses.back();
|
return &mPasses.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
PassVector MaterialInstance::getPasses()
|
void MaterialInstance::deletePass(unsigned int index)
|
||||||
|
{
|
||||||
|
assert(mPasses.size() > index);
|
||||||
|
mPasses.erase(mPasses.begin()+index);
|
||||||
|
}
|
||||||
|
|
||||||
|
PassVector* MaterialInstance::getParentPasses()
|
||||||
{
|
{
|
||||||
if (mParent)
|
if (mParent)
|
||||||
return static_cast<MaterialInstance*>(mParent)->getPasses();
|
return static_cast<MaterialInstance*>(mParent)->getParentPasses();
|
||||||
else
|
else
|
||||||
return mPasses;
|
return &mPasses;
|
||||||
|
}
|
||||||
|
|
||||||
|
PassVector* MaterialInstance::getPasses()
|
||||||
|
{
|
||||||
|
return &mPasses;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaterialInstance::setShadersEnabled (bool enabled)
|
void MaterialInstance::setShadersEnabled (bool enabled)
|
||||||
@ -206,7 +238,7 @@ namespace sh
|
|||||||
|
|
||||||
if (mParent)
|
if (mParent)
|
||||||
{
|
{
|
||||||
stream << "\t" << static_cast<MaterialInstance*>(mParent)->getName() << "\n";
|
stream << "\t" << "parent " << static_cast<MaterialInstance*>(mParent)->getName() << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
const PropertyMap& properties = listProperties ();
|
const PropertyMap& properties = listProperties ();
|
||||||
@ -215,6 +247,14 @@ namespace sh
|
|||||||
stream << "\t" << it->first << " " << retrieveValue<StringValue>(getProperty(it->first), NULL).get() << "\n";
|
stream << "\t" << it->first << " " << retrieveValue<StringValue>(getProperty(it->first), NULL).get() << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (PassVector::iterator it = mPasses.begin(); it != mPasses.end(); ++it)
|
||||||
|
{
|
||||||
|
stream << "\tpass" << '\n';
|
||||||
|
stream << "\t{" << '\n';
|
||||||
|
it->save(stream);
|
||||||
|
stream << "\t}" << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
stream << "}\n";
|
stream << "}\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
32
extern/shiny/Main/MaterialInstance.hpp
vendored
32
extern/shiny/Main/MaterialInstance.hpp
vendored
@ -41,8 +41,12 @@ namespace sh
|
|||||||
MaterialInstance (const std::string& name, Factory* f);
|
MaterialInstance (const std::string& name, Factory* f);
|
||||||
virtual ~MaterialInstance ();
|
virtual ~MaterialInstance ();
|
||||||
|
|
||||||
|
PassVector* getParentPasses(); ///< gets the passes of the top-most parent
|
||||||
|
|
||||||
|
PassVector* getPasses(); ///< get our passes (for derived materials, none)
|
||||||
|
|
||||||
MaterialInstancePass* createPass ();
|
MaterialInstancePass* createPass ();
|
||||||
PassVector getPasses(); ///< gets the passes of the top-most parent
|
void deletePass (unsigned int index);
|
||||||
|
|
||||||
/// @attention Because the backend material passes are created on demand, the returned material here might not contain anything yet!
|
/// @attention Because the backend material passes are created on demand, the returned material here might not contain anything yet!
|
||||||
/// The only place where you should use this method, is for the MaterialInstance given by the MaterialListener::materialCreated event!
|
/// The only place where you should use this method, is for the MaterialInstance given by the MaterialListener::materialCreated event!
|
||||||
@ -55,25 +59,25 @@ namespace sh
|
|||||||
|
|
||||||
virtual void setProperty (const std::string& name, PropertyValuePtr value);
|
virtual void setProperty (const std::string& name, PropertyValuePtr value);
|
||||||
|
|
||||||
private:
|
|
||||||
void setParentInstance (const std::string& name);
|
|
||||||
std::string getParentInstance ();
|
|
||||||
|
|
||||||
void create (Platform* platform);
|
|
||||||
void createForConfiguration (const std::string& configuration, unsigned short lodIndex);
|
|
||||||
|
|
||||||
void destroyAll ();
|
|
||||||
|
|
||||||
void setShadersEnabled (bool enabled);
|
|
||||||
|
|
||||||
void setSourceFile(const std::string& sourceFile) { mSourceFile = sourceFile; }
|
void setSourceFile(const std::string& sourceFile) { mSourceFile = sourceFile; }
|
||||||
|
|
||||||
std::string getSourceFile() { return mSourceFile; }
|
std::string getSourceFile() { return mSourceFile; }
|
||||||
///< get the name of the file this material was read from, or empty if it was created dynamically by code
|
///< get the name of the file this material was read from, or empty if it was created dynamically by code
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setParentInstance (const std::string& name);
|
||||||
|
std::string getParentInstance ();
|
||||||
|
|
||||||
|
void create (Platform* platform);
|
||||||
|
bool createForConfiguration (const std::string& configuration, unsigned short lodIndex);
|
||||||
|
|
||||||
|
void destroyAll ();
|
||||||
|
|
||||||
|
void setShadersEnabled (bool enabled);
|
||||||
|
|
||||||
void save (std::ofstream& stream);
|
void save (std::ofstream& stream);
|
||||||
///< this will only save the properties, not the passes and texture units, and as such
|
|
||||||
/// is only intended to be used for derived materials
|
bool mFailedToCreate;
|
||||||
|
|
||||||
friend class Factory;
|
friend class Factory;
|
||||||
|
|
||||||
|
23
extern/shiny/Main/MaterialInstancePass.cpp
vendored
23
extern/shiny/Main/MaterialInstancePass.cpp
vendored
@ -1,5 +1,7 @@
|
|||||||
#include "MaterialInstancePass.hpp"
|
#include "MaterialInstancePass.hpp"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
namespace sh
|
namespace sh
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -9,8 +11,25 @@ namespace sh
|
|||||||
return &mTexUnits.back();
|
return &mTexUnits.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector <MaterialInstanceTextureUnit> MaterialInstancePass::getTexUnits ()
|
void MaterialInstancePass::save(std::ofstream &stream)
|
||||||
{
|
{
|
||||||
return mTexUnits;
|
if (mShaderProperties.listProperties().size())
|
||||||
|
{
|
||||||
|
stream << "\t\t" << "shader_properties" << '\n';
|
||||||
|
stream << "\t\t{\n";
|
||||||
|
mShaderProperties.save(stream, "\t\t\t");
|
||||||
|
stream << "\t\t}\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertySetGet::save(stream, "\t\t");
|
||||||
|
|
||||||
|
for (std::vector <MaterialInstanceTextureUnit>::iterator it = mTexUnits.begin();
|
||||||
|
it != mTexUnits.end(); ++it)
|
||||||
|
{
|
||||||
|
stream << "\t\ttexture_unit " << it->getName() << '\n';
|
||||||
|
stream << "\t\t{\n";
|
||||||
|
it->save(stream, "\t\t\t");
|
||||||
|
stream << "\t\t}\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
4
extern/shiny/Main/MaterialInstancePass.hpp
vendored
4
extern/shiny/Main/MaterialInstancePass.hpp
vendored
@ -18,10 +18,10 @@ namespace sh
|
|||||||
public:
|
public:
|
||||||
MaterialInstanceTextureUnit* createTextureUnit (const std::string& name);
|
MaterialInstanceTextureUnit* createTextureUnit (const std::string& name);
|
||||||
|
|
||||||
|
void save (std::ofstream& stream);
|
||||||
|
|
||||||
PropertySetGet mShaderProperties;
|
PropertySetGet mShaderProperties;
|
||||||
|
|
||||||
std::vector <MaterialInstanceTextureUnit> getTexUnits ();
|
|
||||||
private:
|
|
||||||
std::vector <MaterialInstanceTextureUnit> mTexUnits;
|
std::vector <MaterialInstanceTextureUnit> mTexUnits;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ namespace sh
|
|||||||
public:
|
public:
|
||||||
MaterialInstanceTextureUnit (const std::string& name);
|
MaterialInstanceTextureUnit (const std::string& name);
|
||||||
std::string getName() const;
|
std::string getName() const;
|
||||||
|
void setName (const std::string& name) { mName = name; }
|
||||||
private:
|
private:
|
||||||
std::string mName;
|
std::string mName;
|
||||||
};
|
};
|
||||||
|
7
extern/shiny/Main/Platform.cpp
vendored
7
extern/shiny/Main/Platform.cpp
vendored
@ -9,7 +9,7 @@ namespace sh
|
|||||||
Platform::Platform (const std::string& basePath)
|
Platform::Platform (const std::string& basePath)
|
||||||
: mBasePath(basePath)
|
: mBasePath(basePath)
|
||||||
, mCacheFolder("./")
|
, mCacheFolder("./")
|
||||||
, mShaderCachingEnabled(false)
|
, mFactory(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,11 +57,6 @@ namespace sh
|
|||||||
mCacheFolder = folder;
|
mCacheFolder = folder;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Platform::setShaderCachingEnabled (bool enabled)
|
|
||||||
{
|
|
||||||
mShaderCachingEnabled = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Platform::getCacheFolder() const
|
std::string Platform::getCacheFolder() const
|
||||||
{
|
{
|
||||||
return mCacheFolder;
|
return mCacheFolder;
|
||||||
|
17
extern/shiny/Main/Platform.hpp
vendored
17
extern/shiny/Main/Platform.hpp
vendored
@ -24,6 +24,7 @@ namespace sh
|
|||||||
class GpuProgram
|
class GpuProgram
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
virtual ~GpuProgram() {}
|
||||||
virtual bool getSupported () = 0; ///< @return true if the compilation was successful
|
virtual bool getSupported () = 0; ///< @return true if the compilation was successful
|
||||||
|
|
||||||
/// @param name name of the uniform in the shader
|
/// @param name name of the uniform in the shader
|
||||||
@ -35,8 +36,7 @@ namespace sh
|
|||||||
class TextureUnitState : public PropertySet
|
class TextureUnitState : public PropertySet
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~TextureUnitState();
|
virtual ~TextureUnitState();
|
||||||
|
|
||||||
virtual void setTextureName (const std::string& textureName) = 0;
|
virtual void setTextureName (const std::string& textureName) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -46,7 +46,7 @@ namespace sh
|
|||||||
class Pass : public PropertySet
|
class Pass : public PropertySet
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual boost::shared_ptr<TextureUnitState> createTextureUnitState () = 0;
|
virtual boost::shared_ptr<TextureUnitState> createTextureUnitState (const std::string& name) = 0;
|
||||||
virtual void assignProgram (GpuProgramType type, const std::string& name) = 0;
|
virtual void assignProgram (GpuProgramType type, const std::string& name) = 0;
|
||||||
|
|
||||||
/// @param type gpu program type
|
/// @param type gpu program type
|
||||||
@ -68,6 +68,9 @@ namespace sh
|
|||||||
virtual bool createConfiguration (const std::string& name, unsigned short lodIndex) = 0; ///< @return false if already exists
|
virtual bool createConfiguration (const std::string& name, unsigned short lodIndex) = 0; ///< @return false if already exists
|
||||||
virtual void removeAll () = 0; ///< remove all configurations
|
virtual void removeAll () = 0; ///< remove all configurations
|
||||||
|
|
||||||
|
virtual bool isUnreferenced() = 0;
|
||||||
|
virtual void ensureLoaded() = 0;
|
||||||
|
|
||||||
virtual void setLodLevels (const std::string& lodLevels) = 0;
|
virtual void setLodLevels (const std::string& lodLevels) = 0;
|
||||||
|
|
||||||
virtual void setShadowCasterMaterial (const std::string& name) = 0;
|
virtual void setShadowCasterMaterial (const std::string& name) = 0;
|
||||||
@ -79,8 +82,6 @@ namespace sh
|
|||||||
Platform (const std::string& basePath);
|
Platform (const std::string& basePath);
|
||||||
virtual ~Platform ();
|
virtual ~Platform ();
|
||||||
|
|
||||||
void setShaderCachingEnabled (bool enabled);
|
|
||||||
|
|
||||||
/// set the folder to use for shader caching
|
/// set the folder to use for shader caching
|
||||||
void setCacheFolder (const std::string& folder);
|
void setCacheFolder (const std::string& folder);
|
||||||
|
|
||||||
@ -93,6 +94,8 @@ namespace sh
|
|||||||
const std::string& name, const std::string& profile,
|
const std::string& name, const std::string& profile,
|
||||||
const std::string& source, Language lang) = 0;
|
const std::string& source, Language lang) = 0;
|
||||||
|
|
||||||
|
virtual void destroyGpuProgram (const std::string& name) = 0;
|
||||||
|
|
||||||
virtual void setSharedParameter (const std::string& name, PropertyValuePtr value) = 0;
|
virtual void setSharedParameter (const std::string& name, PropertyValuePtr value) = 0;
|
||||||
|
|
||||||
virtual bool isProfileSupported (const std::string& profile) = 0;
|
virtual bool isProfileSupported (const std::string& profile) = 0;
|
||||||
@ -105,6 +108,7 @@ namespace sh
|
|||||||
friend class Factory;
|
friend class Factory;
|
||||||
friend class MaterialInstance;
|
friend class MaterialInstance;
|
||||||
friend class ShaderInstance;
|
friend class ShaderInstance;
|
||||||
|
friend class ShaderSet;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
@ -131,9 +135,6 @@ namespace sh
|
|||||||
std::string mCacheFolder;
|
std::string mCacheFolder;
|
||||||
Factory* mFactory;
|
Factory* mFactory;
|
||||||
|
|
||||||
protected:
|
|
||||||
bool mShaderCachingEnabled;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setFactory (Factory* factory);
|
void setFactory (Factory* factory);
|
||||||
|
|
||||||
|
48
extern/shiny/Main/PropertyBase.cpp
vendored
48
extern/shiny/Main/PropertyBase.cpp
vendored
@ -6,6 +6,8 @@
|
|||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
namespace sh
|
namespace sh
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -39,8 +41,9 @@ namespace sh
|
|||||||
mValue = false;
|
mValue = false;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cerr << "sh::BooleanValue: Warning: Unrecognized value \"" << in << "\" for property value of type BooleanValue" << std::endl;
|
std::stringstream msg;
|
||||||
mValue = false;
|
msg << "sh::BooleanValue: Warning: Unrecognized value \"" << in << "\" for property value of type BooleanValue";
|
||||||
|
throw std::runtime_error(msg.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,12 +186,16 @@ namespace sh
|
|||||||
void PropertySet::setProperty (const std::string& name, PropertyValuePtr &value, PropertySetGet* context)
|
void PropertySet::setProperty (const std::string& name, PropertyValuePtr &value, PropertySetGet* context)
|
||||||
{
|
{
|
||||||
if (!setPropertyOverride (name, value, context))
|
if (!setPropertyOverride (name, value, context))
|
||||||
std::cerr << "sh::PropertySet: Warning: No match for property with name '" << name << "'" << std::endl;
|
{
|
||||||
|
std::stringstream msg;
|
||||||
|
msg << "sh::PropertySet: Warning: No match for property with name '" << name << "'";
|
||||||
|
throw std::runtime_error(msg.str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PropertySet::setPropertyOverride (const std::string& name, PropertyValuePtr &value, PropertySetGet* context)
|
bool PropertySet::setPropertyOverride (const std::string& name, PropertyValuePtr &value, PropertySetGet* context)
|
||||||
{
|
{
|
||||||
// if we got here, none of the sub-classes was able to make use of the property
|
// if we got here, none of the sub-classes were able to make use of the property
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,6 +233,11 @@ namespace sh
|
|||||||
mProperties [name] = value;
|
mProperties [name] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PropertySetGet::deleteProperty(const std::string &name)
|
||||||
|
{
|
||||||
|
mProperties.erase(name);
|
||||||
|
}
|
||||||
|
|
||||||
PropertyValuePtr& PropertySetGet::getProperty (const std::string& name)
|
PropertyValuePtr& PropertySetGet::getProperty (const std::string& name)
|
||||||
{
|
{
|
||||||
bool found = (mProperties.find(name) != mProperties.end());
|
bool found = (mProperties.find(name) != mProperties.end());
|
||||||
@ -241,7 +253,7 @@ namespace sh
|
|||||||
return mProperties[name];
|
return mProperties[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PropertySetGet::hasProperty (const std::string& name)
|
bool PropertySetGet::hasProperty (const std::string& name) const
|
||||||
{
|
{
|
||||||
bool found = (mProperties.find(name) != mProperties.end());
|
bool found = (mProperties.find(name) != mProperties.end());
|
||||||
|
|
||||||
@ -256,13 +268,35 @@ namespace sh
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PropertySetGet::copyAll (PropertySet* target, PropertySetGet* context)
|
void PropertySetGet::copyAll (PropertySet* target, PropertySetGet* context, bool copyParent)
|
||||||
{
|
{
|
||||||
if (mParent)
|
if (mParent && copyParent)
|
||||||
mParent->copyAll (target, context);
|
mParent->copyAll (target, context);
|
||||||
for (PropertyMap::iterator it = mProperties.begin(); it != mProperties.end(); ++it)
|
for (PropertyMap::iterator it = mProperties.begin(); it != mProperties.end(); ++it)
|
||||||
{
|
{
|
||||||
target->setProperty(it->first, it->second, context);
|
target->setProperty(it->first, it->second, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PropertySetGet::copyAll (PropertySetGet* target, PropertySetGet* context, bool copyParent)
|
||||||
|
{
|
||||||
|
if (mParent && copyParent)
|
||||||
|
mParent->copyAll (target, context);
|
||||||
|
for (PropertyMap::iterator it = mProperties.begin(); it != mProperties.end(); ++it)
|
||||||
|
{
|
||||||
|
std::string val = retrieveValue<StringValue>(it->second, this).get();
|
||||||
|
target->setProperty(it->first, sh::makeProperty(new sh::StringValue(val)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PropertySetGet::save(std::ofstream &stream, const std::string& indentation)
|
||||||
|
{
|
||||||
|
for (PropertyMap::iterator it = mProperties.begin(); it != mProperties.end(); ++it)
|
||||||
|
{
|
||||||
|
if (typeid( *(it->second) ) == typeid(LinkedValue))
|
||||||
|
stream << indentation << it->first << " " << "$" + static_cast<LinkedValue*>(&*(it->second))->_getStringValue() << '\n';
|
||||||
|
else
|
||||||
|
stream << indentation << it->first << " " << retrieveValue<StringValue>(it->second, this).get() << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
15
extern/shiny/Main/PropertyBase.hpp
vendored
15
extern/shiny/Main/PropertyBase.hpp
vendored
@ -133,6 +133,7 @@ namespace sh
|
|||||||
class PropertySet
|
class PropertySet
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
virtual ~PropertySet() {}
|
||||||
void setProperty (const std::string& name, PropertyValuePtr& value, PropertySetGet* context);
|
void setProperty (const std::string& name, PropertyValuePtr& value, PropertySetGet* context);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -151,18 +152,26 @@ namespace sh
|
|||||||
|
|
||||||
virtual ~PropertySetGet() {}
|
virtual ~PropertySetGet() {}
|
||||||
|
|
||||||
void copyAll (PropertySet* target, PropertySetGet* context); ///< call setProperty for each property/value pair stored in \a this
|
void save (std::ofstream& stream, const std::string& indentation);
|
||||||
|
|
||||||
|
void copyAll (PropertySet* target, PropertySetGet* context, bool copyParent=true);
|
||||||
|
///< call setProperty for each property/value pair stored in \a this
|
||||||
|
void copyAll (PropertySetGet* target, PropertySetGet* context, bool copyParent=true);
|
||||||
|
///< call setProperty for each property/value pair stored in \a this
|
||||||
|
|
||||||
void setParent (PropertySetGet* parent);
|
void setParent (PropertySetGet* parent);
|
||||||
|
PropertySetGet* getParent () { return mParent; }
|
||||||
void setContext (PropertySetGet* context);
|
void setContext (PropertySetGet* context);
|
||||||
PropertySetGet* getContext();
|
PropertySetGet* getContext();
|
||||||
|
|
||||||
virtual void setProperty (const std::string& name, PropertyValuePtr value);
|
virtual void setProperty (const std::string& name, PropertyValuePtr value);
|
||||||
PropertyValuePtr& getProperty (const std::string& name);
|
PropertyValuePtr& getProperty (const std::string& name);
|
||||||
|
|
||||||
|
void deleteProperty (const std::string& name);
|
||||||
|
|
||||||
const PropertyMap& listProperties() { return mProperties; }
|
const PropertyMap& listProperties() { return mProperties; }
|
||||||
|
|
||||||
bool hasProperty (const std::string& name);
|
bool hasProperty (const std::string& name) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PropertyMap mProperties;
|
PropertyMap mProperties;
|
||||||
@ -225,7 +234,7 @@ namespace sh
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
/// Create a property of any type
|
/// Create a property of any type
|
||||||
/// Example: sh::makeProperty\<sh::Vector4\> (new sh::Vector4(1, 1, 1, 1))
|
/// Example: sh::makeProperty (new sh::Vector4(1, 1, 1, 1))
|
||||||
inline PropertyValuePtr makeProperty (T* p)
|
inline PropertyValuePtr makeProperty (T* p)
|
||||||
{
|
{
|
||||||
return PropertyValuePtr ( static_cast<PropertyValue*>(p) );
|
return PropertyValuePtr ( static_cast<PropertyValue*>(p) );
|
||||||
|
23
extern/shiny/Main/ScriptLoader.cpp
vendored
23
extern/shiny/Main/ScriptLoader.cpp
vendored
@ -24,6 +24,10 @@ namespace sh
|
|||||||
}
|
}
|
||||||
|
|
||||||
ScriptLoader::ScriptLoader(const std::string& fileEnding)
|
ScriptLoader::ScriptLoader(const std::string& fileEnding)
|
||||||
|
: mLoadOrder(0)
|
||||||
|
, mToken(TOKEN_NewLine)
|
||||||
|
, mLastToken(TOKEN_NewLine)
|
||||||
|
|
||||||
{
|
{
|
||||||
mFileEnding = fileEnding;
|
mFileEnding = fileEnding;
|
||||||
}
|
}
|
||||||
@ -36,7 +40,7 @@ namespace sh
|
|||||||
void ScriptLoader::clearScriptList()
|
void ScriptLoader::clearScriptList()
|
||||||
{
|
{
|
||||||
std::map <std::string, ScriptNode *>::iterator i;
|
std::map <std::string, ScriptNode *>::iterator i;
|
||||||
for (i = m_scriptList.begin(); i != m_scriptList.end(); i++)
|
for (i = m_scriptList.begin(); i != m_scriptList.end(); ++i)
|
||||||
{
|
{
|
||||||
delete i->second;
|
delete i->second;
|
||||||
}
|
}
|
||||||
@ -293,7 +297,7 @@ namespace sh
|
|||||||
{
|
{
|
||||||
//Delete all children
|
//Delete all children
|
||||||
std::vector<ScriptNode*>::iterator i;
|
std::vector<ScriptNode*>::iterator i;
|
||||||
for (i = mChildren.begin(); i != mChildren.end(); i++)
|
for (i = mChildren.begin(); i != mChildren.end(); ++i)
|
||||||
{
|
{
|
||||||
ScriptNode *node = *i;
|
ScriptNode *node = *i;
|
||||||
node->mRemoveSelf = false;
|
node->mRemoveSelf = false;
|
||||||
@ -323,15 +327,24 @@ namespace sh
|
|||||||
|
|
||||||
ScriptNode *ScriptNode::findChild(const std::string &name, bool recursive)
|
ScriptNode *ScriptNode::findChild(const std::string &name, bool recursive)
|
||||||
{
|
{
|
||||||
int indx, prevC, nextC;
|
int indx;
|
||||||
int childCount = (int)mChildren.size();
|
int childCount = (int)mChildren.size();
|
||||||
|
|
||||||
if (mLastChildFound != -1)
|
if (mLastChildFound != -1)
|
||||||
{
|
{
|
||||||
//If possible, try checking the nodes neighboring the last successful search
|
//If possible, try checking the nodes neighboring the last successful search
|
||||||
//(often nodes searched for in sequence, so this will boost search speeds).
|
//(often nodes searched for in sequence, so this will boost search speeds).
|
||||||
prevC = mLastChildFound-1; if (prevC < 0) prevC = 0; else if (prevC >= childCount) prevC = childCount-1;
|
int prevC = mLastChildFound-1;
|
||||||
nextC = mLastChildFound+1; if (nextC < 0) nextC = 0; else if (nextC >= childCount) nextC = childCount-1;
|
if (prevC < 0)
|
||||||
|
prevC = 0;
|
||||||
|
else if (prevC >= childCount)
|
||||||
|
prevC = childCount-1;
|
||||||
|
int nextC = mLastChildFound+1;
|
||||||
|
if (nextC < 0)
|
||||||
|
nextC = 0;
|
||||||
|
else if (nextC >= childCount)
|
||||||
|
nextC = childCount-1;
|
||||||
|
|
||||||
for (indx = prevC; indx <= nextC; ++indx)
|
for (indx = prevC; indx <= nextC; ++indx)
|
||||||
{
|
{
|
||||||
ScriptNode *node = mChildren[indx];
|
ScriptNode *node = mChildren[indx];
|
||||||
|
8
extern/shiny/Main/ShaderSet.cpp
vendored
8
extern/shiny/Main/ShaderSet.cpp
vendored
@ -37,6 +37,14 @@ namespace sh
|
|||||||
parse();
|
parse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ShaderSet::~ShaderSet()
|
||||||
|
{
|
||||||
|
for (ShaderInstanceMap::iterator it = mInstances.begin(); it != mInstances.end(); ++it)
|
||||||
|
{
|
||||||
|
sh::Factory::getInstance().getPlatform()->destroyGpuProgram(it->second.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ShaderSet::parse()
|
void ShaderSet::parse()
|
||||||
{
|
{
|
||||||
std::string currentToken;
|
std::string currentToken;
|
||||||
|
1
extern/shiny/Main/ShaderSet.hpp
vendored
1
extern/shiny/Main/ShaderSet.hpp
vendored
@ -21,6 +21,7 @@ namespace sh
|
|||||||
public:
|
public:
|
||||||
ShaderSet (const std::string& type, const std::string& cgProfile, const std::string& hlslProfile, const std::string& sourceFile, const std::string& basePath,
|
ShaderSet (const std::string& type, const std::string& cgProfile, const std::string& hlslProfile, const std::string& sourceFile, const std::string& basePath,
|
||||||
const std::string& name, PropertySetGet* globalSettingsPtr);
|
const std::string& name, PropertySetGet* globalSettingsPtr);
|
||||||
|
~ShaderSet();
|
||||||
|
|
||||||
/// Retrieve a shader instance for the given properties. \n
|
/// Retrieve a shader instance for the given properties. \n
|
||||||
/// If a \a ShaderInstance with the same properties exists already, simply returns this instance. \n
|
/// If a \a ShaderInstance with the same properties exists already, simply returns this instance. \n
|
||||||
|
18
extern/shiny/Platforms/Ogre/OgreMaterial.cpp
vendored
18
extern/shiny/Platforms/Ogre/OgreMaterial.cpp
vendored
@ -15,6 +15,7 @@ namespace sh
|
|||||||
OgreMaterial::OgreMaterial (const std::string& name, const std::string& resourceGroup)
|
OgreMaterial::OgreMaterial (const std::string& name, const std::string& resourceGroup)
|
||||||
: Material()
|
: Material()
|
||||||
{
|
{
|
||||||
|
mName = name;
|
||||||
assert (Ogre::MaterialManager::getSingleton().getByName(name).isNull() && "Material already exists");
|
assert (Ogre::MaterialManager::getSingleton().getByName(name).isNull() && "Material already exists");
|
||||||
mMaterial = Ogre::MaterialManager::getSingleton().create (name, resourceGroup);
|
mMaterial = Ogre::MaterialManager::getSingleton().create (name, resourceGroup);
|
||||||
mMaterial->removeAllTechniques();
|
mMaterial->removeAllTechniques();
|
||||||
@ -22,9 +23,22 @@ namespace sh
|
|||||||
mMaterial->compile();
|
mMaterial->compile();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OgreMaterial::ensureLoaded()
|
||||||
|
{
|
||||||
|
if (mMaterial.isNull())
|
||||||
|
mMaterial = Ogre::MaterialManager::getSingleton().getByName(mName);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OgreMaterial::isUnreferenced()
|
||||||
|
{
|
||||||
|
// Resource system internals hold 3 shared pointers, we hold one, so usecount of 4 means unused
|
||||||
|
return (!mMaterial.isNull() && mMaterial.useCount() <= Ogre::ResourceGroupManager::RESOURCE_SYSTEM_NUM_REFERENCE_COUNTS+1);
|
||||||
|
}
|
||||||
|
|
||||||
OgreMaterial::~OgreMaterial()
|
OgreMaterial::~OgreMaterial()
|
||||||
{
|
{
|
||||||
Ogre::MaterialManager::getSingleton().remove(mMaterial->getName());
|
if (!mMaterial.isNull())
|
||||||
|
Ogre::MaterialManager::getSingleton().remove(mMaterial->getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<Pass> OgreMaterial::createPass (const std::string& configuration, unsigned short lodIndex)
|
boost::shared_ptr<Pass> OgreMaterial::createPass (const std::string& configuration, unsigned short lodIndex)
|
||||||
@ -34,6 +48,8 @@ namespace sh
|
|||||||
|
|
||||||
void OgreMaterial::removeAll ()
|
void OgreMaterial::removeAll ()
|
||||||
{
|
{
|
||||||
|
if (mMaterial.isNull())
|
||||||
|
return;
|
||||||
mMaterial->removeAllTechniques();
|
mMaterial->removeAllTechniques();
|
||||||
mMaterial->createTechnique()->setSchemeName (sDefaultTechniqueName);
|
mMaterial->createTechnique()->setSchemeName (sDefaultTechniqueName);
|
||||||
mMaterial->compile();
|
mMaterial->compile();
|
||||||
|
4
extern/shiny/Platforms/Ogre/OgreMaterial.hpp
vendored
4
extern/shiny/Platforms/Ogre/OgreMaterial.hpp
vendored
@ -18,6 +18,9 @@ namespace sh
|
|||||||
virtual boost::shared_ptr<Pass> createPass (const std::string& configuration, unsigned short lodIndex);
|
virtual boost::shared_ptr<Pass> createPass (const std::string& configuration, unsigned short lodIndex);
|
||||||
virtual bool createConfiguration (const std::string& name, unsigned short lodIndex);
|
virtual bool createConfiguration (const std::string& name, unsigned short lodIndex);
|
||||||
|
|
||||||
|
virtual bool isUnreferenced();
|
||||||
|
virtual void ensureLoaded();
|
||||||
|
|
||||||
virtual void removeAll ();
|
virtual void removeAll ();
|
||||||
|
|
||||||
Ogre::MaterialPtr getOgreMaterial();
|
Ogre::MaterialPtr getOgreMaterial();
|
||||||
@ -30,6 +33,7 @@ namespace sh
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Ogre::MaterialPtr mMaterial;
|
Ogre::MaterialPtr mMaterial;
|
||||||
|
std::string mName;
|
||||||
|
|
||||||
std::string mShadowCasterMaterial;
|
std::string mShadowCasterMaterial;
|
||||||
};
|
};
|
||||||
|
16
extern/shiny/Platforms/Ogre/OgrePass.cpp
vendored
16
extern/shiny/Platforms/Ogre/OgrePass.cpp
vendored
@ -20,9 +20,9 @@ namespace sh
|
|||||||
mPass = t->createPass();
|
mPass = t->createPass();
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<TextureUnitState> OgrePass::createTextureUnitState ()
|
boost::shared_ptr<TextureUnitState> OgrePass::createTextureUnitState (const std::string& name)
|
||||||
{
|
{
|
||||||
return boost::shared_ptr<TextureUnitState> (new OgreTextureUnitState (this));
|
return boost::shared_ptr<TextureUnitState> (new OgreTextureUnitState (this, name));
|
||||||
}
|
}
|
||||||
|
|
||||||
void OgrePass::assignProgram (GpuProgramType type, const std::string& name)
|
void OgrePass::assignProgram (GpuProgramType type, const std::string& name)
|
||||||
@ -105,7 +105,17 @@ namespace sh
|
|||||||
else if (type == GPT_Fragment)
|
else if (type == GPT_Fragment)
|
||||||
params = mPass->getFragmentProgramParameters();
|
params = mPass->getFragmentProgramParameters();
|
||||||
|
|
||||||
params->addSharedParameters (name);
|
try
|
||||||
|
{
|
||||||
|
params->addSharedParameters (name);
|
||||||
|
}
|
||||||
|
catch (Ogre::Exception& e)
|
||||||
|
{
|
||||||
|
std::stringstream msg;
|
||||||
|
msg << "Could not create a shared parameter instance for '"
|
||||||
|
<< name << "'. Make sure this shared parameter has a value set (via Factory::setSharedParameter)!";
|
||||||
|
throw std::runtime_error(msg.str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OgrePass::setTextureUnitIndex (int programType, const std::string& name, int index)
|
void OgrePass::setTextureUnitIndex (int programType, const std::string& name, int index)
|
||||||
|
2
extern/shiny/Platforms/Ogre/OgrePass.hpp
vendored
2
extern/shiny/Platforms/Ogre/OgrePass.hpp
vendored
@ -14,7 +14,7 @@ namespace sh
|
|||||||
public:
|
public:
|
||||||
OgrePass (OgreMaterial* parent, const std::string& configuration, unsigned short lodIndex);
|
OgrePass (OgreMaterial* parent, const std::string& configuration, unsigned short lodIndex);
|
||||||
|
|
||||||
virtual boost::shared_ptr<TextureUnitState> createTextureUnitState ();
|
virtual boost::shared_ptr<TextureUnitState> createTextureUnitState (const std::string& name);
|
||||||
virtual void assignProgram (GpuProgramType type, const std::string& name);
|
virtual void assignProgram (GpuProgramType type, const std::string& name);
|
||||||
|
|
||||||
Ogre::Pass* getOgrePass();
|
Ogre::Pass* getOgrePass();
|
||||||
|
7
extern/shiny/Platforms/Ogre/OgrePlatform.cpp
vendored
7
extern/shiny/Platforms/Ogre/OgrePlatform.cpp
vendored
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include <OgreDataStream.h>
|
#include <OgreDataStream.h>
|
||||||
#include <OgreGpuProgramManager.h>
|
#include <OgreGpuProgramManager.h>
|
||||||
|
#include <OgreHighLevelGpuProgramManager.h>
|
||||||
#include <OgreRoot.h>
|
#include <OgreRoot.h>
|
||||||
|
|
||||||
#include "OgreMaterial.hpp"
|
#include "OgreMaterial.hpp"
|
||||||
@ -76,6 +77,11 @@ namespace sh
|
|||||||
return boost::shared_ptr<Material> (material);
|
return boost::shared_ptr<Material> (material);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OgrePlatform::destroyGpuProgram(const std::string &name)
|
||||||
|
{
|
||||||
|
Ogre::HighLevelGpuProgramManager::getSingleton().remove(name);
|
||||||
|
}
|
||||||
|
|
||||||
boost::shared_ptr<GpuProgram> OgrePlatform::createGpuProgram (
|
boost::shared_ptr<GpuProgram> OgrePlatform::createGpuProgram (
|
||||||
GpuProgramType type,
|
GpuProgramType type,
|
||||||
const std::string& compileArguments,
|
const std::string& compileArguments,
|
||||||
@ -122,6 +128,7 @@ namespace sh
|
|||||||
if (mSharedParameters.find(name) == mSharedParameters.end())
|
if (mSharedParameters.find(name) == mSharedParameters.end())
|
||||||
{
|
{
|
||||||
params = Ogre::GpuProgramManager::getSingleton().createSharedParameters(name);
|
params = Ogre::GpuProgramManager::getSingleton().createSharedParameters(name);
|
||||||
|
|
||||||
Ogre::GpuConstantType type;
|
Ogre::GpuConstantType type;
|
||||||
if (typeid(*value) == typeid(Vector4))
|
if (typeid(*value) == typeid(Vector4))
|
||||||
type = Ogre::GCT_FLOAT4;
|
type = Ogre::GCT_FLOAT4;
|
||||||
|
2
extern/shiny/Platforms/Ogre/OgrePlatform.hpp
vendored
2
extern/shiny/Platforms/Ogre/OgrePlatform.hpp
vendored
@ -47,6 +47,8 @@ namespace sh
|
|||||||
const std::string& name, const std::string& profile,
|
const std::string& name, const std::string& profile,
|
||||||
const std::string& source, Language lang);
|
const std::string& source, Language lang);
|
||||||
|
|
||||||
|
virtual void destroyGpuProgram (const std::string& name);
|
||||||
|
|
||||||
virtual void setSharedParameter (const std::string& name, PropertyValuePtr value);
|
virtual void setSharedParameter (const std::string& name, PropertyValuePtr value);
|
||||||
|
|
||||||
friend class ShaderInstance;
|
friend class ShaderInstance;
|
||||||
|
@ -6,10 +6,11 @@
|
|||||||
|
|
||||||
namespace sh
|
namespace sh
|
||||||
{
|
{
|
||||||
OgreTextureUnitState::OgreTextureUnitState (OgrePass* parent)
|
OgreTextureUnitState::OgreTextureUnitState (OgrePass* parent, const std::string& name)
|
||||||
: TextureUnitState()
|
: TextureUnitState()
|
||||||
{
|
{
|
||||||
mTextureUnitState = parent->getOgrePass()->createTextureUnitState("");
|
mTextureUnitState = parent->getOgrePass()->createTextureUnitState("");
|
||||||
|
mTextureUnitState->setName(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OgreTextureUnitState::setPropertyOverride (const std::string &name, PropertyValuePtr& value, PropertySetGet* context)
|
bool OgreTextureUnitState::setPropertyOverride (const std::string &name, PropertyValuePtr& value, PropertySetGet* context)
|
||||||
|
@ -12,7 +12,7 @@ namespace sh
|
|||||||
class OgreTextureUnitState : public TextureUnitState
|
class OgreTextureUnitState : public TextureUnitState
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
OgreTextureUnitState (OgrePass* parent);
|
OgreTextureUnitState (OgrePass* parent, const std::string& name);
|
||||||
|
|
||||||
virtual void setTextureName (const std::string& textureName);
|
virtual void setTextureName (const std::string& textureName);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user