mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-30 06:15:32 +00:00
Merge branch 'master' into water
This commit is contained in:
commit
bd9e165e3f
11 changed files with 433 additions and 168 deletions
|
@ -223,6 +223,9 @@ endif (APPLE)
|
|||
|
||||
# Other files
|
||||
|
||||
configure_file(${OpenMW_SOURCE_DIR}/files/settings-default.cfg
|
||||
"${OpenMW_BINARY_DIR}/settings-default.cfg")
|
||||
|
||||
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg.local
|
||||
"${OpenMW_BINARY_DIR}/openmw.cfg")
|
||||
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg
|
||||
|
@ -303,6 +306,7 @@ if(DPKG_PROGRAM)
|
|||
INSTALL(FILES "${OpenMW_SOURCE_DIR}/apps/launcher/resources/images/openmw.png" DESTINATION "share/pixmaps/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
|
||||
|
||||
#Install global configuration files
|
||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/settings-default.cfg" DESTINATION "../etc/openmw/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
|
||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "../etc/openmw/" RENAME "openmw.cfg" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
|
||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/plugins.cfg" DESTINATION "../etc/openmw/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <components/esm/esm_reader.hpp>
|
||||
#include <components/files/fixedpath.hpp>
|
||||
#include <components/files/configurationmanager.hpp>
|
||||
#include <components/settings/settings.hpp>
|
||||
|
||||
#include <components/nifbullet/bullet_nif_loader.hpp>
|
||||
#include <components/nifogre/ogre_nif_loader.hpp>
|
||||
|
@ -321,6 +322,29 @@ void OMW::Engine::go()
|
|||
{
|
||||
boost::filesystem::create_directories(configPath);
|
||||
}
|
||||
|
||||
// Create the settings manager and load default settings file
|
||||
Settings::Manager settings;
|
||||
const std::string localdefault = mCfgMgr.getLocalPath().string() + "/settings-default.cfg";
|
||||
const std::string globaldefault = mCfgMgr.getGlobalPath().string() + "/settings-default.cfg";
|
||||
|
||||
// prefer local
|
||||
if (boost::filesystem::exists(localdefault))
|
||||
settings.loadDefault(localdefault);
|
||||
else if (boost::filesystem::exists(globaldefault))
|
||||
settings.loadDefault(globaldefault);
|
||||
|
||||
// load user settings if they exist, otherwise just load the default settings as user settings
|
||||
const std::string settingspath = mCfgMgr.getUserPath().string() + "/settings.cfg";
|
||||
if (boost::filesystem::exists(settingspath))
|
||||
settings.loadUser(settingspath);
|
||||
else if (boost::filesystem::exists(localdefault))
|
||||
settings.loadUser(localdefault);
|
||||
else if (boost::filesystem::exists(globaldefault))
|
||||
settings.loadUser(globaldefault);
|
||||
|
||||
mFpsLevel = settings.getInt("fps", "HUD");
|
||||
|
||||
mOgre->configure(!boost::filesystem::is_regular_file(mCfgMgr.getOgreConfigPath()),
|
||||
mCfgMgr.getOgreConfigPath().string(),
|
||||
mCfgMgr.getLogPath().string(),
|
||||
|
@ -415,6 +439,9 @@ void OMW::Engine::go()
|
|||
// Start the main rendering loop
|
||||
mOgre->start();
|
||||
|
||||
// Save user settings
|
||||
settings.saveUser(settingspath);
|
||||
|
||||
std::cout << "Quitting peacefully.\n";
|
||||
}
|
||||
|
||||
|
|
|
@ -92,9 +92,6 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
|
|||
("plugin", bpo::value<StringsVector>()->default_value(StringsVector(), "")
|
||||
->multitoken(), "plugin file(s)")
|
||||
|
||||
("fps", boost::program_options::value<int>()->implicit_value(1)
|
||||
->default_value(0), "fps counter detail (0 = off, 1 = fps counter, 2 = full detail)")
|
||||
|
||||
("anim-verbose", boost::program_options::value<bool>()->implicit_value(true)
|
||||
->default_value(false), "output animation indices files")
|
||||
|
||||
|
@ -225,7 +222,6 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
|
|||
engine.setNewGame(variables["new-game"].as<bool>());
|
||||
|
||||
// other settings
|
||||
engine.showFPS(variables["fps"].as<int>());
|
||||
engine.setDebugMode(variables["debug"].as<bool>());
|
||||
engine.setSoundUsage(!variables["nosound"].as<bool>());
|
||||
engine.setScriptsVerbosity(variables["script-verbose"].as<bool>());
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <OgreSceneNode.h>
|
||||
|
||||
#include <components/nifogre/ogre_nif_loader.hpp>
|
||||
#include <components/settings/settings.hpp>
|
||||
|
||||
using namespace MWRender;
|
||||
|
||||
|
@ -88,18 +89,16 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh)
|
|||
NifOgre::NIFLoader::load(mesh);
|
||||
Ogre::Entity *ent = mRenderer.getScene()->createEntity(mesh);
|
||||
|
||||
/*
|
||||
|
||||
Ogre::Vector3 extents = ent->getBoundingBox().getSize();
|
||||
extents *= insert->getScale();
|
||||
// float size = std::max(std::max(extents.x, extents.y), extents.z);
|
||||
float size = std::max(std::max(extents.x, extents.y), extents.z);
|
||||
|
||||
bool small = (size < 250); /// \todo config value
|
||||
bool small = (size < Settings::Manager::getInt("small object size", "Viewing distance")) && Settings::Manager::getBool("limit small object distance", "Objects");
|
||||
|
||||
// do not fade out doors. that will cause holes and look stupid
|
||||
if (ptr.getTypeName().find("Door") != std::string::npos)
|
||||
small = false;
|
||||
*/
|
||||
const bool small = false;
|
||||
|
||||
if (mBounds.find(ptr.getCell()) == mBounds.end())
|
||||
mBounds[ptr.getCell()] = Ogre::AxisAlignedBox::BOX_NULL;
|
||||
|
@ -113,11 +112,11 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh)
|
|||
bounds.scale(insert->getScale());
|
||||
mBounds[ptr.getCell()].merge(bounds);
|
||||
|
||||
if(!mIsStatic)
|
||||
if(!mIsStatic || !Settings::Manager::getBool("use static geometry", "Objects"))
|
||||
{
|
||||
insert->attachObject(ent);
|
||||
|
||||
ent->setRenderingDistance(small ? 2500 : 0); /// \todo config value
|
||||
ent->setRenderingDistance(small ? Settings::Manager::getInt("small object distance", "Viewing distance") : 0); /// \todo config value
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -131,7 +130,7 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh)
|
|||
sg = mRenderer.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID));
|
||||
mStaticGeometrySmall[ptr.getCell()] = sg;
|
||||
|
||||
sg->setRenderingDistance(2500); /// \todo config value
|
||||
sg->setRenderingDistance(Settings::Manager::getInt("small object distance", "Viewing distance")); /// \todo config value
|
||||
}
|
||||
else
|
||||
sg = mStaticGeometrySmall[ptr.getCell()];
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "../mwworld/world.hpp" // these includes can be removed once the static-hack is gone
|
||||
#include "../mwworld/ptr.hpp"
|
||||
#include <components/esm/loadstat.hpp>
|
||||
#include <components/settings/settings.hpp>
|
||||
|
||||
|
||||
using namespace MWRender;
|
||||
|
@ -273,18 +274,14 @@ void RenderingManager::configureFog(ESMS::CellStore<MWWorld::RefData> &mCell)
|
|||
|
||||
void RenderingManager::configureFog(const float density, const Ogre::ColourValue& colour)
|
||||
{
|
||||
/// \todo make the viewing distance and fog start/end configurable
|
||||
float max = Settings::Manager::getFloat("max viewing distance", "Viewing distance");
|
||||
|
||||
// right now we load 3x3 cells, so the maximum viewing distance we
|
||||
// can allow (to prevent objects suddenly popping up) equals:
|
||||
// 8192 * 0.69
|
||||
// ^ cell size ^ minimum density value used (clear weather)
|
||||
float low = 5652.48 / density / 2.f;
|
||||
float high = 5652.48 / density;
|
||||
float low = max / (density) * Settings::Manager::getFloat("fog start factor", "Viewing distance");
|
||||
float high = max / (density) * Settings::Manager::getFloat("fog end factor", "Viewing distance");
|
||||
|
||||
mRendering.getScene()->setFog (FOG_LINEAR, colour, 0, low, high);
|
||||
|
||||
mRendering.getCamera()->setFarClipDistance ( high );
|
||||
mRendering.getCamera()->setFarClipDistance ( max / density );
|
||||
mRendering.getViewport()->setBackgroundColour (colour);
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ THE SOFTWARE.
|
|||
#include "OgreHardwarePixelBuffer.h"
|
||||
#include "OgreShadowCameraSetupPSSM.h"
|
||||
|
||||
#define POINTLIGHTS
|
||||
#include <components/settings/settings.hpp>
|
||||
|
||||
namespace Ogre
|
||||
{
|
||||
|
@ -220,22 +220,10 @@ namespace Ogre
|
|||
|
||||
|
||||
}
|
||||
int TerrainMaterialGeneratorB::SM2Profile::getNumberOfLightsSupported() const
|
||||
{
|
||||
#ifndef POINTLIGHTS
|
||||
return 1;
|
||||
#else
|
||||
// number of supported lights depends on the number of available constant registers,
|
||||
// which in turn depends on the shader profile used
|
||||
if (GpuProgramManager::getSingleton().isSyntaxSupported("ps_3_0")
|
||||
|| GpuProgramManager::getSingleton().isSyntaxSupported("ps_4_0")
|
||||
|| GpuProgramManager::getSingleton().isSyntaxSupported("fp40")
|
||||
)
|
||||
return 32;
|
||||
else
|
||||
return 8;
|
||||
#endif
|
||||
}
|
||||
int TerrainMaterialGeneratorB::SM2Profile::getNumberOfLightsSupported() const
|
||||
{
|
||||
return Settings::Manager::getInt("num lights", "Terrain");
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
MaterialPtr TerrainMaterialGeneratorB::SM2Profile::generate(const Terrain* terrain)
|
||||
{
|
||||
|
@ -565,7 +553,8 @@ namespace Ogre
|
|||
{
|
||||
params->setNamedAutoConstant("lightPosObjSpace"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_POSITION_OBJECT_SPACE, i);
|
||||
params->setNamedAutoConstant("lightDiffuseColour"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR, i);
|
||||
params->setNamedAutoConstant("lightAttenuation"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_ATTENUATION, i);
|
||||
if (prof->getNumberOfLightsSupported() > 1)
|
||||
params->setNamedAutoConstant("lightAttenuation"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_ATTENUATION, i);
|
||||
//params->setNamedAutoConstant("lightSpecularColour"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_SPECULAR_COLOUR, i);
|
||||
}
|
||||
|
||||
|
@ -980,10 +969,9 @@ namespace Ogre
|
|||
//"uniform float3 lightSpecularColour"<<i<<",\n"
|
||||
;
|
||||
|
||||
#ifdef POINTLIGHTS
|
||||
outStream <<
|
||||
"uniform float4 lightAttenuation"<<i<<",\n";
|
||||
#endif
|
||||
if (prof->getNumberOfLightsSupported() > 1)
|
||||
outStream <<
|
||||
"uniform float4 lightAttenuation"<<i<<",\n";
|
||||
|
||||
}
|
||||
|
||||
|
@ -1130,10 +1118,9 @@ namespace Ogre
|
|||
}
|
||||
else
|
||||
{
|
||||
#ifdef POINTLIGHTS
|
||||
outStream << "float d; \n"
|
||||
if (prof->getNumberOfLightsSupported() > 1)
|
||||
outStream << "float d; \n"
|
||||
"float attn; \n";
|
||||
#endif
|
||||
|
||||
outStream <<
|
||||
" eyeDir = normalize(eyeDir); \n";
|
||||
|
@ -1144,13 +1131,12 @@ namespace Ogre
|
|||
outStream << " float3 halfAngle"<<i<<" = normalize(lightDir"<<i<<" + eyeDir);\n"
|
||||
" float4 litRes"<<i<<" = lit(dot(normalize(lightDir"<<i<<"), normal), dot(halfAngle"<<i<<", normal), scaleBiasSpecular.z);\n";
|
||||
|
||||
#ifdef POINTLIGHTS
|
||||
if (prof->getNumberOfLightsSupported() > 1)
|
||||
outStream <<
|
||||
// pre-multiply light color with attenuation factor
|
||||
"d = length( lightDir"<<i<<" ); \n"
|
||||
"attn = ( 1.0 / (( lightAttenuation"<<i<<".y ) + ( lightAttenuation"<<i<<".z * d ) + ( lightAttenuation"<<i<<".w * d * d ))); \n"
|
||||
"lightDiffuseColour"<<i<<" *= attn; \n";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,10 @@ project (Components)
|
|||
|
||||
# source files
|
||||
|
||||
add_component_dir (settings
|
||||
settings
|
||||
)
|
||||
|
||||
add_component_dir (bsa
|
||||
bsa_archive bsa_file
|
||||
)
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "ogre_nif_loader.hpp"
|
||||
|
||||
#include <components/settings/settings.hpp>
|
||||
|
||||
typedef unsigned char ubyte;
|
||||
|
||||
|
@ -299,138 +300,136 @@ void NIFLoader::createMaterial(const String &name,
|
|||
material->setSelfIllumination(emissive.array[0], emissive.array[1], emissive.array[2]);
|
||||
material->setShininess(glossiness);
|
||||
|
||||
// Create shader for the material
|
||||
// vertex
|
||||
HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
|
||||
|
||||
HighLevelGpuProgramPtr vertex;
|
||||
if (mgr.getByName("main_vp").isNull())
|
||||
if (Settings::Manager::getBool("shaders", "Objects"))
|
||||
{
|
||||
vertex = mgr.createProgram("main_vp", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
|
||||
"cg", GPT_VERTEX_PROGRAM);
|
||||
vertex->setParameter("profiles", "vs_4_0 vs_2_x vp40 arbvp1");
|
||||
vertex->setParameter("entry_point", "main_vp");
|
||||
StringUtil::StrStreamType outStream;
|
||||
outStream <<
|
||||
"void main_vp( \n"
|
||||
" float4 position : POSITION, \n"
|
||||
" float4 normal : NORMAL, \n"
|
||||
" float4 colour : COLOR, \n"
|
||||
" in float2 uv : TEXCOORD0, \n"
|
||||
" out float2 oUV : TEXCOORD0, \n"
|
||||
" out float4 oPosition : POSITION, \n"
|
||||
" out float4 oPositionObjSpace : TEXCOORD1, \n"
|
||||
" out float4 oNormal : TEXCOORD2, \n"
|
||||
" out float oFogValue : TEXCOORD3, \n"
|
||||
" out float4 oVertexColour : TEXCOORD4, \n"
|
||||
" uniform float4 fogParams, \n"
|
||||
" uniform float4x4 worldViewProj \n"
|
||||
") \n"
|
||||
"{ \n"
|
||||
" oVertexColour = colour; \n"
|
||||
" oUV = uv; \n"
|
||||
" oNormal = normal; \n"
|
||||
" oPosition = mul( worldViewProj, position ); \n"
|
||||
" oFogValue = saturate((oPosition.z - fogParams.y) * fogParams.w); \n"
|
||||
" oPositionObjSpace = position; \n"
|
||||
"}";
|
||||
vertex->setSource(outStream.str());
|
||||
vertex->load();
|
||||
vertex->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
|
||||
vertex->getDefaultParameters()->setNamedAutoConstant("fogParams", GpuProgramParameters::ACT_FOG_PARAMS);
|
||||
}
|
||||
else
|
||||
vertex = mgr.getByName("main_vp");
|
||||
material->getTechnique(0)->getPass(0)->setVertexProgram(vertex->getName());
|
||||
// Create shader for the material
|
||||
// vertex
|
||||
HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
|
||||
|
||||
// the number of lights to support.
|
||||
// when rendering an object, OGRE automatically picks the lights that are
|
||||
// closest to the object being rendered. unfortunately this mechanism does
|
||||
// not work perfectly for objects batched together (they will all use the same
|
||||
// lights). to work around this, we are simply pushing the maximum number
|
||||
// of lights here in order to minimize disappearing lights.
|
||||
float num_lights;
|
||||
if (GpuProgramManager::getSingleton().isSyntaxSupported("fp40") ||
|
||||
GpuProgramManager::getSingleton().isSyntaxSupported("ps_4_0"))
|
||||
num_lights = 8 /* 32 */;
|
||||
else
|
||||
num_lights = 8;
|
||||
|
||||
// fragment
|
||||
HighLevelGpuProgramPtr fragment;
|
||||
if (mgr.getByName("main_fp").isNull())
|
||||
{
|
||||
fragment = mgr.createProgram("main_fp", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
|
||||
"cg", GPT_FRAGMENT_PROGRAM);
|
||||
fragment->setParameter("profiles", "ps_4_0 ps_2_x fp40 arbfp1");
|
||||
fragment->setParameter("entry_point", "main_fp");
|
||||
StringUtil::StrStreamType outStream;
|
||||
outStream <<
|
||||
"void main_fp( \n"
|
||||
" in float2 uv : TEXCOORD0, \n"
|
||||
" out float4 oColor : COLOR, \n"
|
||||
" uniform sampler2D texture : TEXUNIT0, \n"
|
||||
" float4 positionObjSpace : TEXCOORD1, \n"
|
||||
" float4 normal : TEXCOORD2, \n"
|
||||
" float fogValue : TEXCOORD3, \n"
|
||||
" float4 vertexColour : TEXCOORD4, \n"
|
||||
" uniform float4 fogColour, \n";
|
||||
|
||||
for (int i=0; i<num_lights; ++i)
|
||||
HighLevelGpuProgramPtr vertex;
|
||||
if (mgr.getByName("main_vp").isNull())
|
||||
{
|
||||
vertex = mgr.createProgram("main_vp", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
|
||||
"cg", GPT_VERTEX_PROGRAM);
|
||||
vertex->setParameter("profiles", "vs_4_0 vs_2_x vp40 arbvp1");
|
||||
vertex->setParameter("entry_point", "main_vp");
|
||||
StringUtil::StrStreamType outStream;
|
||||
outStream <<
|
||||
" uniform float4 lightDiffuse"<<i<<", \n"
|
||||
" uniform float4 lightPositionObjSpace"<<i<<", \n"
|
||||
" uniform float4 lightAttenuation"<<i<<", \n";
|
||||
"void main_vp( \n"
|
||||
" float4 position : POSITION, \n"
|
||||
" float4 normal : NORMAL, \n"
|
||||
" float4 colour : COLOR, \n"
|
||||
" in float2 uv : TEXCOORD0, \n"
|
||||
" out float2 oUV : TEXCOORD0, \n"
|
||||
" out float4 oPosition : POSITION, \n"
|
||||
" out float4 oPositionObjSpace : TEXCOORD1, \n"
|
||||
" out float4 oNormal : TEXCOORD2, \n"
|
||||
" out float oFogValue : TEXCOORD3, \n"
|
||||
" out float4 oVertexColour : TEXCOORD4, \n"
|
||||
" uniform float4 fogParams, \n"
|
||||
" uniform float4x4 worldViewProj \n"
|
||||
") \n"
|
||||
"{ \n"
|
||||
" oVertexColour = colour; \n"
|
||||
" oUV = uv; \n"
|
||||
" oNormal = normal; \n"
|
||||
" oPosition = mul( worldViewProj, position ); \n"
|
||||
" oFogValue = saturate((oPosition.z - fogParams.y) * fogParams.w); \n"
|
||||
" oPositionObjSpace = position; \n"
|
||||
"}";
|
||||
vertex->setSource(outStream.str());
|
||||
vertex->load();
|
||||
vertex->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
|
||||
vertex->getDefaultParameters()->setNamedAutoConstant("fogParams", GpuProgramParameters::ACT_FOG_PARAMS);
|
||||
}
|
||||
outStream <<
|
||||
" uniform float4 lightAmbient, \n"
|
||||
" uniform float4 ambient, \n"
|
||||
" uniform float4 diffuse, \n"
|
||||
" uniform float4 emissive \n"
|
||||
") \n"
|
||||
"{ \n"
|
||||
" float4 tex = tex2D(texture, uv); \n"
|
||||
" float d; \n"
|
||||
" float attn; \n"
|
||||
" float3 lightColour = float3(0, 0, 0); \n";
|
||||
|
||||
for (int i=0; i<num_lights; ++i)
|
||||
else
|
||||
vertex = mgr.getByName("main_vp");
|
||||
material->getTechnique(0)->getPass(0)->setVertexProgram(vertex->getName());
|
||||
|
||||
// the number of lights to support.
|
||||
// when rendering an object, OGRE automatically picks the lights that are
|
||||
// closest to the object being rendered. unfortunately this mechanism does
|
||||
// not work perfectly for objects batched together (they will all use the same
|
||||
// lights). to work around this, we are simply pushing the maximum number
|
||||
// of lights here in order to minimize disappearing lights.
|
||||
int num_lights = Settings::Manager::getInt("num lights", "Objects");
|
||||
|
||||
// fragment
|
||||
HighLevelGpuProgramPtr fragment;
|
||||
if (mgr.getByName("main_fp").isNull())
|
||||
{
|
||||
fragment = mgr.createProgram("main_fp", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
|
||||
"cg", GPT_FRAGMENT_PROGRAM);
|
||||
fragment->setParameter("profiles", "ps_4_0 ps_2_x fp40 arbfp1");
|
||||
fragment->setParameter("entry_point", "main_fp");
|
||||
StringUtil::StrStreamType outStream;
|
||||
outStream <<
|
||||
" float3 lightDir"<<i<<" = lightPositionObjSpace"<<i<<".xyz - (positionObjSpace.xyz * lightPositionObjSpace"<<i<<".w); \n"
|
||||
"void main_fp( \n"
|
||||
" in float2 uv : TEXCOORD0, \n"
|
||||
" out float4 oColor : COLOR, \n"
|
||||
" uniform sampler2D texture : TEXUNIT0, \n"
|
||||
" float4 positionObjSpace : TEXCOORD1, \n"
|
||||
" float4 normal : TEXCOORD2, \n"
|
||||
" float fogValue : TEXCOORD3, \n"
|
||||
" float4 vertexColour : TEXCOORD4, \n"
|
||||
" uniform float4 fogColour, \n";
|
||||
|
||||
// pre-multiply light color with attenuation factor
|
||||
" d = length( lightDir"<<i<<" ); \n"
|
||||
" attn = ( 1.0 / (( lightAttenuation"<<i<<".y ) + ( lightAttenuation"<<i<<".z * d ) + ( lightAttenuation"<<i<<".w * d * d ))); \n"
|
||||
" lightDiffuse"<<i<<" *= attn; \n"
|
||||
for (int i=0; i<num_lights; ++i)
|
||||
{
|
||||
outStream <<
|
||||
" uniform float4 lightDiffuse"<<i<<", \n"
|
||||
" uniform float4 lightPositionObjSpace"<<i<<", \n"
|
||||
" uniform float4 lightAttenuation"<<i<<", \n";
|
||||
}
|
||||
outStream <<
|
||||
" uniform float4 lightAmbient, \n"
|
||||
" uniform float4 ambient, \n"
|
||||
" uniform float4 diffuse, \n"
|
||||
" uniform float4 emissive \n"
|
||||
") \n"
|
||||
"{ \n"
|
||||
" float4 tex = tex2D(texture, uv); \n"
|
||||
" float d; \n"
|
||||
" float attn; \n"
|
||||
" float3 lightColour = float3(0, 0, 0); \n";
|
||||
|
||||
for (int i=0; i<num_lights; ++i)
|
||||
{
|
||||
outStream <<
|
||||
" float3 lightDir"<<i<<" = lightPositionObjSpace"<<i<<".xyz - (positionObjSpace.xyz * lightPositionObjSpace"<<i<<".w); \n"
|
||||
|
||||
" lightColour.xyz += lit(dot(normalize(lightDir"<<i<<"), normalize(normal)), 0, 0).y * lightDiffuse"<<i<<".xyz;\n";
|
||||
// pre-multiply light color with attenuation factor
|
||||
" d = length( lightDir"<<i<<" ); \n"
|
||||
" attn = ( 1.0 / (( lightAttenuation"<<i<<".y ) + ( lightAttenuation"<<i<<".z * d ) + ( lightAttenuation"<<i<<".w * d * d ))); \n"
|
||||
" lightDiffuse"<<i<<" *= attn; \n"
|
||||
|
||||
" lightColour.xyz += lit(dot(normalize(lightDir"<<i<<"), normalize(normal)), 0, 0).y * lightDiffuse"<<i<<".xyz;\n";
|
||||
}
|
||||
|
||||
outStream <<
|
||||
" float3 lightingFinal = lightColour.xyz * diffuse.xyz * vertexColour.xyz + ambient.xyz * lightAmbient.xyz + emissive.xyz; \n"
|
||||
" oColor.xyz = lerp(lightingFinal * tex.xyz, fogColour, fogValue); \n"
|
||||
" oColor.a = tex.a * diffuse.a * vertexColour.a; \n"
|
||||
"}";
|
||||
fragment->setSource(outStream.str());
|
||||
fragment->load();
|
||||
|
||||
for (int i=0; i<num_lights; ++i)
|
||||
{
|
||||
fragment->getDefaultParameters()->setNamedAutoConstant("lightPositionObjSpace"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_POSITION_OBJECT_SPACE, i);
|
||||
fragment->getDefaultParameters()->setNamedAutoConstant("lightDiffuse"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR, i);
|
||||
fragment->getDefaultParameters()->setNamedAutoConstant("lightAttenuation"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_ATTENUATION, i);
|
||||
}
|
||||
fragment->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR);
|
||||
fragment->getDefaultParameters()->setNamedAutoConstant("diffuse", GpuProgramParameters::ACT_SURFACE_DIFFUSE_COLOUR);
|
||||
fragment->getDefaultParameters()->setNamedAutoConstant("ambient", GpuProgramParameters::ACT_SURFACE_AMBIENT_COLOUR);
|
||||
fragment->getDefaultParameters()->setNamedAutoConstant("lightAmbient", GpuProgramParameters::ACT_AMBIENT_LIGHT_COLOUR);
|
||||
fragment->getDefaultParameters()->setNamedAutoConstant("fogColour", GpuProgramParameters::ACT_FOG_COLOUR);
|
||||
}
|
||||
|
||||
outStream <<
|
||||
" float3 lightingFinal = lightColour.xyz * diffuse.xyz * vertexColour.xyz + ambient.xyz * lightAmbient.xyz + emissive.xyz; \n"
|
||||
" oColor.xyz = lerp(lightingFinal * tex.xyz, fogColour, fogValue); \n"
|
||||
" oColor.a = tex.a * diffuse.a * vertexColour.a; \n"
|
||||
"}";
|
||||
fragment->setSource(outStream.str());
|
||||
fragment->load();
|
||||
|
||||
for (int i=0; i<num_lights; ++i)
|
||||
{
|
||||
fragment->getDefaultParameters()->setNamedAutoConstant("lightPositionObjSpace"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_POSITION_OBJECT_SPACE, i);
|
||||
fragment->getDefaultParameters()->setNamedAutoConstant("lightDiffuse"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR, i);
|
||||
fragment->getDefaultParameters()->setNamedAutoConstant("lightAttenuation"+StringConverter::toString(i), GpuProgramParameters::ACT_LIGHT_ATTENUATION, i);
|
||||
}
|
||||
fragment->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR);
|
||||
fragment->getDefaultParameters()->setNamedAutoConstant("diffuse", GpuProgramParameters::ACT_SURFACE_DIFFUSE_COLOUR);
|
||||
fragment->getDefaultParameters()->setNamedAutoConstant("ambient", GpuProgramParameters::ACT_SURFACE_AMBIENT_COLOUR);
|
||||
fragment->getDefaultParameters()->setNamedAutoConstant("lightAmbient", GpuProgramParameters::ACT_AMBIENT_LIGHT_COLOUR);
|
||||
fragment->getDefaultParameters()->setNamedAutoConstant("fogColour", GpuProgramParameters::ACT_FOG_COLOUR);
|
||||
else
|
||||
fragment = mgr.getByName("main_fp");
|
||||
material->getTechnique(0)->getPass(0)->setFragmentProgram(fragment->getName());
|
||||
}
|
||||
else
|
||||
fragment = mgr.getByName("main_fp");
|
||||
material->getTechnique(0)->getPass(0)->setFragmentProgram(fragment->getName());
|
||||
}
|
||||
|
||||
// Takes a name and adds a unique part to it. This is just used to
|
||||
|
|
158
components/settings/settings.cpp
Normal file
158
components/settings/settings.cpp
Normal file
|
@ -0,0 +1,158 @@
|
|||
#include "settings.hpp"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include <OgreResourceGroupManager.h>
|
||||
#include <OgreStringConverter.h>
|
||||
|
||||
using namespace Settings;
|
||||
|
||||
Ogre::ConfigFile Manager::mFile = Ogre::ConfigFile();
|
||||
Ogre::ConfigFile Manager::mDefaultFile = Ogre::ConfigFile();
|
||||
CategorySettingVector Manager::mChangedSettings = CategorySettingVector();
|
||||
CategorySettingValueMap Manager::mNewSettings = CategorySettingValueMap();
|
||||
|
||||
void Manager::loadUser (const std::string& file)
|
||||
{
|
||||
mFile.load(file);
|
||||
}
|
||||
|
||||
void Manager::loadDefault (const std::string& file)
|
||||
{
|
||||
mDefaultFile.load(file);
|
||||
}
|
||||
|
||||
void Manager::saveUser(const std::string& file)
|
||||
{
|
||||
std::fstream fout(file.c_str(), std::ios::out);
|
||||
|
||||
Ogre::ConfigFile::SectionIterator seci = mFile.getSectionIterator();
|
||||
|
||||
while (seci.hasMoreElements())
|
||||
{
|
||||
Ogre::String sectionName = seci.peekNextKey();
|
||||
|
||||
if (sectionName.length() > 0)
|
||||
fout << '\n' << '[' << seci.peekNextKey() << ']' << '\n';
|
||||
|
||||
Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
|
||||
Ogre::ConfigFile::SettingsMultiMap::iterator i;
|
||||
for (i = settings->begin(); i != settings->end(); ++i)
|
||||
{
|
||||
fout << i->first.c_str() << " = " << i->second.c_str() << '\n';
|
||||
}
|
||||
|
||||
CategorySettingValueMap::iterator it = mNewSettings.begin();
|
||||
while (it != mNewSettings.end())
|
||||
{
|
||||
if (it->first.first == sectionName)
|
||||
{
|
||||
fout << it->first.second << " = " << it->second << '\n';
|
||||
mNewSettings.erase(it++);
|
||||
}
|
||||
else
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
std::string category = "";
|
||||
for (CategorySettingValueMap::iterator it = mNewSettings.begin();
|
||||
it != mNewSettings.end(); ++it)
|
||||
{
|
||||
if (category != it->first.first)
|
||||
{
|
||||
category = it->first.first;
|
||||
fout << '\n' << '[' << category << ']' << '\n';
|
||||
}
|
||||
fout << it->first.second << " = " << it->second << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
const std::string Manager::getString (const std::string& setting, const std::string& category)
|
||||
{
|
||||
if (mNewSettings.find(std::make_pair(category, setting)) != mNewSettings.end())
|
||||
return mNewSettings[std::make_pair(category, setting)];
|
||||
|
||||
std::string defaultval = mDefaultFile.getSetting(setting, category);
|
||||
return mFile.getSetting(setting, category, defaultval);
|
||||
}
|
||||
|
||||
const float Manager::getFloat (const std::string& setting, const std::string& category)
|
||||
{
|
||||
return Ogre::StringConverter::parseReal( getString(setting, category) );
|
||||
}
|
||||
|
||||
const int Manager::getInt (const std::string& setting, const std::string& category)
|
||||
{
|
||||
return Ogre::StringConverter::parseInt( getString(setting, category) );
|
||||
}
|
||||
|
||||
const bool Manager::getBool (const std::string& setting, const std::string& category)
|
||||
{
|
||||
return Ogre::StringConverter::parseBool( getString(setting, category) );
|
||||
}
|
||||
|
||||
void Manager::setString (const std::string& setting, const std::string& category, const std::string& value)
|
||||
{
|
||||
CategorySetting s = std::make_pair(category, setting);
|
||||
|
||||
bool found=false;
|
||||
try
|
||||
{
|
||||
Ogre::ConfigFile::SettingsIterator it = mFile.getSettingsIterator(category);
|
||||
while (it.hasMoreElements())
|
||||
{
|
||||
Ogre::ConfigFile::SettingsMultiMap::iterator i = it.current();
|
||||
|
||||
if ((*i).first == setting)
|
||||
{
|
||||
if ((*i).second != value)
|
||||
{
|
||||
mChangedSettings.push_back(std::make_pair(category, setting));
|
||||
(*i).second = value;
|
||||
}
|
||||
found = true;
|
||||
}
|
||||
|
||||
it.getNext();
|
||||
}
|
||||
}
|
||||
catch (Ogre::Exception&)
|
||||
{}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
if (mNewSettings.find(s) != mNewSettings.end())
|
||||
{
|
||||
if (mNewSettings[s] != value)
|
||||
{
|
||||
mChangedSettings.push_back(std::make_pair(category, setting));
|
||||
mNewSettings[s] = value;
|
||||
}
|
||||
}
|
||||
else
|
||||
mNewSettings[s] = value;
|
||||
}
|
||||
}
|
||||
|
||||
void Manager::setInt (const std::string& setting, const std::string& category, const int value)
|
||||
{
|
||||
setString(setting, category, Ogre::StringConverter::toString(value));
|
||||
}
|
||||
|
||||
void Manager::setFloat (const std::string& setting, const std::string& category, const float value)
|
||||
{
|
||||
setString(setting, category, Ogre::StringConverter::toString(value));
|
||||
}
|
||||
|
||||
void Manager::setBool (const std::string& setting, const std::string& category, const bool value)
|
||||
{
|
||||
setString(setting, category, Ogre::StringConverter::toString(value));
|
||||
}
|
||||
|
||||
const CategorySettingVector Manager::apply()
|
||||
{
|
||||
CategorySettingVector vec = mChangedSettings;
|
||||
mChangedSettings.clear();
|
||||
return vec;
|
||||
}
|
52
components/settings/settings.hpp
Normal file
52
components/settings/settings.hpp
Normal file
|
@ -0,0 +1,52 @@
|
|||
#ifndef _COMPONENTS_SETTINGS_H
|
||||
#define _COMPONENTS_SETTINGS_H
|
||||
|
||||
#include <OgreConfigFile.h>
|
||||
|
||||
namespace Settings
|
||||
{
|
||||
typedef std::pair < std::string, std::string > CategorySetting;
|
||||
typedef std::vector< std::pair<std::string, std::string> > CategorySettingVector;
|
||||
typedef std::map < CategorySetting, std::string > CategorySettingValueMap;
|
||||
|
||||
///
|
||||
/// \brief Settings management (can change during runtime)
|
||||
///
|
||||
class Manager
|
||||
{
|
||||
public:
|
||||
static Ogre::ConfigFile mFile;
|
||||
static Ogre::ConfigFile mDefaultFile;
|
||||
|
||||
static CategorySettingVector mChangedSettings;
|
||||
///< tracks all the settings that were changed since the last apply() call
|
||||
|
||||
static CategorySettingValueMap mNewSettings;
|
||||
///< tracks all the settings that are in the default file, but not in user file yet
|
||||
|
||||
void loadDefault (const std::string& file);
|
||||
///< load file as the default settings (can be overridden by user settings)
|
||||
|
||||
void loadUser (const std::string& file);
|
||||
///< load file as user settings
|
||||
|
||||
void saveUser (const std::string& file);
|
||||
///< save user settings to file
|
||||
|
||||
static const CategorySettingVector apply();
|
||||
///< returns the list of changed settings and then clears it
|
||||
|
||||
static const int getInt (const std::string& setting, const std::string& category);
|
||||
static const float getFloat (const std::string& setting, const std::string& category);
|
||||
static const std::string getString (const std::string& setting, const std::string& category);
|
||||
static const bool getBool (const std::string& setting, const std::string& category);
|
||||
|
||||
static void setInt (const std::string& setting, const std::string& category, const int value);
|
||||
static void setFloat (const std::string& setting, const std::string& category, const float value);
|
||||
static void setString (const std::string& setting, const std::string& category, const std::string& value);
|
||||
static void setBool (const std::string& setting, const std::string& category, const bool value);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // _COMPONENTS_SETTINGS_H
|
43
files/settings-default.cfg
Normal file
43
files/settings-default.cfg
Normal file
|
@ -0,0 +1,43 @@
|
|||
[HUD]
|
||||
|
||||
# FPS counter
|
||||
# 0: not visible
|
||||
# 1: basic FPS display
|
||||
# 2: advanced FPS display (batches, triangles)
|
||||
fps = 0
|
||||
|
||||
[Objects]
|
||||
|
||||
shaders = true
|
||||
|
||||
# Max. number of lights that affect objects. Setting to 1 will only reflect sunlight
|
||||
# Note: has no effect when shaders are turned off
|
||||
num lights = 8
|
||||
|
||||
# Use static geometry for static objects. Improves rendering speed.
|
||||
use static geometry = true
|
||||
|
||||
[Viewing distance]
|
||||
|
||||
# Limit the rendering distance of small objects
|
||||
limit small object distance = false
|
||||
|
||||
# Size below which an object is considered as small
|
||||
small object size = 250
|
||||
|
||||
# Rendering distance for small objects
|
||||
small object distance = 3500
|
||||
|
||||
# Max viewing distance at clear weather conditions
|
||||
max viewing distance = 5600
|
||||
|
||||
# Distance at which fog starts (proportional to viewing distance)
|
||||
fog start factor = 0.5
|
||||
|
||||
# Distance at which fog ends (proportional to viewing distance)
|
||||
fog end factor = 1.0
|
||||
|
||||
[Terrain]
|
||||
|
||||
# Max. number of lights that affect the terrain. Setting to 1 will only reflect sunlight
|
||||
num lights = 8
|
Loading…
Reference in a new issue