mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-30 09:45:36 +00:00
Merge remote-tracking branch 'scrawl/master'
This commit is contained in:
commit
07f692bdd2
25 changed files with 518 additions and 103 deletions
|
@ -184,7 +184,7 @@ int list(Bsa::BSAFile& bsa, Arguments& info)
|
|||
{
|
||||
// List all files
|
||||
const Bsa::BSAFile::FileList &files = bsa.getList();
|
||||
for(int i=0; i<files.size(); i++)
|
||||
for(unsigned int i=0; i<files.size(); i++)
|
||||
{
|
||||
if(info.longformat)
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "engine.hpp"
|
||||
|
||||
#include "components/esm/loadcell.hpp"
|
||||
#include <stdexcept>
|
||||
|
||||
#include <OgreRoot.h>
|
||||
#include <OgreRenderWindow.h>
|
||||
|
@ -18,6 +18,8 @@
|
|||
#include <components/nifbullet/bulletnifloader.hpp>
|
||||
#include <components/nifogre/ogrenifloader.hpp>
|
||||
|
||||
#include <components/esm/loadcell.hpp>
|
||||
|
||||
#include "mwinput/inputmanagerimp.hpp"
|
||||
|
||||
#include "mwgui/windowmanagerimp.hpp"
|
||||
|
@ -211,7 +213,9 @@ void OMW::Engine::loadBSA()
|
|||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Archive " << *archive << " not found" << std::endl;
|
||||
std::stringstream message;
|
||||
message << "Archive '" << *archive << "' not found";
|
||||
throw std::runtime_error(message.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
#include <iostream>
|
||||
#include <cstdio>
|
||||
|
||||
#include <components/files/configurationmanager.hpp>
|
||||
|
||||
#include <SDL_messagebox.h>
|
||||
#include <SDL_main.h>
|
||||
#include "engine.hpp"
|
||||
|
||||
|
@ -280,7 +282,11 @@ int main(int argc, char**argv)
|
|||
}
|
||||
catch (std::exception &e)
|
||||
{
|
||||
std::cout << "\nERROR: " << e.what() << std::endl;
|
||||
if (isatty(fileno(stdin)))
|
||||
std::cerr << "\nERROR: " << e.what() << std::endl;
|
||||
else
|
||||
SDL_ShowSimpleMessageBox(0, "OpenMW: Fatal error", e.what(), NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,10 +37,6 @@ namespace MWGui
|
|||
, mPreviewDirty(true)
|
||||
, mDragAndDrop(dragAndDrop)
|
||||
, mSelectedItem(-1)
|
||||
, mPositionInventory(0, 342, 498, 258)
|
||||
, mPositionContainer(0, 342, 498, 258)
|
||||
, mPositionCompanion(0, 342, 498, 258)
|
||||
, mPositionBarter(0, 342, 498, 258)
|
||||
, mGuiMode(GM_Inventory)
|
||||
{
|
||||
static_cast<MyGUI::Window*>(mMainWidget)->eventWindowChangeCoord += MyGUI::newDelegate(this, &InventoryWindow::onWindowResize);
|
||||
|
@ -71,8 +67,19 @@ namespace MWGui
|
|||
|
||||
mFilterAll->setStateSelected(true);
|
||||
|
||||
setCoord(mPositionInventory.left, mPositionInventory.top, mPositionInventory.width, mPositionInventory.height);
|
||||
onWindowResize(static_cast<MyGUI::Window*>(mMainWidget));
|
||||
setGuiMode(mGuiMode);
|
||||
|
||||
adjustPanes();
|
||||
}
|
||||
|
||||
void InventoryWindow::adjustPanes()
|
||||
{
|
||||
const float aspect = 0.5; // fixed aspect ratio for the left pane
|
||||
mLeftPane->setSize( (mMainWidget->getSize().height-44) * aspect, mMainWidget->getSize().height-44 );
|
||||
mRightPane->setCoord( mLeftPane->getPosition().left + (mMainWidget->getSize().height-44) * aspect + 4,
|
||||
mRightPane->getPosition().top,
|
||||
mMainWidget->getSize().width - 12 - (mMainWidget->getSize().height-44) * aspect - 15,
|
||||
mMainWidget->getSize().height-44 );
|
||||
}
|
||||
|
||||
void InventoryWindow::updatePlayer()
|
||||
|
@ -87,27 +94,36 @@ namespace MWGui
|
|||
|
||||
void InventoryWindow::setGuiMode(GuiMode mode)
|
||||
{
|
||||
std::string setting = "inventory";
|
||||
mGuiMode = mode;
|
||||
switch(mode) {
|
||||
case GM_Container:
|
||||
setPinButtonVisible(false);
|
||||
mMainWidget->setCoord(mPositionContainer);
|
||||
setting += " container";
|
||||
break;
|
||||
case GM_Companion:
|
||||
setPinButtonVisible(false);
|
||||
mMainWidget->setCoord(mPositionCompanion);
|
||||
setting += " companion";
|
||||
break;
|
||||
case GM_Barter:
|
||||
setPinButtonVisible(false);
|
||||
mMainWidget->setCoord(mPositionBarter);
|
||||
setting += " barter";
|
||||
break;
|
||||
case GM_Inventory:
|
||||
default:
|
||||
setPinButtonVisible(true);
|
||||
mMainWidget->setCoord(mPositionInventory);
|
||||
break;
|
||||
}
|
||||
onWindowResize(static_cast<MyGUI::Window*>(mMainWidget));
|
||||
|
||||
MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
|
||||
MyGUI::IntPoint pos (Settings::Manager::getFloat(setting + " x", "Windows") * viewSize.width,
|
||||
Settings::Manager::getFloat(setting + " y", "Windows") * viewSize.height);
|
||||
MyGUI::IntSize size (Settings::Manager::getFloat(setting + " w", "Windows") * viewSize.width,
|
||||
Settings::Manager::getFloat(setting + " h", "Windows") * viewSize.height);
|
||||
mMainWidget->setPosition(pos);
|
||||
mMainWidget->setSize(size);
|
||||
adjustPanes();
|
||||
mPreviewDirty = true;
|
||||
}
|
||||
|
||||
TradeItemModel* InventoryWindow::getTradeModel()
|
||||
|
@ -256,32 +272,37 @@ namespace MWGui
|
|||
mItemView->update();
|
||||
|
||||
notifyContentChanged();
|
||||
adjustPanes();
|
||||
}
|
||||
|
||||
void InventoryWindow::onWindowResize(MyGUI::Window* _sender)
|
||||
{
|
||||
const float aspect = 0.5; // fixed aspect ratio for the left pane
|
||||
mLeftPane->setSize( (_sender->getSize().height-44) * aspect, _sender->getSize().height-44 );
|
||||
mRightPane->setCoord( mLeftPane->getPosition().left + (_sender->getSize().height-44) * aspect + 4,
|
||||
mRightPane->getPosition().top,
|
||||
_sender->getSize().width - 12 - (_sender->getSize().height-44) * aspect - 15,
|
||||
_sender->getSize().height-44 );
|
||||
|
||||
adjustPanes();
|
||||
std::string setting = "inventory";
|
||||
switch(mGuiMode) {
|
||||
case GM_Container:
|
||||
mPositionContainer = _sender->getCoord();
|
||||
setting += " container";
|
||||
break;
|
||||
case GM_Companion:
|
||||
mPositionCompanion = _sender->getCoord();
|
||||
setting += " companion";
|
||||
break;
|
||||
case GM_Barter:
|
||||
mPositionBarter = _sender->getCoord();
|
||||
setting += " barter";
|
||||
break;
|
||||
case GM_Inventory:
|
||||
default:
|
||||
mPositionInventory = _sender->getCoord();
|
||||
break;
|
||||
}
|
||||
|
||||
MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
|
||||
float x = _sender->getPosition().left / float(viewSize.width);
|
||||
float y = _sender->getPosition().top / float(viewSize.height);
|
||||
float w = _sender->getSize().width / float(viewSize.width);
|
||||
float h = _sender->getSize().height / float(viewSize.height);
|
||||
Settings::Manager::setFloat(setting + " x", "Windows", x);
|
||||
Settings::Manager::setFloat(setting + " y", "Windows", y);
|
||||
Settings::Manager::setFloat(setting + " w", "Windows", w);
|
||||
Settings::Manager::setFloat(setting + " h", "Windows", h);
|
||||
|
||||
if (mMainWidget->getSize().width != mLastXSize || mMainWidget->getSize().height != mLastYSize)
|
||||
{
|
||||
mLastXSize = mMainWidget->getSize().width;
|
||||
|
|
|
@ -76,11 +76,6 @@ namespace MWGui
|
|||
MyGUI::Button* mFilterMagic;
|
||||
MyGUI::Button* mFilterMisc;
|
||||
|
||||
MyGUI::IntCoord mPositionInventory;
|
||||
MyGUI::IntCoord mPositionContainer;
|
||||
MyGUI::IntCoord mPositionCompanion;
|
||||
MyGUI::IntCoord mPositionBarter;
|
||||
|
||||
GuiMode mGuiMode;
|
||||
|
||||
int mLastXSize;
|
||||
|
@ -105,6 +100,8 @@ namespace MWGui
|
|||
|
||||
void updateEncumbranceBar();
|
||||
void notifyContentChanged();
|
||||
|
||||
void adjustPanes();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -154,10 +154,6 @@ namespace MWGui
|
|||
size.width = mFixedWidth;
|
||||
size.height = 100; // dummy
|
||||
|
||||
MyGUI::IntCoord coord;
|
||||
coord.left = 10; // dummy
|
||||
coord.top = 10; // dummy
|
||||
|
||||
mMessageWidget->setSize(size);
|
||||
|
||||
MyGUI::IntSize textSize = mMessageWidget->getTextSize();
|
||||
|
|
|
@ -37,6 +37,8 @@ namespace MWGui
|
|||
void setBounty (int bounty) { if (bounty != mBounty) mChanged = true; this->mBounty = bounty; }
|
||||
void updateSkillArea();
|
||||
|
||||
virtual void open() { onWindowResize(static_cast<MyGUI::Window*>(mMainWidget)); }
|
||||
|
||||
private:
|
||||
void addSkills(const SkillList &skills, const std::string &titleId, const std::string &titleDefault, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
|
||||
void addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
|
||||
|
|
|
@ -203,16 +203,22 @@ namespace MWGui
|
|||
mRecharge = new Recharge();
|
||||
mMenu = new MainMenu(w,h);
|
||||
mMap = new MapWindow("");
|
||||
trackWindow(mMap, "map");
|
||||
mStatsWindow = new StatsWindow();
|
||||
trackWindow(mStatsWindow, "stats");
|
||||
mConsole = new Console(w,h, mConsoleOnlyScripts);
|
||||
trackWindow(mConsole, "console");
|
||||
mJournal = JournalWindow::create(JournalViewModel::create ());
|
||||
mMessageBoxManager = new MessageBoxManager();
|
||||
mInventoryWindow = new InventoryWindow(mDragAndDrop);
|
||||
mTradeWindow = new TradeWindow();
|
||||
trackWindow(mTradeWindow, "barter");
|
||||
mSpellBuyingWindow = new SpellBuyingWindow();
|
||||
mTravelWindow = new TravelWindow();
|
||||
mDialogueWindow = new DialogueWindow();
|
||||
trackWindow(mDialogueWindow, "dialogue");
|
||||
mContainerWindow = new ContainerWindow(mDragAndDrop);
|
||||
trackWindow(mContainerWindow, "container");
|
||||
mHud = new HUD(w,h, mShowFPSLevel, mDragAndDrop);
|
||||
mToolTips = new ToolTips();
|
||||
mScrollWindow = new ScrollWindow();
|
||||
|
@ -221,7 +227,9 @@ namespace MWGui
|
|||
mSettingsWindow = new SettingsWindow();
|
||||
mConfirmationDialog = new ConfirmationDialog();
|
||||
mAlchemyWindow = new AlchemyWindow();
|
||||
trackWindow(mAlchemyWindow, "alchemy");
|
||||
mSpellWindow = new SpellWindow();
|
||||
trackWindow(mSpellWindow, "spells");
|
||||
mQuickKeysMenu = new QuickKeysMenu();
|
||||
mLevelupDialog = new LevelupDialog();
|
||||
mWaitDialog = new WaitDialog();
|
||||
|
@ -232,6 +240,7 @@ namespace MWGui
|
|||
mRepair = new Repair();
|
||||
mSoulgemDialog = new SoulgemDialog(mMessageBoxManager);
|
||||
mCompanionWindow = new CompanionWindow(mDragAndDrop, mMessageBoxManager);
|
||||
trackWindow(mCompanionWindow, "companion");
|
||||
|
||||
mInputBlocker = mGui->createWidget<MyGUI::Widget>("",0,0,w,h,MyGUI::Align::Default,"Windows","");
|
||||
|
||||
|
@ -926,6 +935,17 @@ namespace MWGui
|
|||
mLoadingScreen->onResChange (x,y);
|
||||
if (!mHud)
|
||||
return; // UI not initialized yet
|
||||
|
||||
for (std::map<MyGUI::Window*, std::string>::iterator it = mTrackedWindows.begin(); it != mTrackedWindows.end(); ++it)
|
||||
{
|
||||
MyGUI::IntPoint pos (Settings::Manager::getFloat(it->second + " x", "Windows") * x,
|
||||
Settings::Manager::getFloat(it->second+ " y", "Windows") * y);
|
||||
MyGUI::IntSize size (Settings::Manager::getFloat(it->second + " w", "Windows") * x,
|
||||
Settings::Manager::getFloat(it->second + " h", "Windows") * y);
|
||||
it->first->setPosition(pos);
|
||||
it->first->setSize(size);
|
||||
}
|
||||
|
||||
mHud->onResChange(x, y);
|
||||
mConsole->onResChange(x, y);
|
||||
mMenu->onResChange(x, y);
|
||||
|
@ -1364,4 +1384,35 @@ namespace MWGui
|
|||
return mCursorVisible;
|
||||
}
|
||||
|
||||
void WindowManager::trackWindow(OEngine::GUI::Layout *layout, const std::string &name)
|
||||
{
|
||||
MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
|
||||
MyGUI::IntPoint pos (Settings::Manager::getFloat(name + " x", "Windows") * viewSize.width,
|
||||
Settings::Manager::getFloat(name + " y", "Windows") * viewSize.height);
|
||||
MyGUI::IntSize size (Settings::Manager::getFloat(name + " w", "Windows") * viewSize.width,
|
||||
Settings::Manager::getFloat(name + " h", "Windows") * viewSize.height);
|
||||
layout->mMainWidget->setPosition(pos);
|
||||
layout->mMainWidget->setSize(size);
|
||||
|
||||
MyGUI::Window* window = dynamic_cast<MyGUI::Window*>(layout->mMainWidget);
|
||||
if (!window)
|
||||
throw std::runtime_error("Attempting to track size of a non-resizable window");
|
||||
window->eventWindowChangeCoord += MyGUI::newDelegate(this, &WindowManager::onWindowChangeCoord);
|
||||
mTrackedWindows[window] = name;
|
||||
}
|
||||
|
||||
void WindowManager::onWindowChangeCoord(MyGUI::Window *_sender)
|
||||
{
|
||||
std::string setting = mTrackedWindows[_sender];
|
||||
MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
|
||||
float x = _sender->getPosition().left / float(viewSize.width);
|
||||
float y = _sender->getPosition().top / float(viewSize.height);
|
||||
float w = _sender->getSize().width / float(viewSize.width);
|
||||
float h = _sender->getSize().height / float(viewSize.height);
|
||||
Settings::Manager::setFloat(setting + " x", "Windows", x);
|
||||
Settings::Manager::setFloat(setting + " y", "Windows", y);
|
||||
Settings::Manager::setFloat(setting + " w", "Windows", w);
|
||||
Settings::Manager::setFloat(setting + " h", "Windows", h);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ namespace MyGUI
|
|||
{
|
||||
class Gui;
|
||||
class Widget;
|
||||
class Window;
|
||||
class UString;
|
||||
}
|
||||
|
||||
|
@ -283,6 +284,10 @@ namespace MWGui
|
|||
private:
|
||||
bool mConsoleOnlyScripts;
|
||||
|
||||
std::map<MyGUI::Window*, std::string> mTrackedWindows;
|
||||
void trackWindow(OEngine::GUI::Layout* layout, const std::string& name);
|
||||
void onWindowChangeCoord(MyGUI::Window* _sender);
|
||||
|
||||
OEngine::GUI::MyGUIManager *mGuiManager;
|
||||
OEngine::Render::OgreRenderer *mRendering;
|
||||
HUD *mHud;
|
||||
|
|
|
@ -878,6 +878,8 @@ void RenderingManager::setMenuTransparency(float val)
|
|||
|
||||
void RenderingManager::windowResized(int x, int y)
|
||||
{
|
||||
Settings::Manager::setInt("resolution x", "Video", x);
|
||||
Settings::Manager::setInt("resolution y", "Video", y);
|
||||
mRendering.adjustViewport();
|
||||
mCompositors->recreate();
|
||||
|
||||
|
|
|
@ -334,6 +334,10 @@ Ogre::String NIFMaterialLoader::getMaterial(const Nif::ShapeData *shapedata,
|
|||
instance->setProperty("detailMapUVSet", sh::makeProperty(new sh::IntValue(texprop->textures[Nif::NiTexturingProperty::DetailTexture].uvSet)));
|
||||
}
|
||||
|
||||
bool useParallax = !texName[Nif::NiTexturingProperty::BumpTexture].empty()
|
||||
&& texName[Nif::NiTexturingProperty::BumpTexture].find("_nh.") != std::string::npos;
|
||||
instance->setProperty("use_parallax", sh::makeProperty(new sh::BooleanValue(useParallax)));
|
||||
|
||||
for(int i = 0;i < 7;i++)
|
||||
{
|
||||
if(i == Nif::NiTexturingProperty::BaseTexture ||
|
||||
|
|
|
@ -36,7 +36,7 @@ namespace OgreInit
|
|||
{
|
||||
// Set up logging first
|
||||
new Ogre::LogManager;
|
||||
Ogre::Log *log = Ogre::LogManager::getSingleton().createLog(logPath + std::string("Ogre.log"));
|
||||
Ogre::Log *log = Ogre::LogManager::getSingleton().createLog(logPath);
|
||||
|
||||
// Disable logging to cout/cerr
|
||||
log->setDebugOutputEnabled(false);
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include <OgreTechnique.h>
|
||||
#include <OgrePass.h>
|
||||
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
||||
#include <extern/shiny/Main/Factory.hpp>
|
||||
|
||||
namespace
|
||||
|
@ -36,6 +38,8 @@ namespace Terrain
|
|||
: mShaders(shaders)
|
||||
, mShadows(false)
|
||||
, mSplitShadows(false)
|
||||
, mNormalMapping(true)
|
||||
, mParallaxMapping(true)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -85,7 +89,7 @@ namespace Terrain
|
|||
{
|
||||
assert(mLayerList.size() == mBlendmapList.size()+1);
|
||||
std::vector<Ogre::TexturePtr>::iterator blend = mBlendmapList.begin();
|
||||
for (std::vector<std::string>::iterator layer = mLayerList.begin(); layer != mLayerList.end(); ++layer)
|
||||
for (std::vector<LayerInfo>::iterator layer = mLayerList.begin(); layer != mLayerList.end(); ++layer)
|
||||
{
|
||||
Ogre::Pass* pass = technique->createPass();
|
||||
pass->setLightingEnabled(false);
|
||||
|
@ -117,7 +121,7 @@ namespace Terrain
|
|||
}
|
||||
|
||||
// Add the actual layer texture on top of the alpha map.
|
||||
tus = pass->createTextureUnitState("textures\\" + *layer);
|
||||
tus = pass->createTextureUnitState(layer->mDiffuseMap);
|
||||
if (!first)
|
||||
tus->setColourOperationEx(Ogre::LBX_BLEND_DIFFUSE_ALPHA,
|
||||
Ogre::LBS_TEXTURE,
|
||||
|
@ -156,6 +160,10 @@ namespace Terrain
|
|||
p->mShaderProperties.setProperty ("display_composite_map", sh::makeProperty(new sh::BooleanValue(true)));
|
||||
p->mShaderProperties.setProperty ("num_layers", sh::makeProperty (new sh::StringValue("0")));
|
||||
p->mShaderProperties.setProperty ("num_blendmaps", sh::makeProperty (new sh::StringValue("0")));
|
||||
p->mShaderProperties.setProperty ("normal_map_enabled", sh::makeProperty (new sh::BooleanValue(false)));
|
||||
p->mShaderProperties.setProperty ("parallax_enabled", sh::makeProperty (new sh::BooleanValue(false)));
|
||||
p->mShaderProperties.setProperty ("normal_maps",
|
||||
sh::makeProperty (new sh::IntValue(0)));
|
||||
|
||||
sh::MaterialInstanceTextureUnit* tex = p->createTextureUnit ("compositeMap");
|
||||
tex->setProperty ("direct_texture", sh::makeProperty (new sh::StringValue(mCompositeMap)));
|
||||
|
@ -210,6 +218,11 @@ namespace Terrain
|
|||
}
|
||||
}
|
||||
++neededTextureUnits; // layer texture
|
||||
|
||||
// Check if this layer has a normal map
|
||||
if (mNormalMapping && !mLayerList[layerOffset].mNormalMap.empty())
|
||||
++neededTextureUnits; // normal map
|
||||
|
||||
if (neededTextureUnits <= remainingTextureUnits)
|
||||
{
|
||||
// We can fit another!
|
||||
|
@ -238,6 +251,8 @@ namespace Terrain
|
|||
|
||||
p->mShaderProperties.setProperty ("num_layers", sh::makeProperty (new sh::StringValue(Ogre::StringConverter::toString(numLayersInThisPass))));
|
||||
p->mShaderProperties.setProperty ("num_blendmaps", sh::makeProperty (new sh::StringValue(Ogre::StringConverter::toString(numBlendTextures))));
|
||||
p->mShaderProperties.setProperty ("normal_map_enabled",
|
||||
sh::makeProperty (new sh::BooleanValue(false)));
|
||||
|
||||
// blend maps
|
||||
// the index of the first blend map used in this pass
|
||||
|
@ -254,17 +269,39 @@ namespace Terrain
|
|||
}
|
||||
|
||||
// layer maps
|
||||
bool anyNormalMaps = false;
|
||||
bool anyParallax = false;
|
||||
size_t normalMaps = 0;
|
||||
for (int i = 0; i < numLayersInThisPass; ++i)
|
||||
{
|
||||
const LayerInfo& layer = mLayerList[layerOffset+i];
|
||||
// diffuse map
|
||||
sh::MaterialInstanceTextureUnit* diffuseTex = p->createTextureUnit ("diffuseMap" + Ogre::StringConverter::toString(i));
|
||||
diffuseTex->setProperty ("direct_texture", sh::makeProperty (new sh::StringValue("textures\\"+mLayerList[layerOffset+i])));
|
||||
diffuseTex->setProperty ("direct_texture", sh::makeProperty (new sh::StringValue(layer.mDiffuseMap)));
|
||||
|
||||
// normal map (optional)
|
||||
bool useNormalMap = mNormalMapping && !mLayerList[layerOffset+i].mNormalMap.empty() && !renderCompositeMap;
|
||||
bool useParallax = useNormalMap && mParallaxMapping && layer.mParallax;
|
||||
if (useNormalMap)
|
||||
{
|
||||
anyNormalMaps = true;
|
||||
anyParallax = anyParallax || useParallax;
|
||||
sh::MaterialInstanceTextureUnit* normalTex = p->createTextureUnit ("normalMap" + Ogre::StringConverter::toString(i));
|
||||
normalTex->setProperty ("direct_texture", sh::makeProperty (new sh::StringValue(layer.mNormalMap)));
|
||||
}
|
||||
p->mShaderProperties.setProperty ("use_normal_map_" + Ogre::StringConverter::toString(i),
|
||||
sh::makeProperty (new sh::BooleanValue(useNormalMap)));
|
||||
p->mShaderProperties.setProperty ("use_parallax_" + Ogre::StringConverter::toString(i),
|
||||
sh::makeProperty (new sh::BooleanValue(useParallax)));
|
||||
boost::hash_combine(normalMaps, useNormalMap);
|
||||
boost::hash_combine(normalMaps, useNormalMap && layer.mParallax);
|
||||
|
||||
if (i+layerOffset > 0)
|
||||
{
|
||||
int blendTextureIndex = getBlendmapIndexForLayer(layerOffset+i);
|
||||
std::string blendTextureComponent = getBlendmapComponentForLayer(layerOffset+i);
|
||||
p->mShaderProperties.setProperty ("blendmap_component_" + Ogre::StringConverter::toString(i),
|
||||
sh::makeProperty (new sh::StringValue(Ogre::StringConverter::toString(blendTextureIndex-blendmapStart) + "." + blendTextureComponent)));
|
||||
sh::makeProperty (new sh::StringValue(Ogre::StringConverter::toString(blendTextureIndex-blendmapStart) + "." + blendTextureComponent)));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -274,6 +311,14 @@ namespace Terrain
|
|||
sh::makeProperty (new sh::StringValue("")));
|
||||
}
|
||||
}
|
||||
p->mShaderProperties.setProperty ("normal_map_enabled",
|
||||
sh::makeProperty (new sh::BooleanValue(anyNormalMaps)));
|
||||
p->mShaderProperties.setProperty ("parallax_enabled",
|
||||
sh::makeProperty (new sh::BooleanValue(anyParallax)));
|
||||
// Since the permutation handler can't handle dynamic property names,
|
||||
// combine normal map settings for all layers into one value
|
||||
p->mShaderProperties.setProperty ("normal_maps",
|
||||
sh::makeProperty (new sh::IntValue(normalMaps)));
|
||||
|
||||
// shadow
|
||||
if (shadows)
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#include <OgreMaterial.h>
|
||||
|
||||
#include "storage.hpp"
|
||||
|
||||
namespace Terrain
|
||||
{
|
||||
|
||||
|
@ -15,13 +17,15 @@ namespace Terrain
|
|||
/// so if this parameter is true, then the supplied blend maps are expected to be packed.
|
||||
MaterialGenerator (bool shaders);
|
||||
|
||||
void setLayerList (const std::vector<std::string>& layerList) { mLayerList = layerList; }
|
||||
void setLayerList (const std::vector<LayerInfo>& layerList) { mLayerList = layerList; }
|
||||
bool hasLayers() { return mLayerList.size(); }
|
||||
void setBlendmapList (const std::vector<Ogre::TexturePtr>& blendmapList) { mBlendmapList = blendmapList; }
|
||||
const std::vector<Ogre::TexturePtr>& getBlendmapList() { return mBlendmapList; }
|
||||
void setCompositeMap (const std::string& name) { mCompositeMap = name; }
|
||||
|
||||
void enableShadows(bool shadows) { mShadows = shadows; }
|
||||
void enableNormalMapping(bool normalMapping) { mNormalMapping = normalMapping; }
|
||||
void enableParallaxMapping(bool parallaxMapping) { mParallaxMapping = parallaxMapping; }
|
||||
void enableSplitShadows(bool splitShadows) { mSplitShadows = splitShadows; }
|
||||
|
||||
/// Creates a material suitable for displaying a chunk of terrain using alpha-blending.
|
||||
|
@ -43,12 +47,14 @@ namespace Terrain
|
|||
private:
|
||||
Ogre::MaterialPtr create (Ogre::MaterialPtr mat, bool renderCompositeMap, bool displayCompositeMap);
|
||||
|
||||
std::vector<std::string> mLayerList;
|
||||
std::vector<LayerInfo> mLayerList;
|
||||
std::vector<Ogre::TexturePtr> mBlendmapList;
|
||||
std::string mCompositeMap;
|
||||
bool mShaders;
|
||||
bool mShadows;
|
||||
bool mSplitShadows;
|
||||
bool mNormalMapping;
|
||||
bool mParallaxMapping;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -371,7 +371,7 @@ void QuadTreeNode::destroyChunks(bool children)
|
|||
for (std::vector<Ogre::TexturePtr>::const_iterator it = list.begin(); it != list.end(); ++it)
|
||||
Ogre::TextureManager::getSingleton().remove((*it)->getName());
|
||||
mMaterialGenerator->setBlendmapList(std::vector<Ogre::TexturePtr>());
|
||||
mMaterialGenerator->setLayerList(std::vector<std::string>());
|
||||
mMaterialGenerator->setLayerList(std::vector<LayerInfo>());
|
||||
mMaterialGenerator->setCompositeMap("");
|
||||
}
|
||||
|
||||
|
@ -414,7 +414,7 @@ void QuadTreeNode::ensureLayerInfo()
|
|||
return;
|
||||
|
||||
std::vector<Ogre::TexturePtr> blendmaps;
|
||||
std::vector<std::string> layerList;
|
||||
std::vector<LayerInfo> layerList;
|
||||
mTerrain->getStorage()->getBlendmaps(mSize, mCenter, mTerrain->getShadersEnabled(), blendmaps, layerList);
|
||||
|
||||
mMaterialGenerator->setLayerList(layerList);
|
||||
|
@ -427,11 +427,13 @@ void QuadTreeNode::prepareForCompositeMap(Ogre::TRect<float> area)
|
|||
|
||||
if (mIsDummy)
|
||||
{
|
||||
// TODO - why is this completely black?
|
||||
// TODO - store this default material somewhere instead of creating one for each empty cell
|
||||
MaterialGenerator matGen(mTerrain->getShadersEnabled());
|
||||
std::vector<std::string> layer;
|
||||
layer.push_back("_land_default.dds");
|
||||
std::vector<LayerInfo> layer;
|
||||
LayerInfo info;
|
||||
info.mDiffuseMap = "textures\\_land_default.dds";
|
||||
info.mParallax = false;
|
||||
layer.push_back(info);
|
||||
matGen.setLayerList(layer);
|
||||
makeQuad(sceneMgr, area.left, area.top, area.right, area.bottom, matGen.generateForCompositeMapRTT(Ogre::MaterialPtr()));
|
||||
return;
|
||||
|
|
|
@ -4,9 +4,10 @@
|
|||
#include <OgreTextureManager.h>
|
||||
#include <OgreStringConverter.h>
|
||||
#include <OgreRenderSystem.h>
|
||||
#include <OgreResourceGroupManager.h>
|
||||
#include <OgreRoot.h>
|
||||
|
||||
#include <boost/multi_array.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
namespace Terrain
|
||||
{
|
||||
|
@ -302,7 +303,7 @@ namespace Terrain
|
|||
}
|
||||
|
||||
void Storage::getBlendmaps(float chunkSize, const Ogre::Vector2 &chunkCenter,
|
||||
bool pack, std::vector<Ogre::TexturePtr> &blendmaps, std::vector<std::string> &layerList)
|
||||
bool pack, std::vector<Ogre::TexturePtr> &blendmaps, std::vector<LayerInfo> &layerList)
|
||||
{
|
||||
// TODO - blending isn't completely right yet; the blending radius appears to be
|
||||
// different at a cell transition (2 vertices, not 4), so we may need to create a larger blendmap
|
||||
|
@ -336,7 +337,7 @@ namespace Terrain
|
|||
{
|
||||
int size = textureIndicesMap.size();
|
||||
textureIndicesMap[*it] = size;
|
||||
layerList.push_back(getTextureName(*it));
|
||||
layerList.push_back(getLayerInfo(getTextureName(*it)));
|
||||
}
|
||||
|
||||
int numTextures = textureIndices.size();
|
||||
|
@ -466,5 +467,34 @@ namespace Terrain
|
|||
return land->mLandData->mHeights[y * ESM::Land::LAND_SIZE + x];
|
||||
}
|
||||
|
||||
LayerInfo Storage::getLayerInfo(const std::string& texture)
|
||||
{
|
||||
// Already have this cached?
|
||||
if (mLayerInfoMap.find(texture) != mLayerInfoMap.end())
|
||||
return mLayerInfoMap[texture];
|
||||
|
||||
LayerInfo info;
|
||||
info.mParallax = false;
|
||||
info.mDiffuseMap = "textures\\" + texture;
|
||||
std::string texture_ = texture;
|
||||
boost::replace_last(texture_, ".", "_nh.");
|
||||
if (Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup("textures\\" + texture_))
|
||||
{
|
||||
info.mNormalMap = "textures\\" + texture_;
|
||||
info.mParallax = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
texture_ = texture;
|
||||
boost::replace_last(texture_, ".", "_n.");
|
||||
if (Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup("textures\\" + texture_))
|
||||
info.mNormalMap = "textures\\" + texture_;
|
||||
}
|
||||
|
||||
mLayerInfoMap[texture] = info;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -11,6 +11,13 @@
|
|||
namespace Terrain
|
||||
{
|
||||
|
||||
struct LayerInfo
|
||||
{
|
||||
std::string mDiffuseMap;
|
||||
std::string mNormalMap;
|
||||
bool mParallax; // Height info in normal map alpha channel?
|
||||
};
|
||||
|
||||
/// We keep storage of terrain data abstract here since we need different implementations for game and editor
|
||||
class Storage
|
||||
{
|
||||
|
@ -58,7 +65,7 @@ namespace Terrain
|
|||
/// @param layerList names of the layer textures used will be written here
|
||||
void getBlendmaps (float chunkSize, const Ogre::Vector2& chunkCenter, bool pack,
|
||||
std::vector<Ogre::TexturePtr>& blendmaps,
|
||||
std::vector<std::string>& layerList);
|
||||
std::vector<LayerInfo>& layerList);
|
||||
|
||||
float getHeightAt (const Ogre::Vector3& worldPos);
|
||||
|
||||
|
@ -77,6 +84,10 @@ namespace Terrain
|
|||
UniqueTextureId getVtexIndexAt(int cellX, int cellY,
|
||||
int x, int y);
|
||||
std::string getTextureName (UniqueTextureId id);
|
||||
|
||||
std::map<std::string, LayerInfo> mLayerInfoMap;
|
||||
|
||||
LayerInfo getLayerInfo(const std::string& texture);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -91,7 +91,7 @@ precision mediump float;
|
|||
|
||||
#define shSamplerCube(name) uniform samplerCube name; @shUseSampler(name)
|
||||
|
||||
#define shMatrixMult(m, v) (m * v)
|
||||
#define shMatrixMult(m, v) ((m) * (v))
|
||||
|
||||
#define shOutputPosition gl_Position
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
material openmw_objects_base
|
||||
{
|
||||
diffuse 1.0 1.0 1.0 1.0
|
||||
specular 0 0 0 0
|
||||
specular 0 0 0 0 1
|
||||
ambient 1.0 1.0 1.0
|
||||
emissive 0.0 0.0 0.0
|
||||
vertmode 0
|
||||
|
@ -12,6 +12,7 @@ material openmw_objects_base
|
|||
use_detail_map false
|
||||
emissiveMapUVSet 0
|
||||
detailMapUVSet 0
|
||||
use_parallax false
|
||||
|
||||
scene_blend default
|
||||
depth_write default
|
||||
|
@ -37,6 +38,7 @@ material openmw_objects_base
|
|||
detailMap $detailMap
|
||||
env_map $env_map
|
||||
env_map_color $env_map_color
|
||||
use_parallax $use_parallax
|
||||
}
|
||||
|
||||
diffuse $diffuse
|
||||
|
|
|
@ -18,6 +18,10 @@
|
|||
#define EMISSIVE_MAP @shPropertyHasValue(emissiveMap)
|
||||
#define DETAIL_MAP @shPropertyHasValue(detailMap)
|
||||
|
||||
#define PARALLAX @shPropertyBool(use_parallax)
|
||||
#define PARALLAX_SCALE 0.04
|
||||
#define PARALLAX_BIAS -0.02
|
||||
|
||||
// right now we support 2 UV sets max. implementing them is tedious, and we're probably not going to need more
|
||||
#define SECOND_UV_SET (@shPropertyString(emissiveMapUVSet) || @shPropertyString(detailMapUVSet))
|
||||
|
||||
|
@ -32,6 +36,10 @@
|
|||
|
||||
#define ENV_MAP @shPropertyBool(env_map)
|
||||
|
||||
#define SPECULAR 1
|
||||
|
||||
#define NEED_NORMAL (!VERTEX_LIGHTING || ENV_MAP) || SPECULAR
|
||||
|
||||
#ifdef SH_VERTEX_SHADER
|
||||
|
||||
// ------------------------------------- VERTEX ---------------------------------------
|
||||
|
@ -63,15 +71,12 @@
|
|||
shOutput(float3, tangentPassthrough)
|
||||
#endif
|
||||
|
||||
#if !VERTEX_LIGHTING || ENV_MAP
|
||||
#if NEED_NORMAL
|
||||
shOutput(float3, normalPassthrough)
|
||||
#endif
|
||||
|
||||
#ifdef NEED_DEPTH
|
||||
shOutput(float, depthPassthrough)
|
||||
#endif
|
||||
|
||||
shOutput(float3, objSpacePositionPassthrough)
|
||||
// Depth in w
|
||||
shOutput(float4, objSpacePositionPassthrough)
|
||||
|
||||
#if VERTEXCOLOR_MODE != 0
|
||||
shColourInput(float4)
|
||||
|
@ -146,7 +151,7 @@
|
|||
#if NORMAL_MAP
|
||||
tangentPassthrough = tangent.xyz;
|
||||
#endif
|
||||
#if !VERTEX_LIGHTING || ENV_MAP
|
||||
#if NEED_NORMAL
|
||||
normalPassthrough = normal.xyz;
|
||||
#endif
|
||||
#if VERTEXCOLOR_MODE != 0 && !VERTEX_LIGHTING
|
||||
|
@ -169,14 +174,14 @@
|
|||
|
||||
float4x4 fixedWVP = shMatrixMult(vpFixed, worldMatrix);
|
||||
|
||||
depthPassthrough = shMatrixMult(fixedWVP, shInputPosition).z;
|
||||
objSpacePositionPassthrough.w = shMatrixMult(fixedWVP, shInputPosition).z;
|
||||
#else
|
||||
depthPassthrough = shOutputPosition.z;
|
||||
objSpacePositionPassthrough.w = shOutputPosition.z;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
objSpacePositionPassthrough = shInputPosition.xyz;
|
||||
objSpacePositionPassthrough.xyz = shInputPosition.xyz;
|
||||
|
||||
#if SHADOWS
|
||||
lightSpacePos0 = shMatrixMult(texViewProjMatrix0, shMatrixMult(worldMatrix, shInputPosition));
|
||||
|
@ -262,7 +267,16 @@
|
|||
#if ENV_MAP
|
||||
shSampler2D(envMap)
|
||||
shUniform(float3, env_map_color) @shUniformProperty3f(env_map_color, env_map_color)
|
||||
shUniform(float3, cameraPosObjSpace) @shAutoConstant(cameraPosObjSpace, camera_position_object_space)
|
||||
#endif
|
||||
|
||||
#if ENV_MAP || SPECULAR || PARALLAX
|
||||
shUniform(float3, cameraPosObjSpace) @shAutoConstant(cameraPosObjSpace, camera_position_object_space)
|
||||
#endif
|
||||
#if SPECULAR
|
||||
shUniform(float3, lightSpec0) @shAutoConstant(lightSpec0, light_specular_colour, 0)
|
||||
shUniform(float3, lightPosObjSpace0) @shAutoConstant(lightPosObjSpace0, light_position_object_space, 0)
|
||||
shUniform(float, matShininess) @shAutoConstant(matShininess, surface_shininess)
|
||||
shUniform(float3, matSpec) @shAutoConstant(matSpec, surface_specular_colour)
|
||||
#endif
|
||||
|
||||
shInput(float4, UV)
|
||||
|
@ -270,15 +284,11 @@
|
|||
#if NORMAL_MAP
|
||||
shInput(float3, tangentPassthrough)
|
||||
#endif
|
||||
#if !VERTEX_LIGHTING || ENV_MAP
|
||||
#if NEED_NORMAL
|
||||
shInput(float3, normalPassthrough)
|
||||
#endif
|
||||
|
||||
#ifdef NEED_DEPTH
|
||||
shInput(float, depthPassthrough)
|
||||
#endif
|
||||
|
||||
shInput(float3, objSpacePositionPassthrough)
|
||||
shInput(float4, objSpacePositionPassthrough)
|
||||
|
||||
#if VERTEXCOLOR_MODE != 0 && !VERTEX_LIGHTING
|
||||
shInput(float4, colourPassthrough)
|
||||
|
@ -321,7 +331,6 @@
|
|||
shInput(float4, lightResult)
|
||||
shInput(float3, directionalResult)
|
||||
#else
|
||||
shUniform(float, lightCount) @shAutoConstant(lightCount, light_count)
|
||||
shUniform(float4, lightPosition[@shGlobalSettingString(num_lights)]) @shAutoConstant(lightPosition, light_position_view_space_array, @shGlobalSettingString(num_lights))
|
||||
shUniform(float4, lightDiffuse[@shGlobalSettingString(num_lights)]) @shAutoConstant(lightDiffuse, light_diffuse_colour_array, @shGlobalSettingString(num_lights))
|
||||
shUniform(float4, lightAttenuation[@shGlobalSettingString(num_lights)]) @shAutoConstant(lightAttenuation, light_attenuation_array, @shGlobalSettingString(num_lights))
|
||||
|
@ -340,17 +349,13 @@
|
|||
|
||||
SH_START_PROGRAM
|
||||
{
|
||||
shOutputColour(0) = shSample(diffuseMap, UV.xy);
|
||||
float4 newUV = UV;
|
||||
|
||||
#if DETAIL_MAP
|
||||
#if @shPropertyString(detailMapUVSet)
|
||||
shOutputColour(0) *= shSample(detailMap, UV.zw)*2;
|
||||
#else
|
||||
shOutputColour(0) *= shSample(detailMap, UV.xy)*2;
|
||||
#endif
|
||||
#ifdef NEED_DEPTH
|
||||
float depthPassthrough = objSpacePositionPassthrough.w;
|
||||
#endif
|
||||
|
||||
#if !VERTEX_LIGHTING || ENV_MAP
|
||||
#if NEED_NORMAL
|
||||
float3 normal = normalPassthrough;
|
||||
#endif
|
||||
|
||||
|
@ -362,13 +367,35 @@
|
|||
tbn = transpose(tbn);
|
||||
#endif
|
||||
|
||||
float3 TSnormal = shSample(normalMap, UV.xy).xyz * 2 - 1;
|
||||
float4 normalTex = shSample(normalMap, UV.xy);
|
||||
|
||||
normal = normalize (shMatrixMult( transpose(tbn), TSnormal ));
|
||||
normal = normalize (shMatrixMult( transpose(tbn), normalTex.xyz * 2 - 1 ));
|
||||
#endif
|
||||
|
||||
#if ENV_MAP || SPECULAR || PARALLAX
|
||||
float3 eyeDir = normalize(cameraPosObjSpace.xyz - objSpacePositionPassthrough.xyz);
|
||||
#endif
|
||||
|
||||
#if PARALLAX
|
||||
float3 TSeyeDir = normalize(shMatrixMult(tbn, eyeDir));
|
||||
|
||||
newUV += (TSeyeDir.xyxy * ( normalTex.a * PARALLAX_SCALE + PARALLAX_BIAS )).xyxy;
|
||||
#endif
|
||||
|
||||
float4 diffuse = shSample(diffuseMap, newUV.xy);
|
||||
shOutputColour(0) = diffuse;
|
||||
|
||||
#if DETAIL_MAP
|
||||
#if @shPropertyString(detailMapUVSet)
|
||||
shOutputColour(0) *= shSample(detailMap, newUV.zw)*2;
|
||||
#else
|
||||
shOutputColour(0) *= shSample(detailMap, newUV.xy)*2;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#if !VERTEX_LIGHTING
|
||||
float3 viewPos = shMatrixMult(worldView, float4(objSpacePositionPassthrough,1)).xyz;
|
||||
float3 viewPos = shMatrixMult(worldView, float4(objSpacePositionPassthrough.xyz,1)).xyz;
|
||||
float3 viewNormal = normalize(shMatrixMult(worldView, float4(normal.xyz, 0)).xyz);
|
||||
|
||||
float3 lightDir;
|
||||
|
@ -433,7 +460,7 @@
|
|||
|
||||
|
||||
#if (UNDERWATER) || (FOG)
|
||||
float3 worldPos = shMatrixMult(worldMatrix, float4(objSpacePositionPassthrough,1)).xyz;
|
||||
float3 worldPos = shMatrixMult(worldMatrix, float4(objSpacePositionPassthrough.xyz,1)).xyz;
|
||||
#endif
|
||||
|
||||
#if UNDERWATER
|
||||
|
@ -448,21 +475,30 @@
|
|||
|
||||
#if EMISSIVE_MAP
|
||||
#if @shPropertyString(emissiveMapUVSet)
|
||||
shOutputColour(0).xyz += shSample(emissiveMap, UV.zw).xyz;
|
||||
shOutputColour(0).xyz += shSample(emissiveMap, newUV.zw).xyz;
|
||||
#else
|
||||
shOutputColour(0).xyz += shSample(emissiveMap, UV.xy).xyz;
|
||||
shOutputColour(0).xyz += shSample(emissiveMap, newUV.xy).xyz;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if ENV_MAP
|
||||
// Everything looks better with fresnel
|
||||
float3 eyeDir = normalize(cameraPosObjSpace.xyz - objSpacePositionPassthrough.xyz);
|
||||
float facing = 1.0 - max(abs(dot(-eyeDir, normal)), 0);
|
||||
float envFactor = shSaturate(0.25 + 0.75 * pow(facing, 1));
|
||||
|
||||
shOutputColour(0).xyz += shSample(envMap, UV.zw).xyz * envFactor * env_map_color;
|
||||
#endif
|
||||
|
||||
#if SPECULAR
|
||||
float3 light0Dir = normalize(lightPosObjSpace0.xyz);
|
||||
|
||||
float NdotL = max(dot(normal, light0Dir), 0);
|
||||
float3 halfVec = normalize (light0Dir + eyeDir);
|
||||
|
||||
float3 specular = pow(max(dot(normal, halfVec), 0), matShininess) * lightSpec0 * matSpec;
|
||||
shOutputColour(0).xyz += specular * shadow * diffuse.a;
|
||||
#endif
|
||||
|
||||
#if FOG
|
||||
float fogValue = shSaturate((depthPassthrough - fogParams.y) * fogParams.w);
|
||||
|
||||
|
|
|
@ -27,6 +27,16 @@
|
|||
|
||||
#define COMPOSITE_MAP @shPropertyBool(display_composite_map)
|
||||
|
||||
#define NORMAL_MAP @shPropertyBool(normal_map_enabled)
|
||||
#define PARALLAX @shPropertyBool(parallax_enabled)
|
||||
|
||||
#define VERTEX_LIGHTING (!NORMAL_MAP)
|
||||
|
||||
#define PARALLAX_SCALE 0.04
|
||||
#define PARALLAX_BIAS -0.02
|
||||
|
||||
// This is just for the permutation handler
|
||||
#define NORMAL_MAPS @shPropertyString(normal_maps)
|
||||
|
||||
#if NEED_DEPTH
|
||||
@shAllocatePassthrough(1, depth)
|
||||
|
@ -37,8 +47,13 @@
|
|||
@shAllocatePassthrough(3, worldPos)
|
||||
|
||||
#if LIGHTING
|
||||
@shAllocatePassthrough(3, normalPassthrough)
|
||||
#if VERTEX_LIGHTING
|
||||
@shAllocatePassthrough(3, lightResult)
|
||||
@shAllocatePassthrough(3, directionalResult)
|
||||
#else
|
||||
@shAllocatePassthrough(3, colourPassthrough)
|
||||
#endif
|
||||
|
||||
#if SHADOWS
|
||||
@shAllocatePassthrough(4, lightSpacePos0)
|
||||
|
@ -69,12 +84,13 @@
|
|||
shNormalInput(float4)
|
||||
shColourInput(float4)
|
||||
|
||||
shUniform(float, lightCount) @shAutoConstant(lightCount, light_count)
|
||||
#if VERTEX_LIGHTING
|
||||
shUniform(float4, lightPosition[@shGlobalSettingString(num_lights)]) @shAutoConstant(lightPosition, light_position_object_space_array, @shGlobalSettingString(num_lights))
|
||||
shUniform(float4, lightDiffuse[@shGlobalSettingString(num_lights)]) @shAutoConstant(lightDiffuse, light_diffuse_colour_array, @shGlobalSettingString(num_lights))
|
||||
shUniform(float4, lightAttenuation[@shGlobalSettingString(num_lights)]) @shAutoConstant(lightAttenuation, light_attenuation_array, @shGlobalSettingString(num_lights))
|
||||
shUniform(float4, lightAmbient) @shAutoConstant(lightAmbient, ambient_light_colour)
|
||||
|
||||
#endif
|
||||
|
||||
#if SHADOWS
|
||||
shUniform(float4x4, texViewProjMatrix0) @shAutoConstant(texViewProjMatrix0, texture_viewproj_matrix)
|
||||
#endif
|
||||
|
@ -122,6 +138,13 @@
|
|||
|
||||
@shPassthroughAssign(worldPos, worldPos.xyz);
|
||||
|
||||
#if LIGHTING
|
||||
@shPassthroughAssign(normalPassthrough, normal.xyz);
|
||||
#endif
|
||||
#if LIGHTING && !VERTEX_LIGHTING
|
||||
@shPassthroughAssign(colourPassthrough, colour.xyz);
|
||||
#endif
|
||||
|
||||
#if LIGHTING
|
||||
|
||||
#if SHADOWS
|
||||
|
@ -139,6 +162,7 @@
|
|||
#endif
|
||||
|
||||
|
||||
#if VERTEX_LIGHTING
|
||||
// Lighting
|
||||
float3 lightDir;
|
||||
float d;
|
||||
|
@ -164,6 +188,7 @@
|
|||
|
||||
@shPassthroughAssign(lightResult, lightResult);
|
||||
@shPassthroughAssign(directionalResult, directionalResult);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
|
@ -189,6 +214,9 @@
|
|||
|
||||
@shForeach(@shPropertyString(num_layers))
|
||||
shSampler2D(diffuseMap@shIterator)
|
||||
#if @shPropertyBool(use_normal_map_@shIterator)
|
||||
shSampler2D(normalMap@shIterator)
|
||||
#endif
|
||||
@shEndForeach
|
||||
|
||||
#endif
|
||||
|
@ -201,6 +229,15 @@
|
|||
@shPassthroughFragmentInputs
|
||||
|
||||
#if LIGHTING
|
||||
|
||||
#if !VERTEX_LIGHTING
|
||||
shUniform(float4, lightPosition[@shGlobalSettingString(num_lights)]) @shAutoConstant(lightPosition, light_position_array, @shGlobalSettingString(num_lights))
|
||||
shUniform(float4, lightDiffuse[@shGlobalSettingString(num_lights)]) @shAutoConstant(lightDiffuse, light_diffuse_colour_array, @shGlobalSettingString(num_lights))
|
||||
shUniform(float4, lightAttenuation[@shGlobalSettingString(num_lights)]) @shAutoConstant(lightAttenuation, light_attenuation_array, @shGlobalSettingString(num_lights))
|
||||
shUniform(float4, lightAmbient) @shAutoConstant(lightAmbient, ambient_light_colour)
|
||||
shUniform(float4x4, worldView) @shAutoConstant(worldView, worldview_matrix)
|
||||
#endif
|
||||
|
||||
#if SHADOWS
|
||||
shSampler2D(shadowMap0)
|
||||
shUniform(float2, invShadowmapSize0) @shAutoConstant(invShadowmapSize0, inverse_texture_size, @shPropertyString(shadowtexture_offset))
|
||||
|
@ -220,13 +257,21 @@
|
|||
|
||||
#if (UNDERWATER) || (FOG)
|
||||
shUniform(float4x4, worldMatrix) @shAutoConstant(worldMatrix, world_matrix)
|
||||
shUniform(float4, cameraPos) @shAutoConstant(cameraPos, camera_position)
|
||||
#endif
|
||||
|
||||
#if UNDERWATER
|
||||
shUniform(float, waterLevel) @shSharedParameter(waterLevel)
|
||||
#endif
|
||||
|
||||
|
||||
// For specular
|
||||
#if LIGHTING
|
||||
shUniform(float3, lightSpec0) @shAutoConstant(lightSpec0, light_specular_colour, 0)
|
||||
shUniform(float3, lightPos0) @shAutoConstant(lightPos0, light_position, 0)
|
||||
#endif
|
||||
|
||||
shUniform(float4, cameraPos) @shAutoConstant(cameraPos, camera_position)
|
||||
|
||||
SH_START_PROGRAM
|
||||
{
|
||||
|
||||
|
@ -237,12 +282,32 @@
|
|||
float2 UV = @shPassthroughReceive(UV);
|
||||
|
||||
float3 worldPos = @shPassthroughReceive(worldPos);
|
||||
|
||||
|
||||
|
||||
#if LIGHTING
|
||||
float3 normal = @shPassthroughReceive(normalPassthrough);
|
||||
#endif
|
||||
|
||||
#if LIGHTING && !VERTEX_LIGHTING
|
||||
|
||||
#if NORMAL_MAP
|
||||
// derive the tangent space basis
|
||||
float3 tangent = float3(1,0, 0);
|
||||
|
||||
float3 binormal = normalize(cross(tangent, normal));
|
||||
tangent = normalize(cross(normal, binormal)); // note, now we need to re-cross to derive tangent again because it wasn't orthonormal
|
||||
|
||||
// derive final matrix
|
||||
float3x3 tbn = float3x3(tangent, binormal, normal);
|
||||
#if SH_GLSL
|
||||
tbn = transpose(tbn);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if UNDERWATER
|
||||
float3 waterEyePos = intercept(worldPos, cameraPos.xyz - worldPos, float3(0,0,1), waterLevel);
|
||||
#endif
|
||||
|
||||
|
||||
#if !IS_FIRST_PASS
|
||||
// Opacity the previous passes should have, i.e. 1 - (opacity of this pass)
|
||||
|
@ -252,6 +317,8 @@ float previousAlpha = 1.f;
|
|||
|
||||
shOutputColour(0) = float4(1,1,1,1);
|
||||
|
||||
float3 TSnormal = float3(0,0,1);
|
||||
|
||||
#if COMPOSITE_MAP
|
||||
shOutputColour(0).xyz = shSample(compositeMap, UV).xyz;
|
||||
#else
|
||||
|
@ -266,39 +333,90 @@ float2 blendUV = (UV - 0.5) * (16.0 / (16.0+1.0)) + 0.5;
|
|||
@shEndForeach
|
||||
|
||||
|
||||
float3 albedo = float3(0,0,0);
|
||||
float4 albedo = float4(0,0,0,1);
|
||||
|
||||
float2 layerUV = UV * 16;
|
||||
float2 thisLayerUV;
|
||||
float4 normalTex;
|
||||
|
||||
float3 eyeDir = normalize(cameraPos.xyz - worldPos);
|
||||
#if PARALLAX
|
||||
float3 TSeyeDir = normalize(shMatrixMult(tbn, eyeDir));
|
||||
#endif
|
||||
|
||||
@shForeach(@shPropertyString(num_layers))
|
||||
#if @shPropertyBool(use_normal_map_@shIterator)
|
||||
normalTex = shSample(normalMap@shIterator, thisLayerUV);
|
||||
#if @shIterator == 0 && IS_FIRST_PASS
|
||||
TSnormal = normalize(normalTex.xyz * 2 - 1);
|
||||
#else
|
||||
TSnormal = shLerp(TSnormal, normalTex.xyz * 2 - 1, blendValues@shPropertyString(blendmap_component_@shIterator));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
thisLayerUV = layerUV;
|
||||
// required to play nicely with the tangents
|
||||
thisLayerUV.y *= -1;
|
||||
#if @shPropertyBool(use_parallax_@shIterator)
|
||||
thisLayerUV += TSeyeDir.xy * ( normalTex.a * PARALLAX_SCALE + PARALLAX_BIAS );
|
||||
#endif
|
||||
|
||||
#if IS_FIRST_PASS
|
||||
#if @shIterator == 0
|
||||
// first layer of first pass is the base layer and doesn't need a blend map
|
||||
albedo = shSample(diffuseMap0, layerUV).rgb;
|
||||
albedo = shSample(diffuseMap0, layerUV);
|
||||
#else
|
||||
albedo = shLerp(albedo, shSample(diffuseMap@shIterator, layerUV).rgb, blendValues@shPropertyString(blendmap_component_@shIterator));
|
||||
albedo = shLerp(albedo, shSample(diffuseMap@shIterator, thisLayerUV), blendValues@shPropertyString(blendmap_component_@shIterator));
|
||||
#endif
|
||||
#else
|
||||
#if @shIterator == 0
|
||||
albedo = shSample(diffuseMap@shIterator, layerUV).rgb, blendValues@shPropertyString(blendmap_component_@shIterator);
|
||||
albedo = shSample(diffuseMap@shIterator, layerUV);
|
||||
#else
|
||||
albedo = shLerp(albedo, shSample(diffuseMap@shIterator, layerUV).rgb, blendValues@shPropertyString(blendmap_component_@shIterator));
|
||||
albedo = shLerp(albedo, shSample(diffuseMap@shIterator, thisLayerUV), blendValues@shPropertyString(blendmap_component_@shIterator));
|
||||
#endif
|
||||
previousAlpha *= 1.f-blendValues@shPropertyString(blendmap_component_@shIterator);
|
||||
#endif
|
||||
|
||||
|
||||
@shEndForeach
|
||||
|
||||
shOutputColour(0).rgb *= albedo;
|
||||
shOutputColour(0).rgb *= albedo.xyz;
|
||||
|
||||
#endif
|
||||
|
||||
#if LIGHTING
|
||||
|
||||
#if VERTEX_LIGHTING
|
||||
// Lighting
|
||||
float3 lightResult = @shPassthroughReceive(lightResult);
|
||||
float3 directionalResult = @shPassthroughReceive(directionalResult);
|
||||
|
||||
#else
|
||||
|
||||
#if NORMAL_MAP
|
||||
normal = normalize (shMatrixMult( transpose(tbn), TSnormal ));
|
||||
#endif
|
||||
|
||||
float3 colour = @shPassthroughReceive(colourPassthrough);
|
||||
float3 lightDir;
|
||||
float d;
|
||||
float3 lightResult = float3(0,0,0);
|
||||
@shForeach(@shGlobalSettingString(num_lights))
|
||||
lightDir = lightPosition[@shIterator].xyz - (worldPos * lightPosition[@shIterator].w);
|
||||
d = length(lightDir);
|
||||
lightDir = normalize(lightDir);
|
||||
|
||||
lightResult.xyz += lightDiffuse[@shIterator].xyz
|
||||
* shSaturate(1.0 / ((lightAttenuation[@shIterator].y) + (lightAttenuation[@shIterator].z * d) + (lightAttenuation[@shIterator].w * d * d)))
|
||||
* max(dot(normal.xyz, lightDir), 0);
|
||||
#if @shIterator == 0
|
||||
float3 directionalResult = lightResult.xyz;
|
||||
#endif
|
||||
@shEndForeach
|
||||
lightResult.xyz += lightAmbient.xyz;
|
||||
lightResult.xyz *= colour.xyz;
|
||||
directionalResult.xyz *= colour.xyz;
|
||||
#endif
|
||||
|
||||
// shadows only for the first (directional) light
|
||||
#if SHADOWS
|
||||
float4 lightSpacePos0 = @shPassthroughReceive(lightSpacePos0);
|
||||
|
@ -325,6 +443,17 @@ float2 blendUV = (UV - 0.5) * (16.0 / (16.0+1.0)) + 0.5;
|
|||
shOutputColour(0).xyz *= (lightResult - directionalResult * (1.0-shadow));
|
||||
#endif
|
||||
|
||||
#if LIGHTING && !COMPOSITE_MAP
|
||||
// Specular
|
||||
float3 light0Dir = normalize(lightPos0.xyz);
|
||||
|
||||
float NdotL = max(dot(normal, light0Dir), 0);
|
||||
float3 halfVec = normalize (light0Dir + eyeDir);
|
||||
|
||||
float3 specular = pow(max(dot(normal, halfVec), 0), 32) * lightSpec0;
|
||||
shOutputColour(0).xyz += specular * (1.f-albedo.a) * shadow;
|
||||
#endif
|
||||
|
||||
#if FOG
|
||||
float fogValue = shSaturate((depth - fogParams.y) * fogParams.w);
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<MyGUI type="Layout">
|
||||
<Widget type="ExposedWindow" skin="MW_Window_Pinnable" layer="Windows" position="0 0 500 342" name="_Main">
|
||||
<Property key="MinSize" value="500 342"/>
|
||||
<Property key="MinSize" value="300 200"/>
|
||||
|
||||
<Widget type="Widget" skin="" name="LeftPane" position="0 0 220 342">
|
||||
|
||||
|
|
|
@ -169,3 +169,69 @@ ui y multiplier = 1.0
|
|||
[Game]
|
||||
# Always use the most powerful attack when striking with a weapon (chop, slash or thrust)
|
||||
best attack = false
|
||||
|
||||
[Windows]
|
||||
inventory x = 0
|
||||
inventory y = 0.4275
|
||||
inventory w = 0.6225
|
||||
inventory h = 0.5725
|
||||
|
||||
inventory container x = 0
|
||||
inventory container y = 0.4275
|
||||
inventory container w = 0.6225
|
||||
inventory container h = 0.5725
|
||||
|
||||
inventory barter x = 0
|
||||
inventory barter y = 0.4275
|
||||
inventory barter w = 0.6225
|
||||
inventory barter h = 0.5725
|
||||
|
||||
inventory companion x = 0
|
||||
inventory companion y = 0.4275
|
||||
inventory companion w = 0.6225
|
||||
inventory companion h = 0.5725
|
||||
|
||||
container x = 0.25
|
||||
container y = 0
|
||||
container w = 0.75
|
||||
container h = 0.375
|
||||
|
||||
companion x = 0.25
|
||||
companion y = 0
|
||||
companion w = 0.75
|
||||
companion h = 0.375
|
||||
|
||||
map x = 0.625
|
||||
map y = 0
|
||||
map w = 0.375
|
||||
map h = 0.5725
|
||||
|
||||
barter x = 0.25
|
||||
barter y = 0
|
||||
barter w = 0.75
|
||||
barter h = 0.375
|
||||
|
||||
alchemy x = 0.25
|
||||
alchemy y = 0.25
|
||||
alchemy w = 0.5
|
||||
alchemy h = 0.5
|
||||
|
||||
stats x = 0
|
||||
stats y = 0
|
||||
stats w = 0.375
|
||||
stats h = 0.4275
|
||||
|
||||
spells x = 0.3775
|
||||
spells y = 0.4275
|
||||
spells w = 0.375
|
||||
spells h = 0.5725
|
||||
|
||||
console x = 0
|
||||
console y = 0
|
||||
console w = 1
|
||||
console h = 0.5
|
||||
|
||||
dialogue h = 0.810
|
||||
dialogue w = 0.810
|
||||
dialogue x = 0.095
|
||||
dialogue y = 0.095
|
||||
|
|
|
@ -150,10 +150,10 @@ namespace GUI
|
|||
MyGUI::IntSize size = button->getTextSize();
|
||||
button->setSize(size.width + 24, button->getSize().height);
|
||||
}
|
||||
MyGUI::Widget* mMainWidget;
|
||||
|
||||
protected:
|
||||
|
||||
MyGUI::Widget* mMainWidget;
|
||||
std::string mPrefix;
|
||||
std::string mLayoutName;
|
||||
MyGUI::VectorWidgetPtr mListWindowRoot;
|
||||
|
|
|
@ -50,7 +50,7 @@ void OgreRenderer::configure(const std::string &logPath,
|
|||
const std::string& rttMode
|
||||
)
|
||||
{
|
||||
mRoot = mOgreInit.init(logPath);
|
||||
mRoot = mOgreInit.init(logPath + "/ogre.log");
|
||||
|
||||
RenderSystem* rs = mRoot->getRenderSystemByName(renderSystem);
|
||||
if (rs == 0)
|
||||
|
|
Loading…
Reference in a new issue