mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-21 10:53:51 +00:00
Merge branch 'master' of https://github.com/zinnschlag/openmw
This commit is contained in:
commit
a62c684222
87 changed files with 3391 additions and 3922 deletions
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "extern/shiny"]
|
||||||
|
path = extern/shiny
|
||||||
|
url = git@github.com:scrawl/shiny.git
|
|
@ -20,14 +20,6 @@ set (OPENMW_VERSION_RELEASE 0)
|
||||||
|
|
||||||
set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}")
|
set (OPENMW_VERSION "${OPENMW_VERSION_MAJOR}.${OPENMW_VERSION_MINOR}.${OPENMW_VERSION_RELEASE}")
|
||||||
|
|
||||||
# Debug suffix for plugins
|
|
||||||
set(DEBUG_SUFFIX "")
|
|
||||||
if (DEFINED CMAKE_BUILD_TYPE)
|
|
||||||
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|
||||||
set(DEBUG_SUFFIX "_d")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# doxygen main page
|
# doxygen main page
|
||||||
|
|
||||||
configure_file ("${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp.cmake" "${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp")
|
configure_file ("${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp.cmake" "${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp")
|
||||||
|
@ -194,14 +186,21 @@ if (UNIX AND NOT APPLE)
|
||||||
find_package (Threads)
|
find_package (Threads)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
set(BOOST_COMPONENTS system filesystem program_options thread)
|
||||||
|
|
||||||
|
if (Boost_VERSION LESS 104900)
|
||||||
|
set(SHINY_USE_WAVE_SYSTEM_INSTALL "TRUE")
|
||||||
|
set(BOOST_COMPONENTS ${BOOST_COMPONENTS} wave)
|
||||||
|
endif()
|
||||||
|
|
||||||
find_package(OGRE REQUIRED)
|
find_package(OGRE REQUIRED)
|
||||||
find_package(MyGUI REQUIRED)
|
find_package(MyGUI REQUIRED)
|
||||||
find_package(Boost REQUIRED COMPONENTS system filesystem program_options thread)
|
find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS})
|
||||||
find_package(OIS REQUIRED)
|
find_package(OIS REQUIRED)
|
||||||
find_package(OpenAL REQUIRED)
|
find_package(OpenAL REQUIRED)
|
||||||
find_package(Bullet REQUIRED)
|
find_package(Bullet REQUIRED)
|
||||||
IF(OGRE_STATIC)
|
IF(OGRE_STATIC)
|
||||||
find_package(Cg REQUIRED)
|
find_package(Cg)
|
||||||
IF(WIN32)
|
IF(WIN32)
|
||||||
set(OGRE_PLUGIN_INCLUDE_DIRS ${OGRE_Plugin_CgProgramManager_INCLUDE_DIRS} ${OGRE_Plugin_OctreeSceneManager_INCLUDE_DIRS} ${OGRE_Plugin_ParticleFX_INCLUDE_DIRS} ${OGRE_RenderSystem_Direct3D9_INCLUDE_DIRS} ${OGRE_RenderSystem_GL_INCLUDE_DIRS})
|
set(OGRE_PLUGIN_INCLUDE_DIRS ${OGRE_Plugin_CgProgramManager_INCLUDE_DIRS} ${OGRE_Plugin_OctreeSceneManager_INCLUDE_DIRS} ${OGRE_Plugin_ParticleFX_INCLUDE_DIRS} ${OGRE_RenderSystem_Direct3D9_INCLUDE_DIRS} ${OGRE_RenderSystem_GL_INCLUDE_DIRS})
|
||||||
ELSE(WIN32)
|
ELSE(WIN32)
|
||||||
|
@ -230,6 +229,22 @@ if (APPLE)
|
||||||
${OGRE_Plugin_ParticleFX_LIBRARY_REL})
|
${OGRE_Plugin_ParticleFX_LIBRARY_REL})
|
||||||
endif (APPLE)
|
endif (APPLE)
|
||||||
|
|
||||||
|
|
||||||
|
# Set up Ogre plugin folder & debug suffix
|
||||||
|
set(DEBUG_SUFFIX "")
|
||||||
|
if (DEFINED CMAKE_BUILD_TYPE)
|
||||||
|
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
|
set(DEBUG_SUFFIX "_d")
|
||||||
|
add_definitions(-DOGRE_PLUGIN_DEBUG_SUFFIX="_d")
|
||||||
|
else()
|
||||||
|
add_definitions(-DOGRE_PLUGIN_DEBUG_SUFFIX="")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
add_definitions(-DOGRE_PLUGIN_DIR_REL="${OGRE_PLUGIN_DIR_REL}")
|
||||||
|
add_definitions(-DOGRE_PLUGIN_DIR_DBG="${OGRE_PLUGIN_DIR_DBG}")
|
||||||
|
add_definitions(-DOGRE_PLUGIN_DIR="${OGRE_PLUGIN_DIR}")
|
||||||
|
|
||||||
|
|
||||||
add_subdirectory(files/)
|
add_subdirectory(files/)
|
||||||
add_subdirectory(files/mygui)
|
add_subdirectory(files/mygui)
|
||||||
|
|
||||||
|
@ -254,15 +269,8 @@ configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg.local
|
||||||
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg
|
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg
|
||||||
"${OpenMW_BINARY_DIR}/openmw.cfg.install")
|
"${OpenMW_BINARY_DIR}/openmw.cfg.install")
|
||||||
|
|
||||||
if (WIN32)
|
|
||||||
configure_file(${OpenMW_SOURCE_DIR}/files/plugins.cfg.win32
|
|
||||||
"${OpenMW_BINARY_DIR}/plugins.cfg" COPYONLY)
|
|
||||||
endif (WIN32)
|
|
||||||
|
|
||||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||||
configure_file(${OpenMW_SOURCE_DIR}/files/plugins.cfg.linux
|
|
||||||
"${OpenMW_BINARY_DIR}/plugins.cfg")
|
|
||||||
|
|
||||||
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.desktop
|
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.desktop
|
||||||
"${OpenMW_BINARY_DIR}/openmw.desktop")
|
"${OpenMW_BINARY_DIR}/openmw.desktop")
|
||||||
endif()
|
endif()
|
||||||
|
@ -284,13 +292,8 @@ if (APPLE)
|
||||||
|
|
||||||
set(OGRE_PLUGIN_DIR "${OGRE_PLUGIN_DIR}/")
|
set(OGRE_PLUGIN_DIR "${OGRE_PLUGIN_DIR}/")
|
||||||
|
|
||||||
configure_file(${OpenMW_SOURCE_DIR}/files/plugins.cfg.mac
|
|
||||||
"${OpenMW_BINARY_DIR}/plugins.cfg")
|
|
||||||
|
|
||||||
set(OGRE_PLUGIN_DIR_2 ${OGRE_PLUGIN_DIR})
|
set(OGRE_PLUGIN_DIR_2 ${OGRE_PLUGIN_DIR})
|
||||||
set(OGRE_PLUGIN_DIR "")
|
set(OGRE_PLUGIN_DIR "")
|
||||||
configure_file(${OpenMW_SOURCE_DIR}/files/plugins.cfg.mac
|
|
||||||
"${OpenMW_BINARY_DIR}/plugins.cfg.install")
|
|
||||||
set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_2})
|
set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_2})
|
||||||
|
|
||||||
configure_file(${OpenMW_SOURCE_DIR}/files/mac/Info.plist
|
configure_file(${OpenMW_SOURCE_DIR}/files/mac/Info.plist
|
||||||
|
@ -337,7 +340,6 @@ if(DPKG_PROGRAM)
|
||||||
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}/settings-default.cfg" DESTINATION "../etc/openmw/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
|
||||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/transparency-overrides.cfg" DESTINATION "../etc/openmw/" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ COMPONENT "openmw")
|
INSTALL(FILES "${OpenMW_BINARY_DIR}/transparency-overrides.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}/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")
|
|
||||||
|
|
||||||
#Install resources
|
#Install resources
|
||||||
INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION "share/games/openmw/" FILE_PERMISSIONS OWNER_READ GROUP_READ WORLD_READ COMPONENT "Resources")
|
INSTALL(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION "share/games/openmw/" FILE_PERMISSIONS OWNER_READ GROUP_READ WORLD_READ COMPONENT "Resources")
|
||||||
|
@ -354,7 +356,7 @@ if(DPKG_PROGRAM)
|
||||||
SET(CPACK_DEBIAN_PACKAGE_NAME "openmw")
|
SET(CPACK_DEBIAN_PACKAGE_NAME "openmw")
|
||||||
SET(CPACK_DEBIAN_PACKAGE_VERSION "${VERSION_STRING}")
|
SET(CPACK_DEBIAN_PACKAGE_VERSION "${VERSION_STRING}")
|
||||||
SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW esmtool;Esmtool omwlauncher;OMWLauncher mwiniimporter;MWiniImporter")
|
SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW esmtool;Esmtool omwlauncher;OMWLauncher mwiniimporter;MWiniImporter")
|
||||||
SET(CPACK_DEBIAN_PACKAGE_DEPENDS "nvidia-cg-toolkit (>= 2.1), libboost-filesystem1.46.1 (>= 1.46.1), libboost-program-options1.46.1 (>= 1.46.1), libboost-system1.46.1 (>= 1.46.1), libboost-thread1.46.1 (>= 1.46.1), libc6 (>= 2.11.2), libfreetype6 (>= 2.2.1), libgcc1 (>= 1:4.1.1), libmpg123-0 (>= 1.12.1), libois-1.3.0 (>= 1.3.0), libopenal1 (>= 1:1.12.854), libsndfile1 (>= 1.0.23), libstdc++6 (>= 4.4.5), libuuid1 (>= 2.17.2), libqtgui4 (>= 4.7.0)")
|
SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libboost-filesystem1.46.1 (>= 1.46.1), libboost-program-options1.46.1 (>= 1.46.1), libboost-system1.46.1 (>= 1.46.1), libboost-thread1.46.1 (>= 1.46.1), libc6 (>= 2.11.2), libfreetype6 (>= 2.2.1), libgcc1 (>= 1:4.1.1), libmpg123-0 (>= 1.12.1), libois-1.3.0 (>= 1.3.0), libopenal1 (>= 1:1.12.854), libsndfile1 (>= 1.0.23), libstdc++6 (>= 4.4.5), libuuid1 (>= 2.17.2), libqtgui4 (>= 4.7.0)")
|
||||||
|
|
||||||
SET(CPACK_DEBIAN_PACKAGE_SECTION "Games")
|
SET(CPACK_DEBIAN_PACKAGE_SECTION "Games")
|
||||||
|
|
||||||
|
@ -375,7 +377,6 @@ if(WIN32)
|
||||||
INSTALL(FILES ${dll_files} DESTINATION ".")
|
INSTALL(FILES ${dll_files} DESTINATION ".")
|
||||||
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "." RENAME "openmw.cfg")
|
INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" DESTINATION "." RENAME "openmw.cfg")
|
||||||
INSTALL(FILES
|
INSTALL(FILES
|
||||||
"${OpenMW_BINARY_DIR}/plugins.cfg"
|
|
||||||
"${OpenMW_SOURCE_DIR}/readme.txt"
|
"${OpenMW_SOURCE_DIR}/readme.txt"
|
||||||
"${OpenMW_SOURCE_DIR}/GPL3.txt"
|
"${OpenMW_SOURCE_DIR}/GPL3.txt"
|
||||||
"${OpenMW_SOURCE_DIR}/OFL.txt"
|
"${OpenMW_SOURCE_DIR}/OFL.txt"
|
||||||
|
@ -439,6 +440,9 @@ if(WIN32)
|
||||||
include(CPack)
|
include(CPack)
|
||||||
endif(WIN32)
|
endif(WIN32)
|
||||||
|
|
||||||
|
# Extern
|
||||||
|
add_subdirectory (extern/shiny)
|
||||||
|
|
||||||
# Components
|
# Components
|
||||||
add_subdirectory (components)
|
add_subdirectory (components)
|
||||||
|
|
||||||
|
@ -544,7 +548,6 @@ if (APPLE)
|
||||||
install(DIRECTORY "${APP_BUNDLE_DIR}" USE_SOURCE_PERMISSIONS DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
install(DIRECTORY "${APP_BUNDLE_DIR}" USE_SOURCE_PERMISSIONS DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
||||||
install(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
install(DIRECTORY "${OpenMW_BINARY_DIR}/resources" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
||||||
install(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" RENAME "openmw.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
install(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" RENAME "openmw.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
||||||
install(FILES "${OpenMW_BINARY_DIR}/plugins.cfg.install" RENAME "plugins.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
|
||||||
install(FILES "${OpenMW_BINARY_DIR}/launcher.qss" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
install(FILES "${OpenMW_BINARY_DIR}/launcher.qss" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
||||||
|
|
||||||
install(FILES "${OpenMW_BINARY_DIR}/settings-default.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
install(FILES "${OpenMW_BINARY_DIR}/settings-default.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
#include <QtGui>
|
#include <QtGui>
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
#include <boost/math/common_factor.hpp>
|
#include <boost/math/common_factor.hpp>
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
|
||||||
#include <components/files/configurationmanager.hpp>
|
#include <components/files/configurationmanager.hpp>
|
||||||
#include <components/settings/settings.hpp>
|
#include <components/settings/settings.hpp>
|
||||||
|
@ -70,20 +73,13 @@ GraphicsPage::GraphicsPage(Files::ConfigurationManager &cfg, QWidget *parent)
|
||||||
|
|
||||||
bool GraphicsPage::setupOgre()
|
bool GraphicsPage::setupOgre()
|
||||||
{
|
{
|
||||||
QString pluginCfg = mCfgMgr.getPluginsConfigPath().string().c_str();
|
|
||||||
QFile file(pluginCfg);
|
|
||||||
|
|
||||||
// Create a log manager so we can surpress debug text to stdout/stderr
|
// Create a log manager so we can surpress debug text to stdout/stderr
|
||||||
Ogre::LogManager* logMgr = OGRE_NEW Ogre::LogManager;
|
Ogre::LogManager* logMgr = OGRE_NEW Ogre::LogManager;
|
||||||
logMgr->createLog((mCfgMgr.getLogPath().string() + "/launcherOgre.log"), true, false, false);
|
logMgr->createLog((mCfgMgr.getLogPath().string() + "/launcherOgre.log"), true, false, false);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
#if defined(ENABLE_PLUGIN_GL) || defined(ENABLE_PLUGIN_Direct3D9)
|
|
||||||
mOgre = new Ogre::Root("", "", "./launcherOgre.log");
|
mOgre = new Ogre::Root("", "", "./launcherOgre.log");
|
||||||
#else
|
|
||||||
mOgre = new Ogre::Root(pluginCfg.toStdString(), "", "./launcherOgre.log");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
catch(Ogre::Exception &ex)
|
catch(Ogre::Exception &ex)
|
||||||
{
|
{
|
||||||
|
@ -93,7 +89,6 @@ bool GraphicsPage::setupOgre()
|
||||||
msgBox.setIcon(QMessageBox::Critical);
|
msgBox.setIcon(QMessageBox::Critical);
|
||||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||||
msgBox.setText(tr("<br><b>Failed to create the Ogre::Root object</b><br><br> \
|
msgBox.setText(tr("<br><b>Failed to create the Ogre::Root object</b><br><br> \
|
||||||
Make sure the plugins.cfg is present and valid.<br><br> \
|
|
||||||
Press \"Show Details...\" for more information.<br>"));
|
Press \"Show Details...\" for more information.<br>"));
|
||||||
msgBox.setDetailedText(ogreError);
|
msgBox.setDetailedText(ogreError);
|
||||||
msgBox.exec();
|
msgBox.exec();
|
||||||
|
@ -102,6 +97,32 @@ bool GraphicsPage::setupOgre()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string pluginDir;
|
||||||
|
const char* pluginEnv = getenv("OPENMW_OGRE_PLUGIN_DIR");
|
||||||
|
if (pluginEnv)
|
||||||
|
pluginDir = pluginEnv;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
|
||||||
|
pluginDir = ".\\";
|
||||||
|
#endif
|
||||||
|
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
|
||||||
|
pluginDir = OGRE_PLUGIN_DIR;
|
||||||
|
#endif
|
||||||
|
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
|
||||||
|
pluginDir = OGRE_PLUGIN_DIR_REL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string glPlugin = std::string(pluginDir) + "/RenderSystem_GL" + OGRE_PLUGIN_DEBUG_SUFFIX;
|
||||||
|
if (boost::filesystem::exists(glPlugin + ".so") || boost::filesystem::exists(glPlugin + ".dll"))
|
||||||
|
mOgre->loadPlugin (glPlugin);
|
||||||
|
|
||||||
|
std::string dxPlugin = std::string(pluginDir) + "/RenderSystem_Direct3D9" + OGRE_PLUGIN_DEBUG_SUFFIX;
|
||||||
|
if (boost::filesystem::exists(dxPlugin + ".so") || boost::filesystem::exists(dxPlugin + ".dll"))
|
||||||
|
mOgre->loadPlugin (dxPlugin);
|
||||||
|
|
||||||
#ifdef ENABLE_PLUGIN_GL
|
#ifdef ENABLE_PLUGIN_GL
|
||||||
mGLPlugin = new Ogre::GLPlugin();
|
mGLPlugin = new Ogre::GLPlugin();
|
||||||
mOgre->installPlugin(mGLPlugin);
|
mOgre->installPlugin(mGLPlugin);
|
||||||
|
|
|
@ -15,7 +15,7 @@ source_group(game FILES ${GAME} ${GAME_HEADER})
|
||||||
|
|
||||||
add_openmw_dir (mwrender
|
add_openmw_dir (mwrender
|
||||||
renderingmanager debugging sky player animation npcanimation creatureanimation actors objects
|
renderingmanager debugging sky player animation npcanimation creatureanimation actors objects
|
||||||
renderinginterface localmap occlusionquery terrain terrainmaterial water shadows shaderhelper
|
renderinginterface localmap occlusionquery terrain terrainmaterial water shadows
|
||||||
compositors
|
compositors
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -100,6 +100,8 @@ target_link_libraries(openmw
|
||||||
${BULLET_LIBRARIES}
|
${BULLET_LIBRARIES}
|
||||||
${MYGUI_LIBRARIES}
|
${MYGUI_LIBRARIES}
|
||||||
${MYGUI_PLATFORM_LIBRARIES}
|
${MYGUI_PLATFORM_LIBRARIES}
|
||||||
|
"shiny"
|
||||||
|
"shiny.OgrePlatform"
|
||||||
components
|
components
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -292,7 +292,6 @@ void OMW::Engine::go()
|
||||||
}
|
}
|
||||||
mOgre->configure(
|
mOgre->configure(
|
||||||
mCfgMgr.getLogPath().string(),
|
mCfgMgr.getLogPath().string(),
|
||||||
mCfgMgr.getPluginsConfigPath().string(),
|
|
||||||
renderSystem,
|
renderSystem,
|
||||||
false);
|
false);
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,14 @@ namespace
|
||||||
return "16 : 10";
|
return "16 : 10";
|
||||||
return boost::lexical_cast<std::string>(xaspect) + " : " + boost::lexical_cast<std::string>(yaspect);
|
return boost::lexical_cast<std::string>(xaspect) + " : " + boost::lexical_cast<std::string>(yaspect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string hlslGlsl ()
|
||||||
|
{
|
||||||
|
if (Ogre::Root::getSingleton ().getRenderSystem ()->getName ().find("OpenGL") == std::string::npos)
|
||||||
|
return "hlsl";
|
||||||
|
else
|
||||||
|
return "glsl";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
|
@ -103,8 +111,19 @@ namespace MWGui
|
||||||
getWidget(mReflectObjectsButton, "ReflectObjectsButton");
|
getWidget(mReflectObjectsButton, "ReflectObjectsButton");
|
||||||
getWidget(mReflectActorsButton, "ReflectActorsButton");
|
getWidget(mReflectActorsButton, "ReflectActorsButton");
|
||||||
getWidget(mReflectTerrainButton, "ReflectTerrainButton");
|
getWidget(mReflectTerrainButton, "ReflectTerrainButton");
|
||||||
|
getWidget(mShadersButton, "ShadersButton");
|
||||||
|
getWidget(mShadowsEnabledButton, "ShadowsEnabledButton");
|
||||||
|
getWidget(mShadowsLargeDistance, "ShadowsLargeDistance");
|
||||||
|
getWidget(mShadowsTextureSize, "ShadowsTextureSize");
|
||||||
|
getWidget(mActorShadows, "ActorShadows");
|
||||||
|
getWidget(mStaticsShadows, "StaticsShadows");
|
||||||
|
getWidget(mMiscShadows, "MiscShadows");
|
||||||
|
getWidget(mShadowsDebug, "ShadowsDebug");
|
||||||
|
getWidget(mUnderwaterButton, "UnderwaterButton");
|
||||||
|
|
||||||
mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onOkButtonClicked);
|
mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onOkButtonClicked);
|
||||||
|
mUnderwaterButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
||||||
|
mShadersButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onShadersToggled);
|
||||||
mFullscreenButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
mFullscreenButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
||||||
mWaterShaderButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
mWaterShaderButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
||||||
mReflectObjectsButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
mReflectObjectsButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
||||||
|
@ -120,6 +139,14 @@ namespace MWGui
|
||||||
mResolutionList->eventListChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onResolutionSelected);
|
mResolutionList->eventListChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onResolutionSelected);
|
||||||
mAnisotropySlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
|
mAnisotropySlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
|
||||||
|
|
||||||
|
mShadowsEnabledButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
||||||
|
mShadowsLargeDistance->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
||||||
|
mShadowsTextureSize->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onShadowTextureSize);
|
||||||
|
mActorShadows->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
||||||
|
mStaticsShadows->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
||||||
|
mMiscShadows->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
||||||
|
mShadowsDebug->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
|
||||||
|
|
||||||
mMasterVolumeSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
|
mMasterVolumeSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
|
||||||
mVoiceVolumeSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
|
mVoiceVolumeSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
|
||||||
mEffectsVolumeSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
|
mEffectsVolumeSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition);
|
||||||
|
@ -172,7 +199,6 @@ namespace MWGui
|
||||||
std::string tf = Settings::Manager::getString("texture filtering", "General");
|
std::string tf = Settings::Manager::getString("texture filtering", "General");
|
||||||
mTextureFilteringButton->setCaption(textureFilteringToStr(tf));
|
mTextureFilteringButton->setCaption(textureFilteringToStr(tf));
|
||||||
mAnisotropyLabel->setCaption("Anisotropy (" + boost::lexical_cast<std::string>(Settings::Manager::getInt("anisotropy", "General")) + ")");
|
mAnisotropyLabel->setCaption("Anisotropy (" + boost::lexical_cast<std::string>(Settings::Manager::getInt("anisotropy", "General")) + ")");
|
||||||
mAnisotropyBox->setVisible(tf == "anisotropic");
|
|
||||||
|
|
||||||
float val = (Settings::Manager::getFloat("max viewing distance", "Viewing distance")-sViewDistMin)/(sViewDistMax-sViewDistMin);
|
float val = (Settings::Manager::getFloat("max viewing distance", "Viewing distance")-sViewDistMin)/(sViewDistMax-sViewDistMin);
|
||||||
int viewdist = (mViewDistanceSlider->getScrollRange()-1) * val;
|
int viewdist = (mViewDistanceSlider->getScrollRange()-1) * val;
|
||||||
|
@ -185,9 +211,27 @@ namespace MWGui
|
||||||
mVoiceVolumeSlider->setScrollPosition(Settings::Manager::getFloat("voice volume", "Sound") * (mVoiceVolumeSlider->getScrollRange()-1));
|
mVoiceVolumeSlider->setScrollPosition(Settings::Manager::getFloat("voice volume", "Sound") * (mVoiceVolumeSlider->getScrollRange()-1));
|
||||||
|
|
||||||
mWaterShaderButton->setCaptionWithReplacing(Settings::Manager::getBool("shader", "Water") ? "#{sOn}" : "#{sOff}");
|
mWaterShaderButton->setCaptionWithReplacing(Settings::Manager::getBool("shader", "Water") ? "#{sOn}" : "#{sOff}");
|
||||||
mReflectObjectsButton->setCaptionWithReplacing(Settings::Manager::getBool("reflect objects", "Water") ? "#{sOn}" : "#{sOff}");
|
mReflectObjectsButton->setCaptionWithReplacing(Settings::Manager::getBool("reflect statics", "Water") ? "#{sOn}" : "#{sOff}");
|
||||||
mReflectActorsButton->setCaptionWithReplacing(Settings::Manager::getBool("reflect actors", "Water") ? "#{sOn}" : "#{sOff}");
|
mReflectActorsButton->setCaptionWithReplacing(Settings::Manager::getBool("reflect actors", "Water") ? "#{sOn}" : "#{sOff}");
|
||||||
mReflectTerrainButton->setCaptionWithReplacing(Settings::Manager::getBool("reflect terrain", "Water") ? "#{sOn}" : "#{sOff}");
|
mReflectTerrainButton->setCaptionWithReplacing(Settings::Manager::getBool("reflect terrain", "Water") ? "#{sOn}" : "#{sOff}");
|
||||||
|
mUnderwaterButton->setCaptionWithReplacing(Settings::Manager::getBool("underwater effect", "Water") ? "#{sOn}" : "#{sOff}");
|
||||||
|
|
||||||
|
mShadowsTextureSize->setCaption (Settings::Manager::getString ("texture size", "Shadows"));
|
||||||
|
mShadowsLargeDistance->setCaptionWithReplacing(Settings::Manager::getBool("split", "Shadows") ? "#{sOn}" : "#{sOff}");
|
||||||
|
mShadowsEnabledButton->setCaptionWithReplacing(Settings::Manager::getBool("enabled", "Shadows") ? "#{sOn}" : "#{sOff}");
|
||||||
|
mActorShadows->setCaptionWithReplacing(Settings::Manager::getBool("actor shadows", "Shadows") ? "#{sOn}" : "#{sOff}");
|
||||||
|
mStaticsShadows->setCaptionWithReplacing(Settings::Manager::getBool("statics shadows", "Shadows") ? "#{sOn}" : "#{sOff}");
|
||||||
|
mMiscShadows->setCaptionWithReplacing(Settings::Manager::getBool("misc shadows", "Shadows") ? "#{sOn}" : "#{sOff}");
|
||||||
|
mShadowsDebug->setCaptionWithReplacing(Settings::Manager::getBool("debug", "Shadows") ? "#{sOn}" : "#{sOff}");
|
||||||
|
|
||||||
|
std::string shaders;
|
||||||
|
if (!Settings::Manager::getBool("shaders", "Objects"))
|
||||||
|
shaders = "off";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
shaders = Settings::Manager::getString("shader mode", "General");
|
||||||
|
}
|
||||||
|
mShadersButton->setCaption (shaders);
|
||||||
|
|
||||||
if (!MWRender::RenderingManager::waterShaderSupported())
|
if (!MWRender::RenderingManager::waterShaderSupported())
|
||||||
{
|
{
|
||||||
|
@ -237,6 +281,25 @@ namespace MWGui
|
||||||
mResolutionList->setIndexSelected(MyGUI::ITEM_NONE);
|
mResolutionList->setIndexSelected(MyGUI::ITEM_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SettingsWindow::onShadowTextureSize(MyGUI::Widget* _sender)
|
||||||
|
{
|
||||||
|
std::string size = mShadowsTextureSize->getCaption();
|
||||||
|
|
||||||
|
if (size == "512")
|
||||||
|
size = "1024";
|
||||||
|
else if (size == "1024")
|
||||||
|
size = "2048";
|
||||||
|
else if (size == "2048")
|
||||||
|
size = "4096";
|
||||||
|
else
|
||||||
|
size = "512";
|
||||||
|
|
||||||
|
mShadowsTextureSize->setCaption(size);
|
||||||
|
|
||||||
|
Settings::Manager::setString("texture size", "Shadows", size);
|
||||||
|
apply();
|
||||||
|
}
|
||||||
|
|
||||||
void SettingsWindow::onButtonToggled(MyGUI::Widget* _sender)
|
void SettingsWindow::onButtonToggled(MyGUI::Widget* _sender)
|
||||||
{
|
{
|
||||||
std::string on = mWindowManager.getGameSettingString("sOn", "On");
|
std::string on = mWindowManager.getGameSettingString("sOn", "On");
|
||||||
|
@ -291,6 +354,10 @@ namespace MWGui
|
||||||
{
|
{
|
||||||
if (_sender == mWaterShaderButton)
|
if (_sender == mWaterShaderButton)
|
||||||
Settings::Manager::setBool("shader", "Water", newState);
|
Settings::Manager::setBool("shader", "Water", newState);
|
||||||
|
else if (_sender == mUnderwaterButton)
|
||||||
|
{
|
||||||
|
Settings::Manager::setBool("underwater effect", "Water", newState);
|
||||||
|
}
|
||||||
else if (_sender == mReflectObjectsButton)
|
else if (_sender == mReflectObjectsButton)
|
||||||
{
|
{
|
||||||
Settings::Manager::setBool("reflect misc", "Water", newState);
|
Settings::Manager::setBool("reflect misc", "Water", newState);
|
||||||
|
@ -301,11 +368,68 @@ namespace MWGui
|
||||||
Settings::Manager::setBool("reflect actors", "Water", newState);
|
Settings::Manager::setBool("reflect actors", "Water", newState);
|
||||||
else if (_sender == mReflectTerrainButton)
|
else if (_sender == mReflectTerrainButton)
|
||||||
Settings::Manager::setBool("reflect terrain", "Water", newState);
|
Settings::Manager::setBool("reflect terrain", "Water", newState);
|
||||||
|
else if (_sender == mShadowsEnabledButton)
|
||||||
|
Settings::Manager::setBool("enabled", "Shadows", newState);
|
||||||
|
else if (_sender == mShadowsLargeDistance)
|
||||||
|
Settings::Manager::setBool("split", "Shadows", newState);
|
||||||
|
else if (_sender == mActorShadows)
|
||||||
|
Settings::Manager::setBool("actor shadows", "Shadows", newState);
|
||||||
|
else if (_sender == mStaticsShadows)
|
||||||
|
Settings::Manager::setBool("statics shadows", "Shadows", newState);
|
||||||
|
else if (_sender == mMiscShadows)
|
||||||
|
Settings::Manager::setBool("misc shadows", "Shadows", newState);
|
||||||
|
else if (_sender == mShadowsDebug)
|
||||||
|
Settings::Manager::setBool("debug", "Shadows", newState);
|
||||||
|
|
||||||
apply();
|
apply();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SettingsWindow::onShadersToggled(MyGUI::Widget* _sender)
|
||||||
|
{
|
||||||
|
std::string val = static_cast<MyGUI::Button*>(_sender)->getCaption();
|
||||||
|
if (val == "off")
|
||||||
|
val = hlslGlsl();
|
||||||
|
else if (val == hlslGlsl())
|
||||||
|
val = "cg";
|
||||||
|
else
|
||||||
|
val = "off";
|
||||||
|
|
||||||
|
static_cast<MyGUI::Button*>(_sender)->setCaption(val);
|
||||||
|
|
||||||
|
if (val == "off")
|
||||||
|
{
|
||||||
|
Settings::Manager::setBool("shaders", "Objects", false);
|
||||||
|
|
||||||
|
// water shader not supported with object shaders off
|
||||||
|
mWaterShaderButton->setCaptionWithReplacing("#{sOff}");
|
||||||
|
mWaterShaderButton->setEnabled(false);
|
||||||
|
mReflectObjectsButton->setEnabled(false);
|
||||||
|
mReflectActorsButton->setEnabled(false);
|
||||||
|
mReflectTerrainButton->setEnabled(false);
|
||||||
|
Settings::Manager::setBool("shader", "Water", false);
|
||||||
|
|
||||||
|
// shadows not supported
|
||||||
|
mShadowsEnabledButton->setEnabled(false);
|
||||||
|
mShadowsEnabledButton->setCaptionWithReplacing("#{sOff}");
|
||||||
|
Settings::Manager::setBool("enabled", "Shadows", false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// re-enable
|
||||||
|
mWaterShaderButton->setEnabled(true);
|
||||||
|
mReflectObjectsButton->setEnabled(true);
|
||||||
|
mReflectActorsButton->setEnabled(true);
|
||||||
|
mReflectTerrainButton->setEnabled(true);
|
||||||
|
mShadowsEnabledButton->setEnabled(true);
|
||||||
|
|
||||||
|
Settings::Manager::setBool("shaders", "Objects", true);
|
||||||
|
Settings::Manager::setString("shader mode", "General", val);
|
||||||
|
}
|
||||||
|
|
||||||
|
apply();
|
||||||
|
}
|
||||||
|
|
||||||
void SettingsWindow::onFpsToggled(MyGUI::Widget* _sender)
|
void SettingsWindow::onFpsToggled(MyGUI::Widget* _sender)
|
||||||
{
|
{
|
||||||
int newLevel = (Settings::Manager::getInt("fps", "HUD") + 1) % 3;
|
int newLevel = (Settings::Manager::getInt("fps", "HUD") + 1) % 3;
|
||||||
|
@ -328,7 +452,6 @@ namespace MWGui
|
||||||
next = "none";
|
next = "none";
|
||||||
|
|
||||||
mTextureFilteringButton->setCaption(textureFilteringToStr(next));
|
mTextureFilteringButton->setCaption(textureFilteringToStr(next));
|
||||||
mAnisotropyBox->setVisible(next == "anisotropic");
|
|
||||||
|
|
||||||
Settings::Manager::setString("texture filtering", "General", next);
|
Settings::Manager::setString("texture filtering", "General", next);
|
||||||
apply();
|
apply();
|
||||||
|
|
|
@ -42,6 +42,16 @@ namespace MWGui
|
||||||
MyGUI::Button* mReflectObjectsButton;
|
MyGUI::Button* mReflectObjectsButton;
|
||||||
MyGUI::Button* mReflectActorsButton;
|
MyGUI::Button* mReflectActorsButton;
|
||||||
MyGUI::Button* mReflectTerrainButton;
|
MyGUI::Button* mReflectTerrainButton;
|
||||||
|
MyGUI::Button* mShadersButton;
|
||||||
|
MyGUI::Button* mUnderwaterButton;
|
||||||
|
|
||||||
|
MyGUI::Button* mShadowsEnabledButton;
|
||||||
|
MyGUI::Button* mShadowsLargeDistance;
|
||||||
|
MyGUI::Button* mShadowsTextureSize;
|
||||||
|
MyGUI::Button* mActorShadows;
|
||||||
|
MyGUI::Button* mStaticsShadows;
|
||||||
|
MyGUI::Button* mMiscShadows;
|
||||||
|
MyGUI::Button* mShadowsDebug;
|
||||||
|
|
||||||
// audio
|
// audio
|
||||||
MyGUI::ScrollBar* mMasterVolumeSlider;
|
MyGUI::ScrollBar* mMasterVolumeSlider;
|
||||||
|
@ -59,6 +69,9 @@ namespace MWGui
|
||||||
void onResolutionAccept();
|
void onResolutionAccept();
|
||||||
void onResolutionCancel();
|
void onResolutionCancel();
|
||||||
|
|
||||||
|
void onShadersToggled(MyGUI::Widget* _sender);
|
||||||
|
void onShadowTextureSize(MyGUI::Widget* _sender);
|
||||||
|
|
||||||
void apply();
|
void apply();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -229,7 +229,7 @@ void LocalMap::render(const float x, const float y,
|
||||||
vp->setVisibilityMask(RV_Map);
|
vp->setVisibilityMask(RV_Map);
|
||||||
|
|
||||||
// use fallback techniques without shadows and without mrt
|
// use fallback techniques without shadows and without mrt
|
||||||
vp->setMaterialScheme("Fallback");
|
vp->setMaterialScheme("local_map");
|
||||||
|
|
||||||
rtt->update();
|
rtt->update();
|
||||||
|
|
||||||
|
|
|
@ -450,3 +450,18 @@ void Objects::update(const float dt)
|
||||||
it = mLights.erase(it);
|
it = mLights.erase(it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Objects::rebuildStaticGeometry()
|
||||||
|
{
|
||||||
|
for (std::map<MWWorld::CellStore *, Ogre::StaticGeometry*>::iterator it = mStaticGeometry.begin(); it != mStaticGeometry.end(); ++it)
|
||||||
|
{
|
||||||
|
it->second->destroy();
|
||||||
|
it->second->build();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::map<MWWorld::CellStore *, Ogre::StaticGeometry*>::iterator it = mStaticGeometrySmall.begin(); it != mStaticGeometrySmall.end(); ++it)
|
||||||
|
{
|
||||||
|
it->second->destroy();
|
||||||
|
it->second->build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -93,6 +93,8 @@ public:
|
||||||
void removeCell(MWWorld::CellStore* store);
|
void removeCell(MWWorld::CellStore* store);
|
||||||
void buildStaticGeometry(MWWorld::CellStore &cell);
|
void buildStaticGeometry(MWWorld::CellStore &cell);
|
||||||
void setMwRoot(Ogre::SceneNode* root);
|
void setMwRoot(Ogre::SceneNode* root);
|
||||||
|
|
||||||
|
void rebuildStaticGeometry();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -14,14 +14,14 @@ enum RenderQueueGroups
|
||||||
|
|
||||||
RQG_Main = Ogre::RENDER_QUEUE_MAIN,
|
RQG_Main = Ogre::RENDER_QUEUE_MAIN,
|
||||||
|
|
||||||
|
RQG_Alpha = Ogre::RENDER_QUEUE_MAIN+1,
|
||||||
|
|
||||||
|
RQG_OcclusionQuery = Ogre::RENDER_QUEUE_6,
|
||||||
|
|
||||||
|
RQG_UnderWater = Ogre::RENDER_QUEUE_4,
|
||||||
|
|
||||||
RQG_Water = Ogre::RENDER_QUEUE_7+1,
|
RQG_Water = Ogre::RENDER_QUEUE_7+1,
|
||||||
|
|
||||||
RQG_Alpha = Ogre::RENDER_QUEUE_MAIN,
|
|
||||||
|
|
||||||
RQG_UnderWater = Ogre::RENDER_QUEUE_7+1,
|
|
||||||
|
|
||||||
RQG_OcclusionQuery = Ogre::RENDER_QUEUE_8,
|
|
||||||
|
|
||||||
// Sky late (sun & sun flare)
|
// Sky late (sun & sun flare)
|
||||||
RQG_SkiesLate = Ogre::RENDER_QUEUE_SKIES_LATE
|
RQG_SkiesLate = Ogre::RENDER_QUEUE_SKIES_LATE
|
||||||
};
|
};
|
||||||
|
@ -49,12 +49,12 @@ enum VisibilityFlags
|
||||||
|
|
||||||
RV_Sky = 64,
|
RV_Sky = 64,
|
||||||
|
|
||||||
// Sun glare (not visible in reflection)
|
// not visible in reflection
|
||||||
RV_Glare = 128,
|
RV_NoReflection = 128,
|
||||||
|
|
||||||
RV_OcclusionQuery = 256,
|
RV_OcclusionQuery = 256,
|
||||||
|
|
||||||
RV_Map = RV_Terrain + RV_Statics + RV_StaticsSmall + RV_Misc + RV_Water,
|
RV_Map = RV_Terrain + RV_Statics + RV_StaticsSmall + RV_Misc + RV_Water
|
||||||
|
|
||||||
/// \todo markers (normally hidden)
|
/// \todo markers (normally hidden)
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,6 +14,9 @@
|
||||||
#include <OgreCompositionPass.h>
|
#include <OgreCompositionPass.h>
|
||||||
#include <OgreHardwarePixelBuffer.h>
|
#include <OgreHardwarePixelBuffer.h>
|
||||||
|
|
||||||
|
#include <extern/shiny/Main/Factory.hpp>
|
||||||
|
#include <extern/shiny/Platforms/Ogre/OgrePlatform.hpp>
|
||||||
|
|
||||||
#include <components/esm/loadstat.hpp>
|
#include <components/esm/loadstat.hpp>
|
||||||
#include <components/settings/settings.hpp>
|
#include <components/settings/settings.hpp>
|
||||||
|
|
||||||
|
@ -27,7 +30,6 @@
|
||||||
#include "../mwinput/inputmanager.hpp" // FIXME
|
#include "../mwinput/inputmanager.hpp" // FIXME
|
||||||
|
|
||||||
#include "shadows.hpp"
|
#include "shadows.hpp"
|
||||||
#include "shaderhelper.hpp"
|
|
||||||
#include "localmap.hpp"
|
#include "localmap.hpp"
|
||||||
#include "water.hpp"
|
#include "water.hpp"
|
||||||
#include "compositors.hpp"
|
#include "compositors.hpp"
|
||||||
|
@ -40,6 +42,15 @@ namespace MWRender {
|
||||||
RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, OEngine::Physic::PhysicEngine* engine)
|
RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, OEngine::Physic::PhysicEngine* engine)
|
||||||
:mRendering(_rend), mObjects(mRendering), mActors(mRendering), mAmbientMode(0), mSunEnabled(0)
|
:mRendering(_rend), mObjects(mRendering), mActors(mRendering), mAmbientMode(0), mSunEnabled(0)
|
||||||
{
|
{
|
||||||
|
// select best shader mode
|
||||||
|
if (Settings::Manager::getString("shader mode", "General") == "")
|
||||||
|
{
|
||||||
|
if (Ogre::Root::getSingleton ().getRenderSystem ()->getName().find("OpenGL") == std::string::npos)
|
||||||
|
Settings::Manager::setString("shader mode", "General", "hlsl");
|
||||||
|
else
|
||||||
|
Settings::Manager::setString("shader mode", "General", "glsl");
|
||||||
|
}
|
||||||
|
|
||||||
mRendering.createScene("PlayerCam", Settings::Manager::getFloat("field of view", "General"), 5);
|
mRendering.createScene("PlayerCam", Settings::Manager::getFloat("field of view", "General"), 5);
|
||||||
mRendering.setWindowEventListener(this);
|
mRendering.setWindowEventListener(this);
|
||||||
|
|
||||||
|
@ -47,6 +58,21 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
|
||||||
|
|
||||||
mWater = 0;
|
mWater = 0;
|
||||||
|
|
||||||
|
// material system
|
||||||
|
sh::OgrePlatform* platform = new sh::OgrePlatform("General", (resDir / "materials").string());
|
||||||
|
platform->setCacheFolder ("./");
|
||||||
|
mFactory = new sh::Factory(platform);
|
||||||
|
|
||||||
|
sh::Language lang;
|
||||||
|
std::string l = Settings::Manager::getString("shader mode", "General");
|
||||||
|
if (l == "glsl")
|
||||||
|
lang = sh::Language_GLSL;
|
||||||
|
else if (l == "hlsl")
|
||||||
|
lang = sh::Language_HLSL;
|
||||||
|
else
|
||||||
|
lang = sh::Language_CG;
|
||||||
|
mFactory->setCurrentLanguage (lang);
|
||||||
|
|
||||||
//The fog type must be set before any terrain objects are created as if the
|
//The fog type must be set before any terrain objects are created as if the
|
||||||
//fog type is set to FOG_NONE then the initially created terrain won't have any fog
|
//fog type is set to FOG_NONE then the initially created terrain won't have any fog
|
||||||
configureFog(1, ColourValue(1,1,1));
|
configureFog(1, ColourValue(1,1,1));
|
||||||
|
@ -68,18 +94,26 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
|
||||||
// Load resources
|
// Load resources
|
||||||
ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
|
ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
|
||||||
|
|
||||||
// Due to the huge world size of MW, we'll want camera-relative rendering.
|
// causes light flicker in opengl when moving..
|
||||||
// This prevents precision artifacts when moving very far from the origin.
|
//mRendering.getScene()->setCameraRelativeRendering(true);
|
||||||
mRendering.getScene()->setCameraRelativeRendering(true);
|
|
||||||
|
|
||||||
// disable unsupported effects
|
// disable unsupported effects
|
||||||
const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities();
|
//const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities();
|
||||||
if (!waterShaderSupported())
|
if (!waterShaderSupported())
|
||||||
Settings::Manager::setBool("shader", "Water", false);
|
Settings::Manager::setBool("shader", "Water", false);
|
||||||
if ( !(caps->isShaderProfileSupported("fp40") || caps->isShaderProfileSupported("ps_4_0"))
|
if (!Settings::Manager::getBool("shaders", "Objects"))
|
||||||
|| !Settings::Manager::getBool("shaders", "Objects"))
|
|
||||||
Settings::Manager::setBool("enabled", "Shadows", false);
|
Settings::Manager::setBool("enabled", "Shadows", false);
|
||||||
|
|
||||||
|
sh::Factory::getInstance ().setGlobalSetting ("mrt_output", useMRT() ? "true" : "false");
|
||||||
|
sh::Factory::getInstance ().setGlobalSetting ("fog", "true");
|
||||||
|
sh::Factory::getInstance ().setGlobalSetting ("lighting", "true");
|
||||||
|
sh::Factory::getInstance ().setGlobalSetting ("num_lights", Settings::Manager::getString ("num lights", "Objects"));
|
||||||
|
sh::Factory::getInstance ().setGlobalSetting ("underwater_effects", Settings::Manager::getString("underwater effect", "Water"));
|
||||||
|
sh::Factory::getInstance ().setGlobalSetting ("simple_water", Settings::Manager::getBool("shader", "Water") ? "false" : "true");
|
||||||
|
|
||||||
|
sh::Factory::getInstance ().setSharedParameter ("viewportBackground", sh::makeProperty<sh::Vector3> (new sh::Vector3(0,0,0)));
|
||||||
|
sh::Factory::getInstance ().setSharedParameter ("waterEnabled", sh::makeProperty<sh::FloatValue> (new sh::FloatValue(0.0)));
|
||||||
|
|
||||||
applyCompositors();
|
applyCompositors();
|
||||||
|
|
||||||
// Turn the entire scene (represented by the 'root' node) -90
|
// Turn the entire scene (represented by the 'root' node) -90
|
||||||
|
@ -100,7 +134,6 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const
|
||||||
cameraPitchNode->attachObject(mRendering.getCamera());
|
cameraPitchNode->attachObject(mRendering.getCamera());
|
||||||
|
|
||||||
mShadows = new Shadows(&mRendering);
|
mShadows = new Shadows(&mRendering);
|
||||||
mShaderHelper = new ShaderHelper(this);
|
|
||||||
|
|
||||||
mTerrainManager = new TerrainManager(mRendering.getScene(), this);
|
mTerrainManager = new TerrainManager(mRendering.getScene(), this);
|
||||||
|
|
||||||
|
@ -124,7 +157,6 @@ RenderingManager::~RenderingManager ()
|
||||||
delete mPlayer;
|
delete mPlayer;
|
||||||
delete mSkyManager;
|
delete mSkyManager;
|
||||||
delete mDebugging;
|
delete mDebugging;
|
||||||
delete mShaderHelper;
|
|
||||||
delete mShadows;
|
delete mShadows;
|
||||||
delete mTerrainManager;
|
delete mTerrainManager;
|
||||||
delete mLocalMap;
|
delete mLocalMap;
|
||||||
|
@ -237,7 +269,7 @@ void RenderingManager::update (float duration){
|
||||||
|
|
||||||
checkUnderwater();
|
checkUnderwater();
|
||||||
|
|
||||||
mWater->update();
|
mWater->update(duration);
|
||||||
}
|
}
|
||||||
void RenderingManager::waterAdded (MWWorld::Ptr::CellStore *store){
|
void RenderingManager::waterAdded (MWWorld::Ptr::CellStore *store){
|
||||||
if(store->cell->data.flags & store->cell->HasWater
|
if(store->cell->data.flags & store->cell->HasWater
|
||||||
|
@ -336,6 +368,9 @@ void RenderingManager::configureFog(MWWorld::Ptr::CellStore &mCell)
|
||||||
color.setAsABGR (mCell.cell->ambi.fog);
|
color.setAsABGR (mCell.cell->ambi.fog);
|
||||||
|
|
||||||
configureFog(mCell.cell->ambi.fogDensity, color);
|
configureFog(mCell.cell->ambi.fogDensity, color);
|
||||||
|
|
||||||
|
if (mWater)
|
||||||
|
mWater->setViewportBackground (Ogre::ColourValue(0.8f, 0.9f, 1.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderingManager::configureFog(const float density, const Ogre::ColourValue& colour)
|
void RenderingManager::configureFog(const float density, const Ogre::ColourValue& colour)
|
||||||
|
@ -350,11 +385,12 @@ void RenderingManager::configureFog(const float density, const Ogre::ColourValue
|
||||||
mRendering.getCamera()->setFarClipDistance ( max / density );
|
mRendering.getCamera()->setFarClipDistance ( max / density );
|
||||||
mRendering.getViewport()->setBackgroundColour (colour);
|
mRendering.getViewport()->setBackgroundColour (colour);
|
||||||
|
|
||||||
CompositorInstance* inst = CompositorManager::getSingleton().getCompositorChain(mRendering.getViewport())->getCompositor("gbuffer");
|
|
||||||
if (inst != 0)
|
|
||||||
inst->getCompositor()->getTechnique(0)->getTargetPass(0)->getPass(0)->setClearColour(colour);
|
|
||||||
if (mWater)
|
if (mWater)
|
||||||
mWater->setViewportBackground(colour);
|
mWater->setViewportBackground (colour);
|
||||||
|
|
||||||
|
sh::Factory::getInstance ().setSharedParameter ("viewportBackground",
|
||||||
|
sh::makeProperty<sh::Vector3> (new sh::Vector3(colour.r, colour.g, colour.b)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -517,12 +553,14 @@ Shadows* RenderingManager::getShadows()
|
||||||
|
|
||||||
void RenderingManager::switchToInterior()
|
void RenderingManager::switchToInterior()
|
||||||
{
|
{
|
||||||
mRendering.getScene()->setCameraRelativeRendering(false);
|
// causes light flicker in opengl when moving..
|
||||||
|
//mRendering.getScene()->setCameraRelativeRendering(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderingManager::switchToExterior()
|
void RenderingManager::switchToExterior()
|
||||||
{
|
{
|
||||||
mRendering.getScene()->setCameraRelativeRendering(true);
|
// causes light flicker in opengl when moving..
|
||||||
|
//mRendering.getScene()->setCameraRelativeRendering(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ogre::Vector4 RenderingManager::boundingBoxToScreen(Ogre::AxisAlignedBox bounds)
|
Ogre::Vector4 RenderingManager::boundingBoxToScreen(Ogre::AxisAlignedBox bounds)
|
||||||
|
@ -607,7 +645,38 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec
|
||||||
else if (it->second == "shader" && it->first == "Water")
|
else if (it->second == "shader" && it->first == "Water")
|
||||||
{
|
{
|
||||||
applyCompositors();
|
applyCompositors();
|
||||||
mShaderHelper->applyShaders();
|
sh::Factory::getInstance ().setGlobalSetting ("mrt_output", useMRT() ? "true" : "false");
|
||||||
|
sh::Factory::getInstance ().setGlobalSetting ("simple_water", Settings::Manager::getBool("shader", "Water") ? "false" : "true");
|
||||||
|
mObjects.rebuildStaticGeometry ();
|
||||||
|
}
|
||||||
|
else if (it->second == "underwater effect" && it->first == "Water")
|
||||||
|
{
|
||||||
|
sh::Factory::getInstance ().setGlobalSetting ("underwater_effects", Settings::Manager::getString("underwater effect", "Water"));
|
||||||
|
mObjects.rebuildStaticGeometry ();
|
||||||
|
}
|
||||||
|
else if (it->second == "shaders" && it->first == "Objects")
|
||||||
|
{
|
||||||
|
sh::Factory::getInstance ().setShadersEnabled (Settings::Manager::getBool("shaders", "Objects"));
|
||||||
|
mObjects.rebuildStaticGeometry ();
|
||||||
|
}
|
||||||
|
else if (it->second == "shader mode" && it->first == "General")
|
||||||
|
{
|
||||||
|
sh::Language lang;
|
||||||
|
std::string l = Settings::Manager::getString("shader mode", "General");
|
||||||
|
if (l == "glsl")
|
||||||
|
lang = sh::Language_GLSL;
|
||||||
|
else if (l == "hlsl")
|
||||||
|
lang = sh::Language_HLSL;
|
||||||
|
else
|
||||||
|
lang = sh::Language_CG;
|
||||||
|
sh::Factory::getInstance ().setCurrentLanguage (lang);
|
||||||
|
mObjects.rebuildStaticGeometry ();
|
||||||
|
}
|
||||||
|
else if (it->first == "Shadows")
|
||||||
|
{
|
||||||
|
mShadows->recreate ();
|
||||||
|
|
||||||
|
mObjects.rebuildStaticGeometry ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -671,14 +740,9 @@ void RenderingManager::applyCompositors()
|
||||||
{
|
{
|
||||||
mCompositors->addCompositor("gbuffer", 0);
|
mCompositors->addCompositor("gbuffer", 0);
|
||||||
mCompositors->setCompositorEnabled("gbuffer", true);
|
mCompositors->setCompositorEnabled("gbuffer", true);
|
||||||
mCompositors->addCompositor("Underwater", 1);
|
|
||||||
mCompositors->addCompositor("gbufferFinalizer", 2);
|
mCompositors->addCompositor("gbufferFinalizer", 2);
|
||||||
mCompositors->setCompositorEnabled("gbufferFinalizer", true);
|
mCompositors->setCompositorEnabled("gbufferFinalizer", true);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
mCompositors->addCompositor("UnderwaterNoMRT", 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mWater)
|
if (mWater)
|
||||||
mWater->assignTextures();
|
mWater->assignTextures();
|
||||||
|
|
|
@ -32,10 +32,14 @@ namespace MWWorld
|
||||||
class CellStore;
|
class CellStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace sh
|
||||||
|
{
|
||||||
|
class Factory;
|
||||||
|
}
|
||||||
|
|
||||||
namespace MWRender
|
namespace MWRender
|
||||||
{
|
{
|
||||||
class Shadows;
|
class Shadows;
|
||||||
class ShaderHelper;
|
|
||||||
class LocalMap;
|
class LocalMap;
|
||||||
class Water;
|
class Water;
|
||||||
class Compositors;
|
class Compositors;
|
||||||
|
@ -162,6 +166,8 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
sh::Factory* mFactory;
|
||||||
|
|
||||||
void setAmbientMode();
|
void setAmbientMode();
|
||||||
|
|
||||||
void setMenuTransparency(float val);
|
void setMenuTransparency(float val);
|
||||||
|
@ -204,8 +210,6 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList
|
||||||
|
|
||||||
MWRender::Shadows* mShadows;
|
MWRender::Shadows* mShadows;
|
||||||
|
|
||||||
MWRender::ShaderHelper* mShaderHelper;
|
|
||||||
|
|
||||||
MWRender::Compositors* mCompositors;
|
MWRender::Compositors* mCompositors;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,309 +0,0 @@
|
||||||
#include "shaderhelper.hpp"
|
|
||||||
#include "renderingmanager.hpp"
|
|
||||||
#include "shadows.hpp"
|
|
||||||
|
|
||||||
#include <OgreHighLevelGpuProgramManager.h>
|
|
||||||
#include <OgreHighLevelGpuProgram.h>
|
|
||||||
#include <OgreGpuProgramParams.h>
|
|
||||||
#include <OgreShadowCameraSetupPSSM.h>
|
|
||||||
|
|
||||||
#include <components/settings/settings.hpp>
|
|
||||||
|
|
||||||
using namespace Ogre;
|
|
||||||
using namespace MWRender;
|
|
||||||
|
|
||||||
ShaderHelper::ShaderHelper(RenderingManager* rend)
|
|
||||||
{
|
|
||||||
mRendering = rend;
|
|
||||||
applyShaders();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShaderHelper::applyShaders()
|
|
||||||
{
|
|
||||||
if (!Settings::Manager::getBool("shaders", "Objects")) return;
|
|
||||||
|
|
||||||
bool mrt = RenderingManager::useMRT();
|
|
||||||
bool shadows = Settings::Manager::getBool("enabled", "Shadows");
|
|
||||||
bool split = Settings::Manager::getBool("split", "Shadows");
|
|
||||||
|
|
||||||
// shader for normal rendering
|
|
||||||
createShader(mrt, shadows, split, "main");
|
|
||||||
|
|
||||||
// fallback shader without mrt and without shadows
|
|
||||||
// (useful for reflection and for minimap)
|
|
||||||
createShader(false, false, false, "main_fallback");
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShaderHelper::createShader(const bool mrt, const bool shadows, const bool split, const std::string& name)
|
|
||||||
{
|
|
||||||
HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
|
|
||||||
|
|
||||||
const int numsplits = 3;
|
|
||||||
|
|
||||||
// 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");
|
|
||||||
|
|
||||||
{
|
|
||||||
// vertex
|
|
||||||
HighLevelGpuProgramPtr vertex;
|
|
||||||
if (!mgr.getByName(name+"_vp").isNull())
|
|
||||||
mgr.remove(name+"_vp");
|
|
||||||
|
|
||||||
vertex = mgr.createProgram(name+"_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 oDepth : TEXCOORD3, \n"
|
|
||||||
" out float4 oVertexColour : TEXCOORD4, \n";
|
|
||||||
if (shadows && !split) outStream <<
|
|
||||||
" out float4 oLightSpacePos0 : TEXCOORD5, \n"
|
|
||||||
" uniform float4x4 worldMatrix, \n"
|
|
||||||
" uniform float4x4 texViewProjMatrix0, \n";
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (int i=0; i<numsplits; ++i)
|
|
||||||
{
|
|
||||||
outStream <<
|
|
||||||
" out float4 oLightSpacePos"<<i<<" : TEXCOORD"<<i+5<<", \n"
|
|
||||||
" uniform float4x4 texViewProjMatrix"<<i<<", \n";
|
|
||||||
}
|
|
||||||
outStream <<
|
|
||||||
" uniform float4x4 worldMatrix, \n";
|
|
||||||
}
|
|
||||||
outStream <<
|
|
||||||
" uniform float4x4 worldViewProj \n"
|
|
||||||
") \n"
|
|
||||||
"{ \n"
|
|
||||||
" oVertexColour = colour; \n"
|
|
||||||
" oUV = uv; \n"
|
|
||||||
" oNormal = normal; \n"
|
|
||||||
" oPosition = mul( worldViewProj, position ); \n"
|
|
||||||
" oDepth = oPosition.z; \n"
|
|
||||||
" oPositionObjSpace = position; \n";
|
|
||||||
if (shadows && !split) outStream <<
|
|
||||||
" oLightSpacePos0 = mul(texViewProjMatrix0, mul(worldMatrix, position)); \n";
|
|
||||||
else
|
|
||||||
{
|
|
||||||
outStream <<
|
|
||||||
" float4 wPos = mul(worldMatrix, position); \n";
|
|
||||||
for (int i=0; i<numsplits; ++i)
|
|
||||||
{
|
|
||||||
outStream <<
|
|
||||||
" oLightSpacePos"<<i<<" = mul(texViewProjMatrix"<<i<<", wPos); \n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
outStream <<
|
|
||||||
"}";
|
|
||||||
vertex->setSource(outStream.str());
|
|
||||||
vertex->load();
|
|
||||||
vertex->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
|
|
||||||
if (shadows)
|
|
||||||
{
|
|
||||||
vertex->getDefaultParameters()->setNamedAutoConstant("worldMatrix", GpuProgramParameters::ACT_WORLD_MATRIX);
|
|
||||||
if (!split)
|
|
||||||
vertex->getDefaultParameters()->setNamedAutoConstant("texViewProjMatrix0", GpuProgramParameters::ACT_TEXTURE_VIEWPROJ_MATRIX, 0);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (int i=0; i<numsplits; ++i)
|
|
||||||
{
|
|
||||||
vertex->getDefaultParameters()->setNamedAutoConstant("texViewProjMatrix"+StringConverter::toString(i), GpuProgramParameters::ACT_TEXTURE_VIEWPROJ_MATRIX, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
// fragment
|
|
||||||
HighLevelGpuProgramPtr fragment;
|
|
||||||
if (!mgr.getByName(name+"_fp").isNull())
|
|
||||||
mgr.remove(name+"_fp");
|
|
||||||
|
|
||||||
fragment = mgr.createProgram(name+"_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;
|
|
||||||
|
|
||||||
if (shadows) outStream <<
|
|
||||||
"float depthShadow(sampler2D shadowMap, float4 shadowMapPos, float2 offset) \n"
|
|
||||||
"{ \n"
|
|
||||||
" shadowMapPos /= shadowMapPos.w; \n"
|
|
||||||
" float3 o = float3(offset.xy, -offset.x) * 0.3f; \n"
|
|
||||||
" float c = (shadowMapPos.z <= tex2D(shadowMap, shadowMapPos.xy - o.xy).r) ? 1 : 0; // top left \n"
|
|
||||||
" c += (shadowMapPos.z <= tex2D(shadowMap, shadowMapPos.xy + o.xy).r) ? 1 : 0; // bottom right \n"
|
|
||||||
" c += (shadowMapPos.z <= tex2D(shadowMap, shadowMapPos.xy + o.zy).r) ? 1 : 0; // bottom left \n"
|
|
||||||
" c += (shadowMapPos.z <= tex2D(shadowMap, shadowMapPos.xy - o.zy).r) ? 1 : 0; // top right \n"
|
|
||||||
" return c / 4; \n"
|
|
||||||
"} \n";
|
|
||||||
|
|
||||||
outStream <<
|
|
||||||
"void main_fp( \n"
|
|
||||||
" in float2 uv : TEXCOORD0, \n"
|
|
||||||
" out float4 oColor : COLOR, \n"
|
|
||||||
" uniform sampler2D texture : register(s0), \n"
|
|
||||||
" float4 positionObjSpace : TEXCOORD1, \n"
|
|
||||||
" float4 normal : TEXCOORD2, \n"
|
|
||||||
" float iDepth : TEXCOORD3, \n"
|
|
||||||
" float4 vertexColour : TEXCOORD4, \n"
|
|
||||||
" uniform float4 fogColour, \n"
|
|
||||||
" uniform float4 fogParams, \n";
|
|
||||||
|
|
||||||
if (shadows) outStream <<
|
|
||||||
" uniform float4 shadowFar_fadeStart, \n";
|
|
||||||
|
|
||||||
if (shadows && !split) outStream <<
|
|
||||||
" uniform sampler2D shadowMap : register(s1), \n"
|
|
||||||
" float4 lightSpacePos0 : TEXCOORD5, \n"
|
|
||||||
" uniform float4 invShadowmapSize0, \n";
|
|
||||||
else
|
|
||||||
{
|
|
||||||
outStream <<
|
|
||||||
" uniform float4 pssmSplitPoints, \n";
|
|
||||||
for (int i=0; i<numsplits; ++i)
|
|
||||||
{
|
|
||||||
outStream <<
|
|
||||||
" uniform sampler2D shadowMap"<<i<<" : register(s"<<i+1<<"), \n"
|
|
||||||
" float4 lightSpacePos"<<i<<" : TEXCOORD"<<i+5<<", \n"
|
|
||||||
" uniform float4 invShadowmapSize"<<i<<", \n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mrt) outStream <<
|
|
||||||
" out float4 oColor1 : COLOR1, \n"
|
|
||||||
" uniform float far, \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 lightDir; \n"
|
|
||||||
" float3 lightColour = float3(0, 0, 0); \n";
|
|
||||||
|
|
||||||
for (int i=0; i<num_lights; ++i)
|
|
||||||
{
|
|
||||||
outStream <<
|
|
||||||
" lightDir = lightPositionObjSpace"<<i<<".xyz - (positionObjSpace.xyz * lightPositionObjSpace"<<i<<".w); \n"
|
|
||||||
|
|
||||||
// pre-multiply light color with attenuation factor
|
|
||||||
" d = length( lightDir ); \n"
|
|
||||||
" attn = ( 1.0 / (( lightAttenuation"<<i<<".y ) + ( lightAttenuation"<<i<<".z * d ) + ( lightAttenuation"<<i<<".w * d * d ))); \n"
|
|
||||||
" lightDiffuse"<<i<<" *= attn; \n";
|
|
||||||
|
|
||||||
if (i == 0 && shadows)
|
|
||||||
{
|
|
||||||
outStream <<
|
|
||||||
" float shadow; \n";
|
|
||||||
if (!split) outStream <<
|
|
||||||
" shadow = depthShadow(shadowMap, lightSpacePos0, invShadowmapSize0.xy); \n";
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (int j=0; j<numsplits; ++j)
|
|
||||||
{
|
|
||||||
std::string channel;
|
|
||||||
if (j==0) channel = "x";
|
|
||||||
else if (j==1) channel = "y";
|
|
||||||
else if (j==2) channel = "z";
|
|
||||||
|
|
||||||
if (j==0)
|
|
||||||
outStream << " if (iDepth <= pssmSplitPoints." << channel << ") \n";
|
|
||||||
else if (j < numsplits - 1)
|
|
||||||
outStream << " else if (iDepth <= pssmSplitPoints." << channel << ") \n";
|
|
||||||
else
|
|
||||||
outStream << " else \n";
|
|
||||||
|
|
||||||
outStream <<
|
|
||||||
" { \n"
|
|
||||||
" shadow = depthShadow(shadowMap" << j << ", lightSpacePos" << j << ", invShadowmapSize" << j << ".xy); \n"
|
|
||||||
" } \n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
outStream <<
|
|
||||||
" float fadeRange = shadowFar_fadeStart.x - shadowFar_fadeStart.y; \n"
|
|
||||||
" float fade = 1-((iDepth - shadowFar_fadeStart.y) / fadeRange); \n"
|
|
||||||
" shadow = (iDepth > shadowFar_fadeStart.x) ? 1 : ((iDepth > shadowFar_fadeStart.y) ? 1-((1-shadow)*fade) : shadow); \n"
|
|
||||||
" lightColour.xyz += shadow * lit(dot(normalize(lightDir), normalize(normal)), 0, 0).y * lightDiffuse"<<i<<".xyz;\n";
|
|
||||||
}
|
|
||||||
else outStream <<
|
|
||||||
" lightColour.xyz += lit(dot(normalize(lightDir), normalize(normal)), 0, 0).y * lightDiffuse"<<i<<".xyz;\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
outStream <<
|
|
||||||
" float3 lightingFinal = lightColour.xyz * diffuse.xyz + ambient.xyz * lightAmbient.xyz + emissive.xyz; \n"
|
|
||||||
" float fogValue = saturate((iDepth - fogParams.y) * fogParams.w); \n"
|
|
||||||
" oColor.xyz = saturate(lerp(lightingFinal * tex.xyz * vertexColour.xyz, fogColour.xyz, fogValue)); \n" // saturate output to prevent negative output colors - TODO: replace this once there is HDR-rendering
|
|
||||||
" oColor.a = tex.a * diffuse.a * vertexColour.a; \n";
|
|
||||||
|
|
||||||
if (mrt) outStream <<
|
|
||||||
" oColor1 = float4(iDepth / far, 0, 0, (oColor.a == 1)); \n"; // only write to MRT if alpha is 1
|
|
||||||
|
|
||||||
outStream <<
|
|
||||||
"}";
|
|
||||||
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);
|
|
||||||
fragment->getDefaultParameters()->setNamedAutoConstant("fogParams", GpuProgramParameters::ACT_FOG_PARAMS);
|
|
||||||
|
|
||||||
if (shadows)
|
|
||||||
{
|
|
||||||
fragment->getDefaultParameters()->setNamedConstant("shadowFar_fadeStart", Vector4(mRendering->getShadows()->getShadowFar(), mRendering->getShadows()->getFadeStart()*mRendering->getShadows()->getShadowFar(), 0, 0));
|
|
||||||
for (int i=0; i < (split ? numsplits : 1); ++i)
|
|
||||||
{
|
|
||||||
fragment->getDefaultParameters()->setNamedAutoConstant("invShadowmapSize" + StringConverter::toString(i), GpuProgramParameters::ACT_INVERSE_TEXTURE_SIZE, i+1);
|
|
||||||
}
|
|
||||||
if (split)
|
|
||||||
{
|
|
||||||
Vector4 splitPoints;
|
|
||||||
const PSSMShadowCameraSetup::SplitPointList& splitPointList = mRendering->getShadows()->getPSSMSetup()->getSplitPoints();
|
|
||||||
// Populate from split point 1, not 0, since split 0 isn't useful (usually 0)
|
|
||||||
for (int i = 1; i < numsplits; ++i)
|
|
||||||
{
|
|
||||||
splitPoints[i-1] = splitPointList[i];
|
|
||||||
}
|
|
||||||
fragment->getDefaultParameters()->setNamedConstant("pssmSplitPoints", splitPoints);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mrt)
|
|
||||||
fragment->getDefaultParameters()->setNamedAutoConstant("far", GpuProgramParameters::ACT_FAR_CLIP_DISTANCE);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
#ifndef GAME_SHADERHELPER_H
|
|
||||||
#define GAME_SHADERHELPER_H
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace MWRender
|
|
||||||
{
|
|
||||||
class RenderingManager;
|
|
||||||
|
|
||||||
///
|
|
||||||
/// \brief manages the main shader
|
|
||||||
///
|
|
||||||
class ShaderHelper
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ShaderHelper(RenderingManager* rend);
|
|
||||||
|
|
||||||
void applyShaders();
|
|
||||||
///< apply new settings
|
|
||||||
|
|
||||||
private:
|
|
||||||
RenderingManager* mRendering;
|
|
||||||
|
|
||||||
void createShader(const bool mrt, const bool shadows, const bool split, const std::string& name);
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -12,6 +12,8 @@
|
||||||
#include <OgreOverlayContainer.h>
|
#include <OgreOverlayContainer.h>
|
||||||
#include <OgreOverlayManager.h>
|
#include <OgreOverlayManager.h>
|
||||||
|
|
||||||
|
#include <extern/shiny/Main/Factory.hpp>
|
||||||
|
|
||||||
#include "renderconst.hpp"
|
#include "renderconst.hpp"
|
||||||
|
|
||||||
using namespace Ogre;
|
using namespace Ogre;
|
||||||
|
@ -34,6 +36,9 @@ void Shadows::recreate()
|
||||||
bool split = Settings::Manager::getBool("split", "Shadows");
|
bool split = Settings::Manager::getBool("split", "Shadows");
|
||||||
//const bool split = false;
|
//const bool split = false;
|
||||||
|
|
||||||
|
sh::Factory::getInstance ().setGlobalSetting ("shadows", enabled && !split ? "true" : "false");
|
||||||
|
sh::Factory::getInstance ().setGlobalSetting ("shadows_pssm", enabled && split ? "true" : "false");
|
||||||
|
|
||||||
if (!enabled)
|
if (!enabled)
|
||||||
{
|
{
|
||||||
mSceneMgr->setShadowTechnique(SHADOWTYPE_NONE);
|
mSceneMgr->setShadowTechnique(SHADOWTYPE_NONE);
|
||||||
|
@ -53,7 +58,7 @@ void Shadows::recreate()
|
||||||
|
|
||||||
mSceneMgr->setShadowTextureSelfShadow(true);
|
mSceneMgr->setShadowTextureSelfShadow(true);
|
||||||
mSceneMgr->setShadowCasterRenderBackFaces(true);
|
mSceneMgr->setShadowCasterRenderBackFaces(true);
|
||||||
mSceneMgr->setShadowTextureCasterMaterial("depth_shadow_caster");
|
mSceneMgr->setShadowTextureCasterMaterial("openmw_shadowcaster_default");
|
||||||
mSceneMgr->setShadowTexturePixelFormat(PF_FLOAT32_R);
|
mSceneMgr->setShadowTexturePixelFormat(PF_FLOAT32_R);
|
||||||
mSceneMgr->setShadowDirectionalLightExtrusionDistance(1000000);
|
mSceneMgr->setShadowDirectionalLightExtrusionDistance(1000000);
|
||||||
|
|
||||||
|
@ -84,18 +89,27 @@ void Shadows::recreate()
|
||||||
mSceneMgr->setShadowTextureConfig(i, texsize/4, texsize/4, Ogre::PF_FLOAT32_R);*/
|
mSceneMgr->setShadowTextureConfig(i, texsize/4, texsize/4, Ogre::PF_FLOAT32_R);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Populate from split point 1, not 0, since split 0 isn't useful (usually 0)
|
||||||
|
const PSSMShadowCameraSetup::SplitPointList& splitPointList = getPSSMSetup()->getSplitPoints();
|
||||||
|
sh::Vector3* splitPoints = new sh::Vector3(splitPointList[1], splitPointList[2], splitPointList[3]);
|
||||||
|
|
||||||
|
sh::Factory::getInstance ().setSharedParameter ("pssmSplitPoints", sh::makeProperty<sh::Vector3>(splitPoints));
|
||||||
|
|
||||||
shadowCameraSetup = ShadowCameraSetupPtr(mPSSMSetup);
|
shadowCameraSetup = ShadowCameraSetupPtr(mPSSMSetup);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LiSPSMShadowCameraSetup* lispsmSetup = new LiSPSMShadowCameraSetup();
|
LiSPSMShadowCameraSetup* lispsmSetup = new LiSPSMShadowCameraSetup();
|
||||||
lispsmSetup->setOptimalAdjustFactor(2);
|
lispsmSetup->setOptimalAdjustFactor(64);
|
||||||
//lispsmSetup->setCameraLightDirectionThreshold(Degree(0));
|
//lispsmSetup->setCameraLightDirectionThreshold(Degree(0));
|
||||||
//lispsmSetup->setUseAggressiveFocusRegion(false);
|
//lispsmSetup->setUseAggressiveFocusRegion(false);
|
||||||
shadowCameraSetup = ShadowCameraSetupPtr(lispsmSetup);
|
shadowCameraSetup = ShadowCameraSetupPtr(lispsmSetup);
|
||||||
}
|
}
|
||||||
mSceneMgr->setShadowCameraSetup(shadowCameraSetup);
|
mSceneMgr->setShadowCameraSetup(shadowCameraSetup);
|
||||||
|
|
||||||
|
sh::Vector4* shadowFar_fadeStart = new sh::Vector4(mShadowFar, mFadeStart * mShadowFar, 0, 0);
|
||||||
|
sh::Factory::getInstance ().setSharedParameter ("shadowFar_fadeStart", sh::makeProperty<sh::Vector4>(shadowFar_fadeStart));
|
||||||
|
|
||||||
// Set visibility mask for the shadow render textures
|
// Set visibility mask for the shadow render textures
|
||||||
int visibilityMask = RV_Actors * Settings::Manager::getBool("actor shadows", "Shadows")
|
int visibilityMask = RV_Actors * Settings::Manager::getBool("actor shadows", "Shadows")
|
||||||
+ (RV_Statics + RV_StaticsSmall) * Settings::Manager::getBool("statics shadows", "Shadows")
|
+ (RV_Statics + RV_StaticsSmall) * Settings::Manager::getBool("statics shadows", "Shadows")
|
||||||
|
@ -111,53 +125,62 @@ void Shadows::recreate()
|
||||||
// --------------------------------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------------------------------
|
||||||
// --------------------------- Debug overlays to display the content of shadow maps -----------------------------------
|
// --------------------------- Debug overlays to display the content of shadow maps -----------------------------------
|
||||||
// --------------------------------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------------------------------
|
||||||
/*
|
if (Settings::Manager::getBool("debug", "Shadows"))
|
||||||
OverlayManager& mgr = OverlayManager::getSingleton();
|
{
|
||||||
Overlay* overlay;
|
OverlayManager& mgr = OverlayManager::getSingleton();
|
||||||
|
Overlay* overlay;
|
||||||
// destroy if already exists
|
|
||||||
if (overlay = mgr.getByName("DebugOverlay"))
|
|
||||||
mgr.destroy(overlay);
|
|
||||||
|
|
||||||
overlay = mgr.create("DebugOverlay");
|
|
||||||
for (size_t i = 0; i < (split ? 3 : 1); ++i) {
|
|
||||||
TexturePtr tex = mRendering->getScene()->getShadowTexture(i);
|
|
||||||
|
|
||||||
// Set up a debug panel to display the shadow
|
|
||||||
|
|
||||||
if (MaterialManager::getSingleton().resourceExists("Ogre/DebugTexture" + StringConverter::toString(i)))
|
|
||||||
MaterialManager::getSingleton().remove("Ogre/DebugTexture" + StringConverter::toString(i));
|
|
||||||
MaterialPtr debugMat = MaterialManager::getSingleton().create(
|
|
||||||
"Ogre/DebugTexture" + StringConverter::toString(i),
|
|
||||||
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
|
|
||||||
|
|
||||||
debugMat->getTechnique(0)->getPass(0)->setLightingEnabled(false);
|
|
||||||
TextureUnitState *t = debugMat->getTechnique(0)->getPass(0)->createTextureUnitState(tex->getName());
|
|
||||||
t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
|
|
||||||
|
|
||||||
OverlayContainer* debugPanel;
|
// destroy if already exists
|
||||||
|
if ((overlay = mgr.getByName("DebugOverlay")))
|
||||||
// destroy container if exists
|
mgr.destroy(overlay);
|
||||||
try
|
|
||||||
{
|
overlay = mgr.create("DebugOverlay");
|
||||||
if (debugPanel =
|
for (size_t i = 0; i < (split ? 3 : 1); ++i) {
|
||||||
static_cast<OverlayContainer*>(
|
TexturePtr tex = mRendering->getScene()->getShadowTexture(i);
|
||||||
mgr.getOverlayElement("Ogre/DebugTexPanel" + StringConverter::toString(i)
|
|
||||||
)))
|
// Set up a debug panel to display the shadow
|
||||||
mgr.destroyOverlayElement(debugPanel);
|
|
||||||
}
|
if (MaterialManager::getSingleton().resourceExists("Ogre/DebugTexture" + StringConverter::toString(i)))
|
||||||
catch (Ogre::Exception&) {}
|
MaterialManager::getSingleton().remove("Ogre/DebugTexture" + StringConverter::toString(i));
|
||||||
|
MaterialPtr debugMat = MaterialManager::getSingleton().create(
|
||||||
debugPanel = (OverlayContainer*)
|
"Ogre/DebugTexture" + StringConverter::toString(i),
|
||||||
(OverlayManager::getSingleton().createOverlayElement("Panel", "Ogre/DebugTexPanel" + StringConverter::toString(i)));
|
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
|
||||||
debugPanel->_setPosition(0.8, i*0.25);
|
|
||||||
debugPanel->_setDimensions(0.2, 0.24);
|
debugMat->getTechnique(0)->getPass(0)->setLightingEnabled(false);
|
||||||
debugPanel->setMaterialName(debugMat->getName());
|
TextureUnitState *t = debugMat->getTechnique(0)->getPass(0)->createTextureUnitState(tex->getName());
|
||||||
debugPanel->show();
|
t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
|
||||||
overlay->add2D(debugPanel);
|
|
||||||
overlay->show();
|
OverlayContainer* debugPanel;
|
||||||
}
|
|
||||||
*/
|
// destroy container if exists
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if ((debugPanel =
|
||||||
|
static_cast<OverlayContainer*>(
|
||||||
|
mgr.getOverlayElement("Ogre/DebugTexPanel" + StringConverter::toString(i)
|
||||||
|
))))
|
||||||
|
mgr.destroyOverlayElement(debugPanel);
|
||||||
|
}
|
||||||
|
catch (Ogre::Exception&) {}
|
||||||
|
|
||||||
|
debugPanel = (OverlayContainer*)
|
||||||
|
(OverlayManager::getSingleton().createOverlayElement("Panel", "Ogre/DebugTexPanel" + StringConverter::toString(i)));
|
||||||
|
debugPanel->_setPosition(0.8, i*0.25);
|
||||||
|
debugPanel->_setDimensions(0.2, 0.24);
|
||||||
|
debugPanel->setMaterialName(debugMat->getName());
|
||||||
|
debugPanel->show();
|
||||||
|
overlay->add2D(debugPanel);
|
||||||
|
overlay->show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OverlayManager& mgr = OverlayManager::getSingleton();
|
||||||
|
Overlay* overlay;
|
||||||
|
|
||||||
|
if ((overlay = mgr.getByName("DebugOverlay")))
|
||||||
|
mgr.destroy(overlay);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PSSMShadowCameraSetup* Shadows::getPSSMSetup()
|
PSSMShadowCameraSetup* Shadows::getPSSMSetup()
|
||||||
|
|
|
@ -15,8 +15,12 @@
|
||||||
#include <OgreOverlayManager.h>
|
#include <OgreOverlayManager.h>
|
||||||
#include <OgreOverlayContainer.h>
|
#include <OgreOverlayContainer.h>
|
||||||
|
|
||||||
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
#include <components/nifogre/ogre_nif_loader.hpp>
|
#include <components/nifogre/ogre_nif_loader.hpp>
|
||||||
|
|
||||||
|
#include <extern/shiny/Platforms/Ogre/OgreMaterial.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
|
|
||||||
|
@ -29,15 +33,51 @@ using namespace Ogre;
|
||||||
BillboardObject::BillboardObject( const String& textureName,
|
BillboardObject::BillboardObject( const String& textureName,
|
||||||
const float initialSize,
|
const float initialSize,
|
||||||
const Vector3& position,
|
const Vector3& position,
|
||||||
SceneNode* rootNode)
|
SceneNode* rootNode,
|
||||||
|
const std::string& material)
|
||||||
{
|
{
|
||||||
init(textureName, initialSize, position, rootNode);
|
SceneManager* sceneMgr = rootNode->getCreator();
|
||||||
|
|
||||||
|
Vector3 finalPosition = position.normalisedCopy() * 1000.f;
|
||||||
|
|
||||||
|
static unsigned int bodyCount=0;
|
||||||
|
|
||||||
|
/// \todo These billboards are not 100% correct, might want to revisit them later
|
||||||
|
mBBSet = sceneMgr->createBillboardSet("SkyBillboardSet"+StringConverter::toString(bodyCount), 1);
|
||||||
|
mBBSet->setDefaultDimensions(550.f*initialSize, 550.f*initialSize);
|
||||||
|
mBBSet->setBillboardType(BBT_PERPENDICULAR_COMMON);
|
||||||
|
mBBSet->setCommonDirection( -position.normalisedCopy() );
|
||||||
|
mBBSet->setVisibilityFlags(RV_Sky);
|
||||||
|
mNode = rootNode->createChildSceneNode();
|
||||||
|
mNode->setPosition(finalPosition);
|
||||||
|
mNode->attachObject(mBBSet);
|
||||||
|
mBBSet->createBillboard(0,0,0);
|
||||||
|
mBBSet->setCastShadows(false);
|
||||||
|
|
||||||
|
mMaterial = sh::Factory::getInstance().createMaterialInstance ("BillboardMaterial"+StringConverter::toString(bodyCount), material);
|
||||||
|
mMaterial->setProperty("texture", sh::makeProperty<sh::StringValue>(new sh::StringValue(textureName)));
|
||||||
|
|
||||||
|
sh::Factory::getInstance().getMaterialInstance ("BillboardMaterial"+StringConverter::toString(bodyCount))->setListener(this);
|
||||||
|
|
||||||
|
mBBSet->setMaterialName("BillboardMaterial"+StringConverter::toString(bodyCount));
|
||||||
|
|
||||||
|
bodyCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
BillboardObject::BillboardObject()
|
BillboardObject::BillboardObject()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BillboardObject::requestedConfiguration (sh::MaterialInstance* m, const std::string& configuration)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void BillboardObject::createdConfiguration (sh::MaterialInstance* m, const std::string& configuration)
|
||||||
|
{
|
||||||
|
setVisibility(mVisibility);
|
||||||
|
setColour(mColour);
|
||||||
|
}
|
||||||
|
|
||||||
void BillboardObject::setVisible(const bool visible)
|
void BillboardObject::setVisible(const bool visible)
|
||||||
{
|
{
|
||||||
mBBSet->setVisible(visible);
|
mBBSet->setVisible(visible);
|
||||||
|
@ -50,7 +90,14 @@ void BillboardObject::setSize(const float size)
|
||||||
|
|
||||||
void BillboardObject::setVisibility(const float visibility)
|
void BillboardObject::setVisibility(const float visibility)
|
||||||
{
|
{
|
||||||
mMaterial->getTechnique(0)->getPass(0)->setDiffuse(0.0, 0.0, 0.0, visibility);
|
mVisibility = visibility;
|
||||||
|
Ogre::MaterialPtr m = static_cast<sh::OgreMaterial*>(mMaterial->getMaterial ())->getOgreMaterial ();
|
||||||
|
for (int i=0; i<m->getNumTechniques(); ++i)
|
||||||
|
{
|
||||||
|
Ogre::Technique* t = m->getTechnique(i);
|
||||||
|
if (t->getNumPasses ())
|
||||||
|
t->getPass(0)->setDiffuse (0,0,0, visibility);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BillboardObject::setPosition(const Vector3& pPosition)
|
void BillboardObject::setPosition(const Vector3& pPosition)
|
||||||
|
@ -76,7 +123,14 @@ void BillboardObject::setVisibilityFlags(int flags)
|
||||||
|
|
||||||
void BillboardObject::setColour(const ColourValue& pColour)
|
void BillboardObject::setColour(const ColourValue& pColour)
|
||||||
{
|
{
|
||||||
mMaterial->getTechnique(0)->getPass(0)->setSelfIllumination(pColour);
|
mColour = pColour;
|
||||||
|
Ogre::MaterialPtr m = static_cast<sh::OgreMaterial*>(mMaterial->getMaterial ())->getOgreMaterial ();
|
||||||
|
for (int i=0; i<m->getNumTechniques(); ++i)
|
||||||
|
{
|
||||||
|
Ogre::Technique* t = m->getTechnique(i);
|
||||||
|
if (t->getNumPasses ())
|
||||||
|
t->getPass(0)->setSelfIllumination (pColour);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BillboardObject::setRenderQueue(unsigned int id)
|
void BillboardObject::setRenderQueue(unsigned int id)
|
||||||
|
@ -89,178 +143,13 @@ SceneNode* BillboardObject::getNode()
|
||||||
return mNode;
|
return mNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BillboardObject::init(const String& textureName,
|
|
||||||
const float initialSize,
|
|
||||||
const Vector3& position,
|
|
||||||
SceneNode* rootNode)
|
|
||||||
{
|
|
||||||
SceneManager* sceneMgr = rootNode->getCreator();
|
|
||||||
|
|
||||||
Vector3 finalPosition = position.normalisedCopy() * 1000.f;
|
|
||||||
|
|
||||||
static unsigned int bodyCount=0;
|
|
||||||
|
|
||||||
/// \todo These billboards are not 100% correct, might want to revisit them later
|
|
||||||
mBBSet = sceneMgr->createBillboardSet("SkyBillboardSet"+StringConverter::toString(bodyCount), 1);
|
|
||||||
mBBSet->setDefaultDimensions(550.f*initialSize, 550.f*initialSize);
|
|
||||||
mBBSet->setBillboardType(BBT_PERPENDICULAR_COMMON);
|
|
||||||
mBBSet->setCommonDirection( -position.normalisedCopy() );
|
|
||||||
mBBSet->setVisibilityFlags(RV_Sky);
|
|
||||||
mNode = rootNode->createChildSceneNode();
|
|
||||||
mNode->setPosition(finalPosition);
|
|
||||||
mNode->attachObject(mBBSet);
|
|
||||||
mBBSet->createBillboard(0,0,0);
|
|
||||||
mBBSet->setCastShadows(false);
|
|
||||||
|
|
||||||
mMaterial = MaterialManager::getSingleton().create("BillboardMaterial"+StringConverter::toString(bodyCount), ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
|
|
||||||
mMaterial->removeAllTechniques();
|
|
||||||
Pass* p = mMaterial->createTechnique()->createPass();
|
|
||||||
p->setSceneBlending(SBT_TRANSPARENT_ALPHA);
|
|
||||||
p->setDepthCheckEnabled(false);
|
|
||||||
p->setDepthWriteEnabled(false);
|
|
||||||
p->setSelfIllumination(1.0,1.0,1.0);
|
|
||||||
p->setDiffuse(0.0,0.0,0.0,1.0);
|
|
||||||
p->setAmbient(0.0,0.0,0.0);
|
|
||||||
p->setPolygonModeOverrideable(false);
|
|
||||||
p->createTextureUnitState(textureName);
|
|
||||||
mBBSet->setMaterialName("BillboardMaterial"+StringConverter::toString(bodyCount));
|
|
||||||
|
|
||||||
HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
|
|
||||||
HighLevelGpuProgramPtr vshader;
|
|
||||||
if (mgr.resourceExists("BBO_VP"))
|
|
||||||
vshader = mgr.getByName("BBO_VP");
|
|
||||||
else
|
|
||||||
vshader = mgr.createProgram("BBO_VP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, "cg", GPT_VERTEX_PROGRAM);
|
|
||||||
vshader->setParameter("profiles", "vs_2_x arbvp1");
|
|
||||||
vshader->setParameter("entry_point", "main_vp");
|
|
||||||
StringUtil::StrStreamType outStream;
|
|
||||||
outStream <<
|
|
||||||
"void main_vp( \n"
|
|
||||||
" float4 position : POSITION, \n"
|
|
||||||
" in float2 uv : TEXCOORD0, \n"
|
|
||||||
" out float2 oUV : TEXCOORD0, \n"
|
|
||||||
" out float4 oPosition : POSITION, \n"
|
|
||||||
" uniform float4x4 worldViewProj \n"
|
|
||||||
") \n"
|
|
||||||
"{ \n"
|
|
||||||
" oUV = uv; \n"
|
|
||||||
" oPosition = mul( worldViewProj, position ); \n"
|
|
||||||
"}";
|
|
||||||
vshader->setSource(outStream.str());
|
|
||||||
vshader->load();
|
|
||||||
vshader->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
|
|
||||||
mMaterial->getTechnique(0)->getPass(0)->setVertexProgram(vshader->getName());
|
|
||||||
|
|
||||||
HighLevelGpuProgramPtr fshader;
|
|
||||||
if (mgr.resourceExists("BBO_FP"))
|
|
||||||
fshader = mgr.getByName("BBO_FP");
|
|
||||||
else
|
|
||||||
fshader = mgr.createProgram("BBO_FP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, "cg", GPT_FRAGMENT_PROGRAM);
|
|
||||||
|
|
||||||
fshader->setParameter("profiles", "ps_2_x arbfp1");
|
|
||||||
fshader->setParameter("entry_point", "main_fp");
|
|
||||||
StringUtil::StrStreamType outStream2;
|
|
||||||
outStream2 <<
|
|
||||||
"void main_fp( \n"
|
|
||||||
" in float2 uv : TEXCOORD0, \n"
|
|
||||||
" out float4 oColor : COLOR, \n";
|
|
||||||
if (RenderingManager::useMRT()) outStream2 <<
|
|
||||||
" out float4 oColor1 : COLOR1, \n";
|
|
||||||
outStream2 <<
|
|
||||||
" uniform sampler2D texture : TEXUNIT0, \n"
|
|
||||||
" uniform float4 diffuse, \n"
|
|
||||||
" uniform float4 emissive \n"
|
|
||||||
") \n"
|
|
||||||
"{ \n"
|
|
||||||
" float4 tex = tex2D(texture, uv); \n"
|
|
||||||
" oColor = float4(emissive.xyz,1) * tex * float4(1,1,1,diffuse.a); \n";
|
|
||||||
if (RenderingManager::useMRT()) outStream2 <<
|
|
||||||
" oColor1 = float4(1, 0, 0, 1); \n";
|
|
||||||
outStream2 <<
|
|
||||||
"}";
|
|
||||||
fshader->setSource(outStream2.str());
|
|
||||||
fshader->load();
|
|
||||||
fshader->getDefaultParameters()->setNamedAutoConstant("diffuse", GpuProgramParameters::ACT_SURFACE_DIFFUSE_COLOUR);
|
|
||||||
fshader->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR);
|
|
||||||
mMaterial->getTechnique(0)->getPass(0)->setFragmentProgram(fshader->getName());
|
|
||||||
|
|
||||||
bodyCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
Moon::Moon( const String& textureName,
|
Moon::Moon( const String& textureName,
|
||||||
const float initialSize,
|
const float initialSize,
|
||||||
const Vector3& position,
|
const Vector3& position,
|
||||||
SceneNode* rootNode)
|
SceneNode* rootNode,
|
||||||
|
const std::string& material)
|
||||||
|
: BillboardObject(textureName, initialSize, position, rootNode, material)
|
||||||
{
|
{
|
||||||
init(textureName, initialSize, position, rootNode);
|
|
||||||
|
|
||||||
HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
|
|
||||||
HighLevelGpuProgramPtr vshader;
|
|
||||||
if (mgr.resourceExists("Moon_VP"))
|
|
||||||
vshader = mgr.getByName("Moon_VP");
|
|
||||||
else
|
|
||||||
vshader = mgr.createProgram("Moon_VP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, "cg", GPT_VERTEX_PROGRAM);
|
|
||||||
vshader->setParameter("profiles", "vs_2_x arbvp1");
|
|
||||||
vshader->setParameter("entry_point", "main_vp");
|
|
||||||
StringUtil::StrStreamType outStream;
|
|
||||||
outStream <<
|
|
||||||
"void main_vp( \n"
|
|
||||||
" float4 position : POSITION, \n"
|
|
||||||
" in float2 uv : TEXCOORD0, \n"
|
|
||||||
" out float2 oUV : TEXCOORD0, \n"
|
|
||||||
" out float4 oPosition : POSITION, \n"
|
|
||||||
" uniform float4x4 worldViewProj \n"
|
|
||||||
") \n"
|
|
||||||
"{ \n"
|
|
||||||
" oUV = uv; \n"
|
|
||||||
" oPosition = mul( worldViewProj, position ); \n"
|
|
||||||
"}";
|
|
||||||
vshader->setSource(outStream.str());
|
|
||||||
vshader->load();
|
|
||||||
vshader->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
|
|
||||||
mMaterial->getTechnique(0)->getPass(0)->setVertexProgram(vshader->getName());
|
|
||||||
|
|
||||||
HighLevelGpuProgramPtr fshader;
|
|
||||||
if (mgr.resourceExists("Moon_FP"))
|
|
||||||
fshader = mgr.getByName("Moon_FP");
|
|
||||||
else
|
|
||||||
fshader = mgr.createProgram("Moon_FP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, "cg", GPT_FRAGMENT_PROGRAM);
|
|
||||||
|
|
||||||
fshader->setParameter("profiles", "ps_2_x arbfp1");
|
|
||||||
fshader->setParameter("entry_point", "main_fp");
|
|
||||||
StringUtil::StrStreamType outStream2;
|
|
||||||
outStream2 <<
|
|
||||||
"void main_fp( \n"
|
|
||||||
" in float2 uv : TEXCOORD0, \n"
|
|
||||||
" out float4 oColor : COLOR, \n";
|
|
||||||
if (RenderingManager::useMRT()) outStream2 <<
|
|
||||||
" out float4 oColor1 : COLOR1, \n";
|
|
||||||
outStream2 <<
|
|
||||||
" uniform sampler2D texture : TEXUNIT0, \n"
|
|
||||||
" uniform float4 skyColour, \n"
|
|
||||||
" uniform float4 diffuse, \n"
|
|
||||||
" uniform float4 emissive \n"
|
|
||||||
") \n"
|
|
||||||
"{ \n"
|
|
||||||
" float4 tex = tex2D(texture, uv); \n"
|
|
||||||
" oColor = float4(emissive.xyz,1) * tex; \n";
|
|
||||||
if (RenderingManager::useMRT()) outStream2 <<
|
|
||||||
" oColor1 = float4(1, 0, 0, 1); \n";
|
|
||||||
outStream2 <<
|
|
||||||
// use a circle for the alpha (compute UV distance to center)
|
|
||||||
// looks a bit bad because its not filtered on the edges,
|
|
||||||
// but it's cheaper than a seperate alpha texture.
|
|
||||||
" float sqrUVdist = pow(uv.x-0.5,2) + pow(uv.y-0.5, 2); \n"
|
|
||||||
" oColor.a = diffuse.a * (sqrUVdist >= 0.24 ? 0 : 1); \n"
|
|
||||||
" oColor.rgb += (1-tex.a) * oColor.a * skyColour.rgb; \n"//fill dark side of moon with skycolour
|
|
||||||
" oColor.rgb += (1-diffuse.a) * skyColour.rgb; \n"//fade bump
|
|
||||||
"}";
|
|
||||||
fshader->setSource(outStream2.str());
|
|
||||||
fshader->load();
|
|
||||||
fshader->getDefaultParameters()->setNamedAutoConstant("diffuse", GpuProgramParameters::ACT_SURFACE_DIFFUSE_COLOUR);
|
|
||||||
fshader->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR);
|
|
||||||
mMaterial->getTechnique(0)->getPass(0)->setFragmentProgram(fshader->getName());
|
|
||||||
|
|
||||||
setVisibility(1.0);
|
setVisibility(1.0);
|
||||||
|
|
||||||
mPhase = Moon::Phase_Full;
|
mPhase = Moon::Phase_Full;
|
||||||
|
@ -271,11 +160,6 @@ void Moon::setType(const Moon::Type& type)
|
||||||
mType = type;
|
mType = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Moon::setSkyColour(const Ogre::ColourValue& colour)
|
|
||||||
{
|
|
||||||
mMaterial->getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstant("skyColour", colour);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Moon::setPhase(const Moon::Phase& phase)
|
void Moon::setPhase(const Moon::Phase& phase)
|
||||||
{
|
{
|
||||||
// Colour texture
|
// Colour texture
|
||||||
|
@ -295,7 +179,10 @@ void Moon::setPhase(const Moon::Phase& phase)
|
||||||
|
|
||||||
textureName += ".dds";
|
textureName += ".dds";
|
||||||
|
|
||||||
mMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName(textureName);
|
if (mType == Moon::Type_Secunda)
|
||||||
|
sh::Factory::getInstance ().setTextureAlias ("secunda_texture", textureName);
|
||||||
|
else
|
||||||
|
sh::Factory::getInstance ().setTextureAlias ("masser_texture", textureName);
|
||||||
|
|
||||||
mPhase = phase;
|
mPhase = phase;
|
||||||
}
|
}
|
||||||
|
@ -344,25 +231,12 @@ void SkyManager::ModVertexAlpha(Entity* ent, unsigned int meshType)
|
||||||
else if (i>= 33 && i <= 48) alpha = 64; // second bottom-most row
|
else if (i>= 33 && i <= 48) alpha = 64; // second bottom-most row
|
||||||
else alpha = 255;
|
else alpha = 255;
|
||||||
}
|
}
|
||||||
|
// NB we would have to swap R and B depending on rendersystem specific VertexElementType, but doesn't matter since they are both 1
|
||||||
uint8 tmpR = static_cast<uint8>(255);
|
uint8 tmpR = static_cast<uint8>(255);
|
||||||
uint8 tmpG = static_cast<uint8>(255);
|
uint8 tmpG = static_cast<uint8>(255);
|
||||||
uint8 tmpB = static_cast<uint8>(255);
|
uint8 tmpB = static_cast<uint8>(255);
|
||||||
uint8 tmpA = static_cast<uint8>(alpha);
|
uint8 tmpA = static_cast<uint8>(alpha);
|
||||||
|
|
||||||
// This does not matter since R and B are always 1.
|
|
||||||
/*VertexElementType format = Root::getSingleton().getRenderSystem()->getColourVertexElementType();
|
|
||||||
switch (format)
|
|
||||||
{
|
|
||||||
case VET_COLOUR_ARGB:
|
|
||||||
std::swap(tmpR, tmpB);
|
|
||||||
break;
|
|
||||||
case VET_COLOUR_ABGR:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// Modify
|
// Modify
|
||||||
*((uint32*)currentVertex) = tmpR | (tmpG << 8) | (tmpB << 16) | (tmpA << 24);
|
*((uint32*)currentVertex) = tmpR | (tmpG << 8) | (tmpB << 16) | (tmpA << 24);
|
||||||
|
|
||||||
|
@ -387,8 +261,6 @@ SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera)
|
||||||
, mSceneMgr(NULL)
|
, mSceneMgr(NULL)
|
||||||
, mAtmosphereDay(NULL)
|
, mAtmosphereDay(NULL)
|
||||||
, mAtmosphereNight(NULL)
|
, mAtmosphereNight(NULL)
|
||||||
, mCloudMaterial()
|
|
||||||
, mAtmosphereMaterial()
|
|
||||||
, mCloudFragmentShader()
|
, mCloudFragmentShader()
|
||||||
, mClouds()
|
, mClouds()
|
||||||
, mNextClouds()
|
, mNextClouds()
|
||||||
|
@ -396,8 +268,6 @@ SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera)
|
||||||
, mCloudOpacity(0.0f)
|
, mCloudOpacity(0.0f)
|
||||||
, mCloudSpeed(0.0f)
|
, mCloudSpeed(0.0f)
|
||||||
, mStarsOpacity(0.0f)
|
, mStarsOpacity(0.0f)
|
||||||
, mThunderOverlay(NULL)
|
|
||||||
, mThunderTextureUnit(NULL)
|
|
||||||
, mRemainingTransitionTime(0.0f)
|
, mRemainingTransitionTime(0.0f)
|
||||||
, mGlareFade(0.0f)
|
, mGlareFade(0.0f)
|
||||||
, mGlare(0.0f)
|
, mGlare(0.0f)
|
||||||
|
@ -406,6 +276,8 @@ SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera)
|
||||||
, mMasserEnabled(true)
|
, mMasserEnabled(true)
|
||||||
, mSecundaEnabled(true)
|
, mSecundaEnabled(true)
|
||||||
, mCreated(false)
|
, mCreated(false)
|
||||||
|
, mCloudAnimationTimer(0.f)
|
||||||
|
, mMoonRed(false)
|
||||||
{
|
{
|
||||||
mSceneMgr = pMwRoot->getCreator();
|
mSceneMgr = pMwRoot->getCreator();
|
||||||
mRootNode = mCamera->getParentSceneNode()->createChildSceneNode();
|
mRootNode = mCamera->getParentSceneNode()->createChildSceneNode();
|
||||||
|
@ -415,45 +287,42 @@ SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera)
|
||||||
|
|
||||||
void SkyManager::create()
|
void SkyManager::create()
|
||||||
{
|
{
|
||||||
/// \todo preload all the textures and meshes that are used for sky rendering
|
sh::Factory::getInstance().setSharedParameter ("cloudBlendFactor",
|
||||||
|
sh::makeProperty<sh::FloatValue>(new sh::FloatValue(0)));
|
||||||
|
sh::Factory::getInstance().setSharedParameter ("cloudOpacity",
|
||||||
|
sh::makeProperty<sh::FloatValue>(new sh::FloatValue(1)));
|
||||||
|
sh::Factory::getInstance().setSharedParameter ("cloudColour",
|
||||||
|
sh::makeProperty<sh::Vector3>(new sh::Vector3(1,1,1)));
|
||||||
|
sh::Factory::getInstance().setSharedParameter ("cloudAnimationTimer",
|
||||||
|
sh::makeProperty<sh::FloatValue>(new sh::FloatValue(0)));
|
||||||
|
sh::Factory::getInstance().setSharedParameter ("nightFade",
|
||||||
|
sh::makeProperty<sh::FloatValue>(new sh::FloatValue(0)));
|
||||||
|
|
||||||
|
sh::Factory::getInstance().setTextureAlias ("cloud_texture_1", "");
|
||||||
|
sh::Factory::getInstance().setTextureAlias ("cloud_texture_2", "");
|
||||||
|
|
||||||
// Create overlay used for thunderstorm
|
// Create overlay used for thunderstorm
|
||||||
MaterialPtr material = MaterialManager::getSingleton().create( "ThunderMaterial", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME );
|
mLightning = mSceneMgr->createLight();
|
||||||
Pass* pass = material->getTechnique(0)->getPass(0);
|
mLightning->setType (Ogre::Light::LT_DIRECTIONAL);
|
||||||
pass->setSceneBlending(SBT_TRANSPARENT_ALPHA);
|
mLightning->setDirection (Ogre::Vector3(0.3, -0.7, 0.3));
|
||||||
mThunderTextureUnit = pass->createTextureUnitState();
|
mLightning->setVisible (false);
|
||||||
mThunderTextureUnit->setColourOperationEx(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, ColourValue(1.f, 1.f, 1.f));
|
mLightning->setDiffuseColour (ColourValue(3,3,3));
|
||||||
mThunderTextureUnit->setAlphaOperation(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, 0.5f);
|
|
||||||
OverlayManager& ovm = OverlayManager::getSingleton();
|
|
||||||
mThunderOverlay = ovm.create( "ThunderOverlay" );
|
|
||||||
OverlayContainer* overlay_panel;
|
|
||||||
overlay_panel = (OverlayContainer*)ovm.createOverlayElement("Panel", "ThunderPanel");
|
|
||||||
overlay_panel->_setPosition(0, 0);
|
|
||||||
overlay_panel->_setDimensions(1, 1);
|
|
||||||
overlay_panel->setMaterialName( "ThunderMaterial" );
|
|
||||||
overlay_panel->show();
|
|
||||||
mThunderOverlay->add2D(overlay_panel);
|
|
||||||
mThunderOverlay->hide();
|
|
||||||
|
|
||||||
mSecunda = new Moon("textures\\tx_secunda_full.dds", 0.5, Vector3(-0.4, 0.4, 0.5), mRootNode);
|
mSecunda = new Moon("secunda_texture", 0.5, Vector3(-0.4, 0.4, 0.5), mRootNode, "openmw_moon");
|
||||||
mSecunda->setType(Moon::Type_Secunda);
|
mSecunda->setType(Moon::Type_Secunda);
|
||||||
mSecunda->setRenderQueue(RQG_SkiesEarly+4);
|
mSecunda->setRenderQueue(RQG_SkiesEarly+4);
|
||||||
|
|
||||||
mMasser = new Moon("textures\\tx_masser_full.dds", 0.75, Vector3(-0.4, 0.4, 0.5), mRootNode);
|
mMasser = new Moon("masser_texture", 0.75, Vector3(-0.4, 0.4, 0.5), mRootNode, "openmw_moon");
|
||||||
mMasser->setRenderQueue(RQG_SkiesEarly+3);
|
mMasser->setRenderQueue(RQG_SkiesEarly+3);
|
||||||
mMasser->setType(Moon::Type_Masser);
|
mMasser->setType(Moon::Type_Masser);
|
||||||
|
|
||||||
mSun = new BillboardObject("textures\\tx_sun_05.dds", 1, Vector3(0.4, 0.4, 0.4), mRootNode);
|
mSun = new BillboardObject("textures\\tx_sun_05.dds", 1, Vector3(0.4, 0.4, 0.4), mRootNode, "openmw_sun");
|
||||||
mSun->setRenderQueue(RQG_SkiesEarly+4);
|
mSun->setRenderQueue(RQG_SkiesEarly+4);
|
||||||
mSunGlare = new BillboardObject("textures\\tx_sun_flash_grey_05.dds", 3, Vector3(0.4, 0.4, 0.4), mRootNode);
|
mSunGlare = new BillboardObject("textures\\tx_sun_flash_grey_05.dds", 3, Vector3(0.4, 0.4, 0.4), mRootNode, "openmw_sun");
|
||||||
mSunGlare->setRenderQueue(RQG_SkiesLate);
|
mSunGlare->setRenderQueue(RQG_SkiesLate);
|
||||||
mSunGlare->setVisibilityFlags(RV_Glare);
|
mSunGlare->setVisibilityFlags(RV_NoReflection);
|
||||||
|
|
||||||
|
|
||||||
HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
|
|
||||||
|
|
||||||
// Stars
|
// Stars
|
||||||
/// \todo sky_night_02.nif (available in Bloodmoon)
|
|
||||||
MeshPtr mesh = NifOgre::NIFLoader::load("meshes\\sky_night_01.nif");
|
MeshPtr mesh = NifOgre::NIFLoader::load("meshes\\sky_night_01.nif");
|
||||||
Entity* night1_ent = mSceneMgr->createEntity("meshes\\sky_night_01.nif");
|
Entity* night1_ent = mSceneMgr->createEntity("meshes\\sky_night_01.nif");
|
||||||
night1_ent->setRenderQueueGroup(RQG_SkiesEarly+1);
|
night1_ent->setRenderQueueGroup(RQG_SkiesEarly+1);
|
||||||
|
@ -463,73 +332,17 @@ void SkyManager::create()
|
||||||
mAtmosphereNight = mRootNode->createChildSceneNode();
|
mAtmosphereNight = mRootNode->createChildSceneNode();
|
||||||
mAtmosphereNight->attachObject(night1_ent);
|
mAtmosphereNight->attachObject(night1_ent);
|
||||||
|
|
||||||
// Stars vertex shader
|
|
||||||
HighLevelGpuProgramPtr stars_vp = mgr.createProgram("Stars_VP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
|
|
||||||
"cg", GPT_VERTEX_PROGRAM);
|
|
||||||
stars_vp->setParameter("profiles", "vs_2_x arbvp1");
|
|
||||||
stars_vp->setParameter("entry_point", "main_vp");
|
|
||||||
StringUtil::StrStreamType outStream4;
|
|
||||||
outStream4 <<
|
|
||||||
"void main_vp( \n"
|
|
||||||
" float4 position : POSITION, \n"
|
|
||||||
" in float2 uv : TEXCOORD0, \n"
|
|
||||||
" out float2 oUV : TEXCOORD0, \n"
|
|
||||||
" out float oFade : TEXCOORD1, \n"
|
|
||||||
" out float4 oPosition : POSITION, \n"
|
|
||||||
" uniform float4x4 worldViewProj \n"
|
|
||||||
") \n"
|
|
||||||
"{ \n"
|
|
||||||
" oUV = uv; \n"
|
|
||||||
" oFade = (position.z > 50) ? 1.f : 0.f; \n"
|
|
||||||
" oPosition = mul( worldViewProj, position ); \n"
|
|
||||||
"}";
|
|
||||||
stars_vp->setSource(outStream4.str());
|
|
||||||
stars_vp->load();
|
|
||||||
stars_vp->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
|
|
||||||
|
|
||||||
// Stars fragment shader
|
|
||||||
HighLevelGpuProgramPtr stars_fp = mgr.createProgram("Stars_FP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
|
|
||||||
"cg", GPT_FRAGMENT_PROGRAM);
|
|
||||||
stars_fp->setParameter("profiles", "ps_2_x arbfp1");
|
|
||||||
stars_fp->setParameter("entry_point", "main_fp");
|
|
||||||
StringUtil::StrStreamType outStream5;
|
|
||||||
outStream5 <<
|
|
||||||
"void main_fp( \n"
|
|
||||||
" in float2 uv : TEXCOORD0, \n"
|
|
||||||
" out float4 oColor : COLOR, \n";
|
|
||||||
if (RenderingManager::useMRT()) outStream5 <<
|
|
||||||
" out float4 oColor1 : COLOR1, \n";
|
|
||||||
outStream5 <<
|
|
||||||
" in float fade : TEXCOORD1, \n"
|
|
||||||
" uniform sampler2D texture : TEXUNIT0, \n"
|
|
||||||
" uniform float opacity, \n"
|
|
||||||
" uniform float4 diffuse, \n"
|
|
||||||
" uniform float4 emissive \n"
|
|
||||||
") \n"
|
|
||||||
"{ \n"
|
|
||||||
" oColor = tex2D(texture, uv) * float4(emissive.xyz, 1) * float4(1,1,1,fade*diffuse.a); \n";
|
|
||||||
if (RenderingManager::useMRT()) outStream5 <<
|
|
||||||
" oColor1 = float4(1, 0, 0, 1); \n";
|
|
||||||
outStream5 <<
|
|
||||||
"}";
|
|
||||||
stars_fp->setSource(outStream5.str());
|
|
||||||
stars_fp->load();
|
|
||||||
stars_fp->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR);
|
|
||||||
stars_fp->getDefaultParameters()->setNamedAutoConstant("diffuse", GpuProgramParameters::ACT_SURFACE_DIFFUSE_COLOUR);
|
|
||||||
|
|
||||||
for (unsigned int i=0; i<night1_ent->getNumSubEntities(); ++i)
|
for (unsigned int i=0; i<night1_ent->getNumSubEntities(); ++i)
|
||||||
{
|
{
|
||||||
MaterialPtr mp = night1_ent->getSubEntity(i)->getMaterial();
|
std::string matName = "openmw_stars_" + boost::lexical_cast<std::string>(i);
|
||||||
mp->getTechnique(0)->getPass(0)->setSelfIllumination(1.0, 1.0, 1.0);
|
sh::MaterialInstance* m = sh::Factory::getInstance ().createMaterialInstance (matName, "openmw_stars");
|
||||||
mp->getTechnique(0)->getPass(0)->setAmbient(0.0, 0.0, 0.0);
|
|
||||||
mp->getTechnique(0)->getPass(0)->setDiffuse(0.0, 0.0, 0.0, 1.0);
|
std::string textureName = sh::retrieveValue<sh::StringValue>(
|
||||||
mp->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false);
|
sh::Factory::getInstance().getMaterialInstance(night1_ent->getSubEntity (i)->getMaterialName ())->getProperty("diffuseMap"), NULL).get();
|
||||||
mp->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false);
|
|
||||||
mp->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA);
|
m->setProperty ("texture", sh::makeProperty<sh::StringValue>(new sh::StringValue(textureName)));
|
||||||
mp->getTechnique(0)->getPass(0)->setVertexProgram(stars_vp->getName());
|
|
||||||
mp->getTechnique(0)->getPass(0)->setFragmentProgram(stars_fp->getName());
|
night1_ent->getSubEntity(i)->setMaterialName (matName);
|
||||||
mp->getTechnique(0)->getPass(0)->setPolygonModeOverrideable(false);
|
|
||||||
mStarsMaterials[i] = mp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Atmosphere (day)
|
// Atmosphere (day)
|
||||||
|
@ -543,62 +356,7 @@ void SkyManager::create()
|
||||||
atmosphere_ent->setVisibilityFlags(RV_Sky);
|
atmosphere_ent->setVisibilityFlags(RV_Sky);
|
||||||
mAtmosphereDay = mRootNode->createChildSceneNode();
|
mAtmosphereDay = mRootNode->createChildSceneNode();
|
||||||
mAtmosphereDay->attachObject(atmosphere_ent);
|
mAtmosphereDay->attachObject(atmosphere_ent);
|
||||||
mAtmosphereMaterial = atmosphere_ent->getSubEntity(0)->getMaterial();
|
atmosphere_ent->getSubEntity (0)->setMaterialName ("openmw_atmosphere");
|
||||||
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setPolygonModeOverrideable(false);
|
|
||||||
|
|
||||||
// Atmosphere shader
|
|
||||||
HighLevelGpuProgramPtr vshader = mgr.createProgram("Atmosphere_VP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
|
|
||||||
"cg", GPT_VERTEX_PROGRAM);
|
|
||||||
|
|
||||||
vshader->setParameter("profiles", "vs_2_x arbvp1");
|
|
||||||
vshader->setParameter("entry_point", "main_vp");
|
|
||||||
|
|
||||||
StringUtil::StrStreamType outStream;
|
|
||||||
outStream <<
|
|
||||||
"void main_vp( \n"
|
|
||||||
" float4 position : POSITION, \n"
|
|
||||||
" in float4 color : COLOR, \n"
|
|
||||||
" out float4 oPosition : POSITION, \n"
|
|
||||||
" out float4 oVertexColor : TEXCOORD0, \n"
|
|
||||||
" uniform float4x4 worldViewProj \n"
|
|
||||||
") \n"
|
|
||||||
"{ \n"
|
|
||||||
" oPosition = mul( worldViewProj, position ); \n"
|
|
||||||
" oVertexColor = color; \n"
|
|
||||||
"}";
|
|
||||||
vshader->setSource(outStream.str());
|
|
||||||
vshader->load();
|
|
||||||
|
|
||||||
vshader->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
|
|
||||||
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setVertexProgram(vshader->getName());
|
|
||||||
|
|
||||||
HighLevelGpuProgramPtr fshader = mgr.createProgram("Atmosphere_FP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
|
|
||||||
"cg", GPT_FRAGMENT_PROGRAM);
|
|
||||||
|
|
||||||
fshader->setParameter("profiles", "ps_2_x arbfp1");
|
|
||||||
fshader->setParameter("entry_point", "main_fp");
|
|
||||||
|
|
||||||
StringUtil::StrStreamType _outStream;
|
|
||||||
_outStream <<
|
|
||||||
"void main_fp( \n"
|
|
||||||
" in float4 iVertexColor : TEXCOORD0, \n"
|
|
||||||
" out float4 oColor : COLOR, \n";
|
|
||||||
if (RenderingManager::useMRT()) _outStream <<
|
|
||||||
" out float4 oColor1 : COLOR1, \n";
|
|
||||||
_outStream <<
|
|
||||||
" uniform float4 emissive \n"
|
|
||||||
") \n"
|
|
||||||
"{ \n"
|
|
||||||
" oColor = iVertexColor * emissive; \n";
|
|
||||||
if (RenderingManager::useMRT()) _outStream <<
|
|
||||||
" oColor1 = float4(1, 0, 0, 1); \n";
|
|
||||||
_outStream <<
|
|
||||||
"}";
|
|
||||||
fshader->setSource(_outStream.str());
|
|
||||||
fshader->load();
|
|
||||||
|
|
||||||
fshader->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR);
|
|
||||||
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setFragmentProgram(fshader->getName());
|
|
||||||
|
|
||||||
// Clouds
|
// Clouds
|
||||||
NifOgre::NIFLoader::load("meshes\\sky_clouds_01.nif");
|
NifOgre::NIFLoader::load("meshes\\sky_clouds_01.nif");
|
||||||
|
@ -607,94 +365,11 @@ void SkyManager::create()
|
||||||
clouds_ent->setRenderQueueGroup(RQG_SkiesEarly+5);
|
clouds_ent->setRenderQueueGroup(RQG_SkiesEarly+5);
|
||||||
SceneNode* clouds_node = mRootNode->createChildSceneNode();
|
SceneNode* clouds_node = mRootNode->createChildSceneNode();
|
||||||
clouds_node->attachObject(clouds_ent);
|
clouds_node->attachObject(clouds_ent);
|
||||||
mCloudMaterial = clouds_ent->getSubEntity(0)->getMaterial();
|
clouds_ent->getSubEntity(0)->setMaterialName ("openmw_clouds");
|
||||||
mCloudMaterial->getTechnique(0)->getPass(0)->setPolygonModeOverrideable(false);
|
|
||||||
clouds_ent->setCastShadows(false);
|
clouds_ent->setCastShadows(false);
|
||||||
|
|
||||||
// Clouds vertex shader
|
|
||||||
HighLevelGpuProgramPtr vshader2 = mgr.createProgram("Clouds_VP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
|
|
||||||
"cg", GPT_VERTEX_PROGRAM);
|
|
||||||
vshader2->setParameter("profiles", "vs_2_x arbvp1");
|
|
||||||
vshader2->setParameter("entry_point", "main_vp");
|
|
||||||
StringUtil::StrStreamType outStream3;
|
|
||||||
outStream3 <<
|
|
||||||
"void main_vp( \n"
|
|
||||||
" float4 position : POSITION, \n"
|
|
||||||
" in float4 color : COLOR, \n"
|
|
||||||
" out float4 oColor : TEXCOORD1, \n"
|
|
||||||
" in float2 uv : TEXCOORD0, \n"
|
|
||||||
" out float2 oUV : TEXCOORD0, \n"
|
|
||||||
" out float4 oPosition : POSITION, \n"
|
|
||||||
" uniform float4x4 worldViewProj \n"
|
|
||||||
") \n"
|
|
||||||
"{ \n"
|
|
||||||
" oUV = uv; \n"
|
|
||||||
" oColor = color; \n"
|
|
||||||
" oPosition = mul( worldViewProj, position ); \n"
|
|
||||||
"}";
|
|
||||||
vshader2->setSource(outStream3.str());
|
|
||||||
vshader2->load();
|
|
||||||
vshader2->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
|
|
||||||
mCloudMaterial->getTechnique(0)->getPass(0)->setVertexProgram(vshader2->getName());
|
|
||||||
|
|
||||||
// Clouds fragment shader
|
|
||||||
mCloudFragmentShader = mgr.createProgram("Clouds_FP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
|
|
||||||
"cg", GPT_FRAGMENT_PROGRAM);
|
|
||||||
mCloudFragmentShader->setParameter("profiles", "ps_2_x arbfp1");
|
|
||||||
mCloudFragmentShader->setParameter("entry_point", "main_fp");
|
|
||||||
StringUtil::StrStreamType outStream2;
|
|
||||||
outStream2 <<
|
|
||||||
"void main_fp( \n"
|
|
||||||
" in float2 uv : TEXCOORD0, \n"
|
|
||||||
" in float4 color : TEXCOORD1, \n"
|
|
||||||
" out float4 oColor : COLOR, \n";
|
|
||||||
if (RenderingManager::useMRT()) outStream2 <<
|
|
||||||
" out float4 oColor1 : COLOR1, \n";
|
|
||||||
outStream2 <<
|
|
||||||
" uniform sampler2D texture : TEXUNIT0, \n"
|
|
||||||
" uniform sampler2D secondTexture : TEXUNIT1, \n"
|
|
||||||
" uniform float transitionFactor, \n"
|
|
||||||
" uniform float time, \n"
|
|
||||||
" uniform float speed, \n"
|
|
||||||
" uniform float opacity, \n"
|
|
||||||
" uniform float4 emissive \n"
|
|
||||||
") \n"
|
|
||||||
"{ \n"
|
|
||||||
" uv += float2(0,1) * time * speed * 0.003; \n" // Scroll in y direction
|
|
||||||
" float4 tex = lerp(tex2D(texture, uv), tex2D(secondTexture, uv), transitionFactor); \n"
|
|
||||||
" oColor = color * float4(emissive.xyz,1) * tex * float4(1,1,1,opacity); \n";
|
|
||||||
if (RenderingManager::useMRT()) outStream2 <<
|
|
||||||
" oColor1 = float4(1, 0, 0, 1); \n";
|
|
||||||
outStream2 <<
|
|
||||||
"}";
|
|
||||||
mCloudFragmentShader->setSource(outStream2.str());
|
|
||||||
mCloudFragmentShader->load();
|
|
||||||
mCloudFragmentShader->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR);
|
|
||||||
mCloudMaterial->getTechnique(0)->getPass(0)->setFragmentProgram(mCloudFragmentShader->getName());
|
|
||||||
setCloudsOpacity(0.75);
|
|
||||||
|
|
||||||
ModVertexAlpha(clouds_ent, 1);
|
ModVertexAlpha(clouds_ent, 1);
|
||||||
|
|
||||||
// I'm not sure if the materials are being used by any other objects
|
|
||||||
// Make a unique "modifiable" copy of the materials to be sure
|
|
||||||
mCloudMaterial = mCloudMaterial->clone("Clouds");
|
|
||||||
clouds_ent->getSubEntity(0)->setMaterial(mCloudMaterial);
|
|
||||||
mAtmosphereMaterial = mAtmosphereMaterial->clone("Atmosphere");
|
|
||||||
atmosphere_ent->getSubEntity(0)->setMaterial(mAtmosphereMaterial);
|
|
||||||
|
|
||||||
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setSelfIllumination(1.0, 1.0, 1.0);
|
|
||||||
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setDiffuse(0.0, 0.0, 0.0, 0.0);
|
|
||||||
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setAmbient(0.0, 0.0, 0.0);
|
|
||||||
mCloudMaterial->getTechnique(0)->getPass(0)->setSelfIllumination(1.0, 1.0, 1.0);
|
|
||||||
mCloudMaterial->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false);
|
|
||||||
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false);
|
|
||||||
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA);
|
|
||||||
mCloudMaterial->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA);
|
|
||||||
|
|
||||||
mCloudMaterial->getTechnique(0)->getPass(0)->removeAllTextureUnitStates();
|
|
||||||
mCloudMaterial->getTechnique(0)->getPass(0)->createTextureUnitState("textures\\tx_sky_cloudy.dds");
|
|
||||||
mCloudMaterial->getTechnique(0)->getPass(0)->createTextureUnitState("");
|
|
||||||
|
|
||||||
mCreated = true;
|
mCreated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -723,24 +398,28 @@ void SkyManager::update(float duration)
|
||||||
if (!mEnabled) return;
|
if (!mEnabled) return;
|
||||||
|
|
||||||
// UV Scroll the clouds
|
// UV Scroll the clouds
|
||||||
mCloudMaterial->getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstantFromTime("time", MWBase::Environment::get().getWorld()->getTimeScaleFactor()/30.f);
|
mCloudAnimationTimer += duration * mCloudSpeed * (MWBase::Environment::get().getWorld()->getTimeScaleFactor()/30.f);
|
||||||
|
sh::Factory::getInstance().setSharedParameter ("cloudAnimationTimer",
|
||||||
|
sh::makeProperty<sh::FloatValue>(new sh::FloatValue(mCloudAnimationTimer)));
|
||||||
|
|
||||||
/// \todo improve this
|
/// \todo improve this
|
||||||
mMasser->setPhase( static_cast<Moon::Phase>( (int) ((mDay % 32)/4.f)) );
|
mMasser->setPhase( static_cast<Moon::Phase>( (int) ((mDay % 32)/4.f)) );
|
||||||
mSecunda->setPhase ( static_cast<Moon::Phase>( (int) ((mDay % 32)/4.f)) );
|
mSecunda->setPhase ( static_cast<Moon::Phase>( (int) ((mDay % 32)/4.f)) );
|
||||||
|
|
||||||
|
mSecunda->setColour ( mMoonRed ? ColourValue(1.0, 0.0784, 0.0784) : ColourValue(1,1,1,1));
|
||||||
|
mMasser->setColour (ColourValue(1,1,1,1));
|
||||||
|
|
||||||
if (mSunEnabled)
|
if (mSunEnabled)
|
||||||
{
|
{
|
||||||
// take 1/5 sec for fading the glare effect from invisible to full
|
// take 1/10 sec for fading the glare effect from invisible to full
|
||||||
if (mGlareFade > mGlare)
|
if (mGlareFade > mGlare)
|
||||||
{
|
{
|
||||||
mGlareFade -= duration*5;
|
mGlareFade -= duration*10;
|
||||||
if (mGlareFade < mGlare) mGlareFade = mGlare;
|
if (mGlareFade < mGlare) mGlareFade = mGlare;
|
||||||
}
|
}
|
||||||
else if (mGlareFade < mGlare)
|
else if (mGlareFade < mGlare)
|
||||||
{
|
{
|
||||||
mGlareFade += duration*5;
|
mGlareFade += duration*10;
|
||||||
if (mGlareFade > mGlare) mGlareFade = mGlare;
|
if (mGlareFade > mGlare) mGlareFade = mGlare;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -782,42 +461,37 @@ void SkyManager::disable()
|
||||||
|
|
||||||
void SkyManager::setMoonColour (bool red)
|
void SkyManager::setMoonColour (bool red)
|
||||||
{
|
{
|
||||||
if (!mCreated) return;
|
mMoonRed = red;
|
||||||
mSecunda->setColour( red ? ColourValue(1.0, 0.0784, 0.0784)
|
|
||||||
: ColourValue(1.0, 1.0, 1.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
void SkyManager::setCloudsOpacity(float opacity)
|
|
||||||
{
|
|
||||||
if (!mCreated) return;
|
|
||||||
mCloudMaterial->getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstant("opacity", Real(opacity));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkyManager::setWeather(const MWWorld::WeatherResult& weather)
|
void SkyManager::setWeather(const MWWorld::WeatherResult& weather)
|
||||||
{
|
{
|
||||||
if (!mCreated) return;
|
if (!mCreated) return;
|
||||||
|
|
||||||
if (mClouds != weather.mCloudTexture)
|
if (mClouds != weather.mCloudTexture)
|
||||||
{
|
{
|
||||||
mCloudMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName("textures\\"+weather.mCloudTexture);
|
sh::Factory::getInstance().setTextureAlias ("cloud_texture_1", "textures\\"+weather.mCloudTexture);
|
||||||
mClouds = weather.mCloudTexture;
|
mClouds = weather.mCloudTexture;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mNextClouds != weather.mNextCloudTexture)
|
if (mNextClouds != weather.mNextCloudTexture)
|
||||||
{
|
{
|
||||||
mCloudMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(1)->setTextureName("textures\\"+weather.mNextCloudTexture);
|
sh::Factory::getInstance().setTextureAlias ("cloud_texture_2", "textures\\"+weather.mNextCloudTexture);
|
||||||
mNextClouds = weather.mNextCloudTexture;
|
mNextClouds = weather.mNextCloudTexture;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mCloudBlendFactor != weather.mCloudBlendFactor)
|
if (mCloudBlendFactor != weather.mCloudBlendFactor)
|
||||||
{
|
{
|
||||||
mCloudMaterial->getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstant("transitionFactor", Real(weather.mCloudBlendFactor));
|
|
||||||
mCloudBlendFactor = weather.mCloudBlendFactor;
|
mCloudBlendFactor = weather.mCloudBlendFactor;
|
||||||
|
sh::Factory::getInstance().setSharedParameter ("cloudBlendFactor",
|
||||||
|
sh::makeProperty<sh::FloatValue>(new sh::FloatValue(weather.mCloudBlendFactor)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mCloudOpacity != weather.mCloudOpacity)
|
if (mCloudOpacity != weather.mCloudOpacity)
|
||||||
{
|
{
|
||||||
mCloudMaterial->getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstant("opacity", Real(weather.mCloudOpacity));
|
|
||||||
mCloudOpacity = weather.mCloudOpacity;
|
mCloudOpacity = weather.mCloudOpacity;
|
||||||
|
sh::Factory::getInstance().setSharedParameter ("cloudOpacity",
|
||||||
|
sh::makeProperty<sh::FloatValue>(new sh::FloatValue(weather.mCloudOpacity)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mCloudColour != weather.mSunColor)
|
if (mCloudColour != weather.mSunColor)
|
||||||
|
@ -826,23 +500,20 @@ void SkyManager::setWeather(const MWWorld::WeatherResult& weather)
|
||||||
weather.mSunColor.g*0.7 + weather.mAmbientColor.g*0.7,
|
weather.mSunColor.g*0.7 + weather.mAmbientColor.g*0.7,
|
||||||
weather.mSunColor.b*0.7 + weather.mAmbientColor.b*0.7);
|
weather.mSunColor.b*0.7 + weather.mAmbientColor.b*0.7);
|
||||||
|
|
||||||
mCloudMaterial->getTechnique(0)->getPass(0)->setSelfIllumination(clr);
|
sh::Factory::getInstance().setSharedParameter ("cloudColour",
|
||||||
|
sh::makeProperty<sh::Vector3>(new sh::Vector3(clr.r, clr.g, clr.b)));
|
||||||
|
|
||||||
mCloudColour = weather.mSunColor;
|
mCloudColour = weather.mSunColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mSkyColour != weather.mSkyColor)
|
if (mSkyColour != weather.mSkyColor)
|
||||||
{
|
{
|
||||||
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setSelfIllumination(weather.mSkyColor);
|
|
||||||
mMasser->setSkyColour(weather.mSkyColor);
|
|
||||||
mSecunda->setSkyColour(weather.mSkyColor);
|
|
||||||
mSkyColour = weather.mSkyColor;
|
mSkyColour = weather.mSkyColor;
|
||||||
|
sh::Factory::getInstance().setSharedParameter ("atmosphereColour", sh::makeProperty<sh::Vector4>(new sh::Vector4(
|
||||||
|
weather.mSkyColor.r, weather.mSkyColor.g, weather.mSkyColor.b, weather.mSkyColor.a)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mCloudSpeed != weather.mCloudSpeed)
|
mCloudSpeed = weather.mCloudSpeed;
|
||||||
{
|
|
||||||
mCloudMaterial->getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstant("speed", Real(weather.mCloudSpeed));
|
|
||||||
mCloudSpeed = weather.mCloudSpeed;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (weather.mNight && mStarsOpacity != weather.mNightFade)
|
if (weather.mNight && mStarsOpacity != weather.mNightFade)
|
||||||
{
|
{
|
||||||
|
@ -851,12 +522,15 @@ void SkyManager::setWeather(const MWWorld::WeatherResult& weather)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mAtmosphereNight->setVisible(true);
|
mAtmosphereNight->setVisible(true);
|
||||||
for (int i=0; i<7; ++i)
|
|
||||||
mStarsMaterials[i]->getTechnique(0)->getPass(0)->setDiffuse(0.0, 0.0, 0.0, weather.mNightFade);
|
sh::Factory::getInstance().setSharedParameter ("nightFade",
|
||||||
|
sh::makeProperty<sh::FloatValue>(new sh::FloatValue(weather.mNightFade)));
|
||||||
|
|
||||||
mStarsOpacity = weather.mNightFade;
|
mStarsOpacity = weather.mNightFade;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float strength;
|
float strength;
|
||||||
float timeofday_angle = std::abs(mSunGlare->getPosition().z/mSunGlare->getPosition().length());
|
float timeofday_angle = std::abs(mSunGlare->getPosition().z/mSunGlare->getPosition().length());
|
||||||
if (timeofday_angle <= 0.44)
|
if (timeofday_angle <= 0.44)
|
||||||
|
@ -897,6 +571,10 @@ void SkyManager::setSunDirection(const Vector3& direction)
|
||||||
if (!mCreated) return;
|
if (!mCreated) return;
|
||||||
mSun->setPosition(direction);
|
mSun->setPosition(direction);
|
||||||
mSunGlare->setPosition(direction);
|
mSunGlare->setPosition(direction);
|
||||||
|
|
||||||
|
float height = direction.z;
|
||||||
|
float fade = ( height > 0.5) ? 1.0 : height * 2;
|
||||||
|
sh::Factory::getInstance ().setSharedParameter ("waterSunFade_sunHeight", sh::makeProperty<sh::Vector2>(new sh::Vector2(fade, height)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkyManager::setMasserDirection(const Vector3& direction)
|
void SkyManager::setMasserDirection(const Vector3& direction)
|
||||||
|
@ -931,16 +609,22 @@ void SkyManager::secundaDisable()
|
||||||
mSecundaEnabled = false;
|
mSecundaEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkyManager::setThunder(const float factor)
|
void SkyManager::setLightningStrength(const float factor)
|
||||||
{
|
{
|
||||||
if (!mCreated) return;
|
if (!mCreated) return;
|
||||||
if (factor > 0.f)
|
if (factor > 0.f)
|
||||||
{
|
{
|
||||||
mThunderOverlay->show();
|
mLightning->setDiffuseColour (ColourValue(2*factor, 2*factor, 2*factor));
|
||||||
mThunderTextureUnit->setAlphaOperation(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, factor*0.6);
|
mLightning->setVisible(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
mThunderOverlay->hide();
|
mLightning->setVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkyManager::setLightningDirection(const Ogre::Vector3& dir)
|
||||||
|
{
|
||||||
|
if (!mCreated) return;
|
||||||
|
mLightning->setDirection (dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkyManager::setMasserFade(const float fade)
|
void SkyManager::setMasserFade(const float fade)
|
||||||
|
@ -986,3 +670,10 @@ void SkyManager::scaleSky(float scale)
|
||||||
{
|
{
|
||||||
mRootNode->setScale(scale, scale, scale);
|
mRootNode->setScale(scale, scale, scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SkyManager::setGlareEnabled (bool enabled)
|
||||||
|
{
|
||||||
|
if (!mCreated)
|
||||||
|
return;
|
||||||
|
mSunGlare->setVisible (mSunEnabled && enabled);
|
||||||
|
}
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
#include <OgreColourValue.h>
|
#include <OgreColourValue.h>
|
||||||
#include <OgreHighLevelGpuProgram.h>
|
#include <OgreHighLevelGpuProgram.h>
|
||||||
|
|
||||||
|
#include <extern/shiny/Main/Factory.hpp>
|
||||||
|
|
||||||
#include "sky.hpp"
|
#include "sky.hpp"
|
||||||
#include "../mwworld/weather.hpp"
|
#include "../mwworld/weather.hpp"
|
||||||
|
|
||||||
|
@ -25,16 +27,20 @@ namespace Ogre
|
||||||
|
|
||||||
namespace MWRender
|
namespace MWRender
|
||||||
{
|
{
|
||||||
class BillboardObject
|
class BillboardObject : public sh::MaterialInstanceListener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BillboardObject( const Ogre::String& textureName,
|
BillboardObject( const Ogre::String& textureName,
|
||||||
const float size,
|
const float size,
|
||||||
const Ogre::Vector3& position,
|
const Ogre::Vector3& position,
|
||||||
Ogre::SceneNode* rootNode
|
Ogre::SceneNode* rootNode,
|
||||||
|
const std::string& material
|
||||||
);
|
);
|
||||||
BillboardObject();
|
BillboardObject();
|
||||||
|
|
||||||
|
void requestedConfiguration (sh::MaterialInstance* m, const std::string& configuration);
|
||||||
|
void createdConfiguration (sh::MaterialInstance* m, const std::string& configuration);
|
||||||
|
|
||||||
virtual ~BillboardObject() {}
|
virtual ~BillboardObject() {}
|
||||||
|
|
||||||
void setColour(const Ogre::ColourValue& pColour);
|
void setColour(const Ogre::ColourValue& pColour);
|
||||||
|
@ -50,13 +56,10 @@ namespace MWRender
|
||||||
Ogre::SceneNode* getNode();
|
Ogre::SceneNode* getNode();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void init(const Ogre::String& textureName,
|
float mVisibility;
|
||||||
const float size,
|
Ogre::ColourValue mColour;
|
||||||
const Ogre::Vector3& position,
|
|
||||||
Ogre::SceneNode* rootNode);
|
|
||||||
|
|
||||||
Ogre::SceneNode* mNode;
|
Ogre::SceneNode* mNode;
|
||||||
Ogre::MaterialPtr mMaterial;
|
sh::MaterialInstance* mMaterial;
|
||||||
Ogre::BillboardSet* mBBSet;
|
Ogre::BillboardSet* mBBSet;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -70,7 +73,8 @@ namespace MWRender
|
||||||
Moon( const Ogre::String& textureName,
|
Moon( const Ogre::String& textureName,
|
||||||
const float size,
|
const float size,
|
||||||
const Ogre::Vector3& position,
|
const Ogre::Vector3& position,
|
||||||
Ogre::SceneNode* rootNode
|
Ogre::SceneNode* rootNode,
|
||||||
|
const std::string& material
|
||||||
);
|
);
|
||||||
|
|
||||||
virtual ~Moon() {}
|
virtual ~Moon() {}
|
||||||
|
@ -95,7 +99,6 @@ namespace MWRender
|
||||||
|
|
||||||
void setPhase(const Phase& phase);
|
void setPhase(const Phase& phase);
|
||||||
void setType(const Type& type);
|
void setType(const Type& type);
|
||||||
void setSkyColour(const Ogre::ColourValue& colour);
|
|
||||||
|
|
||||||
Phase getPhase() const;
|
Phase getPhase() const;
|
||||||
unsigned int getPhaseInt() const;
|
unsigned int getPhaseInt() const;
|
||||||
|
@ -137,9 +140,6 @@ namespace MWRender
|
||||||
void setMoonColour (bool red);
|
void setMoonColour (bool red);
|
||||||
///< change Secunda colour to red
|
///< change Secunda colour to red
|
||||||
|
|
||||||
void setCloudsOpacity(float opacity);
|
|
||||||
///< change opacity of the clouds
|
|
||||||
|
|
||||||
void setWeather(const MWWorld::WeatherResult& weather);
|
void setWeather(const MWWorld::WeatherResult& weather);
|
||||||
|
|
||||||
Ogre::SceneNode* getSunNode();
|
Ogre::SceneNode* getSunNode();
|
||||||
|
@ -164,9 +164,11 @@ namespace MWRender
|
||||||
void secundaEnable();
|
void secundaEnable();
|
||||||
void secundaDisable();
|
void secundaDisable();
|
||||||
|
|
||||||
void setThunder(const float factor);
|
void setLightningStrength(const float factor);
|
||||||
|
void setLightningDirection(const Ogre::Vector3& dir);
|
||||||
|
|
||||||
void setGlare(const float glare);
|
void setGlare(const float glare);
|
||||||
|
void setGlareEnabled(bool enabled);
|
||||||
Ogre::Vector3 getRealSunPos();
|
Ogre::Vector3 getRealSunPos();
|
||||||
|
|
||||||
void setSkyPosition(const Ogre::Vector3& position);
|
void setSkyPosition(const Ogre::Vector3& position);
|
||||||
|
@ -176,10 +178,14 @@ namespace MWRender
|
||||||
private:
|
private:
|
||||||
bool mCreated;
|
bool mCreated;
|
||||||
|
|
||||||
|
bool mMoonRed;
|
||||||
|
|
||||||
float mHour;
|
float mHour;
|
||||||
int mDay;
|
int mDay;
|
||||||
int mMonth;
|
int mMonth;
|
||||||
|
|
||||||
|
float mCloudAnimationTimer;
|
||||||
|
|
||||||
BillboardObject* mSun;
|
BillboardObject* mSun;
|
||||||
BillboardObject* mSunGlare;
|
BillboardObject* mSunGlare;
|
||||||
Moon* mMasser;
|
Moon* mMasser;
|
||||||
|
@ -192,11 +198,6 @@ namespace MWRender
|
||||||
Ogre::SceneNode* mAtmosphereDay;
|
Ogre::SceneNode* mAtmosphereDay;
|
||||||
Ogre::SceneNode* mAtmosphereNight;
|
Ogre::SceneNode* mAtmosphereNight;
|
||||||
|
|
||||||
Ogre::MaterialPtr mCloudMaterial;
|
|
||||||
Ogre::MaterialPtr mAtmosphereMaterial;
|
|
||||||
|
|
||||||
Ogre::MaterialPtr mStarsMaterials[7];
|
|
||||||
|
|
||||||
Ogre::HighLevelGpuProgramPtr mCloudFragmentShader;
|
Ogre::HighLevelGpuProgramPtr mCloudFragmentShader;
|
||||||
|
|
||||||
// remember some settings so we don't have to apply them again if they didnt change
|
// remember some settings so we don't have to apply them again if they didnt change
|
||||||
|
@ -209,8 +210,7 @@ namespace MWRender
|
||||||
Ogre::ColourValue mCloudColour;
|
Ogre::ColourValue mCloudColour;
|
||||||
Ogre::ColourValue mSkyColour;
|
Ogre::ColourValue mSkyColour;
|
||||||
|
|
||||||
Ogre::Overlay* mThunderOverlay;
|
Ogre::Light* mLightning;
|
||||||
Ogre::TextureUnitState* mThunderTextureUnit;
|
|
||||||
|
|
||||||
float mRemainingTransitionTime;
|
float mRemainingTransitionTime;
|
||||||
|
|
||||||
|
|
|
@ -28,22 +28,22 @@ namespace MWRender
|
||||||
mTerrainGroup(TerrainGroup(mgr, Terrain::ALIGN_X_Z, mLandSize, mWorldSize)), mRendering(rend)
|
mTerrainGroup(TerrainGroup(mgr, Terrain::ALIGN_X_Z, mLandSize, mWorldSize)), mRendering(rend)
|
||||||
{
|
{
|
||||||
mTerrainGlobals = OGRE_NEW TerrainGlobalOptions();
|
mTerrainGlobals = OGRE_NEW TerrainGlobalOptions();
|
||||||
|
|
||||||
TerrainMaterialGeneratorPtr matGen;
|
TerrainMaterialGeneratorPtr matGen;
|
||||||
TerrainMaterialGeneratorB* matGenP = new TerrainMaterialGeneratorB();
|
TerrainMaterial* matGenP = new TerrainMaterial();
|
||||||
matGen.bind(matGenP);
|
matGen.bind(matGenP);
|
||||||
mTerrainGlobals->setDefaultMaterialGenerator(matGen);
|
mTerrainGlobals->setDefaultMaterialGenerator(matGen);
|
||||||
|
|
||||||
TerrainMaterialGenerator::Profile* const activeProfile =
|
TerrainMaterialGenerator::Profile* const activeProfile =
|
||||||
mTerrainGlobals->getDefaultMaterialGenerator()
|
mTerrainGlobals->getDefaultMaterialGenerator()
|
||||||
->getActiveProfile();
|
->getActiveProfile();
|
||||||
mActiveProfile = static_cast<TerrainMaterialGeneratorB::SM2Profile*>(activeProfile);
|
mActiveProfile = static_cast<TerrainMaterial::Profile*>(activeProfile);
|
||||||
|
|
||||||
//The pixel error should be as high as possible without it being noticed
|
//The pixel error should be as high as possible without it being noticed
|
||||||
//as it governs how fast mesh quality decreases.
|
//as it governs how fast mesh quality decreases.
|
||||||
mTerrainGlobals->setMaxPixelError(8);
|
mTerrainGlobals->setMaxPixelError(8);
|
||||||
|
|
||||||
mTerrainGlobals->setLayerBlendMapSize(32);
|
mTerrainGlobals->setLayerBlendMapSize(32);
|
||||||
mTerrainGlobals->setDefaultGlobalColourMapSize(65);
|
|
||||||
|
|
||||||
//10 (default) didn't seem to be quite enough
|
//10 (default) didn't seem to be quite enough
|
||||||
mTerrainGlobals->setSkirtSize(128);
|
mTerrainGlobals->setSkirtSize(128);
|
||||||
|
@ -52,26 +52,6 @@ namespace MWRender
|
||||||
//this seemed the distance where it wasn't too noticeable
|
//this seemed the distance where it wasn't too noticeable
|
||||||
mTerrainGlobals->setCompositeMapDistance(mWorldSize*2);
|
mTerrainGlobals->setCompositeMapDistance(mWorldSize*2);
|
||||||
|
|
||||||
mActiveProfile->setLightmapEnabled(false);
|
|
||||||
mActiveProfile->setLayerSpecularMappingEnabled(false);
|
|
||||||
mActiveProfile->setLayerNormalMappingEnabled(false);
|
|
||||||
mActiveProfile->setLayerParallaxMappingEnabled(false);
|
|
||||||
|
|
||||||
bool shadows = Settings::Manager::getBool("enabled", "Shadows");
|
|
||||||
mActiveProfile->setReceiveDynamicShadowsEnabled(shadows);
|
|
||||||
mActiveProfile->setReceiveDynamicShadowsDepth(shadows);
|
|
||||||
if (Settings::Manager::getBool("split", "Shadows"))
|
|
||||||
mActiveProfile->setReceiveDynamicShadowsPSSM(mRendering->getShadows()->getPSSMSetup());
|
|
||||||
else
|
|
||||||
mActiveProfile->setReceiveDynamicShadowsPSSM(0);
|
|
||||||
|
|
||||||
mActiveProfile->setShadowFar(mRendering->getShadows()->getShadowFar());
|
|
||||||
mActiveProfile->setShadowFadeStart(mRendering->getShadows()->getFadeStart());
|
|
||||||
|
|
||||||
//composite maps lead to a drastic increase in loading time so are
|
|
||||||
//disabled
|
|
||||||
mActiveProfile->setCompositeMapEnabled(false);
|
|
||||||
|
|
||||||
mTerrainGroup.setOrigin(Vector3(mWorldSize/2,
|
mTerrainGroup.setOrigin(Vector3(mWorldSize/2,
|
||||||
0,
|
0,
|
||||||
-mWorldSize/2));
|
-mWorldSize/2));
|
||||||
|
@ -178,23 +158,20 @@ namespace MWRender
|
||||||
terrain->setVisibilityFlags(RV_Terrain);
|
terrain->setVisibilityFlags(RV_Terrain);
|
||||||
terrain->setRenderQueueGroup(RQG_Main);
|
terrain->setRenderQueueGroup(RQG_Main);
|
||||||
|
|
||||||
|
// disable or enable global colour map (depends on available vertex colours)
|
||||||
if ( land->landData->usingColours )
|
if ( land->landData->usingColours )
|
||||||
{
|
{
|
||||||
// disable or enable global colour map (depends on available vertex colours)
|
|
||||||
mActiveProfile->setGlobalColourMapEnabled(true);
|
|
||||||
TexturePtr vertex = getVertexColours(land,
|
TexturePtr vertex = getVertexColours(land,
|
||||||
cellX, cellY,
|
cellX, cellY,
|
||||||
x*(mLandSize-1),
|
x*(mLandSize-1),
|
||||||
y*(mLandSize-1),
|
y*(mLandSize-1),
|
||||||
mLandSize);
|
mLandSize);
|
||||||
|
|
||||||
//this is a hack to get around the fact that Ogre seems to
|
mActiveProfile->setGlobalColourMapEnabled(true);
|
||||||
//corrupt the global colour map leading to rendering errors
|
mActiveProfile->setGlobalColourMap (terrain, vertex->getName());
|
||||||
MaterialPtr mat = terrain->getMaterial();
|
|
||||||
mat->getTechnique(0)->getPass(0)->getTextureUnitState(1)->setTextureName( vertex->getName() );
|
|
||||||
//mat = terrain->_getCompositeMapMaterial();
|
|
||||||
//mat->getTechnique(0)->getPass(0)->getTextureUnitState(1)->setTextureName( vertex->getName() );
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
mActiveProfile->setGlobalColourMapEnabled (false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ namespace MWRender{
|
||||||
|
|
||||||
RenderingManager* mRendering;
|
RenderingManager* mRendering;
|
||||||
|
|
||||||
Ogre::TerrainMaterialGeneratorB::SM2Profile* mActiveProfile;
|
TerrainMaterial::Profile* mActiveProfile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The length in verticies of a single terrain block.
|
* The length in verticies of a single terrain block.
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -26,246 +26,59 @@ THE SOFTWARE.
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __Ogre_TerrainMaterialGeneratorB_H__
|
#ifndef MWRENDER_TERRAINMATERIAL_H
|
||||||
#define __Ogre_TerrainMaterialGeneratorB_H__
|
#define MWRENDER_TERRAINMATERIAL_H
|
||||||
|
|
||||||
#include "OgreTerrainPrerequisites.h"
|
#include "OgreTerrainPrerequisites.h"
|
||||||
#include "OgreTerrainMaterialGenerator.h"
|
#include "OgreTerrainMaterialGenerator.h"
|
||||||
#include "OgreGpuProgramParams.h"
|
#include "OgreGpuProgramParams.h"
|
||||||
|
|
||||||
namespace Ogre
|
namespace sh
|
||||||
{
|
{
|
||||||
class PSSMShadowCameraSetup;
|
class MaterialInstance;
|
||||||
|
}
|
||||||
|
|
||||||
/** \addtogroup Optional Components
|
namespace MWRender
|
||||||
* @{
|
{
|
||||||
*/
|
|
||||||
/** \addtogroup Terrain
|
|
||||||
* Some details on the terrain component
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
class TerrainMaterial : public Ogre::TerrainMaterialGenerator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
/** A TerrainMaterialGenerator which can cope with normal mapped, specular mapped
|
class Profile : public Ogre::TerrainMaterialGenerator::Profile
|
||||||
terrain.
|
{
|
||||||
@note Requires the Cg plugin to render correctly
|
public:
|
||||||
*/
|
Profile(Ogre::TerrainMaterialGenerator* parent, const Ogre::String& name, const Ogre::String& desc);
|
||||||
class TerrainMaterialGeneratorB : public TerrainMaterialGenerator
|
virtual ~Profile();
|
||||||
{
|
|
||||||
public:
|
|
||||||
TerrainMaterialGeneratorB();
|
|
||||||
~TerrainMaterialGeneratorB();
|
|
||||||
|
|
||||||
/** Shader model 2 profile target.
|
virtual bool isVertexCompressionSupported() const { return false; }
|
||||||
*/
|
|
||||||
class SM2Profile : public TerrainMaterialGenerator::Profile
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SM2Profile(TerrainMaterialGenerator* parent, const String& name, const String& desc);
|
|
||||||
~SM2Profile();
|
|
||||||
|
|
||||||
bool isVertexCompressionSupported() const {return false;}
|
virtual Ogre::MaterialPtr generate(const Ogre::Terrain* terrain);
|
||||||
|
|
||||||
MaterialPtr generate(const Terrain* terrain);
|
|
||||||
MaterialPtr generateForCompositeMap(const Terrain* terrain);
|
|
||||||
uint8 getMaxLayers(const Terrain* terrain) const;
|
|
||||||
void updateParams(const MaterialPtr& mat, const Terrain* terrain);
|
|
||||||
void updateParamsForCompositeMap(const MaterialPtr& mat, const Terrain* terrain);
|
|
||||||
void requestOptions(Terrain* terrain);
|
|
||||||
|
|
||||||
void setShadowFar(float far);
|
virtual Ogre::MaterialPtr generateForCompositeMap(const Ogre::Terrain* terrain);
|
||||||
void setShadowFadeStart(float fadestart);
|
|
||||||
|
|
||||||
/** Whether to support normal mapping per layer in the shader (default true).
|
virtual Ogre::uint8 getMaxLayers(const Ogre::Terrain* terrain) const;
|
||||||
*/
|
|
||||||
bool isLayerNormalMappingEnabled() const { return mLayerNormalMappingEnabled; }
|
|
||||||
/** Whether to support normal mapping per layer in the shader (default true).
|
|
||||||
*/
|
|
||||||
void setLayerNormalMappingEnabled(bool enabled);
|
|
||||||
/** Whether to support parallax mapping per layer in the shader (default true).
|
|
||||||
*/
|
|
||||||
bool isLayerParallaxMappingEnabled() const { return mLayerParallaxMappingEnabled; }
|
|
||||||
/** Whether to support parallax mapping per layer in the shader (default true).
|
|
||||||
*/
|
|
||||||
void setLayerParallaxMappingEnabled(bool enabled);
|
|
||||||
/** Whether to support specular mapping per layer in the shader (default true).
|
|
||||||
*/
|
|
||||||
bool isLayerSpecularMappingEnabled() const { return mLayerSpecularMappingEnabled; }
|
|
||||||
/** Whether to support specular mapping per layer in the shader (default true).
|
|
||||||
*/
|
|
||||||
void setLayerSpecularMappingEnabled(bool enabled);
|
|
||||||
/** Whether to support a global colour map over the terrain in the shader,
|
|
||||||
if it's present (default true).
|
|
||||||
*/
|
|
||||||
bool isGlobalColourMapEnabled() const { return mGlobalColourMapEnabled; }
|
|
||||||
/** Whether to support a global colour map over the terrain in the shader,
|
|
||||||
if it's present (default true).
|
|
||||||
*/
|
|
||||||
void setGlobalColourMapEnabled(bool enabled);
|
|
||||||
/** Whether to support a light map over the terrain in the shader,
|
|
||||||
if it's present (default true).
|
|
||||||
*/
|
|
||||||
bool isLightmapEnabled() const { return mLightmapEnabled; }
|
|
||||||
/** Whether to support a light map over the terrain in the shader,
|
|
||||||
if it's present (default true).
|
|
||||||
*/
|
|
||||||
void setLightmapEnabled(bool enabled);
|
|
||||||
/** Whether to use the composite map to provide a lower LOD technique
|
|
||||||
in the distance (default true).
|
|
||||||
*/
|
|
||||||
bool isCompositeMapEnabled() const { return mCompositeMapEnabled; }
|
|
||||||
/** Whether to use the composite map to provide a lower LOD technique
|
|
||||||
in the distance (default true).
|
|
||||||
*/
|
|
||||||
void setCompositeMapEnabled(bool enabled);
|
|
||||||
/** Whether to support dynamic texture shadows received from other
|
|
||||||
objects, on the terrain (default true).
|
|
||||||
*/
|
|
||||||
bool getReceiveDynamicShadowsEnabled() const { return mReceiveDynamicShadows; }
|
|
||||||
/** Whether to support dynamic texture shadows received from other
|
|
||||||
objects, on the terrain (default true).
|
|
||||||
*/
|
|
||||||
void setReceiveDynamicShadowsEnabled(bool enabled);
|
|
||||||
|
|
||||||
/** Whether to use PSSM support dynamic texture shadows, and if so the
|
virtual void updateParams(const Ogre::MaterialPtr& mat, const Ogre::Terrain* terrain);
|
||||||
settings to use (default 0).
|
|
||||||
*/
|
|
||||||
void setReceiveDynamicShadowsPSSM(PSSMShadowCameraSetup* pssmSettings);
|
|
||||||
/** Whether to use PSSM support dynamic texture shadows, and if so the
|
|
||||||
settings to use (default 0).
|
|
||||||
*/
|
|
||||||
PSSMShadowCameraSetup* getReceiveDynamicShadowsPSSM() const { return mPSSM; }
|
|
||||||
/** Whether to use depth shadows (default false).
|
|
||||||
*/
|
|
||||||
void setReceiveDynamicShadowsDepth(bool enabled);
|
|
||||||
/** Whether to use depth shadows (default false).
|
|
||||||
*/
|
|
||||||
bool getReceiveDynamicShadowsDepth() const { return mDepthShadows; }
|
|
||||||
/** Whether to use shadows on low LOD material rendering (when using composite map) (default false).
|
|
||||||
*/
|
|
||||||
void setReceiveDynamicShadowsLowLod(bool enabled);
|
|
||||||
/** Whether to use shadows on low LOD material rendering (when using composite map) (default false).
|
|
||||||
*/
|
|
||||||
bool getReceiveDynamicShadowsLowLod() const { return mLowLodShadows; }
|
|
||||||
|
|
||||||
int getNumberOfLightsSupported() const;
|
virtual void updateParamsForCompositeMap(const Ogre::MaterialPtr& mat, const Ogre::Terrain* terrain);
|
||||||
|
|
||||||
/// Internal
|
virtual void requestOptions(Ogre::Terrain* terrain);
|
||||||
bool _isSM3Available() const { return mSM3Available; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
enum TechniqueType
|
void setGlobalColourMapEnabled(bool enabled);
|
||||||
{
|
void setGlobalColourMap (Ogre::Terrain* terrain, const std::string& name);
|
||||||
HIGH_LOD,
|
|
||||||
LOW_LOD,
|
|
||||||
RENDER_COMPOSITE_MAP
|
|
||||||
};
|
|
||||||
void addTechnique(const MaterialPtr& mat, const Terrain* terrain, TechniqueType tt);
|
|
||||||
|
|
||||||
/// Interface definition for helper class to generate shaders
|
private:
|
||||||
class ShaderHelper : public TerrainAlloc
|
sh::MaterialInstance* mMaterial;
|
||||||
{
|
|
||||||
public:
|
|
||||||
ShaderHelper() : mShadowSamplerStartHi(0), mShadowSamplerStartLo(0) {}
|
|
||||||
virtual ~ShaderHelper() {}
|
|
||||||
virtual HighLevelGpuProgramPtr generateVertexProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt);
|
|
||||||
virtual HighLevelGpuProgramPtr generateFragmentProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt);
|
|
||||||
virtual void updateParams(const SM2Profile* prof, const MaterialPtr& mat, const Terrain* terrain, bool compositeMap);
|
|
||||||
protected:
|
|
||||||
virtual String getVertexProgramName(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt);
|
|
||||||
virtual String getFragmentProgramName(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt);
|
|
||||||
virtual HighLevelGpuProgramPtr createVertexProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt) = 0;
|
|
||||||
virtual HighLevelGpuProgramPtr createFragmentProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt) = 0;
|
|
||||||
virtual void generateVertexProgramSource(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringUtil::StrStreamType& outStream);
|
|
||||||
virtual void generateFragmentProgramSource(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringUtil::StrStreamType& outStream);
|
|
||||||
virtual void generateVpHeader(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringUtil::StrStreamType& outStream) = 0;
|
|
||||||
virtual void generateFpHeader(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringUtil::StrStreamType& outStream) = 0;
|
|
||||||
virtual void generateVpLayer(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, uint layer, StringUtil::StrStreamType& outStream) = 0;
|
|
||||||
virtual void generateFpLayer(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, uint layer, StringUtil::StrStreamType& outStream) = 0;
|
|
||||||
virtual void generateVpFooter(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringUtil::StrStreamType& outStream) = 0;
|
|
||||||
virtual void generateFpFooter(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringUtil::StrStreamType& outStream) = 0;
|
|
||||||
virtual void defaultVpParams(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, const HighLevelGpuProgramPtr& prog);
|
|
||||||
virtual void defaultFpParams(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, const HighLevelGpuProgramPtr& prog);
|
|
||||||
virtual void updateVpParams(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, const GpuProgramParametersSharedPtr& params);
|
|
||||||
virtual void updateFpParams(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, const GpuProgramParametersSharedPtr& params);
|
|
||||||
static String getChannel(uint idx);
|
|
||||||
|
|
||||||
size_t mShadowSamplerStartHi;
|
bool mGlobalColourMap;
|
||||||
size_t mShadowSamplerStartLo;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Utility class to help with generating shaders for Cg / HLSL.
|
|
||||||
class ShaderHelperCg : public ShaderHelper
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
HighLevelGpuProgramPtr createVertexProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt);
|
|
||||||
HighLevelGpuProgramPtr createFragmentProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt);
|
|
||||||
void generateVpHeader(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringUtil::StrStreamType& outStream);
|
|
||||||
void generateFpHeader(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringUtil::StrStreamType& outStream);
|
|
||||||
void generateVpLayer(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, uint layer, StringUtil::StrStreamType& outStream);
|
|
||||||
void generateFpLayer(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, uint layer, StringUtil::StrStreamType& outStream);
|
|
||||||
void generateVpFooter(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringUtil::StrStreamType& outStream);
|
|
||||||
void generateFpFooter(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringUtil::StrStreamType& outStream);
|
|
||||||
uint generateVpDynamicShadowsParams(uint texCoordStart, const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringUtil::StrStreamType& outStream);
|
|
||||||
void generateVpDynamicShadows(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringUtil::StrStreamType& outStream);
|
|
||||||
void generateFpDynamicShadowsHelpers(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringUtil::StrStreamType& outStream);
|
|
||||||
void generateFpDynamicShadowsParams(uint* texCoord, uint* sampler, const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringUtil::StrStreamType& outStream);
|
|
||||||
void generateFpDynamicShadows(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringUtil::StrStreamType& outStream);
|
|
||||||
};
|
|
||||||
|
|
||||||
class ShaderHelperHLSL : public ShaderHelperCg
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
HighLevelGpuProgramPtr createVertexProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt);
|
|
||||||
HighLevelGpuProgramPtr createFragmentProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt);
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Utility class to help with generating shaders for GLSL.
|
|
||||||
class ShaderHelperGLSL : public ShaderHelper
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
HighLevelGpuProgramPtr createVertexProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt);
|
|
||||||
HighLevelGpuProgramPtr createFragmentProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt);
|
|
||||||
void generateVpHeader(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringUtil::StrStreamType& outStream) {}
|
|
||||||
void generateFpHeader(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringUtil::StrStreamType& outStream) {}
|
|
||||||
void generateVpLayer(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, uint layer, StringUtil::StrStreamType& outStream) {}
|
|
||||||
void generateFpLayer(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, uint layer, StringUtil::StrStreamType& outStream) {}
|
|
||||||
void generateVpFooter(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringUtil::StrStreamType& outStream) {}
|
|
||||||
void generateFpFooter(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringUtil::StrStreamType& outStream) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
ShaderHelper* mShaderGen;
|
|
||||||
bool mLayerNormalMappingEnabled;
|
|
||||||
bool mLayerParallaxMappingEnabled;
|
|
||||||
bool mLayerSpecularMappingEnabled;
|
|
||||||
bool mGlobalColourMapEnabled;
|
|
||||||
bool mLightmapEnabled;
|
|
||||||
bool mCompositeMapEnabled;
|
|
||||||
bool mReceiveDynamicShadows;
|
|
||||||
PSSMShadowCameraSetup* mPSSM;
|
|
||||||
bool mDepthShadows;
|
|
||||||
bool mLowLodShadows;
|
|
||||||
bool mSM3Available;
|
|
||||||
float mShadowFar;
|
|
||||||
float mShadowFadeStart;
|
|
||||||
|
|
||||||
bool isShadowingEnabled(TechniqueType tt, const Terrain* terrain) const;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
|
TerrainMaterial();
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -8,11 +8,20 @@
|
||||||
#include <OgreCompositorInstance.h>
|
#include <OgreCompositorInstance.h>
|
||||||
#include <OgreCompositorChain.h>
|
#include <OgreCompositorChain.h>
|
||||||
#include <OgreRoot.h>
|
#include <OgreRoot.h>
|
||||||
|
#include <OgreOverlayManager.h>
|
||||||
|
#include <OgreOverlayContainer.h>
|
||||||
|
#include <OgreOverlayElement.h>
|
||||||
|
|
||||||
#include "sky.hpp"
|
#include "sky.hpp"
|
||||||
#include "renderingmanager.hpp"
|
#include "renderingmanager.hpp"
|
||||||
#include "compositors.hpp"
|
#include "compositors.hpp"
|
||||||
|
|
||||||
|
#include <extern/shiny/Main/Factory.hpp>
|
||||||
|
#include <extern/shiny/Platforms/Ogre/OgreMaterial.hpp>
|
||||||
|
|
||||||
|
#include "../mwbase/environment.hpp"
|
||||||
|
#include "../mwbase/world.hpp"
|
||||||
|
|
||||||
using namespace Ogre;
|
using namespace Ogre;
|
||||||
|
|
||||||
namespace MWRender
|
namespace MWRender
|
||||||
|
@ -22,10 +31,18 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel
|
||||||
mCamera (camera), mSceneManager (camera->getSceneManager()),
|
mCamera (camera), mSceneManager (camera->getSceneManager()),
|
||||||
mIsUnderwater(false), mVisibilityFlags(0),
|
mIsUnderwater(false), mVisibilityFlags(0),
|
||||||
mReflectionTarget(0), mActive(1), mToggled(1),
|
mReflectionTarget(0), mActive(1), mToggled(1),
|
||||||
mReflectionRenderActive(false), mRendering(rend)
|
mReflectionRenderActive(false), mRendering(rend),
|
||||||
|
mOldFarClip(0), mOldFarClip2(0),
|
||||||
|
mWaterTimer(0.f)
|
||||||
{
|
{
|
||||||
mSky = rend->getSkyManager();
|
mSky = rend->getSkyManager();
|
||||||
|
|
||||||
|
sh::Factory::getInstance ().setSharedParameter ("windDir_windSpeed", sh::makeProperty<sh::Vector3>(new sh::Vector3(0.5, -0.8, 0.2)));
|
||||||
|
sh::Factory::getInstance ().setSharedParameter ("waterTimer", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(0)));
|
||||||
|
sh::Factory::getInstance ().setSharedParameter ("waterSunFade_sunHeight", sh::makeProperty<sh::Vector2>(new sh::Vector2(1, 0.6)));
|
||||||
|
|
||||||
|
mMaterial = MaterialManager::getSingleton().getByName("Water");
|
||||||
|
|
||||||
mTop = cell->water;
|
mTop = cell->water;
|
||||||
|
|
||||||
mIsUnderwater = false;
|
mIsUnderwater = false;
|
||||||
|
@ -40,7 +57,6 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel
|
||||||
mWater->setCastShadows(false);
|
mWater->setCastShadows(false);
|
||||||
|
|
||||||
mWaterNode = mSceneManager->getRootSceneNode()->createChildSceneNode();
|
mWaterNode = mSceneManager->getRootSceneNode()->createChildSceneNode();
|
||||||
mWaterNode->setPosition(0, mTop, 0);
|
|
||||||
|
|
||||||
mReflectionCamera = mSceneManager->createCamera("ReflectionCamera");
|
mReflectionCamera = mSceneManager->createCamera("ReflectionCamera");
|
||||||
|
|
||||||
|
@ -53,27 +69,38 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel
|
||||||
applyRTT();
|
applyRTT();
|
||||||
applyVisibilityMask();
|
applyVisibilityMask();
|
||||||
|
|
||||||
|
|
||||||
createMaterial();
|
|
||||||
mWater->setMaterial(mMaterial);
|
mWater->setMaterial(mMaterial);
|
||||||
|
|
||||||
mUnderwaterEffect = Settings::Manager::getBool("underwater effect", "Water");
|
/*
|
||||||
|
Ogre::Entity* underwaterDome = mSceneManager->createEntity ("underwater_dome.mesh");
|
||||||
|
underwaterDome->setRenderQueueGroup (RQG_UnderWater);
|
||||||
|
mUnderwaterDome = mSceneManager->getRootSceneNode ()->createChildSceneNode ();
|
||||||
|
mUnderwaterDome->attachObject (underwaterDome);
|
||||||
|
mUnderwaterDome->setScale(10000,10000,10000);
|
||||||
|
mUnderwaterDome->setVisible(false);
|
||||||
|
underwaterDome->setMaterialName("Underwater_Dome");
|
||||||
|
*/
|
||||||
|
|
||||||
mSceneManager->addRenderQueueListener(this);
|
mSceneManager->addRenderQueueListener(this);
|
||||||
|
|
||||||
assignTextures();
|
assignTextures();
|
||||||
|
|
||||||
|
setHeight(mTop);
|
||||||
|
|
||||||
|
sh::MaterialInstance* m = sh::Factory::getInstance ().getMaterialInstance ("Water");
|
||||||
|
m->setListener (this);
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------------
|
||||||
// ---------------------------------- reflection debug overlay ----------------------------------
|
// ---------------------------------- reflection debug overlay ----------------------------------
|
||||||
// ----------------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------------
|
||||||
/*
|
/*
|
||||||
if (Settings::Manager::getBool("shader", "Water"))
|
if (Settings::Manager::getBool("shader", "Water"))
|
||||||
{
|
{
|
||||||
OverlayManager& mgr = OverlayManager::getSingleton();
|
OverlayManager& mgr = OverlayManager::getSingleton();
|
||||||
Overlay* overlay;
|
Overlay* overlay;
|
||||||
// destroy if already exists
|
// destroy if already exists
|
||||||
if (overlay = mgr.getByName("ReflectionDebugOverlay"))
|
if ((overlay = mgr.getByName("ReflectionDebugOverlay")))
|
||||||
mgr.destroy(overlay);
|
mgr.destroy(overlay);
|
||||||
|
|
||||||
overlay = mgr.create("ReflectionDebugOverlay");
|
overlay = mgr.create("ReflectionDebugOverlay");
|
||||||
|
@ -85,18 +112,17 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel
|
||||||
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
|
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
|
||||||
|
|
||||||
debugMat->getTechnique(0)->getPass(0)->setLightingEnabled(false);
|
debugMat->getTechnique(0)->getPass(0)->setLightingEnabled(false);
|
||||||
TextureUnitState *t = debugMat->getTechnique(0)->getPass(0)->createTextureUnitState(tex->getName());
|
debugMat->getTechnique(0)->getPass(0)->createTextureUnitState(mReflectionTexture->getName());
|
||||||
t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
|
|
||||||
|
|
||||||
OverlayContainer* debugPanel;
|
OverlayContainer* debugPanel;
|
||||||
|
|
||||||
// destroy container if exists
|
// destroy container if exists
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (debugPanel =
|
if ((debugPanel =
|
||||||
static_cast<OverlayContainer*>(
|
static_cast<OverlayContainer*>(
|
||||||
mgr.getOverlayElement("Ogre/ReflectionDebugTexPanel"
|
mgr.getOverlayElement("Ogre/ReflectionDebugTexPanel"
|
||||||
)))
|
))))
|
||||||
mgr.destroyOverlayElement(debugPanel);
|
mgr.destroyOverlayElement(debugPanel);
|
||||||
}
|
}
|
||||||
catch (Ogre::Exception&) {}
|
catch (Ogre::Exception&) {}
|
||||||
|
@ -110,13 +136,15 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel
|
||||||
overlay->add2D(debugPanel);
|
overlay->add2D(debugPanel);
|
||||||
overlay->show();
|
overlay->show();
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void Water::setActive(bool active)
|
void Water::setActive(bool active)
|
||||||
{
|
{
|
||||||
mActive = active;
|
mActive = active;
|
||||||
updateVisible();
|
updateVisible();
|
||||||
|
|
||||||
|
sh::Factory::getInstance ().setSharedParameter ("waterEnabled", sh::makeProperty<sh::FloatValue> (new sh::FloatValue(active ? 1.0 : 0.0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Water::~Water()
|
Water::~Water()
|
||||||
|
@ -144,8 +172,14 @@ void Water::changeCell(const ESM::Cell* cell)
|
||||||
void Water::setHeight(const float height)
|
void Water::setHeight(const float height)
|
||||||
{
|
{
|
||||||
mTop = height;
|
mTop = height;
|
||||||
|
|
||||||
mWaterPlane = Plane(Vector3::UNIT_Y, height);
|
mWaterPlane = Plane(Vector3::UNIT_Y, height);
|
||||||
|
|
||||||
|
// small error due to reflection texture size & reflection distortion
|
||||||
|
mErrorPlane = Plane(Vector3::UNIT_Y, height - 5);
|
||||||
|
|
||||||
mWaterNode->setPosition(0, height, 0);
|
mWaterNode->setPosition(0, height, 0);
|
||||||
|
sh::Factory::getInstance ().setSharedParameter ("waterLevel", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(height)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Water::toggle()
|
void Water::toggle()
|
||||||
|
@ -158,36 +192,16 @@ void Water::checkUnderwater(float y)
|
||||||
{
|
{
|
||||||
if (!mActive)
|
if (!mActive)
|
||||||
{
|
{
|
||||||
mRendering->getCompositors()->setCompositorEnabled(mCompositorName, false);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mIsUnderwater && y > mTop) || !mWater->isVisible() || mCamera->getPolygonMode() != Ogre::PM_SOLID)
|
if ((mIsUnderwater && y > mTop) || !mWater->isVisible() || mCamera->getPolygonMode() != Ogre::PM_SOLID)
|
||||||
{
|
{
|
||||||
mRendering->getCompositors()->setCompositorEnabled(mCompositorName, false);
|
|
||||||
|
|
||||||
// tell the shader we are not underwater
|
|
||||||
Ogre::Pass* pass = mMaterial->getTechnique(0)->getPass(0);
|
|
||||||
if (pass->hasFragmentProgram() && pass->getFragmentProgramParameters()->_findNamedConstantDefinition("isUnderwater", false))
|
|
||||||
pass->getFragmentProgramParameters()->setNamedConstant("isUnderwater", Real(0));
|
|
||||||
|
|
||||||
mWater->setRenderQueueGroup(RQG_Water);
|
|
||||||
|
|
||||||
mIsUnderwater = false;
|
mIsUnderwater = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mIsUnderwater && y < mTop && mWater->isVisible() && mCamera->getPolygonMode() == Ogre::PM_SOLID)
|
if (!mIsUnderwater && y < mTop && mWater->isVisible() && mCamera->getPolygonMode() == Ogre::PM_SOLID)
|
||||||
{
|
{
|
||||||
if (mUnderwaterEffect)
|
|
||||||
mRendering->getCompositors()->setCompositorEnabled(mCompositorName, true);
|
|
||||||
|
|
||||||
// tell the shader we are underwater
|
|
||||||
Ogre::Pass* pass = mMaterial->getTechnique(0)->getPass(0);
|
|
||||||
if (pass->hasFragmentProgram() && pass->getFragmentProgramParameters()->_findNamedConstantDefinition("isUnderwater", false))
|
|
||||||
pass->getFragmentProgramParameters()->setNamedConstant("isUnderwater", Real(1));
|
|
||||||
|
|
||||||
mWater->setRenderQueueGroup(RQG_UnderWater);
|
|
||||||
|
|
||||||
mIsUnderwater = true;
|
mIsUnderwater = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,12 +225,11 @@ void Water::preRenderTargetUpdate(const RenderTargetEvent& evt)
|
||||||
mReflectionCamera->setFOVy(mCamera->getFOVy());
|
mReflectionCamera->setFOVy(mCamera->getFOVy());
|
||||||
mReflectionRenderActive = true;
|
mReflectionRenderActive = true;
|
||||||
|
|
||||||
/// \todo For some reason this camera is delayed for 1 frame, which causes ugly sky reflection behaviour..
|
/// \todo the reflection render (and probably all renderingmanager-updates) lag behind 1 camera frame for some reason
|
||||||
/// to circumvent this we just scale the sky up, so it's not that noticable
|
|
||||||
Vector3 pos = mCamera->getRealPosition();
|
Vector3 pos = mCamera->getRealPosition();
|
||||||
pos.y = mTop*2 - pos.y;
|
pos.y = mTop*2 - pos.y;
|
||||||
mSky->setSkyPosition(pos);
|
mSky->setSkyPosition(pos);
|
||||||
mSky->scaleSky(mCamera->getFarClipDistance() / 5000.f);
|
mSky->scaleSky(mCamera->getFarClipDistance() / 50.f);
|
||||||
mReflectionCamera->enableReflection(mWaterPlane);
|
mReflectionCamera->enableReflection(mWaterPlane);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -233,48 +246,18 @@ void Water::postRenderTargetUpdate(const RenderTargetEvent& evt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Water::createMaterial()
|
|
||||||
{
|
|
||||||
if (mReflectionTarget == 0)
|
|
||||||
{
|
|
||||||
mMaterial = MaterialManager::getSingleton().getByName("Water_Fallback");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mMaterial = MaterialManager::getSingleton().getByName("Water");
|
|
||||||
mMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTexture(mReflectionTexture);
|
|
||||||
}
|
|
||||||
|
|
||||||
// these have to be set in code
|
|
||||||
std::string textureNames[32];
|
|
||||||
for (int i=0; i<32; ++i)
|
|
||||||
{
|
|
||||||
textureNames[i] = "textures\\water\\water" + StringConverter::toString(i, 2, '0') + ".dds";
|
|
||||||
}
|
|
||||||
Ogre::Technique* tech;
|
|
||||||
if (mReflectionTarget == 0)
|
|
||||||
tech = mMaterial->getTechnique(0);
|
|
||||||
else
|
|
||||||
tech = mMaterial->getTechnique(1);
|
|
||||||
|
|
||||||
tech->getPass(0)->getTextureUnitState(0)->setAnimatedTextureName(textureNames, 32, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Water::assignTextures()
|
void Water::assignTextures()
|
||||||
{
|
{
|
||||||
if (Settings::Manager::getBool("shader", "Water"))
|
if (Settings::Manager::getBool("shader", "Water"))
|
||||||
{
|
{
|
||||||
|
|
||||||
CompositorInstance* compositor = CompositorManager::getSingleton().getCompositorChain(mRendering->getViewport())->getCompositor("gbuffer");
|
CompositorInstance* compositor = CompositorManager::getSingleton().getCompositorChain(mRendering->getViewport())->getCompositor("gbuffer");
|
||||||
|
|
||||||
TexturePtr colorTexture = compositor->getTextureInstance("mrt_output", 0);
|
TexturePtr colorTexture = compositor->getTextureInstance("mrt_output", 0);
|
||||||
TextureUnitState* tus = mMaterial->getTechnique(0)->getPass(0)->getTextureUnitState("refractionMap");
|
sh::Factory::getInstance ().setTextureAlias ("WaterRefraction", colorTexture->getName());
|
||||||
if (tus != 0)
|
|
||||||
tus->setTexture(colorTexture);
|
|
||||||
|
|
||||||
TexturePtr depthTexture = compositor->getTextureInstance("mrt_output", 1);
|
TexturePtr depthTexture = compositor->getTextureInstance("mrt_output", 1);
|
||||||
tus = mMaterial->getTechnique(0)->getPass(0)->getTextureUnitState("depthMap");
|
sh::Factory::getInstance ().setTextureAlias ("SceneDepth", depthTexture->getName());
|
||||||
if (tus != 0)
|
|
||||||
tus->setTexture(depthTexture);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,7 +271,7 @@ void Water::updateVisible()
|
||||||
{
|
{
|
||||||
mWater->setVisible(mToggled && mActive);
|
mWater->setVisible(mToggled && mActive);
|
||||||
if (mReflectionTarget)
|
if (mReflectionTarget)
|
||||||
mReflectionTarget->setActive(mToggled && mActive && !mIsUnderwater);
|
mReflectionTarget->setActive(mToggled && mActive);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Water::renderQueueStarted (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &skipThisInvocation)
|
void Water::renderQueueStarted (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &skipThisInvocation)
|
||||||
|
@ -296,22 +279,48 @@ void Water::renderQueueStarted (Ogre::uint8 queueGroupId, const Ogre::String &in
|
||||||
// We don't want the sky to get clipped by custom near clip plane (the water plane)
|
// We don't want the sky to get clipped by custom near clip plane (the water plane)
|
||||||
if (queueGroupId < 20 && mReflectionRenderActive)
|
if (queueGroupId < 20 && mReflectionRenderActive)
|
||||||
{
|
{
|
||||||
|
mOldFarClip = mReflectionCamera->getFarClipDistance ();
|
||||||
mReflectionCamera->disableCustomNearClipPlane();
|
mReflectionCamera->disableCustomNearClipPlane();
|
||||||
|
mReflectionCamera->setFarClipDistance (1000000000);
|
||||||
Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mReflectionCamera->getProjectionMatrixRS());
|
Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mReflectionCamera->getProjectionMatrixRS());
|
||||||
}
|
}
|
||||||
|
else if (queueGroupId == RQG_UnderWater)
|
||||||
|
{/*
|
||||||
|
mOldFarClip2 = mCamera->getFarClipDistance ();
|
||||||
|
mCamera->setFarClipDistance (1000000000);
|
||||||
|
Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mCamera->getProjectionMatrixRS());
|
||||||
|
*/}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Water::renderQueueEnded (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &repeatThisInvocation)
|
void Water::renderQueueEnded (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &repeatThisInvocation)
|
||||||
{
|
{
|
||||||
if (queueGroupId < 20 && mReflectionRenderActive)
|
if (queueGroupId < 20 && mReflectionRenderActive)
|
||||||
{
|
{
|
||||||
mReflectionCamera->enableCustomNearClipPlane(mWaterPlane);
|
mReflectionCamera->setFarClipDistance (mOldFarClip);
|
||||||
|
if (!mIsUnderwater)
|
||||||
|
mReflectionCamera->enableCustomNearClipPlane(mErrorPlane);
|
||||||
Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mReflectionCamera->getProjectionMatrixRS());
|
Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mReflectionCamera->getProjectionMatrixRS());
|
||||||
}
|
}
|
||||||
|
if (queueGroupId == RQG_UnderWater)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
mCamera->setFarClipDistance (mOldFarClip2);
|
||||||
|
Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mCamera->getProjectionMatrixRS());
|
||||||
|
*/}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Water::update()
|
void Water::update(float dt)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
Ogre::Vector3 pos = mCamera->getDerivedPosition ();
|
||||||
|
pos.y = -mWaterPlane.d;
|
||||||
|
mUnderwaterDome->setPosition (pos);
|
||||||
|
*/
|
||||||
|
|
||||||
|
mWaterTimer += dt / 30.0 * MWBase::Environment::get().getWorld()->getTimeScaleFactor();
|
||||||
|
sh::Factory::getInstance ().setSharedParameter ("waterTimer", sh::makeProperty<sh::FloatValue>(new sh::FloatValue(mWaterTimer)));
|
||||||
|
|
||||||
|
mRendering->getSkyManager ()->setGlareEnabled (!mIsUnderwater);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Water::applyRTT()
|
void Water::applyRTT()
|
||||||
|
@ -336,14 +345,14 @@ void Water::applyRTT()
|
||||||
vp->setBackgroundColour(ColourValue(0.8f, 0.9f, 1.0f));
|
vp->setBackgroundColour(ColourValue(0.8f, 0.9f, 1.0f));
|
||||||
vp->setShadowsEnabled(false);
|
vp->setShadowsEnabled(false);
|
||||||
// use fallback techniques without shadows and without mrt (currently not implemented for sky and terrain)
|
// use fallback techniques without shadows and without mrt (currently not implemented for sky and terrain)
|
||||||
//vp->setMaterialScheme("Fallback");
|
vp->setMaterialScheme("water_reflection");
|
||||||
rtt->addListener(this);
|
rtt->addListener(this);
|
||||||
rtt->setActive(true);
|
rtt->setActive(true);
|
||||||
|
|
||||||
mReflectionTarget = rtt;
|
mReflectionTarget = rtt;
|
||||||
}
|
|
||||||
|
|
||||||
mCompositorName = RenderingManager::useMRT() ? "Underwater" : "UnderwaterNoMRT";
|
sh::Factory::getInstance ().setTextureAlias ("WaterReflection", mReflectionTexture->getName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Water::applyVisibilityMask()
|
void Water::applyVisibilityMask()
|
||||||
|
@ -386,7 +395,6 @@ void Water::processChangedSettings(const Settings::CategorySettingVector& settin
|
||||||
{
|
{
|
||||||
applyRTT();
|
applyRTT();
|
||||||
applyVisibilityMask();
|
applyVisibilityMask();
|
||||||
createMaterial();
|
|
||||||
mWater->setMaterial(mMaterial);
|
mWater->setMaterial(mMaterial);
|
||||||
assignTextures();
|
assignTextures();
|
||||||
}
|
}
|
||||||
|
@ -394,4 +402,29 @@ void Water::processChangedSettings(const Settings::CategorySettingVector& settin
|
||||||
applyVisibilityMask();
|
applyVisibilityMask();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Water::requestedConfiguration (sh::MaterialInstance* m, const std::string& configuration)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Water::createdConfiguration (sh::MaterialInstance* m, const std::string& configuration)
|
||||||
|
{
|
||||||
|
if (configuration == "local_map" || !Settings::Manager::getBool("shader", "Water"))
|
||||||
|
{
|
||||||
|
// for simple water, set animated texture names
|
||||||
|
// these have to be set in code
|
||||||
|
std::string textureNames[32];
|
||||||
|
for (int i=0; i<32; ++i)
|
||||||
|
{
|
||||||
|
textureNames[i] = "textures\\water\\water" + StringConverter::toString(i, 2, '0') + ".dds";
|
||||||
|
}
|
||||||
|
|
||||||
|
Ogre::Technique* t = static_cast<sh::OgreMaterial*>(m->getMaterial())->getOgreTechniqueForConfiguration(configuration);
|
||||||
|
if (t->getPass(0)->getNumTextureUnitStates () == 0)
|
||||||
|
return;
|
||||||
|
t->getPass(0)->getTextureUnitState(0)->setAnimatedTextureName(textureNames, 32, 2);
|
||||||
|
t->getPass(0)->setDepthWriteEnabled (false);
|
||||||
|
t->getPass(0)->setSceneBlending (Ogre::SBT_TRANSPARENT_ALPHA);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
|
|
||||||
#include "renderconst.hpp"
|
#include "renderconst.hpp"
|
||||||
|
|
||||||
|
#include <extern/shiny/Main/MaterialInstance.hpp>
|
||||||
|
|
||||||
namespace Ogre
|
namespace Ogre
|
||||||
{
|
{
|
||||||
class Camera;
|
class Camera;
|
||||||
|
@ -29,21 +31,30 @@ namespace MWRender {
|
||||||
class RenderingManager;
|
class RenderingManager;
|
||||||
|
|
||||||
/// Water rendering
|
/// Water rendering
|
||||||
class Water : public Ogre::RenderTargetListener, public Ogre::RenderQueueListener
|
class Water : public Ogre::RenderTargetListener, public Ogre::RenderQueueListener, public sh::MaterialInstanceListener
|
||||||
{
|
{
|
||||||
static const int CELL_SIZE = 8192;
|
static const int CELL_SIZE = 8192;
|
||||||
Ogre::Camera *mCamera;
|
Ogre::Camera *mCamera;
|
||||||
Ogre::SceneManager *mSceneManager;
|
Ogre::SceneManager *mSceneManager;
|
||||||
|
|
||||||
Ogre::Plane mWaterPlane;
|
Ogre::Plane mWaterPlane;
|
||||||
|
Ogre::Plane mErrorPlane;
|
||||||
|
|
||||||
Ogre::SceneNode *mWaterNode;
|
Ogre::SceneNode *mWaterNode;
|
||||||
Ogre::Entity *mWater;
|
Ogre::Entity *mWater;
|
||||||
|
|
||||||
|
//Ogre::SceneNode* mUnderwaterDome;
|
||||||
|
|
||||||
bool mIsUnderwater;
|
bool mIsUnderwater;
|
||||||
bool mActive;
|
bool mActive;
|
||||||
bool mToggled;
|
bool mToggled;
|
||||||
int mTop;
|
int mTop;
|
||||||
|
|
||||||
|
int mOldFarClip;
|
||||||
|
int mOldFarClip2;
|
||||||
|
|
||||||
|
float mWaterTimer;
|
||||||
|
|
||||||
bool mReflectionRenderActive;
|
bool mReflectionRenderActive;
|
||||||
|
|
||||||
Ogre::Vector3 getSceneNodeCoordinates(int gridX, int gridY);
|
Ogre::Vector3 getSceneNodeCoordinates(int gridX, int gridY);
|
||||||
|
@ -65,7 +76,6 @@ namespace MWRender {
|
||||||
|
|
||||||
std::string mCompositorName;
|
std::string mCompositorName;
|
||||||
|
|
||||||
void createMaterial();
|
|
||||||
Ogre::MaterialPtr mMaterial;
|
Ogre::MaterialPtr mMaterial;
|
||||||
|
|
||||||
Ogre::Camera* mReflectionCamera;
|
Ogre::Camera* mReflectionCamera;
|
||||||
|
@ -83,7 +93,7 @@ namespace MWRender {
|
||||||
void setActive(bool active);
|
void setActive(bool active);
|
||||||
|
|
||||||
void toggle();
|
void toggle();
|
||||||
void update();
|
void update(float dt);
|
||||||
|
|
||||||
void assignTextures();
|
void assignTextures();
|
||||||
|
|
||||||
|
@ -95,6 +105,9 @@ namespace MWRender {
|
||||||
void changeCell(const ESM::Cell* cell);
|
void changeCell(const ESM::Cell* cell);
|
||||||
void setHeight(const float height);
|
void setHeight(const float height);
|
||||||
|
|
||||||
|
virtual void requestedConfiguration (sh::MaterialInstance* m, const std::string& configuration);
|
||||||
|
virtual void createdConfiguration (sh::MaterialInstance* m, const std::string& configuration);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -181,16 +181,15 @@ namespace MWWorld
|
||||||
playerphysics->ps.viewangles.y = yawQuat.getYaw().valueDegrees() *-1 + 90;
|
playerphysics->ps.viewangles.y = yawQuat.getYaw().valueDegrees() *-1 + 90;
|
||||||
|
|
||||||
|
|
||||||
Ogre::Quaternion quat = yawNode->getOrientation();
|
Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y);
|
||||||
Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y);
|
|
||||||
|
|
||||||
pm_ref.rightmove = -iter->second.x;
|
pm_ref.rightmove = -iter->second.x;
|
||||||
pm_ref.forwardmove = -iter->second.y;
|
pm_ref.forwardmove = -iter->second.y;
|
||||||
pm_ref.upmove = iter->second.z;
|
pm_ref.upmove = iter->second.z;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -476,8 +476,7 @@ WeatherResult WeatherManager::transition(float factor)
|
||||||
result.mSunDiscColor = lerp(current.mSunDiscColor, other.mSunDiscColor);
|
result.mSunDiscColor = lerp(current.mSunDiscColor, other.mSunDiscColor);
|
||||||
result.mFogDepth = lerp(current.mFogDepth, other.mFogDepth);
|
result.mFogDepth = lerp(current.mFogDepth, other.mFogDepth);
|
||||||
result.mWindSpeed = lerp(current.mWindSpeed, other.mWindSpeed);
|
result.mWindSpeed = lerp(current.mWindSpeed, other.mWindSpeed);
|
||||||
//result.mCloudSpeed = lerp(current.mCloudSpeed, other.mCloudSpeed);
|
result.mCloudSpeed = lerp(current.mCloudSpeed, other.mCloudSpeed);
|
||||||
result.mCloudSpeed = current.mCloudSpeed;
|
|
||||||
result.mCloudOpacity = lerp(current.mCloudOpacity, other.mCloudOpacity);
|
result.mCloudOpacity = lerp(current.mCloudOpacity, other.mCloudOpacity);
|
||||||
result.mGlareView = lerp(current.mGlareView, other.mGlareView);
|
result.mGlareView = lerp(current.mGlareView, other.mGlareView);
|
||||||
result.mNightFade = lerp(current.mNightFade, other.mNightFade);
|
result.mNightFade = lerp(current.mNightFade, other.mNightFade);
|
||||||
|
@ -689,13 +688,13 @@ void WeatherManager::update(float duration)
|
||||||
|
|
||||||
mThunderFlash -= duration;
|
mThunderFlash -= duration;
|
||||||
if (mThunderFlash > 0)
|
if (mThunderFlash > 0)
|
||||||
mRendering->getSkyManager()->setThunder( mThunderFlash / WeatherGlobals::mThunderThreshold );
|
mRendering->getSkyManager()->setLightningStrength( mThunderFlash / WeatherGlobals::mThunderThreshold );
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
srand(time(NULL));
|
srand(time(NULL));
|
||||||
mThunderChanceNeeded = rand() % 100;
|
mThunderChanceNeeded = rand() % 100;
|
||||||
mThunderChance = 0;
|
mThunderChance = 0;
|
||||||
mRendering->getSkyManager()->setThunder( 0.f );
|
mRendering->getSkyManager()->setLightningStrength( 0.f );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -706,14 +705,14 @@ void WeatherManager::update(float duration)
|
||||||
{
|
{
|
||||||
mThunderFlash = WeatherGlobals::mThunderThreshold;
|
mThunderFlash = WeatherGlobals::mThunderThreshold;
|
||||||
|
|
||||||
mRendering->getSkyManager()->setThunder( mThunderFlash / WeatherGlobals::mThunderThreshold );
|
mRendering->getSkyManager()->setLightningStrength( mThunderFlash / WeatherGlobals::mThunderThreshold );
|
||||||
|
|
||||||
mThunderSoundDelay = WeatherGlobals::mThunderSoundDelay;
|
mThunderSoundDelay = WeatherGlobals::mThunderSoundDelay;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
mRendering->getSkyManager()->setThunder(0.f);
|
mRendering->getSkyManager()->setLightningStrength(0.f);
|
||||||
|
|
||||||
mRendering->setAmbientColour(result.mAmbientColor);
|
mRendering->setAmbientColour(result.mAmbientColor);
|
||||||
mRendering->sunEnable();
|
mRendering->sunEnable();
|
||||||
|
@ -725,7 +724,7 @@ void WeatherManager::update(float duration)
|
||||||
{
|
{
|
||||||
mRendering->sunDisable();
|
mRendering->sunDisable();
|
||||||
mRendering->skyDisable();
|
mRendering->skyDisable();
|
||||||
mRendering->getSkyManager()->setThunder(0.f);
|
mRendering->getSkyManager()->setLightningStrength(0.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// play sounds
|
// play sounds
|
||||||
|
|
|
@ -22,3 +22,10 @@ endforeach (f)
|
||||||
endforeach (u)
|
endforeach (u)
|
||||||
source_group ("components\\${dir}" FILES ${files})
|
source_group ("components\\${dir}" FILES ${files})
|
||||||
endmacro (add_component_dir)
|
endmacro (add_component_dir)
|
||||||
|
|
||||||
|
macro (copy_all_files source_dir destination_dir files)
|
||||||
|
foreach (f ${files})
|
||||||
|
get_filename_component(filename ${f} NAME)
|
||||||
|
configure_file(${source_dir}/${f} ${destination_dir}/${filename} COPYONLY)
|
||||||
|
endforeach (f)
|
||||||
|
endmacro (copy_all_files)
|
||||||
|
|
|
@ -15,7 +15,6 @@ namespace Files
|
||||||
{
|
{
|
||||||
|
|
||||||
static const char* const openmwCfgFile = "openmw.cfg";
|
static const char* const openmwCfgFile = "openmw.cfg";
|
||||||
static const char* const pluginsCfgFile = "plugins.cfg";
|
|
||||||
|
|
||||||
const char* const mwToken = "?mw?";
|
const char* const mwToken = "?mw?";
|
||||||
const char* const localToken = "?local?";
|
const char* const localToken = "?local?";
|
||||||
|
@ -29,17 +28,6 @@ ConfigurationManager::ConfigurationManager()
|
||||||
|
|
||||||
boost::filesystem::create_directories(mFixedPath.getUserPath());
|
boost::filesystem::create_directories(mFixedPath.getUserPath());
|
||||||
|
|
||||||
mPluginsCfgPath = mFixedPath.getLocalPath() / pluginsCfgFile;
|
|
||||||
if (!boost::filesystem::is_regular_file(mPluginsCfgPath))
|
|
||||||
{
|
|
||||||
mPluginsCfgPath = mFixedPath.getGlobalPath() / pluginsCfgFile;
|
|
||||||
if (!boost::filesystem::is_regular_file(mPluginsCfgPath))
|
|
||||||
{
|
|
||||||
std::cerr << "Failed to find " << pluginsCfgFile << " file!" << std::endl;
|
|
||||||
mPluginsCfgPath.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mLogPath = mFixedPath.getUserPath();
|
mLogPath = mFixedPath.getUserPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,11 +152,6 @@ const boost::filesystem::path& ConfigurationManager::getInstallPath() const
|
||||||
return mFixedPath.getInstallPath();
|
return mFixedPath.getInstallPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
const boost::filesystem::path& ConfigurationManager::getPluginsConfigPath() const
|
|
||||||
{
|
|
||||||
return mPluginsCfgPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
const boost::filesystem::path& ConfigurationManager::getLogPath() const
|
const boost::filesystem::path& ConfigurationManager::getLogPath() const
|
||||||
{
|
{
|
||||||
return mLogPath;
|
return mLogPath;
|
||||||
|
|
|
@ -40,7 +40,6 @@ struct ConfigurationManager
|
||||||
const boost::filesystem::path& getLocalDataPath() const;
|
const boost::filesystem::path& getLocalDataPath() const;
|
||||||
const boost::filesystem::path& getInstallPath() const;
|
const boost::filesystem::path& getInstallPath() const;
|
||||||
|
|
||||||
const boost::filesystem::path& getPluginsConfigPath() const;
|
|
||||||
const boost::filesystem::path& getLogPath() const;
|
const boost::filesystem::path& getLogPath() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -57,7 +56,6 @@ struct ConfigurationManager
|
||||||
|
|
||||||
FixedPathType mFixedPath;
|
FixedPathType mFixedPath;
|
||||||
|
|
||||||
boost::filesystem::path mPluginsCfgPath;
|
|
||||||
boost::filesystem::path mLogPath;
|
boost::filesystem::path mLogPath;
|
||||||
|
|
||||||
TokensMappingContainer mTokensMapping;
|
TokensMappingContainer mTokensMapping;
|
||||||
|
|
|
@ -33,6 +33,11 @@
|
||||||
#include <OgreSubMesh.h>
|
#include <OgreSubMesh.h>
|
||||||
#include <OgreRoot.h>
|
#include <OgreRoot.h>
|
||||||
|
|
||||||
|
#include <boost/lexical_cast.hpp>
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
|
#include <extern/shiny/Main/Factory.hpp>
|
||||||
|
|
||||||
#include <components/settings/settings.hpp>
|
#include <components/settings/settings.hpp>
|
||||||
#include <components/nifoverrides/nifoverrides.hpp>
|
#include <components/nifoverrides/nifoverrides.hpp>
|
||||||
|
|
||||||
|
@ -207,139 +212,82 @@ void NIFLoader::createMaterial(const Ogre::String &name,
|
||||||
const Ogre::Vector3 &emissive,
|
const Ogre::Vector3 &emissive,
|
||||||
float glossiness, float alpha,
|
float glossiness, float alpha,
|
||||||
int alphaFlags, float alphaTest,
|
int alphaFlags, float alphaTest,
|
||||||
const Ogre::String &texName)
|
const Ogre::String &texName, bool vertexColor)
|
||||||
{
|
{
|
||||||
Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().create(name, resourceGroup);
|
if (texName.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
sh::MaterialInstance* instance = sh::Factory::getInstance ().createMaterialInstance (name, "openmw_objects_base");
|
||||||
|
instance->setProperty ("ambient", sh::makeProperty<sh::Vector3> (
|
||||||
|
new sh::Vector3(ambient.x, ambient.y, ambient.z)));
|
||||||
|
|
||||||
//Hardware Skinning code, textures may be the wrong color if enabled
|
instance->setProperty ("diffuse", sh::makeProperty<sh::Vector4> (
|
||||||
|
new sh::Vector4(diffuse.x, diffuse.y, diffuse.z, alpha)));
|
||||||
|
|
||||||
/* if(!mSkel.isNull()){
|
instance->setProperty ("specular", sh::makeProperty<sh::Vector4> (
|
||||||
material->removeAllTechniques();
|
new sh::Vector4(specular.x, specular.y, specular.z, glossiness)));
|
||||||
|
|
||||||
Ogre::Technique* tech = material->createTechnique();
|
instance->setProperty ("emissive", sh::makeProperty<sh::Vector3> (
|
||||||
//tech->setSchemeName("blahblah");
|
new sh::Vector3(emissive.x, emissive.y, emissive.z)));
|
||||||
Pass* pass = tech->createPass();
|
|
||||||
pass->setVertexProgram("Ogre/BasicVertexPrograms/AmbientOneTexture");*/
|
|
||||||
|
|
||||||
|
instance->setProperty ("diffuseMap", sh::makeProperty(texName));
|
||||||
|
|
||||||
// This assigns the texture to this material. If the texture name is
|
if (vertexColor)
|
||||||
// a file name, and this file exists (in a resource directory), it
|
instance->setProperty ("has_vertex_colour", sh::makeProperty<sh::BooleanValue>(new sh::BooleanValue(true)));
|
||||||
// will automatically be loaded when needed. If not (such as for
|
|
||||||
// internal NIF textures that we might support later), we should
|
|
||||||
// already have inserted a manual loader for the texture.
|
|
||||||
|
|
||||||
|
// Add transparency if NiAlphaProperty was present
|
||||||
if (!texName.empty())
|
if (alphaFlags != -1)
|
||||||
{
|
{
|
||||||
Ogre::Pass *pass = material->getTechnique(0)->getPass(0);
|
// The 237 alpha flags are by far the most common. Check
|
||||||
/*TextureUnitState *txt =*/
|
// NiAlphaProperty in nif/property.h if you need to decode
|
||||||
pass->createTextureUnitState(texName);
|
// other values. 237 basically means normal transparencly.
|
||||||
|
if (alphaFlags == 237)
|
||||||
pass->setVertexColourTracking(Ogre::TVC_DIFFUSE);
|
|
||||||
|
|
||||||
// As of yet UNTESTED code from Chris:
|
|
||||||
/*pass->setTextureFiltering(Ogre::TFO_ANISOTROPIC);
|
|
||||||
pass->setDepthFunction(Ogre::CMPF_LESS_EQUAL);
|
|
||||||
pass->setDepthCheckEnabled(true);
|
|
||||||
|
|
||||||
// Add transparency if NiAlphaProperty was present
|
|
||||||
if (alphaFlags != -1)
|
|
||||||
{
|
{
|
||||||
std::cout << "Alpha flags set!" << endl;
|
NifOverrides::TransparencyResult result = NifOverrides::Overrides::getTransparencyOverride(texName);
|
||||||
if ((alphaFlags&1))
|
if (result.first)
|
||||||
{
|
{
|
||||||
pass->setDepthWriteEnabled(false);
|
instance->setProperty("alpha_rejection",
|
||||||
pass->setSceneBlending(getBlendFactor((alphaFlags>>1)&0xf),
|
sh::makeProperty<sh::StringValue>(new sh::StringValue("greater_equal " + boost::lexical_cast<std::string>(result.second))));
|
||||||
getBlendFactor((alphaFlags>>5)&0xf));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
pass->setDepthWriteEnabled(true);
|
|
||||||
|
|
||||||
if ((alphaFlags>>9)&1)
|
|
||||||
pass->setAlphaRejectSettings(getTestMode((alphaFlags>>10)&0x7),
|
|
||||||
alphaTest);
|
|
||||||
|
|
||||||
pass->setTransparentSortingEnabled(!((alphaFlags>>13)&1));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
pass->setDepthWriteEnabled(true); */
|
|
||||||
|
|
||||||
|
|
||||||
// Add transparency if NiAlphaProperty was present
|
|
||||||
if (alphaFlags != -1)
|
|
||||||
{
|
|
||||||
// The 237 alpha flags are by far the most common. Check
|
|
||||||
// NiAlphaProperty in nif/property.h if you need to decode
|
|
||||||
// other values. 237 basically means normal transparencly.
|
|
||||||
if (alphaFlags == 237)
|
|
||||||
{
|
{
|
||||||
NifOverrides::TransparencyResult result = NifOverrides::Overrides::getTransparencyOverride(texName);
|
// Enable transparency
|
||||||
if (result.first)
|
instance->setProperty("scene_blend", sh::makeProperty<sh::StringValue>(new sh::StringValue("alpha_blend")));
|
||||||
{
|
instance->setProperty("depth_write", sh::makeProperty<sh::StringValue>(new sh::StringValue("off")));
|
||||||
pass->setAlphaRejectFunction(Ogre::CMPF_GREATER_EQUAL);
|
|
||||||
pass->setAlphaRejectValue(result.second);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Enable transparency
|
|
||||||
pass->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
|
|
||||||
|
|
||||||
//pass->setDepthCheckEnabled(false);
|
|
||||||
pass->setDepthWriteEnabled(false);
|
|
||||||
//std::cout << "alpha 237; material: " << name << " texName: " << texName << std::endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
warn("Unhandled alpha setting for texture " + texName);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
warn("Unhandled alpha setting for texture " + texName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
instance->getMaterial ()->setShadowCasterMaterial ("openmw_shadowcaster_noalpha");
|
||||||
|
|
||||||
|
// As of yet UNTESTED code from Chris:
|
||||||
|
/*pass->setTextureFiltering(Ogre::TFO_ANISOTROPIC);
|
||||||
|
pass->setDepthFunction(Ogre::CMPF_LESS_EQUAL);
|
||||||
|
pass->setDepthCheckEnabled(true);
|
||||||
|
|
||||||
|
// Add transparency if NiAlphaProperty was present
|
||||||
|
if (alphaFlags != -1)
|
||||||
|
{
|
||||||
|
std::cout << "Alpha flags set!" << endl;
|
||||||
|
if ((alphaFlags&1))
|
||||||
{
|
{
|
||||||
material->getTechnique(0)->setShadowCasterMaterial("depth_shadow_caster_noalpha");
|
pass->setDepthWriteEnabled(false);
|
||||||
|
pass->setSceneBlending(getBlendFactor((alphaFlags>>1)&0xf),
|
||||||
|
getBlendFactor((alphaFlags>>5)&0xf));
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
pass->setDepthWriteEnabled(true);
|
||||||
|
|
||||||
|
if ((alphaFlags>>9)&1)
|
||||||
|
pass->setAlphaRejectSettings(getTestMode((alphaFlags>>10)&0x7),
|
||||||
|
alphaTest);
|
||||||
|
|
||||||
|
pass->setTransparentSortingEnabled(!((alphaFlags>>13)&1));
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (Settings::Manager::getBool("enabled", "Shadows"))
|
pass->setDepthWriteEnabled(true); */
|
||||||
{
|
|
||||||
bool split = Settings::Manager::getBool("split", "Shadows");
|
|
||||||
const int numsplits = 3;
|
|
||||||
for (int i = 0; i < (split ? numsplits : 1); ++i)
|
|
||||||
{
|
|
||||||
Ogre::TextureUnitState* tu = material->getTechnique(0)->getPass(0)->createTextureUnitState();
|
|
||||||
tu->setName("shadowMap" + Ogre::StringConverter::toString(i));
|
|
||||||
tu->setContentType(Ogre::TextureUnitState::CONTENT_SHADOW);
|
|
||||||
tu->setTextureAddressingMode(Ogre::TextureUnitState::TAM_BORDER);
|
|
||||||
tu->setTextureBorderColour(Ogre::ColourValue::White);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Settings::Manager::getBool("shaders", "Objects"))
|
|
||||||
{
|
|
||||||
material->getTechnique(0)->getPass(0)->setVertexProgram("main_vp");
|
|
||||||
material->getTechnique(0)->getPass(0)->setFragmentProgram("main_fp");
|
|
||||||
|
|
||||||
material->getTechnique(0)->getPass(0)->setFog(true); // force-disable fixed function fog, it is calculated in shader
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a fallback technique without shadows and without mrt
|
|
||||||
Ogre::Technique* tech2 = material->createTechnique();
|
|
||||||
tech2->setSchemeName("Fallback");
|
|
||||||
Ogre::Pass* pass2 = tech2->createPass();
|
|
||||||
pass2->createTextureUnitState(texName);
|
|
||||||
pass2->setVertexColourTracking(Ogre::TVC_DIFFUSE);
|
|
||||||
if (Settings::Manager::getBool("shaders", "Objects"))
|
|
||||||
{
|
|
||||||
pass2->setVertexProgram("main_fallback_vp");
|
|
||||||
pass2->setFragmentProgram("main_fallback_fp");
|
|
||||||
pass2->setFog(true); // force-disable fixed function fog, it is calculated in shader
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add material bells and whistles
|
|
||||||
material->setAmbient(ambient[0], ambient[1], ambient[2]);
|
|
||||||
material->setDiffuse(diffuse[0], diffuse[1], diffuse[2], alpha);
|
|
||||||
material->setSpecular(specular[0], specular[1], specular[2], alpha);
|
|
||||||
material->setSelfIllumination(emissive[0], emissive[1], emissive[2]);
|
|
||||||
material->setShininess(glossiness);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Takes a name and adds a unique part to it. This is just used to
|
// Takes a name and adds a unique part to it. This is just used to
|
||||||
|
@ -642,6 +590,8 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
|
||||||
NiTexturingProperty *t = NULL;
|
NiTexturingProperty *t = NULL;
|
||||||
NiMaterialProperty *m = NULL;
|
NiMaterialProperty *m = NULL;
|
||||||
NiAlphaProperty *a = NULL;
|
NiAlphaProperty *a = NULL;
|
||||||
|
// can't make any sense of these values, so ignoring them for now
|
||||||
|
//NiVertexColorProperty *v = NULL;
|
||||||
|
|
||||||
// Scan the property list for material information
|
// Scan the property list for material information
|
||||||
PropertyList &list = shape->props;
|
PropertyList &list = shape->props;
|
||||||
|
@ -659,6 +609,8 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
|
||||||
m = static_cast<NiMaterialProperty*>(pr);
|
m = static_cast<NiMaterialProperty*>(pr);
|
||||||
else if (pr->recType == RC_NiAlphaProperty)
|
else if (pr->recType == RC_NiAlphaProperty)
|
||||||
a = static_cast<NiAlphaProperty*>(pr);
|
a = static_cast<NiAlphaProperty*>(pr);
|
||||||
|
//else if (pr->recType == RC_NiVertexColorProperty)
|
||||||
|
//v = static_cast<NiVertexColorProperty*>(pr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Texture
|
// Texture
|
||||||
|
@ -727,7 +679,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
|
||||||
{
|
{
|
||||||
//std::cout << "new";
|
//std::cout << "new";
|
||||||
createMaterial(material, d->ambient, d->diffuse, d->specular, d->emissive,
|
createMaterial(material, d->ambient, d->diffuse, d->specular, d->emissive,
|
||||||
d->glossiness, d->alpha, alphaFlags, alphaTest, texName);
|
d->glossiness, d->alpha, alphaFlags, alphaTest, texName, shape->data->colors.size() != 0);
|
||||||
MaterialMap.insert(std::make_pair(texName,material));
|
MaterialMap.insert(std::make_pair(texName,material));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -737,7 +689,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
|
||||||
// material for it.
|
// material for it.
|
||||||
const Ogre::Vector3 zero(0.0f), one(1.0f);
|
const Ogre::Vector3 zero(0.0f), one(1.0f);
|
||||||
createMaterial(material, one, one, zero, zero, 0.0f, 1.0f,
|
createMaterial(material, one, one, zero, zero, 0.0f, 1.0f,
|
||||||
alphaFlags, alphaTest, texName);
|
alphaFlags, alphaTest, texName, shape->data->colors.size() != 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // End of material block, if(!hidden) ...
|
} // End of material block, if(!hidden) ...
|
||||||
|
|
|
@ -117,7 +117,8 @@ class NIFLoader : Ogre::ManualResourceLoader
|
||||||
const Ogre::Vector3 &emissive,
|
const Ogre::Vector3 &emissive,
|
||||||
float glossiness, float alpha,
|
float glossiness, float alpha,
|
||||||
int alphaFlags, float alphaTest,
|
int alphaFlags, float alphaTest,
|
||||||
const Ogre::String &texName);
|
const Ogre::String &texName,
|
||||||
|
bool vertexColor);
|
||||||
|
|
||||||
void findRealTexture(Ogre::String &texName);
|
void findRealTexture(Ogre::String &texName);
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ CREDITS
|
||||||
Current Developers:
|
Current Developers:
|
||||||
Aleksandar Jovanov
|
Aleksandar Jovanov
|
||||||
Alexander “Ace” Olofsson
|
Alexander “Ace” Olofsson
|
||||||
|
Artem “greye” Kotsynyak
|
||||||
athile
|
athile
|
||||||
BrotherBrick
|
BrotherBrick
|
||||||
Cris “Mirceam” Mihalache
|
Cris “Mirceam” Mihalache
|
||||||
|
|
1
extern/shiny
vendored
Submodule
1
extern/shiny
vendored
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 5546a5bd8474ef328dfedae2df42126cdaf9515f
|
|
@ -1,16 +1,50 @@
|
||||||
project(resources)
|
project(resources)
|
||||||
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/caustic_0.png "${OpenMW_BINARY_DIR}/resources/water/caustic_0.png" COPYONLY)
|
set(WATER_FILES
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/underwater.cg "${OpenMW_BINARY_DIR}/resources/water/underwater.cg" COPYONLY)
|
underwater_dome.mesh
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/perlinvolume.dds "${OpenMW_BINARY_DIR}/resources/water/perlinvolume.dds" COPYONLY)
|
water_nm.png
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/water.compositor "${OpenMW_BINARY_DIR}/resources/water/water.compositor" COPYONLY)
|
)
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/water.material "${OpenMW_BINARY_DIR}/resources/water/water.material" COPYONLY)
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/WaterNormal2.tga "${OpenMW_BINARY_DIR}/resources/water/WaterNormal2.tga" COPYONLY)
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/water.cg "${OpenMW_BINARY_DIR}/resources/water/water.cg" COPYONLY)
|
|
||||||
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/gbuffer/gbuffer.cg "${OpenMW_BINARY_DIR}/resources/gbuffer/gbuffer.cg" COPYONLY)
|
set(GBUFFER_FILES
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/gbuffer/gbuffer.material "${OpenMW_BINARY_DIR}/resources/gbuffer/gbuffer.material" COPYONLY)
|
gbuffer.compositor
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/gbuffer/gbuffer.compositor "${OpenMW_BINARY_DIR}/resources/gbuffer/gbuffer.compositor" COPYONLY)
|
)
|
||||||
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/shadows/depthshadowcaster.material "${OpenMW_BINARY_DIR}/resources/shadows/depthshadowcaster.material" COPYONLY)
|
set(MATERIAL_FILES
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/shadows/depthshadowcaster.cg "${OpenMW_BINARY_DIR}/resources/shadows/depthshadowcaster.cg" COPYONLY)
|
atmosphere.shader
|
||||||
|
atmosphere.shaderset
|
||||||
|
clouds.shader
|
||||||
|
clouds.shaderset
|
||||||
|
core.h
|
||||||
|
moon.shader
|
||||||
|
moon.shaderset
|
||||||
|
objects.mat
|
||||||
|
objects.shader
|
||||||
|
objects.shaderset
|
||||||
|
openmw.configuration
|
||||||
|
quad2.shader
|
||||||
|
quad.mat
|
||||||
|
quad.shader
|
||||||
|
quad.shaderset
|
||||||
|
shadowcaster.mat
|
||||||
|
shadowcaster.shader
|
||||||
|
shadowcaster.shaderset
|
||||||
|
shadows.h
|
||||||
|
sky.mat
|
||||||
|
stars.shader
|
||||||
|
stars.shaderset
|
||||||
|
sun.shader
|
||||||
|
sun.shaderset
|
||||||
|
terrain.shader
|
||||||
|
terrain.shaderset
|
||||||
|
underwater.h
|
||||||
|
water.mat
|
||||||
|
water.shader
|
||||||
|
water.shaderset
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
copy_all_files(${CMAKE_CURRENT_SOURCE_DIR}/water "${OpenMW_BINARY_DIR}/resources/water/" "${WATER_FILES}")
|
||||||
|
|
||||||
|
copy_all_files(${CMAKE_CURRENT_SOURCE_DIR}/gbuffer "${OpenMW_BINARY_DIR}/resources/gbuffer/" "${GBUFFER_FILES}")
|
||||||
|
|
||||||
|
copy_all_files(${CMAKE_CURRENT_SOURCE_DIR}/materials "${OpenMW_BINARY_DIR}/resources/materials/" "${MATERIAL_FILES}")
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
void RenderScene_vs(in float4 position : POSITION
|
|
||||||
,in float2 uv :TEXCOORD0
|
|
||||||
,uniform float4x4 wvp
|
|
||||||
,out float4 oPosition : POSITION
|
|
||||||
,out float2 oUV :TEXCOORD0)
|
|
||||||
{
|
|
||||||
oPosition = mul(wvp, position);
|
|
||||||
oUV = uv;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RenderScene_ps(in float4 position : POSITION
|
|
||||||
,in float2 uv :TEXCOORD0
|
|
||||||
,uniform sampler2D tex1 : TEXUNIT0
|
|
||||||
,out float4 oColor : COLOR)
|
|
||||||
{
|
|
||||||
float4 scene =tex2D(tex1, uv);
|
|
||||||
oColor= scene;
|
|
||||||
}
|
|
|
@ -9,16 +9,21 @@ compositor gbuffer
|
||||||
target mrt_output
|
target mrt_output
|
||||||
{
|
{
|
||||||
input none
|
input none
|
||||||
|
|
||||||
pass clear
|
pass clear
|
||||||
{
|
{
|
||||||
// make sure to set this to the viewport background color from outside
|
|
||||||
colour_value 0 0 0 1
|
colour_value 0 0 0 1
|
||||||
}
|
}
|
||||||
|
pass render_quad
|
||||||
|
{
|
||||||
|
// this makes sure the depth for background is set to 1
|
||||||
|
material openmw_viewport_init
|
||||||
|
}
|
||||||
pass render_scene
|
pass render_scene
|
||||||
{
|
{
|
||||||
// Renders everything except water
|
// Renders everything except water
|
||||||
first_render_queue 0
|
first_render_queue 0
|
||||||
last_render_queue 70
|
last_render_queue 50
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -29,7 +34,7 @@ compositor gbuffer
|
||||||
|
|
||||||
pass render_quad
|
pass render_quad
|
||||||
{
|
{
|
||||||
material RenderScene
|
material quad
|
||||||
input 0 mrt_output 0
|
input 0 mrt_output 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,12 +66,12 @@ compositor gbufferFinalizer
|
||||||
}
|
}
|
||||||
pass render_quad
|
pass render_quad
|
||||||
{
|
{
|
||||||
material RenderSceneNoDepth
|
material quad_noDepthWrite
|
||||||
input 0 previousscene
|
input 0 previousscene
|
||||||
}
|
}
|
||||||
pass render_scene
|
pass render_scene
|
||||||
{
|
{
|
||||||
first_render_queue 71
|
first_render_queue 51
|
||||||
last_render_queue 100
|
last_render_queue 100
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,7 +83,7 @@ compositor gbufferFinalizer
|
||||||
}
|
}
|
||||||
pass render_quad
|
pass render_quad
|
||||||
{
|
{
|
||||||
material RenderSceneNoDepth
|
material quad_noDepthWrite
|
||||||
input 0 no_mrt_output
|
input 0 no_mrt_output
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,63 +0,0 @@
|
||||||
vertex_program RenderGBuffer_vs cg
|
|
||||||
{
|
|
||||||
source gbuffer.cg
|
|
||||||
profiles vs_4_0 vs_1_1 arbvp1
|
|
||||||
entry_point RenderScene_vs
|
|
||||||
default_params
|
|
||||||
{
|
|
||||||
param_named_auto wvp worldviewproj_matrix
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fragment_program RenderGBuffer_ps cg
|
|
||||||
{
|
|
||||||
source gbuffer.cg
|
|
||||||
entry_point RenderScene_ps
|
|
||||||
profiles ps_4_0 ps_2_x arbfp1
|
|
||||||
default_params
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
material RenderScene
|
|
||||||
{
|
|
||||||
technique
|
|
||||||
{
|
|
||||||
pass
|
|
||||||
{
|
|
||||||
vertex_program_ref RenderGBuffer_vs
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
fragment_program_ref RenderGBuffer_ps
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
texture_unit tex1
|
|
||||||
{
|
|
||||||
//scenebuffer
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
material RenderSceneNoDepth
|
|
||||||
{
|
|
||||||
technique
|
|
||||||
{
|
|
||||||
pass
|
|
||||||
{
|
|
||||||
depth_write off
|
|
||||||
vertex_program_ref RenderGBuffer_vs
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
fragment_program_ref RenderGBuffer_ps
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
texture_unit tex1
|
|
||||||
{
|
|
||||||
//scenebuffer
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
37
files/materials/atmosphere.shader
Normal file
37
files/materials/atmosphere.shader
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
#include "core.h"
|
||||||
|
|
||||||
|
#define MRT @shGlobalSettingBool(mrt_output)
|
||||||
|
|
||||||
|
#ifdef SH_VERTEX_SHADER
|
||||||
|
|
||||||
|
SH_BEGIN_PROGRAM
|
||||||
|
shUniform(float4x4, wvp) @shAutoConstant(wvp, worldviewproj_matrix)
|
||||||
|
|
||||||
|
shColourInput(float4)
|
||||||
|
shOutput(float4, colourPassthrough)
|
||||||
|
|
||||||
|
SH_START_PROGRAM
|
||||||
|
{
|
||||||
|
shOutputPosition = shMatrixMult(wvp, shInputPosition);
|
||||||
|
colourPassthrough = colour;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
SH_BEGIN_PROGRAM
|
||||||
|
shInput(float4, colourPassthrough)
|
||||||
|
#if MRT
|
||||||
|
shDeclareMrtOutput(1)
|
||||||
|
#endif
|
||||||
|
shUniform(float4, atmosphereColour) @shSharedParameter(atmosphereColour)
|
||||||
|
|
||||||
|
SH_START_PROGRAM
|
||||||
|
{
|
||||||
|
shOutputColour(0) = colourPassthrough * atmosphereColour;
|
||||||
|
|
||||||
|
#if MRT
|
||||||
|
shOutputColour(1) = float4(1,1,1,1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
15
files/materials/atmosphere.shaderset
Normal file
15
files/materials/atmosphere.shaderset
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
shader_set atmosphere_vertex
|
||||||
|
{
|
||||||
|
source atmosphere.shader
|
||||||
|
type vertex
|
||||||
|
profiles_cg vs_2_0 arbvp1
|
||||||
|
profiles_hlsl vs_2_0
|
||||||
|
}
|
||||||
|
|
||||||
|
shader_set atmosphere_fragment
|
||||||
|
{
|
||||||
|
source atmosphere.shader
|
||||||
|
type fragment
|
||||||
|
profiles_cg ps_2_x ps_2_0 ps arbfp1
|
||||||
|
profiles_hlsl ps_2_0
|
||||||
|
}
|
52
files/materials/clouds.shader
Normal file
52
files/materials/clouds.shader
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
#include "core.h"
|
||||||
|
|
||||||
|
#define MRT @shGlobalSettingBool(mrt_output)
|
||||||
|
|
||||||
|
#ifdef SH_VERTEX_SHADER
|
||||||
|
|
||||||
|
SH_BEGIN_PROGRAM
|
||||||
|
shUniform(float4x4, wvp) @shAutoConstant(wvp, worldviewproj_matrix)
|
||||||
|
shVertexInput(float2, uv0)
|
||||||
|
shOutput(float2, UV)
|
||||||
|
shColourInput(float4)
|
||||||
|
shOutput(float4, colourPassthrough)
|
||||||
|
|
||||||
|
SH_START_PROGRAM
|
||||||
|
{
|
||||||
|
colourPassthrough = colour;
|
||||||
|
shOutputPosition = shMatrixMult(wvp, shInputPosition);
|
||||||
|
UV = uv0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
SH_BEGIN_PROGRAM
|
||||||
|
shInput(float2, UV)
|
||||||
|
shInput(float4, colourPassthrough)
|
||||||
|
#if MRT
|
||||||
|
shDeclareMrtOutput(1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
shSampler2D(diffuseMap1)
|
||||||
|
shSampler2D(diffuseMap2)
|
||||||
|
|
||||||
|
shUniform(float, cloudBlendFactor) @shSharedParameter(cloudBlendFactor)
|
||||||
|
shUniform(float, cloudAnimationTimer) @shSharedParameter(cloudAnimationTimer)
|
||||||
|
shUniform(float, cloudOpacity) @shSharedParameter(cloudOpacity)
|
||||||
|
shUniform(float3, cloudColour) @shSharedParameter(cloudColour)
|
||||||
|
|
||||||
|
SH_START_PROGRAM
|
||||||
|
{
|
||||||
|
// Scroll in y direction
|
||||||
|
float2 scrolledUV = UV + float2(0,1) * cloudAnimationTimer * 0.003;
|
||||||
|
|
||||||
|
float4 albedo = shSample(diffuseMap1, scrolledUV) * (1-cloudBlendFactor) + shSample(diffuseMap2, scrolledUV) * cloudBlendFactor;
|
||||||
|
|
||||||
|
shOutputColour(0) = colourPassthrough * float4(cloudColour, 1) * albedo * float4(1,1,1, cloudOpacity);
|
||||||
|
|
||||||
|
#if MRT
|
||||||
|
shOutputColour(1) = float4(1,1,1,1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
15
files/materials/clouds.shaderset
Normal file
15
files/materials/clouds.shaderset
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
shader_set clouds_vertex
|
||||||
|
{
|
||||||
|
source clouds.shader
|
||||||
|
type vertex
|
||||||
|
profiles_cg vs_2_0 arbvp1
|
||||||
|
profiles_hlsl vs_2_0
|
||||||
|
}
|
||||||
|
|
||||||
|
shader_set clouds_fragment
|
||||||
|
{
|
||||||
|
source clouds.shader
|
||||||
|
type fragment
|
||||||
|
profiles_cg ps_2_x ps_2_0 ps arbfp1
|
||||||
|
profiles_hlsl ps_2_0
|
||||||
|
}
|
159
files/materials/core.h
Normal file
159
files/materials/core.h
Normal file
|
@ -0,0 +1,159 @@
|
||||||
|
#if SH_HLSL == 1 || SH_CG == 1
|
||||||
|
|
||||||
|
#define shTexture2D sampler2D
|
||||||
|
#define shSample(tex, coord) tex2D(tex, coord)
|
||||||
|
#define shLerp(a, b, t) lerp(a, b, t)
|
||||||
|
#define shSaturate(a) saturate(a)
|
||||||
|
|
||||||
|
#define shSampler2D(name) , uniform sampler2D name : register(s@shCounter(0)) @shUseSampler(name)
|
||||||
|
|
||||||
|
#define shMatrixMult(m, v) mul(m, v)
|
||||||
|
|
||||||
|
#define shUniform(type, name) , uniform type name
|
||||||
|
|
||||||
|
#define shVertexInput(type, name) , in type name : TEXCOORD@shCounter(1)
|
||||||
|
#define shInput(type, name) , in type name : TEXCOORD@shCounter(1)
|
||||||
|
#define shOutput(type, name) , out type name : TEXCOORD@shCounter(2)
|
||||||
|
|
||||||
|
#define shNormalInput(type) , in type normal : NORMAL
|
||||||
|
|
||||||
|
#define shColourInput(type) , in type colour : COLOR
|
||||||
|
|
||||||
|
#ifdef SH_VERTEX_SHADER
|
||||||
|
|
||||||
|
#define shOutputPosition oPosition
|
||||||
|
#define shInputPosition iPosition
|
||||||
|
|
||||||
|
|
||||||
|
#define SH_BEGIN_PROGRAM \
|
||||||
|
void main( \
|
||||||
|
float4 iPosition : POSITION \
|
||||||
|
, out float4 oPosition : POSITION
|
||||||
|
|
||||||
|
#define SH_START_PROGRAM \
|
||||||
|
) \
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SH_FRAGMENT_SHADER
|
||||||
|
|
||||||
|
#define shOutputColour(num) oColor##num
|
||||||
|
|
||||||
|
#define shDeclareMrtOutput(num) , out float4 oColor##num : COLOR##num
|
||||||
|
|
||||||
|
#define SH_BEGIN_PROGRAM \
|
||||||
|
void main( \
|
||||||
|
out float4 oColor0 : COLOR
|
||||||
|
|
||||||
|
#define SH_START_PROGRAM \
|
||||||
|
) \
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SH_GLSL == 1
|
||||||
|
|
||||||
|
@version 120
|
||||||
|
|
||||||
|
#define float2 vec2
|
||||||
|
#define float3 vec3
|
||||||
|
#define float4 vec4
|
||||||
|
#define int2 ivec2
|
||||||
|
#define int3 ivec3
|
||||||
|
#define int4 ivec4/
|
||||||
|
#define shTexture2D sampler2D
|
||||||
|
#define shSample(tex, coord) texture2D(tex, coord)
|
||||||
|
#define shLerp(a, b, t) mix(a, b, t)
|
||||||
|
#define shSaturate(a) clamp(a, 0.0, 1.0)
|
||||||
|
|
||||||
|
#define shUniform(type, name) uniform type name;
|
||||||
|
|
||||||
|
#define shSampler2D(name) uniform sampler2D name; @shUseSampler(name)
|
||||||
|
|
||||||
|
#define shMatrixMult(m, v) (m * v)
|
||||||
|
|
||||||
|
#define shOutputPosition gl_Position
|
||||||
|
|
||||||
|
#define float4x4 mat4
|
||||||
|
|
||||||
|
// GLSL 1.3
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
// automatically recognized by ogre when the input name equals this
|
||||||
|
#define shInputPosition vertex
|
||||||
|
|
||||||
|
#define shOutputColour(num) oColor##num
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define shInput(type, name) in type name;
|
||||||
|
#define shOutput(type, name) out type name;
|
||||||
|
|
||||||
|
// automatically recognized by ogre when the input name equals this
|
||||||
|
#define shNormalInput(type) in type normal;
|
||||||
|
#define shColourInput(type) in type colour;
|
||||||
|
|
||||||
|
#ifdef SH_VERTEX_SHADER
|
||||||
|
|
||||||
|
#define SH_BEGIN_PROGRAM \
|
||||||
|
in float4 shInputPosition;
|
||||||
|
#define SH_START_PROGRAM \
|
||||||
|
void main(void)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SH_FRAGMENT_SHADER
|
||||||
|
|
||||||
|
#define shDeclareMrtOutput(num) out vec4 oColor##num;
|
||||||
|
|
||||||
|
#define SH_BEGIN_PROGRAM \
|
||||||
|
out float4 oColor0;
|
||||||
|
#define SH_START_PROGRAM \
|
||||||
|
void main(void)
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// GLSL 1.2
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
|
||||||
|
// automatically recognized by ogre when the input name equals this
|
||||||
|
#define shInputPosition gl_Vertex
|
||||||
|
|
||||||
|
#define shOutputColour(num) gl_FragData[num]
|
||||||
|
|
||||||
|
#define shVertexInput(type, name) attribute type name;
|
||||||
|
#define shInput(type, name) varying type name;
|
||||||
|
#define shOutput(type, name) varying type name;
|
||||||
|
|
||||||
|
// automatically recognized by ogre when the input name equals this
|
||||||
|
#define shNormalInput(type) attribute type normal;
|
||||||
|
#define shColourInput(type) attribute type colour;
|
||||||
|
|
||||||
|
#ifdef SH_VERTEX_SHADER
|
||||||
|
|
||||||
|
#define SH_BEGIN_PROGRAM
|
||||||
|
|
||||||
|
#define SH_START_PROGRAM \
|
||||||
|
void main(void)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SH_FRAGMENT_SHADER
|
||||||
|
|
||||||
|
#define shDeclareMrtOutput(num)
|
||||||
|
|
||||||
|
#define SH_BEGIN_PROGRAM
|
||||||
|
|
||||||
|
#define SH_START_PROGRAM \
|
||||||
|
void main(void)
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
51
files/materials/moon.shader
Normal file
51
files/materials/moon.shader
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
#include "core.h"
|
||||||
|
|
||||||
|
#define MRT @shGlobalSettingBool(mrt_output)
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef SH_VERTEX_SHADER
|
||||||
|
|
||||||
|
SH_BEGIN_PROGRAM
|
||||||
|
shUniform(float4x4, wvp) @shAutoConstant(wvp, worldviewproj_matrix)
|
||||||
|
shVertexInput(float2, uv0)
|
||||||
|
shOutput(float2, UV)
|
||||||
|
|
||||||
|
SH_START_PROGRAM
|
||||||
|
{
|
||||||
|
shOutputPosition = shMatrixMult(wvp, shInputPosition);
|
||||||
|
UV = uv0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
SH_BEGIN_PROGRAM
|
||||||
|
shSampler2D(diffuseMap)
|
||||||
|
shSampler2D(alphaMap)
|
||||||
|
shInput(float2, UV)
|
||||||
|
#if MRT
|
||||||
|
shDeclareMrtOutput(1)
|
||||||
|
#endif
|
||||||
|
shUniform(float4, materialDiffuse) @shAutoConstant(materialDiffuse, surface_diffuse_colour)
|
||||||
|
shUniform(float4, materialEmissive) @shAutoConstant(materialEmissive, surface_emissive_colour)
|
||||||
|
|
||||||
|
shUniform(float4, atmosphereColour) @shSharedParameter(atmosphereColour)
|
||||||
|
|
||||||
|
SH_START_PROGRAM
|
||||||
|
{
|
||||||
|
|
||||||
|
float4 tex = shSample(diffuseMap, UV);
|
||||||
|
|
||||||
|
shOutputColour(0) = float4(materialEmissive.xyz, 1) * tex;
|
||||||
|
|
||||||
|
shOutputColour(0).a = shSample(alphaMap, UV).a * materialDiffuse.a;
|
||||||
|
|
||||||
|
shOutputColour(0).rgb += (1-tex.a) * shOutputColour(0).a * atmosphereColour.rgb; //fill dark side of moon with atmosphereColour
|
||||||
|
shOutputColour(0).rgb += (1-materialDiffuse.a) * atmosphereColour.rgb; //fade bump
|
||||||
|
|
||||||
|
#if MRT
|
||||||
|
shOutputColour(1) = float4(1,1,1,1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
15
files/materials/moon.shaderset
Normal file
15
files/materials/moon.shaderset
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
shader_set moon_vertex
|
||||||
|
{
|
||||||
|
source moon.shader
|
||||||
|
type vertex
|
||||||
|
profiles_cg vs_2_0 arbvp1
|
||||||
|
profiles_hlsl vs_2_0
|
||||||
|
}
|
||||||
|
|
||||||
|
shader_set moon_fragment
|
||||||
|
{
|
||||||
|
source moon.shader
|
||||||
|
type fragment
|
||||||
|
profiles_cg ps_2_x ps_2_0 ps arbfp1
|
||||||
|
profiles_hlsl ps_2_0
|
||||||
|
}
|
67
files/materials/objects.mat
Normal file
67
files/materials/objects.mat
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
material openmw_objects_base
|
||||||
|
{
|
||||||
|
diffuse 1.0 1.0 1.0 1.0
|
||||||
|
specular 0.4 0.4 0.4 32
|
||||||
|
ambient 1.0 1.0 1.0
|
||||||
|
emissive 0.0 0.0 0.0
|
||||||
|
has_vertex_colour false
|
||||||
|
diffuseMap black.png
|
||||||
|
|
||||||
|
is_transparent false // real transparency, alpha rejection doesn't count here
|
||||||
|
scene_blend default
|
||||||
|
depth_write default
|
||||||
|
alpha_rejection default
|
||||||
|
|
||||||
|
pass
|
||||||
|
{
|
||||||
|
vertex_program openmw_objects_vertex
|
||||||
|
fragment_program openmw_objects_fragment
|
||||||
|
|
||||||
|
shader_properties
|
||||||
|
{
|
||||||
|
has_vertex_colour $has_vertex_colour
|
||||||
|
is_transparent $is_transparent
|
||||||
|
}
|
||||||
|
|
||||||
|
diffuse $diffuse
|
||||||
|
specular $specular
|
||||||
|
ambient $ambient
|
||||||
|
emissive $emissive
|
||||||
|
scene_blend $scene_blend
|
||||||
|
alpha_rejection $alpha_rejection
|
||||||
|
depth_write $depth_write
|
||||||
|
|
||||||
|
ffp_vertex_colour_ambient $has_vertex_colour
|
||||||
|
|
||||||
|
|
||||||
|
texture_unit diffuseMap
|
||||||
|
{
|
||||||
|
direct_texture $diffuseMap
|
||||||
|
create_in_ffp true
|
||||||
|
}
|
||||||
|
|
||||||
|
texture_unit shadowMap0
|
||||||
|
{
|
||||||
|
content_type shadow
|
||||||
|
tex_address_mode clamp
|
||||||
|
filtering none
|
||||||
|
}
|
||||||
|
texture_unit shadowMap1
|
||||||
|
{
|
||||||
|
content_type shadow
|
||||||
|
tex_address_mode clamp
|
||||||
|
filtering none
|
||||||
|
}
|
||||||
|
texture_unit shadowMap2
|
||||||
|
{
|
||||||
|
content_type shadow
|
||||||
|
tex_address_mode clamp
|
||||||
|
filtering none
|
||||||
|
}
|
||||||
|
|
||||||
|
texture_unit causticMap
|
||||||
|
{
|
||||||
|
direct_texture water_nm.png
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
299
files/materials/objects.shader
Normal file
299
files/materials/objects.shader
Normal file
|
@ -0,0 +1,299 @@
|
||||||
|
#include "core.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define FOG @shGlobalSettingBool(fog)
|
||||||
|
#define MRT @shPropertyNotBool(is_transparent) && @shGlobalSettingBool(mrt_output)
|
||||||
|
#define LIGHTING @shGlobalSettingBool(lighting)
|
||||||
|
|
||||||
|
#define SHADOWS_PSSM LIGHTING && @shGlobalSettingBool(shadows_pssm)
|
||||||
|
#define SHADOWS LIGHTING && @shGlobalSettingBool(shadows)
|
||||||
|
|
||||||
|
#if SHADOWS || SHADOWS_PSSM
|
||||||
|
#include "shadows.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if FOG || MRT || SHADOWS_PSSM
|
||||||
|
#define NEED_DEPTH
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define UNDERWATER @shGlobalSettingBool(underwater_effects) && LIGHTING
|
||||||
|
|
||||||
|
|
||||||
|
#define HAS_VERTEXCOLOR @shPropertyBool(has_vertex_colour)
|
||||||
|
|
||||||
|
#ifdef SH_VERTEX_SHADER
|
||||||
|
|
||||||
|
// ------------------------------------- VERTEX ---------------------------------------
|
||||||
|
|
||||||
|
SH_BEGIN_PROGRAM
|
||||||
|
shUniform(float4x4, wvp) @shAutoConstant(wvp, worldviewproj_matrix)
|
||||||
|
shVertexInput(float2, uv0)
|
||||||
|
shOutput(float2, UV)
|
||||||
|
shNormalInput(float4)
|
||||||
|
#ifdef NEED_DEPTH
|
||||||
|
shOutput(float, depthPassthrough)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LIGHTING
|
||||||
|
shOutput(float3, normalPassthrough)
|
||||||
|
shOutput(float3, objSpacePositionPassthrough)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAS_VERTEXCOLOR
|
||||||
|
shColourInput(float4)
|
||||||
|
shOutput(float4, colourPassthrough)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SHADOWS
|
||||||
|
shOutput(float4, lightSpacePos0)
|
||||||
|
shUniform(float4x4, texViewProjMatrix0) @shAutoConstant(texViewProjMatrix0, texture_viewproj_matrix)
|
||||||
|
shUniform(float4x4, worldMatrix) @shAutoConstant(worldMatrix, world_matrix)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SHADOWS_PSSM
|
||||||
|
@shForeach(3)
|
||||||
|
shOutput(float4, lightSpacePos@shIterator)
|
||||||
|
shUniform(float4x4, texViewProjMatrix@shIterator) @shAutoConstant(texViewProjMatrix@shIterator, texture_viewproj_matrix, @shIterator)
|
||||||
|
@shEndForeach
|
||||||
|
shUniform(float4x4, worldMatrix) @shAutoConstant(worldMatrix, world_matrix)
|
||||||
|
#endif
|
||||||
|
SH_START_PROGRAM
|
||||||
|
{
|
||||||
|
shOutputPosition = shMatrixMult(wvp, shInputPosition);
|
||||||
|
UV = uv0;
|
||||||
|
#if LIGHTING
|
||||||
|
normalPassthrough = normal.xyz;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NEED_DEPTH
|
||||||
|
depthPassthrough = shOutputPosition.z;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LIGHTING
|
||||||
|
objSpacePositionPassthrough = shInputPosition.xyz;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAS_VERTEXCOLOR
|
||||||
|
colourPassthrough = colour;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SHADOWS
|
||||||
|
lightSpacePos0 = shMatrixMult(texViewProjMatrix0, shMatrixMult(worldMatrix, shInputPosition));
|
||||||
|
#endif
|
||||||
|
#if SHADOWS_PSSM
|
||||||
|
float4 wPos = shMatrixMult(worldMatrix, shInputPosition);
|
||||||
|
@shForeach(3)
|
||||||
|
lightSpacePos@shIterator = shMatrixMult(texViewProjMatrix@shIterator, wPos);
|
||||||
|
@shEndForeach
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// ----------------------------------- FRAGMENT ------------------------------------------
|
||||||
|
|
||||||
|
#if UNDERWATER
|
||||||
|
#include "underwater.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SH_BEGIN_PROGRAM
|
||||||
|
shSampler2D(diffuseMap)
|
||||||
|
shInput(float2, UV)
|
||||||
|
#if MRT
|
||||||
|
shDeclareMrtOutput(1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NEED_DEPTH
|
||||||
|
shInput(float, depthPassthrough)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MRT
|
||||||
|
shUniform(float, far) @shAutoConstant(far, far_clip_distance)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LIGHTING
|
||||||
|
shInput(float3, normalPassthrough)
|
||||||
|
shInput(float3, objSpacePositionPassthrough)
|
||||||
|
shUniform(float4, lightAmbient) @shAutoConstant(lightAmbient, ambient_light_colour)
|
||||||
|
//shUniform(float, passIteration) @shAutoConstant(passIteration, pass_iteration_number)
|
||||||
|
shUniform(float4, materialAmbient) @shAutoConstant(materialAmbient, surface_ambient_colour)
|
||||||
|
shUniform(float4, materialDiffuse) @shAutoConstant(materialDiffuse, surface_diffuse_colour)
|
||||||
|
shUniform(float4, materialEmissive) @shAutoConstant(materialEmissive, surface_emissive_colour)
|
||||||
|
@shForeach(@shGlobalSettingString(num_lights))
|
||||||
|
shUniform(float4, lightPosObjSpace@shIterator) @shAutoConstant(lightPosObjSpace@shIterator, light_position_object_space, @shIterator)
|
||||||
|
shUniform(float4, lightAttenuation@shIterator) @shAutoConstant(lightAttenuation@shIterator, light_attenuation, @shIterator)
|
||||||
|
shUniform(float4, lightDiffuse@shIterator) @shAutoConstant(lightDiffuse@shIterator, light_diffuse_colour, @shIterator)
|
||||||
|
@shEndForeach
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if FOG
|
||||||
|
shUniform(float3, fogColour) @shAutoConstant(fogColour, fog_colour)
|
||||||
|
shUniform(float4, fogParams) @shAutoConstant(fogParams, fog_params)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAS_VERTEXCOLOR
|
||||||
|
shInput(float4, colourPassthrough)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SHADOWS
|
||||||
|
shInput(float4, lightSpacePos0)
|
||||||
|
shSampler2D(shadowMap0)
|
||||||
|
shUniform(float2, invShadowmapSize0) @shAutoConstant(invShadowmapSize0, inverse_texture_size, 1)
|
||||||
|
#endif
|
||||||
|
#if SHADOWS_PSSM
|
||||||
|
@shForeach(3)
|
||||||
|
shInput(float4, lightSpacePos@shIterator)
|
||||||
|
shSampler2D(shadowMap@shIterator)
|
||||||
|
shUniform(float2, invShadowmapSize@shIterator) @shAutoConstant(invShadowmapSize@shIterator, inverse_texture_size, @shIterator(1))
|
||||||
|
@shEndForeach
|
||||||
|
shUniform(float3, pssmSplitPoints) @shSharedParameter(pssmSplitPoints)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SHADOWS || SHADOWS_PSSM
|
||||||
|
shUniform(float4, shadowFar_fadeStart) @shSharedParameter(shadowFar_fadeStart)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if UNDERWATER
|
||||||
|
shUniform(float4x4, worldMatrix) @shAutoConstant(worldMatrix, world_matrix)
|
||||||
|
shUniform(float, waterLevel) @shSharedParameter(waterLevel)
|
||||||
|
shUniform(float4, cameraPos) @shAutoConstant(cameraPos, camera_position)
|
||||||
|
shUniform(float4, lightDirectionWS0) @shAutoConstant(lightDirectionWS0, light_position, 0)
|
||||||
|
|
||||||
|
shSampler2D(causticMap)
|
||||||
|
|
||||||
|
shUniform(float, waterTimer) @shSharedParameter(waterTimer)
|
||||||
|
shUniform(float2, waterSunFade_sunHeight) @shSharedParameter(waterSunFade_sunHeight)
|
||||||
|
shUniform(float, waterEnabled) @shSharedParameter(waterEnabled)
|
||||||
|
|
||||||
|
shUniform(float3, windDir_windSpeed) @shSharedParameter(windDir_windSpeed)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SH_START_PROGRAM
|
||||||
|
{
|
||||||
|
shOutputColour(0) = shSample(diffuseMap, UV);
|
||||||
|
|
||||||
|
#if LIGHTING
|
||||||
|
float3 normal = normalize(normalPassthrough);
|
||||||
|
float3 lightDir;
|
||||||
|
float3 diffuse = float3(0,0,0);
|
||||||
|
float d;
|
||||||
|
float3 ambient = materialAmbient.xyz * lightAmbient.xyz;
|
||||||
|
|
||||||
|
|
||||||
|
// shadows only for the first (directional) light
|
||||||
|
#if SHADOWS
|
||||||
|
float shadow = depthShadowPCF (shadowMap0, lightSpacePos0, invShadowmapSize0);
|
||||||
|
#endif
|
||||||
|
#if SHADOWS_PSSM
|
||||||
|
float shadow = pssmDepthShadow (lightSpacePos0, invShadowmapSize0, shadowMap0, lightSpacePos1, invShadowmapSize1, shadowMap1, lightSpacePos2, invShadowmapSize2, shadowMap2, depthPassthrough, pssmSplitPoints);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SHADOWS || SHADOWS_PSSM
|
||||||
|
float fadeRange = shadowFar_fadeStart.x - shadowFar_fadeStart.y;
|
||||||
|
float fade = 1-((depthPassthrough - shadowFar_fadeStart.y) / fadeRange);
|
||||||
|
shadow = (depthPassthrough > shadowFar_fadeStart.x) ? 1 : ((depthPassthrough > shadowFar_fadeStart.y) ? 1-((1-shadow)*fade) : shadow);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !SHADOWS && !SHADOWS_PSSM
|
||||||
|
float shadow = 1.0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
float3 caustics = float3(1,1,1);
|
||||||
|
#if UNDERWATER
|
||||||
|
float3 worldPos = shMatrixMult(worldMatrix, float4(objSpacePositionPassthrough,1)).xyz;
|
||||||
|
float3 waterEyePos = float3(1,1,1);
|
||||||
|
if (worldPos.y < waterLevel && waterEnabled == 1)
|
||||||
|
{
|
||||||
|
// NOTE: this calculation would be wrong for non-uniform scaling
|
||||||
|
float4 worldNormal = shMatrixMult(worldMatrix, float4(normal.xyz, 0));
|
||||||
|
waterEyePos = intercept(worldPos, cameraPos.xyz - worldPos, float3(0,1,0), waterLevel);
|
||||||
|
caustics = getCaustics(causticMap, worldPos, waterEyePos.xyz, worldNormal.xyz, lightDirectionWS0.xyz, waterLevel, waterTimer, windDir_windSpeed);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@shForeach(@shGlobalSettingString(num_lights))
|
||||||
|
|
||||||
|
/// \todo use the array auto params for lights, and use a real for-loop with auto param "light_count" iterations
|
||||||
|
lightDir = lightPosObjSpace@shIterator.xyz - (objSpacePositionPassthrough.xyz * lightPosObjSpace@shIterator.w);
|
||||||
|
d = length(lightDir);
|
||||||
|
|
||||||
|
lightDir = normalize(lightDir);
|
||||||
|
|
||||||
|
#if @shIterator == 0
|
||||||
|
|
||||||
|
#if (SHADOWS || SHADOWS_PSSM)
|
||||||
|
diffuse += materialDiffuse.xyz * lightDiffuse@shIterator.xyz * (1.0 / ((lightAttenuation@shIterator.y) + (lightAttenuation@shIterator.z * d) + (lightAttenuation@shIterator.w * d * d))) * max(dot(normal, lightDir), 0) * shadow * caustics;
|
||||||
|
|
||||||
|
#else
|
||||||
|
diffuse += materialDiffuse.xyz * lightDiffuse@shIterator.xyz * (1.0 / ((lightAttenuation@shIterator.y) + (lightAttenuation@shIterator.z * d) + (lightAttenuation@shIterator.w * d * d))) * max(dot(normal, lightDir), 0) * caustics;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
diffuse += materialDiffuse.xyz * lightDiffuse@shIterator.xyz * (1.0 / ((lightAttenuation@shIterator.y) + (lightAttenuation@shIterator.z * d) + (lightAttenuation@shIterator.w * d * d))) * max(dot(normal, lightDir), 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@shEndForeach
|
||||||
|
|
||||||
|
#if HAS_VERTEXCOLOR
|
||||||
|
ambient *= colourPassthrough.xyz;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
shOutputColour(0).xyz *= (ambient + diffuse + materialEmissive.xyz);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if HAS_VERTEXCOLOR && !LIGHTING
|
||||||
|
shOutputColour(0).xyz *= colourPassthrough.xyz;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if FOG
|
||||||
|
float fogValue = shSaturate((depthPassthrough - fogParams.y) * fogParams.w);
|
||||||
|
|
||||||
|
#if UNDERWATER
|
||||||
|
// regular fog only if fragment is above water
|
||||||
|
if (worldPos.y > waterLevel)
|
||||||
|
#endif
|
||||||
|
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, fogColour, fogValue);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// prevent negative colour output (for example with negative lights)
|
||||||
|
shOutputColour(0).xyz = max(shOutputColour(0).xyz, float3(0,0,0));
|
||||||
|
|
||||||
|
#if UNDERWATER
|
||||||
|
float fogAmount = (cameraPos.y > waterLevel)
|
||||||
|
? shSaturate(length(waterEyePos-worldPos) / VISIBILITY)
|
||||||
|
: shSaturate(length(cameraPos.xyz-worldPos)/ VISIBILITY);
|
||||||
|
|
||||||
|
float3 eyeVec = normalize(cameraPos.xyz-worldPos);
|
||||||
|
|
||||||
|
float waterSunGradient = dot(eyeVec, -normalize(lightDirectionWS0.xyz));
|
||||||
|
waterSunGradient = shSaturate(pow(waterSunGradient*0.7+0.3,2.0));
|
||||||
|
float3 waterSunColour = float3(0.0,1.0,0.85)*waterSunGradient * 0.5;
|
||||||
|
|
||||||
|
float waterGradient = dot(eyeVec, float3(0.0,-1.0,0.0));
|
||||||
|
waterGradient = clamp((waterGradient*0.5+0.5),0.2,1.0);
|
||||||
|
float3 watercolour = (float3(0.0078, 0.5176, 0.700)+waterSunColour)*waterGradient*2.0;
|
||||||
|
float3 waterext = float3(0.6, 0.9, 1.0);//water extinction
|
||||||
|
watercolour = shLerp(watercolour*0.3*waterSunFade_sunHeight.x, watercolour, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT)));
|
||||||
|
watercolour = (cameraPos.y <= waterLevel) ? watercolour : watercolour*0.3;
|
||||||
|
|
||||||
|
|
||||||
|
float darkness = VISIBILITY*2.0;
|
||||||
|
darkness = clamp((waterEyePos.y - waterLevel + darkness)/darkness,0.2,1.0);
|
||||||
|
watercolour *= darkness;
|
||||||
|
|
||||||
|
float isUnderwater = (worldPos.y < waterLevel) ? 1.0 : 0.0;
|
||||||
|
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, watercolour, fogAmount * isUnderwater * waterEnabled);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MRT
|
||||||
|
shOutputColour(1) = float4(depthPassthrough / far,1,1,1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
15
files/materials/objects.shaderset
Normal file
15
files/materials/objects.shaderset
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
shader_set openmw_objects_vertex
|
||||||
|
{
|
||||||
|
source objects.shader
|
||||||
|
type vertex
|
||||||
|
profiles_cg vs_2_0 vp40 arbvp1
|
||||||
|
profiles_hlsl vs_2_0
|
||||||
|
}
|
||||||
|
|
||||||
|
shader_set openmw_objects_fragment
|
||||||
|
{
|
||||||
|
source objects.shader
|
||||||
|
type fragment
|
||||||
|
profiles_cg ps_2_x ps_2_0 ps fp40 arbfp1
|
||||||
|
profiles_hlsl ps_2_0
|
||||||
|
}
|
17
files/materials/openmw.configuration
Normal file
17
files/materials/openmw.configuration
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
configuration water_reflection
|
||||||
|
{
|
||||||
|
fog false
|
||||||
|
shadows false
|
||||||
|
shadows_pssm false
|
||||||
|
mrt_output false
|
||||||
|
}
|
||||||
|
|
||||||
|
configuration local_map
|
||||||
|
{
|
||||||
|
fog false
|
||||||
|
mrt_output false
|
||||||
|
lighting false
|
||||||
|
shadows false
|
||||||
|
shadows_pssm false
|
||||||
|
simple_water true
|
||||||
|
}
|
35
files/materials/quad.mat
Normal file
35
files/materials/quad.mat
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
material quad
|
||||||
|
{
|
||||||
|
depth_write on
|
||||||
|
|
||||||
|
pass
|
||||||
|
{
|
||||||
|
vertex_program quad_vertex
|
||||||
|
fragment_program quad_fragment
|
||||||
|
|
||||||
|
depth_write $depth_write
|
||||||
|
|
||||||
|
texture_unit SceneBuffer
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
material quad_noDepthWrite
|
||||||
|
{
|
||||||
|
parent quad
|
||||||
|
depth_write off
|
||||||
|
}
|
||||||
|
|
||||||
|
material openmw_viewport_init
|
||||||
|
{
|
||||||
|
pass
|
||||||
|
{
|
||||||
|
vertex_program viewport_init_vertex
|
||||||
|
fragment_program viewport_init_fragment
|
||||||
|
|
||||||
|
depth_write off
|
||||||
|
depth_check off
|
||||||
|
scene_blend add
|
||||||
|
}
|
||||||
|
}
|
25
files/materials/quad.shader
Normal file
25
files/materials/quad.shader
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#include "core.h"
|
||||||
|
|
||||||
|
#ifdef SH_VERTEX_SHADER
|
||||||
|
|
||||||
|
SH_BEGIN_PROGRAM
|
||||||
|
shVertexInput(float2, uv0)
|
||||||
|
shOutput(float2, UV)
|
||||||
|
shUniform(float4x4, wvp) @shAutoConstant(wvp, worldviewproj_matrix)
|
||||||
|
SH_START_PROGRAM
|
||||||
|
{
|
||||||
|
shOutputPosition = shMatrixMult(wvp, shInputPosition);
|
||||||
|
UV = uv0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
SH_BEGIN_PROGRAM
|
||||||
|
shInput(float2, UV)
|
||||||
|
shSampler2D(SceneBuffer)
|
||||||
|
SH_START_PROGRAM
|
||||||
|
{
|
||||||
|
shOutputColour(0) = shSample(SceneBuffer, UV);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
31
files/materials/quad.shaderset
Normal file
31
files/materials/quad.shaderset
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
shader_set quad_vertex
|
||||||
|
{
|
||||||
|
source quad.shader
|
||||||
|
type vertex
|
||||||
|
profiles_cg vs_2_0 vp40 arbvp1
|
||||||
|
profiles_hlsl vs_2_0
|
||||||
|
}
|
||||||
|
|
||||||
|
shader_set quad_fragment
|
||||||
|
{
|
||||||
|
source quad.shader
|
||||||
|
type fragment
|
||||||
|
profiles_cg ps_2_x ps_2_0 ps fp40 arbfp1
|
||||||
|
profiles_hlsl ps_2_0
|
||||||
|
}
|
||||||
|
|
||||||
|
shader_set viewport_init_vertex
|
||||||
|
{
|
||||||
|
source quad2.shader
|
||||||
|
type vertex
|
||||||
|
profiles_cg vs_2_0 vp40 arbvp1
|
||||||
|
profiles_hlsl vs_2_0
|
||||||
|
}
|
||||||
|
|
||||||
|
shader_set viewport_init_fragment
|
||||||
|
{
|
||||||
|
source quad2.shader
|
||||||
|
type fragment
|
||||||
|
profiles_cg ps_2_x ps_2_0 ps fp40 arbfp1
|
||||||
|
profiles_hlsl ps_2_0
|
||||||
|
}
|
23
files/materials/quad2.shader
Normal file
23
files/materials/quad2.shader
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#include "core.h"
|
||||||
|
|
||||||
|
#ifdef SH_VERTEX_SHADER
|
||||||
|
|
||||||
|
SH_BEGIN_PROGRAM
|
||||||
|
shUniform(float4x4, wvp) @shAutoConstant(wvp, worldviewproj_matrix)
|
||||||
|
SH_START_PROGRAM
|
||||||
|
{
|
||||||
|
shOutputPosition = shMatrixMult(wvp, shInputPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
SH_BEGIN_PROGRAM
|
||||||
|
shUniform(float3, viewportBackground) @shSharedParameter(viewportBackground)
|
||||||
|
shDeclareMrtOutput(1)
|
||||||
|
SH_START_PROGRAM
|
||||||
|
{
|
||||||
|
shOutputColour(0) = float4(viewportBackground, 1);
|
||||||
|
shOutputColour(1) = float4(1,1,1,1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
35
files/materials/shadowcaster.mat
Normal file
35
files/materials/shadowcaster.mat
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
material openmw_shadowcaster_default
|
||||||
|
{
|
||||||
|
create_configuration Default
|
||||||
|
allow_fixed_function false
|
||||||
|
pass
|
||||||
|
{
|
||||||
|
fog_override true
|
||||||
|
|
||||||
|
vertex_program openmw_shadowcaster_vertex
|
||||||
|
fragment_program openmw_shadowcaster_fragment
|
||||||
|
|
||||||
|
shader_properties
|
||||||
|
{
|
||||||
|
shadow_transparency true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
material openmw_shadowcaster_noalpha
|
||||||
|
{
|
||||||
|
create_configuration Default
|
||||||
|
allow_fixed_function false
|
||||||
|
pass
|
||||||
|
{
|
||||||
|
fog_override true
|
||||||
|
|
||||||
|
vertex_program openmw_shadowcaster_vertex
|
||||||
|
fragment_program openmw_shadowcaster_fragment
|
||||||
|
|
||||||
|
shader_properties
|
||||||
|
{
|
||||||
|
shadow_transparency false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
56
files/materials/shadowcaster.shader
Normal file
56
files/materials/shadowcaster.shader
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
#include "core.h"
|
||||||
|
|
||||||
|
#define ALPHA @shPropertyBool(shadow_transparency)
|
||||||
|
|
||||||
|
#ifdef SH_VERTEX_SHADER
|
||||||
|
|
||||||
|
SH_BEGIN_PROGRAM
|
||||||
|
#if ALPHA
|
||||||
|
shVertexInput(float2, uv0)
|
||||||
|
shOutput(float2, UV)
|
||||||
|
#endif
|
||||||
|
shUniform(float4x4, wvp) @shAutoConstant(wvp, worldviewproj_matrix)
|
||||||
|
shOutput(float2, depth)
|
||||||
|
SH_START_PROGRAM
|
||||||
|
{
|
||||||
|
// this is the view space position
|
||||||
|
shOutputPosition = shMatrixMult(wvp, shInputPosition);
|
||||||
|
|
||||||
|
// depth info for the fragment.
|
||||||
|
depth.x = shOutputPosition.z;
|
||||||
|
depth.y = shOutputPosition.w;
|
||||||
|
|
||||||
|
// clamp z to zero. seem to do the trick. :-/
|
||||||
|
shOutputPosition.z = max(shOutputPosition.z, 0);
|
||||||
|
|
||||||
|
#if ALPHA
|
||||||
|
UV = uv0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
SH_BEGIN_PROGRAM
|
||||||
|
#if ALPHA
|
||||||
|
shInput(float2, UV)
|
||||||
|
shSampler2D(texture1)
|
||||||
|
#endif
|
||||||
|
shInput(float2, depth)
|
||||||
|
SH_START_PROGRAM
|
||||||
|
{
|
||||||
|
float finalDepth = depth.x / depth.y;
|
||||||
|
|
||||||
|
|
||||||
|
#if ALPHA
|
||||||
|
// use alpha channel of the first texture
|
||||||
|
float alpha = shSample(texture1, UV).a;
|
||||||
|
|
||||||
|
// discard if alpha is less than 0.5
|
||||||
|
if (alpha < 1.0)
|
||||||
|
discard;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
shOutputColour(0) = float4(finalDepth, finalDepth, finalDepth, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
15
files/materials/shadowcaster.shaderset
Normal file
15
files/materials/shadowcaster.shaderset
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
shader_set openmw_shadowcaster_vertex
|
||||||
|
{
|
||||||
|
source shadowcaster.shader
|
||||||
|
type vertex
|
||||||
|
profiles_cg vs_2_0 arbvp1
|
||||||
|
profiles_hlsl vs_2_0
|
||||||
|
}
|
||||||
|
|
||||||
|
shader_set openmw_shadowcaster_fragment
|
||||||
|
{
|
||||||
|
source shadowcaster.shader
|
||||||
|
type fragment
|
||||||
|
profiles_cg ps_2_x ps_2_0 ps arbfp1
|
||||||
|
profiles_hlsl ps_2_0
|
||||||
|
}
|
45
files/materials/shadows.h
Normal file
45
files/materials/shadows.h
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
|
||||||
|
float depthShadowPCF (shTexture2D shadowMap, float4 shadowMapPos, float2 offset)
|
||||||
|
{
|
||||||
|
shadowMapPos /= shadowMapPos.w;
|
||||||
|
float3 o = float3(offset.xy, -offset.x) * 0.3;
|
||||||
|
//float3 o = float3(0,0,0);
|
||||||
|
float c = (shadowMapPos.z <= shSample(shadowMap, shadowMapPos.xy - o.xy).r) ? 1 : 0; // top left
|
||||||
|
c += (shadowMapPos.z <= shSample(shadowMap, shadowMapPos.xy + o.xy).r) ? 1 : 0; // bottom right
|
||||||
|
c += (shadowMapPos.z <= shSample(shadowMap, shadowMapPos.xy + o.zy).r) ? 1 : 0; // bottom left
|
||||||
|
c += (shadowMapPos.z <= shSample(shadowMap, shadowMapPos.xy - o.zy).r) ? 1 : 0; // top right
|
||||||
|
return c / 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
float pssmDepthShadow (
|
||||||
|
|
||||||
|
|
||||||
|
float4 lightSpacePos0,
|
||||||
|
float2 invShadowmapSize0,
|
||||||
|
shTexture2D shadowMap0,
|
||||||
|
|
||||||
|
float4 lightSpacePos1,
|
||||||
|
float2 invShadowmapSize1,
|
||||||
|
shTexture2D shadowMap1,
|
||||||
|
|
||||||
|
float4 lightSpacePos2,
|
||||||
|
float2 invShadowmapSize2,
|
||||||
|
shTexture2D shadowMap2,
|
||||||
|
|
||||||
|
float depth,
|
||||||
|
float3 pssmSplitPoints)
|
||||||
|
|
||||||
|
{
|
||||||
|
float shadow;
|
||||||
|
|
||||||
|
if (depth < pssmSplitPoints.x)
|
||||||
|
shadow = depthShadowPCF(shadowMap0, lightSpacePos0, invShadowmapSize0);
|
||||||
|
else if (depth < pssmSplitPoints.y)
|
||||||
|
shadow = depthShadowPCF(shadowMap1, lightSpacePos1, invShadowmapSize1);
|
||||||
|
else
|
||||||
|
shadow = depthShadowPCF(shadowMap2, lightSpacePos2, invShadowmapSize2);
|
||||||
|
|
||||||
|
return shadow;
|
||||||
|
}
|
108
files/materials/sky.mat
Normal file
108
files/materials/sky.mat
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
material openmw_moon
|
||||||
|
{
|
||||||
|
allow_fixed_function false
|
||||||
|
pass
|
||||||
|
{
|
||||||
|
vertex_program moon_vertex
|
||||||
|
fragment_program moon_fragment
|
||||||
|
|
||||||
|
polygon_mode_overrideable off
|
||||||
|
depth_write off
|
||||||
|
depth_check off
|
||||||
|
scene_blend alpha_blend
|
||||||
|
|
||||||
|
texture_unit diffuseMap
|
||||||
|
{
|
||||||
|
texture_alias $texture
|
||||||
|
}
|
||||||
|
|
||||||
|
texture_unit alphaMap
|
||||||
|
{
|
||||||
|
direct_texture textures\tx_secunda_full.dds
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
material openmw_clouds
|
||||||
|
{
|
||||||
|
allow_fixed_function false
|
||||||
|
pass
|
||||||
|
{
|
||||||
|
vertex_program clouds_vertex
|
||||||
|
fragment_program clouds_fragment
|
||||||
|
|
||||||
|
polygon_mode_overrideable off
|
||||||
|
|
||||||
|
scene_blend alpha_blend
|
||||||
|
depth_write off
|
||||||
|
|
||||||
|
// second diffuse map is used for weather transitions
|
||||||
|
texture_unit diffuseMap1
|
||||||
|
{
|
||||||
|
texture_alias cloud_texture_1
|
||||||
|
}
|
||||||
|
|
||||||
|
texture_unit diffuseMap2
|
||||||
|
{
|
||||||
|
texture_alias cloud_texture_2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
material openmw_atmosphere
|
||||||
|
{
|
||||||
|
allow_fixed_function false
|
||||||
|
pass
|
||||||
|
{
|
||||||
|
vertex_program atmosphere_vertex
|
||||||
|
fragment_program atmosphere_fragment
|
||||||
|
|
||||||
|
polygon_mode_overrideable off
|
||||||
|
|
||||||
|
scene_blend alpha_blend
|
||||||
|
depth_write off
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
material openmw_stars
|
||||||
|
{
|
||||||
|
allow_fixed_function false
|
||||||
|
pass
|
||||||
|
{
|
||||||
|
vertex_program stars_vertex
|
||||||
|
fragment_program stars_fragment
|
||||||
|
|
||||||
|
polygon_mode_overrideable off
|
||||||
|
|
||||||
|
depth_check off
|
||||||
|
depth_write off
|
||||||
|
scene_blend alpha_blend
|
||||||
|
|
||||||
|
texture_unit diffuseMap
|
||||||
|
{
|
||||||
|
direct_texture $texture
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// used for both sun and sun glare
|
||||||
|
material openmw_sun
|
||||||
|
{
|
||||||
|
allow_fixed_function false
|
||||||
|
pass
|
||||||
|
{
|
||||||
|
vertex_program sun_vertex
|
||||||
|
fragment_program sun_fragment
|
||||||
|
|
||||||
|
polygon_mode_overrideable off
|
||||||
|
|
||||||
|
depth_check off
|
||||||
|
depth_write off
|
||||||
|
scene_blend alpha_blend
|
||||||
|
|
||||||
|
texture_unit diffuseMap
|
||||||
|
{
|
||||||
|
direct_texture $texture
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
46
files/materials/stars.shader
Normal file
46
files/materials/stars.shader
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
#include "core.h"
|
||||||
|
|
||||||
|
#define MRT @shGlobalSettingBool(mrt_output)
|
||||||
|
|
||||||
|
#ifdef SH_VERTEX_SHADER
|
||||||
|
|
||||||
|
SH_BEGIN_PROGRAM
|
||||||
|
shUniform(float4x4, wvp) @shAutoConstant(wvp, worldviewproj_matrix)
|
||||||
|
|
||||||
|
shVertexInput(float2, uv0)
|
||||||
|
shOutput(float2, UV)
|
||||||
|
shOutput(float, fade)
|
||||||
|
|
||||||
|
SH_START_PROGRAM
|
||||||
|
{
|
||||||
|
shOutputPosition = shMatrixMult(wvp, shInputPosition);
|
||||||
|
UV = uv0;
|
||||||
|
|
||||||
|
fade = (shInputPosition.z > 50) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
SH_BEGIN_PROGRAM
|
||||||
|
#if MRT
|
||||||
|
shDeclareMrtOutput(1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
shInput(float2, UV)
|
||||||
|
shInput(float, fade)
|
||||||
|
|
||||||
|
shSampler2D(diffuseMap)
|
||||||
|
shUniform(float, nightFade) @shSharedParameter(nightFade)
|
||||||
|
|
||||||
|
|
||||||
|
SH_START_PROGRAM
|
||||||
|
{
|
||||||
|
shOutputColour(0) = shSample(diffuseMap, UV) * float4(1,1,1, nightFade * fade);
|
||||||
|
|
||||||
|
|
||||||
|
#if MRT
|
||||||
|
shOutputColour(1) = float4(1,1,1,1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
15
files/materials/stars.shaderset
Normal file
15
files/materials/stars.shaderset
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
shader_set stars_vertex
|
||||||
|
{
|
||||||
|
source stars.shader
|
||||||
|
type vertex
|
||||||
|
profiles_cg vs_2_0 arbvp1
|
||||||
|
profiles_hlsl vs_2_0
|
||||||
|
}
|
||||||
|
|
||||||
|
shader_set stars_fragment
|
||||||
|
{
|
||||||
|
source stars.shader
|
||||||
|
type fragment
|
||||||
|
profiles_cg ps_2_x ps_2_0 ps arbfp1
|
||||||
|
profiles_hlsl ps_2_0
|
||||||
|
}
|
39
files/materials/sun.shader
Normal file
39
files/materials/sun.shader
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
#include "core.h"
|
||||||
|
|
||||||
|
#define MRT @shGlobalSettingBool(mrt_output)
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef SH_VERTEX_SHADER
|
||||||
|
|
||||||
|
SH_BEGIN_PROGRAM
|
||||||
|
shUniform(float4x4, wvp) @shAutoConstant(wvp, worldviewproj_matrix)
|
||||||
|
shVertexInput(float2, uv0)
|
||||||
|
shOutput(float2, UV)
|
||||||
|
|
||||||
|
SH_START_PROGRAM
|
||||||
|
{
|
||||||
|
shOutputPosition = shMatrixMult(wvp, shInputPosition);
|
||||||
|
UV = uv0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
SH_BEGIN_PROGRAM
|
||||||
|
shSampler2D(diffuseMap)
|
||||||
|
shInput(float2, UV)
|
||||||
|
#if MRT
|
||||||
|
shDeclareMrtOutput(1)
|
||||||
|
#endif
|
||||||
|
shUniform(float4, materialDiffuse) @shAutoConstant(materialDiffuse, surface_diffuse_colour)
|
||||||
|
//shUniform(float4, materialEmissive) @shAutoConstant(materialEmissive, surface_emissive_colour)
|
||||||
|
|
||||||
|
SH_START_PROGRAM
|
||||||
|
{
|
||||||
|
shOutputColour(0) = float4(1,1,1,materialDiffuse.a) * shSample(diffuseMap, UV);
|
||||||
|
|
||||||
|
#if MRT
|
||||||
|
shOutputColour(1) = float4(1,1,1,1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
15
files/materials/sun.shaderset
Normal file
15
files/materials/sun.shaderset
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
shader_set sun_vertex
|
||||||
|
{
|
||||||
|
source sun.shader
|
||||||
|
type vertex
|
||||||
|
profiles_cg vs_2_0 arbvp1
|
||||||
|
profiles_hlsl vs_2_0
|
||||||
|
}
|
||||||
|
|
||||||
|
shader_set sun_fragment
|
||||||
|
{
|
||||||
|
source sun.shader
|
||||||
|
type fragment
|
||||||
|
profiles_cg ps_2_x ps_2_0 ps arbfp1
|
||||||
|
profiles_hlsl ps_2_0
|
||||||
|
}
|
377
files/materials/terrain.shader
Normal file
377
files/materials/terrain.shader
Normal file
|
@ -0,0 +1,377 @@
|
||||||
|
#include "core.h"
|
||||||
|
|
||||||
|
#define IS_FIRST_PASS 1
|
||||||
|
|
||||||
|
#define FOG @shGlobalSettingBool(fog)
|
||||||
|
#define MRT @shGlobalSettingBool(mrt_output)
|
||||||
|
|
||||||
|
#define LIGHTING @shGlobalSettingBool(lighting)
|
||||||
|
|
||||||
|
#define SHADOWS_PSSM LIGHTING && @shGlobalSettingBool(shadows_pssm)
|
||||||
|
#define SHADOWS LIGHTING && @shGlobalSettingBool(shadows)
|
||||||
|
|
||||||
|
#if SHADOWS || SHADOWS_PSSM
|
||||||
|
#include "shadows.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define COLOUR_MAP @shPropertyBool(colour_map)
|
||||||
|
|
||||||
|
#define NUM_LAYERS @shPropertyString(num_layers)
|
||||||
|
|
||||||
|
#if MRT || FOG || SHADOWS_PSSM
|
||||||
|
#define NEED_DEPTH 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define UNDERWATER @shGlobalSettingBool(underwater_effects) && LIGHTING
|
||||||
|
|
||||||
|
|
||||||
|
#if NEED_DEPTH
|
||||||
|
@shAllocatePassthrough(1, depth)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@shAllocatePassthrough(2, UV)
|
||||||
|
|
||||||
|
#if LIGHTING
|
||||||
|
@shAllocatePassthrough(3, objSpacePosition)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SHADOWS
|
||||||
|
@shAllocatePassthrough(4, lightSpacePos0)
|
||||||
|
#endif
|
||||||
|
#if SHADOWS_PSSM
|
||||||
|
@shForeach(3)
|
||||||
|
@shAllocatePassthrough(4, lightSpacePos@shIterator)
|
||||||
|
@shEndForeach
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SH_VERTEX_SHADER
|
||||||
|
|
||||||
|
// ------------------------------------- VERTEX ---------------------------------------
|
||||||
|
|
||||||
|
SH_BEGIN_PROGRAM
|
||||||
|
shUniform(float4x4, worldMatrix) @shAutoConstant(worldMatrix, world_matrix)
|
||||||
|
shUniform(float4x4, viewProjMatrix) @shAutoConstant(viewProjMatrix, viewproj_matrix)
|
||||||
|
|
||||||
|
shUniform(float2, lodMorph) @shAutoConstant(lodMorph, custom, 1001)
|
||||||
|
|
||||||
|
shVertexInput(float2, uv0)
|
||||||
|
shVertexInput(float2, delta) // lodDelta, lodThreshold
|
||||||
|
|
||||||
|
#if SHADOWS
|
||||||
|
shUniform(float4x4, texViewProjMatrix0) @shAutoConstant(texViewProjMatrix0, texture_viewproj_matrix)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SHADOWS_PSSM
|
||||||
|
@shForeach(3)
|
||||||
|
shUniform(float4x4, texViewProjMatrix@shIterator) @shAutoConstant(texViewProjMatrix@shIterator, texture_viewproj_matrix, @shIterator)
|
||||||
|
@shEndForeach
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@shPassthroughVertexOutputs
|
||||||
|
|
||||||
|
SH_START_PROGRAM
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
float4 worldPos = shMatrixMult(worldMatrix, shInputPosition);
|
||||||
|
|
||||||
|
// determine whether to apply the LOD morph to this vertex
|
||||||
|
// we store the deltas against all vertices so we only want to apply
|
||||||
|
// the morph to the ones which would disappear. The target LOD which is
|
||||||
|
// being morphed to is stored in lodMorph.y, and the LOD at which
|
||||||
|
// the vertex should be morphed is stored in uv.w. If we subtract
|
||||||
|
// the former from the latter, and arrange to only morph if the
|
||||||
|
// result is negative (it will only be -1 in fact, since after that
|
||||||
|
// the vertex will never be indexed), we will achieve our aim.
|
||||||
|
// sign(vertexLOD - targetLOD) == -1 is to morph
|
||||||
|
float toMorph = -min(0, sign(delta.y - lodMorph.y));
|
||||||
|
|
||||||
|
// morph
|
||||||
|
// this assumes XZ terrain alignment
|
||||||
|
worldPos.y += delta.x * toMorph * lodMorph.x;
|
||||||
|
|
||||||
|
|
||||||
|
shOutputPosition = shMatrixMult(viewProjMatrix, worldPos);
|
||||||
|
|
||||||
|
#if NEED_DEPTH
|
||||||
|
@shPassthroughAssign(depth, shOutputPosition.z);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@shPassthroughAssign(UV, uv0);
|
||||||
|
|
||||||
|
#if LIGHTING
|
||||||
|
@shPassthroughAssign(objSpacePosition, shInputPosition.xyz);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SHADOWS
|
||||||
|
float4 lightSpacePos = shMatrixMult(texViewProjMatrix0, shMatrixMult(worldMatrix, shInputPosition));
|
||||||
|
@shPassthroughAssign(lightSpacePos0, lightSpacePos);
|
||||||
|
#endif
|
||||||
|
#if SHADOWS_PSSM
|
||||||
|
float4 wPos = shMatrixMult(worldMatrix, shInputPosition);
|
||||||
|
|
||||||
|
float4 lightSpacePos;
|
||||||
|
@shForeach(3)
|
||||||
|
lightSpacePos = shMatrixMult(texViewProjMatrix@shIterator, wPos);
|
||||||
|
@shPassthroughAssign(lightSpacePos@shIterator, lightSpacePos);
|
||||||
|
@shEndForeach
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// ----------------------------------- FRAGMENT ------------------------------------------
|
||||||
|
|
||||||
|
#if UNDERWATER
|
||||||
|
#include "underwater.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SH_BEGIN_PROGRAM
|
||||||
|
|
||||||
|
|
||||||
|
#if COLOUR_MAP
|
||||||
|
shSampler2D(colourMap)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
shSampler2D(normalMap) // global normal map
|
||||||
|
|
||||||
|
|
||||||
|
@shForeach(@shPropertyString(num_blendmaps))
|
||||||
|
shSampler2D(blendMap@shIterator)
|
||||||
|
@shEndForeach
|
||||||
|
|
||||||
|
@shForeach(@shPropertyString(num_layers))
|
||||||
|
shSampler2D(diffuseMap@shIterator)
|
||||||
|
@shEndForeach
|
||||||
|
|
||||||
|
#if FOG
|
||||||
|
shUniform(float3, fogColour) @shAutoConstant(fogColour, fog_colour)
|
||||||
|
shUniform(float4, fogParams) @shAutoConstant(fogParams, fog_params)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@shPassthroughFragmentInputs
|
||||||
|
|
||||||
|
#if MRT
|
||||||
|
shDeclareMrtOutput(1)
|
||||||
|
shUniform(float, far) @shAutoConstant(far, far_clip_distance)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if LIGHTING
|
||||||
|
shUniform(float4, lightAmbient) @shAutoConstant(lightAmbient, ambient_light_colour)
|
||||||
|
@shForeach(@shGlobalSettingString(num_lights))
|
||||||
|
shUniform(float4, lightPosObjSpace@shIterator) @shAutoConstant(lightPosObjSpace@shIterator, light_position_object_space, @shIterator)
|
||||||
|
shUniform(float4, lightAttenuation@shIterator) @shAutoConstant(lightAttenuation@shIterator, light_attenuation, @shIterator)
|
||||||
|
shUniform(float4, lightDiffuse@shIterator) @shAutoConstant(lightDiffuse@shIterator, light_diffuse_colour, @shIterator)
|
||||||
|
@shEndForeach
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if SHADOWS
|
||||||
|
shSampler2D(shadowMap0)
|
||||||
|
shUniform(float2, invShadowmapSize0) @shAutoConstant(invShadowmapSize0, inverse_texture_size, @shPropertyString(shadowtexture_offset))
|
||||||
|
#endif
|
||||||
|
#if SHADOWS_PSSM
|
||||||
|
@shForeach(3)
|
||||||
|
shSampler2D(shadowMap@shIterator)
|
||||||
|
shUniform(float2, invShadowmapSize@shIterator) @shAutoConstant(invShadowmapSize@shIterator, inverse_texture_size, @shIterator(@shPropertyString(shadowtexture_offset)))
|
||||||
|
@shEndForeach
|
||||||
|
shUniform(float3, pssmSplitPoints) @shSharedParameter(pssmSplitPoints)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SHADOWS || SHADOWS_PSSM
|
||||||
|
shUniform(float4, shadowFar_fadeStart) @shSharedParameter(shadowFar_fadeStart)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if UNDERWATER
|
||||||
|
shUniform(float4x4, worldMatrix) @shAutoConstant(worldMatrix, world_matrix)
|
||||||
|
shUniform(float, waterLevel) @shSharedParameter(waterLevel)
|
||||||
|
shUniform(float4, cameraPos) @shAutoConstant(cameraPos, camera_position)
|
||||||
|
shUniform(float4, lightDirectionWS0) @shAutoConstant(lightDirectionWS0, light_position, 0)
|
||||||
|
|
||||||
|
shSampler2D(causticMap)
|
||||||
|
|
||||||
|
shUniform(float, waterTimer) @shSharedParameter(waterTimer)
|
||||||
|
shUniform(float2, waterSunFade_sunHeight) @shSharedParameter(waterSunFade_sunHeight)
|
||||||
|
|
||||||
|
shUniform(float3, windDir_windSpeed) @shSharedParameter(windDir_windSpeed)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
SH_START_PROGRAM
|
||||||
|
{
|
||||||
|
|
||||||
|
#if NEED_DEPTH
|
||||||
|
float depth = @shPassthroughReceive(depth);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
float2 UV = @shPassthroughReceive(UV);
|
||||||
|
|
||||||
|
#if LIGHTING
|
||||||
|
float3 objSpacePosition = @shPassthroughReceive(objSpacePosition);
|
||||||
|
|
||||||
|
float3 normal = shSample(normalMap, UV).rgb * 2 - 1;
|
||||||
|
normal = normalize(normal);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
float3 caustics = float3(1,1,1);
|
||||||
|
#if UNDERWATER
|
||||||
|
|
||||||
|
float3 worldPos = shMatrixMult(worldMatrix, float4(objSpacePosition,1)).xyz;
|
||||||
|
float3 waterEyePos = float3(1,1,1);
|
||||||
|
if (worldPos.y < waterLevel)
|
||||||
|
{
|
||||||
|
// NOTE: this calculation would be wrong for non-uniform scaling
|
||||||
|
float4 worldNormal = shMatrixMult(worldMatrix, float4(normal.xyz, 0));
|
||||||
|
waterEyePos = intercept(worldPos, cameraPos.xyz - worldPos, float3(0,1,0), waterLevel);
|
||||||
|
caustics = getCaustics(causticMap, worldPos, waterEyePos.xyz, worldNormal.xyz, lightDirectionWS0.xyz, waterLevel, waterTimer, windDir_windSpeed);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// Layer calculations
|
||||||
|
@shForeach(@shPropertyString(num_blendmaps))
|
||||||
|
float4 blendValues@shIterator = shSample(blendMap@shIterator, UV);
|
||||||
|
@shEndForeach
|
||||||
|
|
||||||
|
float3 albedo = float3(0,0,0);
|
||||||
|
@shForeach(@shPropertyString(num_layers))
|
||||||
|
|
||||||
|
|
||||||
|
#if IS_FIRST_PASS == 1 && @shIterator == 0
|
||||||
|
// first layer of first pass doesn't need a blend map
|
||||||
|
albedo = shSample(diffuseMap0, UV * 10).rgb;
|
||||||
|
#else
|
||||||
|
albedo = shLerp(albedo, shSample(diffuseMap@shIterator, UV * 10).rgb, blendValues@shPropertyString(blendmap_component_@shIterator));
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@shEndForeach
|
||||||
|
|
||||||
|
shOutputColour(0) = float4(1,1,1,1);
|
||||||
|
|
||||||
|
#if COLOUR_MAP
|
||||||
|
shOutputColour(0).rgb *= shSample(colourMap, UV).rgb;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
shOutputColour(0).rgb *= albedo;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Lighting
|
||||||
|
|
||||||
|
#if LIGHTING
|
||||||
|
// shadows only for the first (directional) light
|
||||||
|
#if SHADOWS
|
||||||
|
float4 lightSpacePos0 = @shPassthroughReceive(lightSpacePos0);
|
||||||
|
float shadow = depthShadowPCF (shadowMap0, lightSpacePos0, invShadowmapSize0);
|
||||||
|
#endif
|
||||||
|
#if SHADOWS_PSSM
|
||||||
|
@shForeach(3)
|
||||||
|
float4 lightSpacePos@shIterator = @shPassthroughReceive(lightSpacePos@shIterator);
|
||||||
|
@shEndForeach
|
||||||
|
|
||||||
|
float shadow = pssmDepthShadow (lightSpacePos0, invShadowmapSize0, shadowMap0, lightSpacePos1, invShadowmapSize1, shadowMap1, lightSpacePos2, invShadowmapSize2, shadowMap2, depth, pssmSplitPoints);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SHADOWS || SHADOWS_PSSM
|
||||||
|
float fadeRange = shadowFar_fadeStart.x - shadowFar_fadeStart.y;
|
||||||
|
float fade = 1-((depth - shadowFar_fadeStart.y) / fadeRange);
|
||||||
|
shadow = (depth > shadowFar_fadeStart.x) ? 1 : ((depth > shadowFar_fadeStart.y) ? 1-((1-shadow)*fade) : shadow);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !SHADOWS && !SHADOWS_PSSM
|
||||||
|
float shadow = 1.0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
float3 lightDir;
|
||||||
|
float3 diffuse = float3(0,0,0);
|
||||||
|
float d;
|
||||||
|
|
||||||
|
@shForeach(@shGlobalSettingString(num_lights))
|
||||||
|
|
||||||
|
lightDir = lightPosObjSpace@shIterator.xyz - (objSpacePosition.xyz * lightPosObjSpace@shIterator.w);
|
||||||
|
d = length(lightDir);
|
||||||
|
|
||||||
|
|
||||||
|
lightDir = normalize(lightDir);
|
||||||
|
|
||||||
|
#if @shIterator == 0
|
||||||
|
|
||||||
|
#if (SHADOWS || SHADOWS_PSSM)
|
||||||
|
diffuse += lightDiffuse@shIterator.xyz * (1.0 / ((lightAttenuation@shIterator.y) + (lightAttenuation@shIterator.z * d) + (lightAttenuation@shIterator.w * d * d))) * max(dot(normal, lightDir), 0) * shadow * caustics;
|
||||||
|
|
||||||
|
#else
|
||||||
|
diffuse += lightDiffuse@shIterator.xyz * (1.0 / ((lightAttenuation@shIterator.y) + (lightAttenuation@shIterator.z * d) + (lightAttenuation@shIterator.w * d * d))) * max(dot(normal, lightDir), 0) * caustics;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
diffuse += lightDiffuse@shIterator.xyz * (1.0 / ((lightAttenuation@shIterator.y) + (lightAttenuation@shIterator.z * d) + (lightAttenuation@shIterator.w * d * d))) * max(dot(normal, lightDir), 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@shEndForeach
|
||||||
|
|
||||||
|
shOutputColour(0).xyz *= (lightAmbient.xyz + diffuse);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if FOG
|
||||||
|
float fogValue = shSaturate((depth - fogParams.y) * fogParams.w);
|
||||||
|
|
||||||
|
#if UNDERWATER
|
||||||
|
// regular fog only if fragment is above water
|
||||||
|
if (worldPos.y > waterLevel)
|
||||||
|
#endif
|
||||||
|
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, fogColour, fogValue);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// prevent negative colour output (for example with negative lights)
|
||||||
|
shOutputColour(0).xyz = max(shOutputColour(0).xyz, float3(0,0,0));
|
||||||
|
|
||||||
|
#if UNDERWATER
|
||||||
|
float fogAmount = (cameraPos.y > waterLevel)
|
||||||
|
? shSaturate(length(waterEyePos-worldPos) / VISIBILITY)
|
||||||
|
: shSaturate(length(cameraPos.xyz-worldPos)/ VISIBILITY);
|
||||||
|
|
||||||
|
float3 eyeVec = normalize(cameraPos.xyz-worldPos);
|
||||||
|
|
||||||
|
float waterSunGradient = dot(eyeVec, -normalize(lightDirectionWS0.xyz));
|
||||||
|
waterSunGradient = shSaturate(pow(waterSunGradient*0.7+0.3,2.0));
|
||||||
|
float3 waterSunColour = float3(0.0,1.0,0.85)*waterSunGradient * 0.5;
|
||||||
|
|
||||||
|
float waterGradient = dot(eyeVec, float3(0.0,-1.0,0.0));
|
||||||
|
waterGradient = clamp((waterGradient*0.5+0.5),0.2,1.0);
|
||||||
|
float3 watercolour = (float3(0.0078, 0.5176, 0.700)+waterSunColour)*waterGradient*2.0;
|
||||||
|
float3 waterext = float3(0.6, 0.9, 1.0);//water extinction
|
||||||
|
watercolour = shLerp(watercolour*0.3*waterSunFade_sunHeight.x, watercolour, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT)));
|
||||||
|
watercolour = (cameraPos.y <= waterLevel) ? watercolour : watercolour*0.3;
|
||||||
|
|
||||||
|
|
||||||
|
float darkness = VISIBILITY*2.0;
|
||||||
|
darkness = clamp((waterEyePos.y - waterLevel + darkness)/darkness,0.2,1.0);
|
||||||
|
watercolour *= darkness;
|
||||||
|
|
||||||
|
float isUnderwater = (worldPos.y < waterLevel) ? 1.0 : 0.0;
|
||||||
|
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, watercolour, fogAmount * isUnderwater);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if MRT
|
||||||
|
shOutputColour(1) = float4(depth / far,1,1,1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
15
files/materials/terrain.shaderset
Normal file
15
files/materials/terrain.shaderset
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
shader_set terrain_vertex
|
||||||
|
{
|
||||||
|
source terrain.shader
|
||||||
|
type vertex
|
||||||
|
profiles_cg vs_2_0 vp40 arbvp1
|
||||||
|
profiles_hlsl vs_2_0
|
||||||
|
}
|
||||||
|
|
||||||
|
shader_set terrain_fragment
|
||||||
|
{
|
||||||
|
source terrain.shader
|
||||||
|
type fragment
|
||||||
|
profiles_cg ps_2_x ps_2_0 ps fp40 arbfp1
|
||||||
|
profiles_hlsl ps_2_0
|
||||||
|
}
|
118
files/materials/underwater.h
Normal file
118
files/materials/underwater.h
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
#define VISIBILITY 1500.0 // how far you can look through water
|
||||||
|
|
||||||
|
#define BIG_WAVES_X 0.3 // strength of big waves
|
||||||
|
#define BIG_WAVES_Y 0.3
|
||||||
|
|
||||||
|
#define MID_WAVES_X 0.3 // strength of middle sized waves
|
||||||
|
#define MID_WAVES_Y 0.15
|
||||||
|
|
||||||
|
#define SMALL_WAVES_X 0.15 // strength of small waves
|
||||||
|
#define SMALL_WAVES_Y 0.1
|
||||||
|
|
||||||
|
#define WAVE_CHOPPYNESS 0.15 // wave choppyness
|
||||||
|
#define WAVE_SCALE 0.01 // overall wave scale
|
||||||
|
|
||||||
|
#define ABBERATION 0.001 // chromatic abberation amount
|
||||||
|
|
||||||
|
#define SUN_EXT float3(0.45, 0.55, 0.68) //sunlight extinction
|
||||||
|
|
||||||
|
float3 intercept(float3 lineP,
|
||||||
|
float3 lineN,
|
||||||
|
float3 planeN,
|
||||||
|
float planeD)
|
||||||
|
{
|
||||||
|
|
||||||
|
float distance = (planeD - dot(planeN, lineP)) / dot(lineN, planeN);
|
||||||
|
return lineP + lineN * distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
float3 perturb1(shTexture2D tex, float2 coords, float bend, float2 windDir, float windSpeed, float timer)
|
||||||
|
{
|
||||||
|
float2 nCoord = float2(0.0);
|
||||||
|
bend *= WAVE_CHOPPYNESS;
|
||||||
|
nCoord = coords * (WAVE_SCALE * 0.05) + windDir * timer * (windSpeed*0.04);
|
||||||
|
float3 normal0 = 2.0 * shSample(tex, nCoord + float2(-timer*0.015,-timer*0.05)).rgb - 1.0;
|
||||||
|
nCoord = coords * (WAVE_SCALE * 0.1) + windDir * timer * (windSpeed*0.08)-normal0.xy*bend;
|
||||||
|
float3 normal1 = 2.0 * shSample(tex, nCoord + float2(+timer*0.020,+timer*0.015)).rgb - 1.0;
|
||||||
|
|
||||||
|
nCoord = coords * (WAVE_SCALE * 0.25) + windDir * timer * (windSpeed*0.07)-normal1.xy*bend;
|
||||||
|
float3 normal2 = 2.0 * shSample(tex, nCoord + float2(-timer*0.04,-timer*0.03)).rgb - 1.0;
|
||||||
|
nCoord = coords * (WAVE_SCALE * 0.5) + windDir * timer * (windSpeed*0.09)-normal2.xy*bend;
|
||||||
|
float3 normal3 = 2.0 * shSample(tex, nCoord + float2(+timer*0.03,+timer*0.04)).rgb - 1.0;
|
||||||
|
|
||||||
|
nCoord = coords * (WAVE_SCALE* 1.0) + windDir * timer * (windSpeed*0.4)-normal3.xy*bend;
|
||||||
|
float3 normal4 = 2.0 * shSample(tex, nCoord + float2(-timer*0.2,+timer*0.1)).rgb - 1.0;
|
||||||
|
nCoord = coords * (WAVE_SCALE * 2.0) + windDir * timer * (windSpeed*0.7)-normal4.xy*bend;
|
||||||
|
float3 normal5 = 2.0 * shSample(tex, nCoord + float2(+timer*0.1,-timer*0.06)).rgb - 1.0;
|
||||||
|
|
||||||
|
|
||||||
|
float3 normal = normalize(normal0 * BIG_WAVES_X + normal1 * BIG_WAVES_Y +
|
||||||
|
normal2 * MID_WAVES_X + normal3 * MID_WAVES_Y +
|
||||||
|
normal4 * SMALL_WAVES_X + normal5 * SMALL_WAVES_Y);
|
||||||
|
return normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
float3 perturb(shTexture2D tex, float2 coords, float bend, float2 windDir, float windSpeed, float timer)
|
||||||
|
{
|
||||||
|
bend *= WAVE_CHOPPYNESS;
|
||||||
|
float3 col = float3(0.0);
|
||||||
|
float2 nCoord = float2(0.0); //normal coords
|
||||||
|
|
||||||
|
nCoord = coords * (WAVE_SCALE * 0.025) + windDir * timer * (windSpeed*0.03);
|
||||||
|
col += shSample(tex,nCoord + float2(-timer*0.005,-timer*0.01)).rgb*0.20;
|
||||||
|
nCoord = coords * (WAVE_SCALE * 0.1) + windDir * timer * (windSpeed*0.05)-(col.xy/col.zz)*bend;
|
||||||
|
col += shSample(tex,nCoord + float2(+timer*0.01,+timer*0.005)).rgb*0.20;
|
||||||
|
|
||||||
|
nCoord = coords * (WAVE_SCALE * 0.2) + windDir * timer * (windSpeed*0.1)-(col.xy/col.zz)*bend;
|
||||||
|
col += shSample(tex,nCoord + float2(-timer*0.02,-timer*0.03)).rgb*0.20;
|
||||||
|
nCoord = coords * (WAVE_SCALE * 0.5) + windDir * timer * (windSpeed*0.2)-(col.xy/col.zz)*bend;
|
||||||
|
col += shSample(tex,nCoord + float2(+timer*0.03,+timer*0.02)).rgb*0.15;
|
||||||
|
|
||||||
|
nCoord = coords * (WAVE_SCALE* 0.8) + windDir * timer * (windSpeed*1.0)-(col.xy/col.zz)*bend;
|
||||||
|
col += shSample(tex, nCoord + float2(-timer*0.06,+timer*0.08)).rgb*0.15;
|
||||||
|
nCoord = coords * (WAVE_SCALE * 1.0) + windDir * timer * (windSpeed*1.3)-(col.xy/col.zz)*bend;
|
||||||
|
col += shSample(tex,nCoord + float2(+timer*0.08,-timer*0.06)).rgb*0.10;
|
||||||
|
|
||||||
|
return col;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float3 getCaustics (shTexture2D causticMap, float3 worldPos, float3 waterEyePos, float3 worldNormal, float3 lightDirectionWS0, float waterLevel, float waterTimer, float3 windDir_windSpeed)
|
||||||
|
{
|
||||||
|
float waterDepth = shSaturate((waterEyePos.y - worldPos.y) / 50.0);
|
||||||
|
|
||||||
|
float3 causticPos = intercept(worldPos.xyz, lightDirectionWS0.xyz, float3(0,1,0), waterLevel);
|
||||||
|
|
||||||
|
///\ todo clean this up
|
||||||
|
float causticdepth = length(causticPos-worldPos.xyz);
|
||||||
|
causticdepth = 1.0-shSaturate(causticdepth / VISIBILITY);
|
||||||
|
causticdepth = shSaturate(causticdepth);
|
||||||
|
|
||||||
|
// NOTE: the original shader calculated a tangent space basis here,
|
||||||
|
// but using only the world normal is cheaper and i couldn't see a visual difference
|
||||||
|
// also, if this effect gets moved to screen-space some day, it's unlikely to have tangent information
|
||||||
|
float3 causticNorm = worldNormal.xyz * perturb(causticMap, causticPos.xz, causticdepth, windDir_windSpeed.xy, windDir_windSpeed.z, waterTimer).xzy * 2 - 1;
|
||||||
|
|
||||||
|
//float fresnel = pow(clamp(dot(LV,causticnorm),0.0,1.0),2.0);
|
||||||
|
|
||||||
|
float NdotL = max(dot(worldNormal.xyz, lightDirectionWS0.xyz),0.0);
|
||||||
|
|
||||||
|
float causticR = 1.0-perturb(causticMap, causticPos.xz, causticdepth, windDir_windSpeed.xy, windDir_windSpeed.z, waterTimer).z;
|
||||||
|
|
||||||
|
/// \todo sunFade
|
||||||
|
|
||||||
|
// float3 caustics = clamp(pow(float3(causticR)*5.5,float3(5.5*causticdepth)),0.0,1.0)*NdotL*sunFade*causticdepth;
|
||||||
|
float3 caustics = clamp(pow(float3(causticR)*5.5,float3(5.5*causticdepth)),0.0,1.0)*NdotL*causticdepth;
|
||||||
|
float causticG = 1.0-perturb(causticMap,causticPos.xz+(1.0-causticdepth)*ABBERATION, causticdepth, windDir_windSpeed.xy, windDir_windSpeed.z, waterTimer).z;
|
||||||
|
float causticB = 1.0-perturb(causticMap,causticPos.xz+(1.0-causticdepth)*ABBERATION*2.0, causticdepth, windDir_windSpeed.xy, windDir_windSpeed.z, waterTimer).z;
|
||||||
|
//caustics = shSaturate(pow(float3(causticR,causticG,causticB)*5.5,float3(5.5*causticdepth)))*NdotL*sunFade*causticdepth;
|
||||||
|
caustics = shSaturate(pow(float3(causticR,causticG,causticB)*5.5,float3(5.5*causticdepth)))*NdotL*causticdepth;
|
||||||
|
|
||||||
|
caustics *= 3;
|
||||||
|
|
||||||
|
// shore transition
|
||||||
|
caustics = shLerp (float3(1,1,1), caustics, waterDepth);
|
||||||
|
|
||||||
|
return caustics;
|
||||||
|
}
|
||||||
|
|
55
files/materials/water.mat
Normal file
55
files/materials/water.mat
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
material Water
|
||||||
|
{
|
||||||
|
pass
|
||||||
|
{
|
||||||
|
emissive 0.6 0.7 1.0
|
||||||
|
ambient 0 0 0
|
||||||
|
diffuse 0 0 0 1
|
||||||
|
specular 0 0 0 32
|
||||||
|
|
||||||
|
vertex_program water_vertex
|
||||||
|
fragment_program water_fragment
|
||||||
|
|
||||||
|
cull_hardware none
|
||||||
|
|
||||||
|
texture_unit reflectionMap
|
||||||
|
{
|
||||||
|
texture_alias WaterReflection
|
||||||
|
tex_address_mode clamp
|
||||||
|
}
|
||||||
|
|
||||||
|
texture_unit refractionMap
|
||||||
|
{
|
||||||
|
texture_alias WaterRefraction
|
||||||
|
tex_address_mode clamp
|
||||||
|
}
|
||||||
|
|
||||||
|
texture_unit depthMap
|
||||||
|
{
|
||||||
|
texture_alias SceneDepth
|
||||||
|
tex_address_mode clamp
|
||||||
|
}
|
||||||
|
|
||||||
|
texture_unit normalMap
|
||||||
|
{
|
||||||
|
direct_texture water_nm.png
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// for simple_water
|
||||||
|
texture_unit animatedTexture
|
||||||
|
{
|
||||||
|
create_in_ffp true
|
||||||
|
scale 0.1 0.1
|
||||||
|
alpha_op_ex source1 src_manual src_current 0.7
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
material Underwater_Dome
|
||||||
|
{
|
||||||
|
parent openmw_objects_base
|
||||||
|
|
||||||
|
depth_write off
|
||||||
|
}
|
307
files/materials/water.shader
Normal file
307
files/materials/water.shader
Normal file
|
@ -0,0 +1,307 @@
|
||||||
|
#include "core.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define SIMPLE_WATER @shGlobalSettingBool(simple_water)
|
||||||
|
|
||||||
|
|
||||||
|
#if SIMPLE_WATER
|
||||||
|
// --------------------------------------- SIMPLE WATER ---------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
#define MRT @shGlobalSettingBool(mrt_output)
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef SH_VERTEX_SHADER
|
||||||
|
|
||||||
|
SH_BEGIN_PROGRAM
|
||||||
|
shUniform(float4x4, wvp) @shAutoConstant(wvp, worldviewproj_matrix)
|
||||||
|
shVertexInput(float2, uv0)
|
||||||
|
shOutput(float2, UV)
|
||||||
|
shOutput(float, depth)
|
||||||
|
|
||||||
|
SH_START_PROGRAM
|
||||||
|
{
|
||||||
|
shOutputPosition = shMatrixMult(wvp, shInputPosition);
|
||||||
|
UV = uv0;
|
||||||
|
depth = shOutputPosition.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
SH_BEGIN_PROGRAM
|
||||||
|
shSampler2D(animatedTexture)
|
||||||
|
shInput(float2, UV)
|
||||||
|
shInput(float, depth)
|
||||||
|
#if MRT
|
||||||
|
shDeclareMrtOutput(1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
shUniform(float3, fogColor) @shAutoConstant(fogColor, fog_colour)
|
||||||
|
shUniform(float4, fogParams) @shAutoConstant(fogParams, fog_params)
|
||||||
|
|
||||||
|
|
||||||
|
SH_START_PROGRAM
|
||||||
|
{
|
||||||
|
shOutputColour(0).xyz = shSample(animatedTexture, UV * 15).xyz * float3(0.6, 0.7, 1.0);
|
||||||
|
shOutputColour(0).w = 0.7;
|
||||||
|
|
||||||
|
float fogValue = shSaturate((depth - fogParams.y) * fogParams.w);
|
||||||
|
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, fogColor, fogValue);
|
||||||
|
|
||||||
|
#if MRT
|
||||||
|
shOutputColour(1) = float4(1,1,1,1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Inspired by Blender GLSL Water by martinsh ( http://devlog-martinsh.blogspot.de/2012/07/waterundewater-shader-wip.html )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef SH_VERTEX_SHADER
|
||||||
|
|
||||||
|
SH_BEGIN_PROGRAM
|
||||||
|
shUniform(float4x4, wvp) @shAutoConstant(wvp, worldviewproj_matrix)
|
||||||
|
shVertexInput(float2, uv0)
|
||||||
|
shOutput(float2, UV)
|
||||||
|
|
||||||
|
shOutput(float3, screenCoordsPassthrough)
|
||||||
|
shOutput(float4, position)
|
||||||
|
shOutput(float, depthPassthrough)
|
||||||
|
|
||||||
|
SH_START_PROGRAM
|
||||||
|
{
|
||||||
|
shOutputPosition = shMatrixMult(wvp, shInputPosition);
|
||||||
|
UV = uv0;
|
||||||
|
|
||||||
|
|
||||||
|
#if !SH_GLSL
|
||||||
|
float4x4 scalemat = float4x4( 0.5, 0, 0, 0.5,
|
||||||
|
0, -0.5, 0, 0.5,
|
||||||
|
0, 0, 0.5, 0.5,
|
||||||
|
0, 0, 0, 1 );
|
||||||
|
#else
|
||||||
|
mat4 scalemat = mat4(0.5, 0.0, 0.0, 0.0,
|
||||||
|
0.0, -0.5, 0.0, 0.0,
|
||||||
|
0.0, 0.0, 0.5, 0.0,
|
||||||
|
0.5, 0.5, 0.5, 1.0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
float4 texcoordProj = shMatrixMult(scalemat, shOutputPosition);
|
||||||
|
screenCoordsPassthrough = float3(texcoordProj.x, texcoordProj.y, texcoordProj.w);
|
||||||
|
|
||||||
|
position = shInputPosition;
|
||||||
|
|
||||||
|
depthPassthrough = shOutputPosition.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// tweakables ----------------------------------------------------
|
||||||
|
|
||||||
|
#define VISIBILITY 1500.0 // how far you can look through water
|
||||||
|
|
||||||
|
#define BIG_WAVES_X 0.3 // strength of big waves
|
||||||
|
#define BIG_WAVES_Y 0.3
|
||||||
|
|
||||||
|
#define MID_WAVES_X 0.3 // strength of middle sized waves
|
||||||
|
#define MID_WAVES_Y 0.15
|
||||||
|
|
||||||
|
#define SMALL_WAVES_X 0.15 // strength of small waves
|
||||||
|
#define SMALL_WAVES_Y 0.1
|
||||||
|
|
||||||
|
#define WAVE_CHOPPYNESS 0.15 // wave choppyness
|
||||||
|
#define WAVE_SCALE 75 // overall wave scale
|
||||||
|
|
||||||
|
#define ABBERATION 0.001 // chromatic abberation amount
|
||||||
|
#define BUMP 1.5 // overall water surface bumpiness
|
||||||
|
#define REFL_BUMP 0.08 // reflection distortion amount
|
||||||
|
#define REFR_BUMP 0.06 // refraction distortion amount
|
||||||
|
|
||||||
|
#define SCATTER_AMOUNT 3.0 // amount of sunlight scattering
|
||||||
|
#define SCATTER_COLOUR float3(0.0,1.0,0.95) // colour of sunlight scattering
|
||||||
|
|
||||||
|
#define SUN_EXT float3(0.45, 0.55, 0.68) //sunlight extinction
|
||||||
|
|
||||||
|
#define SPEC_HARDNESS 256 // specular highlights hardness
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
float fresnel_dielectric(float3 Incoming, float3 Normal, float eta)
|
||||||
|
{
|
||||||
|
/* compute fresnel reflectance without explicitly computing
|
||||||
|
the refracted direction */
|
||||||
|
float c = abs(dot(Incoming, Normal));
|
||||||
|
float g = eta * eta - 1.0 + c * c;
|
||||||
|
float result;
|
||||||
|
|
||||||
|
if(g > 0.0) {
|
||||||
|
g = sqrt(g);
|
||||||
|
float A =(g - c)/(g + c);
|
||||||
|
float B =(c *(g + c)- 1.0)/(c *(g - c)+ 1.0);
|
||||||
|
result = 0.5 * A * A *(1.0 + B * B);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
result = 1.0; /* TIR (no refracted component) */
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
SH_BEGIN_PROGRAM
|
||||||
|
shInput(float2, UV)
|
||||||
|
shInput(float3, screenCoordsPassthrough)
|
||||||
|
shInput(float4, position)
|
||||||
|
shInput(float, depthPassthrough)
|
||||||
|
|
||||||
|
shUniform(float, far) @shAutoConstant(far, far_clip_distance)
|
||||||
|
|
||||||
|
shSampler2D(reflectionMap)
|
||||||
|
shSampler2D(refractionMap)
|
||||||
|
shSampler2D(depthMap)
|
||||||
|
shSampler2D(normalMap)
|
||||||
|
|
||||||
|
shUniform(float3, windDir_windSpeed) @shSharedParameter(windDir_windSpeed)
|
||||||
|
#define WIND_SPEED windDir_windSpeed.z
|
||||||
|
#define WIND_DIR windDir_windSpeed.xy
|
||||||
|
|
||||||
|
shUniform(float, waterTimer) @shSharedParameter(waterTimer)
|
||||||
|
shUniform(float2, waterSunFade_sunHeight) @shSharedParameter(waterSunFade_sunHeight)
|
||||||
|
|
||||||
|
shUniform(float4, sunPosition) @shAutoConstant(sunPosition, light_position, 0)
|
||||||
|
shUniform(float4, sunSpecular) @shAutoConstant(sunSpecular, light_specular_colour, 0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
shUniform(float, renderTargetFlipping) @shAutoConstant(renderTargetFlipping, render_target_flipping)
|
||||||
|
|
||||||
|
|
||||||
|
shUniform(float3, fogColor) @shAutoConstant(fogColor, fog_colour)
|
||||||
|
shUniform(float4, fogParams) @shAutoConstant(fogParams, fog_params)
|
||||||
|
|
||||||
|
shUniform(float4, cameraPos) @shAutoConstant(cameraPos, camera_position_object_space)
|
||||||
|
|
||||||
|
|
||||||
|
SH_START_PROGRAM
|
||||||
|
{
|
||||||
|
|
||||||
|
float2 screenCoords = screenCoordsPassthrough.xy / screenCoordsPassthrough.z;
|
||||||
|
screenCoords.y = (1-shSaturate(renderTargetFlipping))+renderTargetFlipping*screenCoords.y;
|
||||||
|
|
||||||
|
float depth = shSample(depthMap, screenCoords).x * far - depthPassthrough;
|
||||||
|
float shoreFade = shSaturate(depth / 50.0);
|
||||||
|
|
||||||
|
float2 nCoord = float2(0.0);
|
||||||
|
|
||||||
|
nCoord = UV * (WAVE_SCALE * 0.05) + WIND_DIR * waterTimer * (WIND_SPEED*0.04);
|
||||||
|
float3 normal0 = 2.0 * shSample(normalMap, nCoord + float2(-waterTimer*0.015,-waterTimer*0.005)).rgb - 1.0;
|
||||||
|
nCoord = UV * (WAVE_SCALE * 0.1) + WIND_DIR * waterTimer * (WIND_SPEED*0.08)-(normal0.xy/normal0.zz)*WAVE_CHOPPYNESS;
|
||||||
|
float3 normal1 = 2.0 * shSample(normalMap, nCoord + float2(+waterTimer*0.020,+waterTimer*0.015)).rgb - 1.0;
|
||||||
|
|
||||||
|
nCoord = UV * (WAVE_SCALE * 0.25) + WIND_DIR * waterTimer * (WIND_SPEED*0.07)-(normal1.xy/normal1.zz)*WAVE_CHOPPYNESS;
|
||||||
|
float3 normal2 = 2.0 * shSample(normalMap, nCoord + float2(-waterTimer*0.04,-waterTimer*0.03)).rgb - 1.0;
|
||||||
|
nCoord = UV * (WAVE_SCALE * 0.5) + WIND_DIR * waterTimer * (WIND_SPEED*0.09)-(normal2.xy/normal2.z)*WAVE_CHOPPYNESS;
|
||||||
|
float3 normal3 = 2.0 * shSample(normalMap, nCoord + float2(+waterTimer*0.03,+waterTimer*0.04)).rgb - 1.0;
|
||||||
|
|
||||||
|
nCoord = UV * (WAVE_SCALE* 1.0) + WIND_DIR * waterTimer * (WIND_SPEED*0.4)-(normal3.xy/normal3.zz)*WAVE_CHOPPYNESS;
|
||||||
|
float3 normal4 = 2.0 * shSample(normalMap, nCoord + float2(-waterTimer*0.02,+waterTimer*0.1)).rgb - 1.0;
|
||||||
|
nCoord = UV * (WAVE_SCALE * 2.0) + WIND_DIR * waterTimer * (WIND_SPEED*0.7)-(normal4.xy/normal4.zz)*WAVE_CHOPPYNESS;
|
||||||
|
float3 normal5 = 2.0 * shSample(normalMap, nCoord + float2(+waterTimer*0.1,-waterTimer*0.06)).rgb - 1.0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
float3 normal = (normal0 * BIG_WAVES_X + normal1 * BIG_WAVES_Y +
|
||||||
|
normal2 * MID_WAVES_X + normal3 * MID_WAVES_Y +
|
||||||
|
normal4 * SMALL_WAVES_X + normal5 * SMALL_WAVES_Y).xzy;
|
||||||
|
|
||||||
|
normal = normalize(float3(normal.x * BUMP, normal.y, normal.z * BUMP));
|
||||||
|
|
||||||
|
// normal for sunlight scattering
|
||||||
|
float3 lNormal = (normal0 * BIG_WAVES_X*0.5 + normal1 * BIG_WAVES_Y*0.5 +
|
||||||
|
normal2 * MID_WAVES_X*0.2 + normal3 * MID_WAVES_Y*0.2 +
|
||||||
|
normal4 * SMALL_WAVES_X*0.1 + normal5 * SMALL_WAVES_Y*0.1).xzy;
|
||||||
|
lNormal = normalize(float3(lNormal.x * BUMP, lNormal.y, lNormal.z * BUMP));
|
||||||
|
|
||||||
|
|
||||||
|
float3 lVec = normalize(sunPosition.xyz);
|
||||||
|
float3 vVec = normalize(position.xyz - cameraPos.xyz);
|
||||||
|
|
||||||
|
|
||||||
|
float isUnderwater = (cameraPos.y > 0) ? 0.0 : 1.0;
|
||||||
|
|
||||||
|
// sunlight scattering
|
||||||
|
float3 pNormal = float3(0,1,0);
|
||||||
|
vec3 lR = reflect(lVec, lNormal);
|
||||||
|
vec3 llR = reflect(lVec, pNormal);
|
||||||
|
|
||||||
|
float s = shSaturate(dot(lR, vVec)*2.0-1.2);
|
||||||
|
float lightScatter = shSaturate(dot(-lVec,lNormal)*0.7+0.3) * s * SCATTER_AMOUNT * waterSunFade_sunHeight.x * shSaturate(1.0-exp(-waterSunFade_sunHeight.y));
|
||||||
|
float3 scatterColour = shLerp(vec3(SCATTER_COLOUR)*vec3(1.0,0.4,0.0), SCATTER_COLOUR, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT)));
|
||||||
|
|
||||||
|
// fresnel
|
||||||
|
float ior = (cameraPos.y>0)?(1.333/1.0):(1.0/1.333); //air to water; water to air
|
||||||
|
float fresnel = fresnel_dielectric(-vVec, normal, ior);
|
||||||
|
|
||||||
|
fresnel = shSaturate(fresnel);
|
||||||
|
|
||||||
|
// reflection
|
||||||
|
float3 reflection = shSample(reflectionMap, screenCoords+(normal.xz*REFL_BUMP)).rgb;
|
||||||
|
|
||||||
|
// refraction
|
||||||
|
float3 R = reflect(vVec, normal);
|
||||||
|
|
||||||
|
float3 refraction = float3(0,0,0);
|
||||||
|
refraction.r = shSample(refractionMap, (screenCoords-(shoreFade * normal.xz*REFR_BUMP))*1.0).r;
|
||||||
|
refraction.g = shSample(refractionMap, (screenCoords-(shoreFade * normal.xz*REFR_BUMP))*1.0-(R.xy*ABBERATION)).g;
|
||||||
|
refraction.b = shSample(refractionMap, (screenCoords-(shoreFade * normal.xz*REFR_BUMP))*1.0-(R.xy*ABBERATION*2.0)).b;
|
||||||
|
|
||||||
|
// brighten up the refraction underwater
|
||||||
|
refraction = (cameraPos.y < 0) ? shSaturate(refraction * 1.5) : refraction;
|
||||||
|
|
||||||
|
// specular
|
||||||
|
float specular = pow(max(dot(R, lVec), 0.0),SPEC_HARDNESS);
|
||||||
|
|
||||||
|
shOutputColour(0).xyz = shLerp( shLerp(refraction, scatterColour, lightScatter), reflection, fresnel) + specular * sunSpecular.xyz;
|
||||||
|
|
||||||
|
// smooth transition to shore (above water only)
|
||||||
|
shOutputColour(0).xyz = shLerp(shOutputColour(0).xyz, refraction, (1-shoreFade) * (1-isUnderwater));
|
||||||
|
|
||||||
|
// fog
|
||||||
|
if (isUnderwater == 1)
|
||||||
|
{
|
||||||
|
float waterSunGradient = dot(-vVec, -lVec);
|
||||||
|
waterSunGradient = shSaturate(pow(waterSunGradient*0.7+0.3,2.0));
|
||||||
|
float3 waterSunColour = float3(0.0,1.0,0.85)*waterSunGradient * 0.5;
|
||||||
|
|
||||||
|
float waterGradient = dot(-vVec, float3(0.0,-1.0,0.0));
|
||||||
|
waterGradient = clamp((waterGradient*0.5+0.5),0.2,1.0);
|
||||||
|
float3 watercolour = (float3(0.0078, 0.5176, 0.700)+waterSunColour)*waterGradient*2.0;
|
||||||
|
float3 waterext = float3(0.6, 0.9, 1.0);//water extinction
|
||||||
|
watercolour = mix(watercolour*0.3*waterSunFade_sunHeight.x, watercolour, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT)));
|
||||||
|
|
||||||
|
float darkness = VISIBILITY*2.0;
|
||||||
|
darkness = clamp((cameraPos.y+darkness)/darkness,0.2,1.0);
|
||||||
|
|
||||||
|
|
||||||
|
float fog = shSaturate(length(cameraPos.xyz-position.xyz) / VISIBILITY);
|
||||||
|
shOutputColour(0).xyz = shLerp(shOutputColour(0).xyz, watercolour * darkness, shSaturate(fog / waterext));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float fogValue = shSaturate((depthPassthrough - fogParams.y) * fogParams.w);
|
||||||
|
shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, fogColor, fogValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
15
files/materials/water.shaderset
Normal file
15
files/materials/water.shaderset
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
shader_set water_vertex
|
||||||
|
{
|
||||||
|
source water.shader
|
||||||
|
type vertex
|
||||||
|
profiles_cg vs_2_0 vp40 arbvp1
|
||||||
|
profiles_hlsl vs_2_0
|
||||||
|
}
|
||||||
|
|
||||||
|
shader_set water_fragment
|
||||||
|
{
|
||||||
|
source water.shader
|
||||||
|
type fragment
|
||||||
|
profiles_cg ps_2_x ps_2_0 ps fp40 arbfp1
|
||||||
|
profiles_hlsl ps_2_0
|
||||||
|
}
|
|
@ -1,68 +1,72 @@
|
||||||
# Minimal MyGUI build system for OpenMW
|
|
||||||
|
|
||||||
# Copy resource files into the build directory
|
# Copy resource files into the build directory
|
||||||
set(SDIR ${CMAKE_CURRENT_SOURCE_DIR})
|
set(SDIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
set(DDIR ${OpenMW_BINARY_DIR}/resources/mygui)
|
set(DDIR ${OpenMW_BINARY_DIR}/resources/mygui)
|
||||||
|
|
||||||
configure_file("${SDIR}/bigbars.png" "${DDIR}/bigbars.png" COPYONLY)
|
set(MYGUI_FILES
|
||||||
configure_file("${SDIR}/black.png" "${DDIR}/black.png" COPYONLY)
|
atlas1.cfg
|
||||||
configure_file("${SDIR}/core.skin" "${DDIR}/core.skin" COPYONLY)
|
bigbars.png
|
||||||
configure_file("${SDIR}/core.xml" "${DDIR}/core.xml" COPYONLY)
|
black.png
|
||||||
configure_file("${SDIR}/mwgui.png" "${DDIR}/mwgui.png" COPYONLY)
|
core.skin
|
||||||
configure_file("${SDIR}/openmw_resources.xml" "${DDIR}/openmw_resources.xml" COPYONLY)
|
core.xml
|
||||||
configure_file("${SDIR}/openmw_settings.xml" "${DDIR}/openmw_settings.xml" COPYONLY)
|
EBGaramond-Regular.ttf
|
||||||
configure_file("${SDIR}/openmw_box.skin.xml" "${DDIR}/openmw_box.skin.xml" COPYONLY)
|
mwgui.png
|
||||||
configure_file("${SDIR}/openmw_button.skin.xml" "${DDIR}/openmw_button.skin.xml" COPYONLY)
|
Obliviontt.zip
|
||||||
configure_file("${SDIR}/openmw_list.skin.xml" "${DDIR}/openmw_list.skin.xml" COPYONLY)
|
openmw_alchemy_window.layout
|
||||||
configure_file("${SDIR}/openmw_edit.skin.xml" "${DDIR}/openmw_edit.skin.xml" COPYONLY)
|
openmw_book.layout
|
||||||
configure_file("${SDIR}/openmw_console.layout" "${DDIR}/openmw_console.layout" COPYONLY)
|
openmw_box.skin.xml
|
||||||
configure_file("${SDIR}/openmw_console.skin.xml" "${DDIR}/openmw_console.skin.xml" COPYONLY)
|
openmw_button.skin.xml
|
||||||
configure_file("${SDIR}/openmw.font.xml" "${DDIR}/openmw.font.xml" COPYONLY)
|
openmw_chargen_birth.layout
|
||||||
configure_file("${SDIR}/openmw_hud_box.skin.xml" "${DDIR}/openmw_hud_box.skin.xml" COPYONLY)
|
openmw_chargen_class_description.layout
|
||||||
configure_file("${SDIR}/openmw_hud_energybar.skin.xml" "${DDIR}/openmw_hud_energybar.skin.xml" COPYONLY)
|
openmw_chargen_class.layout
|
||||||
configure_file("${SDIR}/openmw_hud.layout" "${DDIR}/openmw_hud.layout" COPYONLY)
|
openmw_chargen_create_class.layout
|
||||||
configure_file("${SDIR}/openmw_text_input.layout" "${DDIR}/openmw_text_input.layout" COPYONLY)
|
openmw_chargen_generate_class_result.layout
|
||||||
configure_file("${SDIR}/openmw_infobox.layout" "${DDIR}/openmw_infobox.layout" COPYONLY)
|
openmw_chargen_race.layout
|
||||||
configure_file("${SDIR}/openmw_chargen_race.layout" "${DDIR}/openmw_chargen_race.layout" COPYONLY)
|
openmw_chargen_review.layout
|
||||||
configure_file("${SDIR}/openmw_chargen_class.layout" "${DDIR}/openmw_chargen_class.layout" COPYONLY)
|
openmw_chargen_select_attribute.layout
|
||||||
configure_file("${SDIR}/openmw_chargen_generate_class_result.layout" "${DDIR}/openmw_chargen_generate_class_result.layout" COPYONLY)
|
openmw_chargen_select_skill.layout
|
||||||
configure_file("${SDIR}/openmw_chargen_create_class.layout" "${DDIR}/openmw_chargen_create_class.layout" COPYONLY)
|
openmw_chargen_select_specialization.layout
|
||||||
configure_file("${SDIR}/openmw_chargen_select_specialization.layout" "${DDIR}/openmw_chargen_select_specialization.layout" COPYONLY)
|
openmw_confirmation_dialog.layout
|
||||||
configure_file("${SDIR}/openmw_chargen_select_attribute.layout" "${DDIR}/openmw_chargen_select_attribute.layout" COPYONLY)
|
openmw_console.layout
|
||||||
configure_file("${SDIR}/openmw_chargen_select_skill.layout" "${DDIR}/openmw_chargen_select_skill.layout" COPYONLY)
|
openmw_console.skin.xml
|
||||||
configure_file("${SDIR}/openmw_chargen_class_description.layout" "${DDIR}/openmw_chargen_class_description.layout" COPYONLY)
|
openmw_container_window.layout
|
||||||
configure_file("${SDIR}/openmw_chargen_birth.layout" "${DDIR}/openmw_chargen_birth.layout" COPYONLY)
|
openmw_count_window.layout
|
||||||
configure_file("${SDIR}/openmw_chargen_review.layout" "${DDIR}/openmw_chargen_review.layout" COPYONLY)
|
openmw_dialogue_window.layout
|
||||||
configure_file("${SDIR}/openmw_dialogue_window.layout" "${DDIR}/openmw_dialogue_window.layout" COPYONLY)
|
openmw_dialogue_window_skin.xml
|
||||||
configure_file("${SDIR}/openmw_dialogue_window_skin.xml" "${DDIR}/openmw_dialogue_window_skin.xml" COPYONLY)
|
openmw_edit.skin.xml
|
||||||
configure_file("${SDIR}/openmw_inventory_window.layout" "${DDIR}/openmw_inventory_window.layout" COPYONLY)
|
openmw.font.xml
|
||||||
configure_file("${SDIR}/openmw_container_window.layout" "${DDIR}/openmw_container_window.layout" COPYONLY)
|
openmw_hud_box.skin.xml
|
||||||
configure_file("${SDIR}/openmw_layers.xml" "${DDIR}/openmw_layers.xml" COPYONLY)
|
openmw_hud_energybar.skin.xml
|
||||||
configure_file("${SDIR}/openmw_mainmenu.layout" "${DDIR}/openmw_mainmenu.layout" COPYONLY)
|
openmw_hud.layout
|
||||||
configure_file("${SDIR}/openmw_mainmenu_skin.xml" "${DDIR}/openmw_mainmenu_skin.xml" COPYONLY)
|
openmw_infobox.layout
|
||||||
configure_file("${SDIR}/openmw_map_window.layout" "${DDIR}/openmw_map_window.layout" COPYONLY)
|
openmw_interactive_messagebox.layout
|
||||||
configure_file("${SDIR}/openmw_map_window_skin.xml" "${DDIR}/openmw_map_window_skin.xml" COPYONLY)
|
openmw_inventory_window.layout
|
||||||
configure_file("${SDIR}/openmw.pointer.xml" "${DDIR}/openmw.pointer.xml" COPYONLY)
|
openmw_journal.layout
|
||||||
configure_file("${SDIR}/openmw_progress.skin.xml" "${DDIR}/openmw_progress.skin.xml" COPYONLY)
|
openmw_journal_skin.xml
|
||||||
configure_file("${SDIR}/openmw_stats_window.layout" "${DDIR}/openmw_stats_window.layout" COPYONLY)
|
openmw_layers.xml
|
||||||
configure_file("${SDIR}/openmw_text.skin.xml" "${DDIR}/openmw_text.skin.xml" COPYONLY)
|
openmw_list.skin.xml
|
||||||
configure_file("${SDIR}/openmw_windows.skin.xml" "${DDIR}/openmw_windows.skin.xml" COPYONLY)
|
openmw_mainmenu.layout
|
||||||
configure_file("${SDIR}/openmw_messagebox.layout" "${DDIR}/openmw_messagebox.layout" COPYONLY)
|
openmw_mainmenu_skin.xml
|
||||||
configure_file("${SDIR}/openmw_interactive_messagebox.layout" "${DDIR}/openmw_interactive_messagebox.layout" COPYONLY)
|
openmw_map_window.layout
|
||||||
configure_file("${SDIR}/openmw_journal.layout" "${DDIR}/openmw_journal.layout" COPYONLY)
|
openmw_map_window_skin.xml
|
||||||
configure_file("${SDIR}/openmw_journal_skin.xml" "${DDIR}/openmw_journal_skin.xml" COPYONLY)
|
openmw_messagebox.layout
|
||||||
configure_file("${SDIR}/openmw_tooltips.layout" "${DDIR}/openmw_tooltips.layout" COPYONLY)
|
openmw.pointer.xml
|
||||||
configure_file("${SDIR}/openmw_scroll.layout" "${DDIR}/openmw_scroll.layout" COPYONLY)
|
openmw_progress.skin.xml
|
||||||
configure_file("${SDIR}/openmw_scroll_skin.xml" "${DDIR}/openmw_scroll_skin.xml" COPYONLY)
|
openmw_resources.xml
|
||||||
configure_file("${SDIR}/openmw_book.layout" "${DDIR}/openmw_book.layout" COPYONLY)
|
openmw_scroll.layout
|
||||||
configure_file("${SDIR}/openmw_count_window.layout" "${DDIR}/openmw_count_window.layout" COPYONLY)
|
openmw_scroll_skin.xml
|
||||||
configure_file("${SDIR}/openmw_trade_window.layout" "${DDIR}/openmw_trade_window.layout" COPYONLY)
|
openmw_settings_window.layout
|
||||||
configure_file("${SDIR}/openmw_settings_window.layout" "${DDIR}/openmw_settings_window.layout" COPYONLY)
|
openmw_settings.xml
|
||||||
configure_file("${SDIR}/openmw_confirmation_dialog.layout" "${DDIR}/openmw_confirmation_dialog.layout" COPYONLY)
|
openmw_spell_window.layout
|
||||||
configure_file("${SDIR}/openmw_alchemy_window.layout" "${DDIR}/openmw_alchemy_window.layout" COPYONLY)
|
openmw_stats_window.layout
|
||||||
configure_file("${SDIR}/openmw_spell_window.layout" "${DDIR}/openmw_spell_window.layout" COPYONLY)
|
openmw_text_input.layout
|
||||||
configure_file("${SDIR}/atlas1.cfg" "${DDIR}/atlas1.cfg" COPYONLY)
|
openmw_text.skin.xml
|
||||||
configure_file("${SDIR}/smallbars.png" "${DDIR}/smallbars.png" COPYONLY)
|
openmw_tooltips.layout
|
||||||
configure_file("${SDIR}/EBGaramond-Regular.ttf" "${DDIR}/EBGaramond-Regular.ttf" COPYONLY)
|
openmw_trade_window.layout
|
||||||
configure_file("${SDIR}/Obliviontt.zip" "${DDIR}/Obliviontt.zip" COPYONLY)
|
openmw_windows.skin.xml
|
||||||
configure_file("${SDIR}/VeraMono.ttf" "${DDIR}/VeraMono.ttf" COPYONLY)
|
smallbars.png
|
||||||
|
VeraMono.ttf
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
copy_all_files(${CMAKE_CURRENT_SOURCE_DIR} ${DDIR} "${MYGUI_FILES}")
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
<MyGUI type="Layout">
|
<MyGUI type="Layout">
|
||||||
<Widget type="Window" skin="MW_Dialog" layer="Windows" position="0 0 390 390" name="_Main">
|
<Widget type="Window" skin="MW_Window_NoCaption" layer="Windows" position="0 0 400 414" name="_Main">
|
||||||
|
|
||||||
|
<Property key="MinSize" value="400 414"/>
|
||||||
|
<Property key="MaxSize" value="400 414"/>
|
||||||
|
|
||||||
<Widget type="TabControl" skin="TabControl" position="8 8 368 340" align="Left Top" name="SettingsTab">
|
<Widget type="TabControl" skin="TabControl" position="8 8 368 340" align="Left Top" name="SettingsTab">
|
||||||
<Property key="ButtonAutoWidth" value="true"/>
|
<Property key="ButtonAutoWidth" value="true"/>
|
||||||
|
@ -100,6 +103,12 @@
|
||||||
</Widget>
|
</Widget>
|
||||||
<Widget type="Button" skin="MW_Button" position="212 34 34 24" align="Left Top" name="VSyncButton"/>
|
<Widget type="Button" skin="MW_Button" position="212 34 34 24" align="Left Top" name="VSyncButton"/>
|
||||||
|
|
||||||
|
<Widget type="TextBox" skin="SandText" position="262 104 120 24" align="Left Top">
|
||||||
|
<Property key="Caption" value="Shaders"/>
|
||||||
|
</Widget>
|
||||||
|
<Widget type="Button" skin="MW_Button" position="212 104 44 24" align="Left Top" name="ShadersButton"/>
|
||||||
|
|
||||||
|
|
||||||
<Widget type="TextBox" skin="SandText" position="74 163 250 24" align="Left Top">
|
<Widget type="TextBox" skin="SandText" position="74 163 250 24" align="Left Top">
|
||||||
<Property key="Caption" value="Show frames per second"/>
|
<Property key="Caption" value="Show frames per second"/>
|
||||||
</Widget>
|
</Widget>
|
||||||
|
@ -179,6 +188,55 @@
|
||||||
<Widget type="Button" skin="MW_Button" position="4 56 34 24" align="Left Top" name="ReflectTerrainButton"/>
|
<Widget type="Button" skin="MW_Button" position="4 56 34 24" align="Left Top" name="ReflectTerrainButton"/>
|
||||||
|
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
||||||
|
<Widget type="TextBox" skin="SandText" position="42 200 120 24" align="Left Top">
|
||||||
|
<Property key="Caption" value="Underwater effects (caustics, fog)"/>
|
||||||
|
</Widget>
|
||||||
|
<Widget type="Button" skin="MW_Button" position="4 200 34 24" align="Left Top" name="UnderwaterButton"/>
|
||||||
|
</Widget>
|
||||||
|
|
||||||
|
<Widget type="TabItem" skin="" position="4 28 344 272">
|
||||||
|
<Property key="Caption" value=" Shadows "/>
|
||||||
|
|
||||||
|
<Widget type="TextBox" skin="SandText" position="42 4 120 24" align="Left Top">
|
||||||
|
<Property key="Caption" value="Enabled"/>
|
||||||
|
</Widget>
|
||||||
|
<Widget type="Button" skin="MW_Button" position="4 4 34 24" align="Left Top" name="ShadowsEnabledButton"/>
|
||||||
|
|
||||||
|
<Widget type="Widget" skin="" position="24 32 300 230">
|
||||||
|
<Widget type="TextBox" skin="SandText" position="42 0 300 24" align="Left Top">
|
||||||
|
<Property key="Caption" value="Large distance (PSSM3)"/>
|
||||||
|
</Widget>
|
||||||
|
<Widget type="Button" skin="MW_Button" position="4 0 34 24" align="Left Top" name="ShadowsLargeDistance"/>
|
||||||
|
|
||||||
|
<Widget type="TextBox" skin="SandText" position="72 28 120 24" align="Left Top">
|
||||||
|
<Property key="Caption" value="Texture size"/>
|
||||||
|
</Widget>
|
||||||
|
<Widget type="Button" skin="MW_Button" position="4 28 64 24" align="Left Top" name="ShadowsTextureSize"/>
|
||||||
|
|
||||||
|
<Widget type="TextBox" skin="SandText" position="42 56 120 24" align="Left Top">
|
||||||
|
<Property key="Caption" value="Actor shadows"/>
|
||||||
|
</Widget>
|
||||||
|
<Widget type="Button" skin="MW_Button" position="4 56 34 24" align="Left Top" name="ActorShadows"/>
|
||||||
|
|
||||||
|
<Widget type="TextBox" skin="SandText" position="42 84 120 24" align="Left Top">
|
||||||
|
<Property key="Caption" value="World shadows"/>
|
||||||
|
</Widget>
|
||||||
|
<Widget type="Button" skin="MW_Button" position="4 84 34 24" align="Left Top" name="StaticsShadows"/>
|
||||||
|
|
||||||
|
<Widget type="TextBox" skin="SandText" position="42 112 120 24" align="Left Top">
|
||||||
|
<Property key="Caption" value="Misc shadows"/>
|
||||||
|
</Widget>
|
||||||
|
<Widget type="Button" skin="MW_Button" position="4 112 34 24" align="Left Top" name="MiscShadows"/>
|
||||||
|
|
||||||
|
<Widget type="TextBox" skin="SandText" position="42 172 120 24" align="Left Top">
|
||||||
|
<Property key="Caption" value="Debug overlay"/>
|
||||||
|
</Widget>
|
||||||
|
<Widget type="Button" skin="MW_Button" position="4 172 34 24" align="Left Top" name="ShadowsDebug"/>
|
||||||
|
|
||||||
|
|
||||||
|
</Widget>
|
||||||
|
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
||||||
</Widget>
|
</Widget>
|
||||||
|
|
|
@ -322,6 +322,80 @@
|
||||||
</Child>
|
</Child>
|
||||||
</Skin>
|
</Skin>
|
||||||
|
|
||||||
|
<Skin name = "MW_Window_NoCaption" size = "256 54">
|
||||||
|
<Property key="FontName" value = "Default" />
|
||||||
|
<Property key="TextAlign" value = "ALIGN_CENTER" />
|
||||||
|
<Property key="TextColour" value = "0.8 0.8 0.8" />
|
||||||
|
<Property key="Snap" value = "true" />
|
||||||
|
<Property key="MinSize" value="64 64"/>
|
||||||
|
|
||||||
|
<Child type="Widget" skin="BlackBG" offset = "8 28 240 18" align = "ALIGN_STRETCH" name = "Client"/>
|
||||||
|
|
||||||
|
<!-- Outer borders -->
|
||||||
|
<Child type="Widget" skin="TB_T" offset="4 0 248 4" align="ALIGN_TOP ALIGN_HSTRETCH" name="Action">
|
||||||
|
<Property key="Scale" value = "0 1 0 -1"/>
|
||||||
|
</Child>
|
||||||
|
<Child type="Widget" skin="TB_L" offset="0 4 4 46" align="ALIGN_LEFT ALIGN_VSTRETCH" name="Action">
|
||||||
|
<Property key="Scale" value = "1 0 -1 0"/>
|
||||||
|
</Child>
|
||||||
|
<Child type="Widget" skin="TB_B" offset="4 50 248 4" align="ALIGN_BOTTOM ALIGN_HSTRETCH" name="Action">
|
||||||
|
<Property key="Scale" value = "0 0 0 1"/>
|
||||||
|
</Child>
|
||||||
|
<Child type="Widget" skin="TB_R" offset="252 4 4 46" align="ALIGN_RIGHT ALIGN_VSTRETCH" name="Action">
|
||||||
|
<Property key="Scale" value = "0 0 1 0"/>
|
||||||
|
</Child>
|
||||||
|
|
||||||
|
<Child type="Widget" skin="TB_BR" offset="252 50 4 4" align="ALIGN_RIGHT ALIGN_BOTTOM" name="Action">
|
||||||
|
<Property key="Scale" value = "0 0 1 1"/>
|
||||||
|
</Child>
|
||||||
|
<Child type="Widget" skin="TB_BL" offset="0 50 4 4" align="ALIGN_LEFT ALIGN_BOTTOM" name="Action">
|
||||||
|
<Property key="Scale" value = "1 0 -1 1"/>
|
||||||
|
</Child>
|
||||||
|
<Child type="Widget" skin="TB_TR" offset="252 0 4 4" align="ALIGN_RIGHT ALIGN_TOP" name="Action">
|
||||||
|
<Property key="Scale" value = "0 1 1 -1"/>
|
||||||
|
</Child>
|
||||||
|
<Child type="Widget" skin="TB_TL" offset="0 0 4 4" align="ALIGN_LEFT ALIGN_TOP" name="Action">
|
||||||
|
<Property key="Scale" value = "1 1 -1 -1"/>
|
||||||
|
</Child>
|
||||||
|
|
||||||
|
<!-- Inner borders -->
|
||||||
|
<Child type="Widget" skin="TB_T" offset="8 24 240 4" align="ALIGN_TOP ALIGN_HSTRETCH" name="Action">
|
||||||
|
<Property key="Scale" value = "0 1 0 -1"/>
|
||||||
|
</Child>
|
||||||
|
<Child type="Widget" skin="TB_L" offset="4 28 4 18" align="ALIGN_LEFT ALIGN_VSTRETCH" name="Action">
|
||||||
|
<Property key="Scale" value = "1 0 -1 0"/>
|
||||||
|
</Child>
|
||||||
|
<Child type="Widget" skin="TB_B" offset="8 46 240 4" align="ALIGN_BOTTOM ALIGN_HSTRETCH" name="Action">
|
||||||
|
<Property key="Scale" value = "0 0 0 1"/>
|
||||||
|
</Child>
|
||||||
|
<Child type="Widget" skin="TB_R" offset="248 28 4 18" align="ALIGN_RIGHT ALIGN_VSTRETCH" name="Action">
|
||||||
|
<Property key="Scale" value = "0 0 1 0"/>
|
||||||
|
</Child>
|
||||||
|
<Child type="Widget" skin="TB_BR" offset="248 46 4 4" align="ALIGN_BOTTOM ALIGN_RIGHT" name="Action">
|
||||||
|
<Property key="Scale" value = "0 0 1 1"/>
|
||||||
|
</Child>
|
||||||
|
<Child type="Widget" skin="TB_BL" offset="4 46 4 4" align="ALIGN_BOTTOM ALIGN_LEFT" name="Action">
|
||||||
|
<Property key="Scale" value = "1 0 -1 1"/>
|
||||||
|
</Child>
|
||||||
|
<Child type="Widget" skin="TB_TR" offset="248 24 4 4" align="ALIGN_TOP ALIGN_RIGHT" name="Action">
|
||||||
|
<Property key="Scale" value = "0 1 1 -1"/>
|
||||||
|
</Child>
|
||||||
|
<Child type="Widget" skin="TB_TL" offset="4 24 4 4" align="ALIGN_TOP ALIGN_LEFT" name="Action">
|
||||||
|
<Property key="Scale" value = "1 1 -1 -1"/>
|
||||||
|
</Child>
|
||||||
|
|
||||||
|
<!-- Caption -->
|
||||||
|
<Child type="Widget" skin="HB_ALL" offset="4 4 248 20" align = "ALIGN_TOP ALIGN_HSTRETCH">
|
||||||
|
<Property key="Scale" value = "1 1 0 0"/>
|
||||||
|
</Child>
|
||||||
|
|
||||||
|
<!-- This invisible button makes it possible to move the
|
||||||
|
window by dragging the caption. -->
|
||||||
|
<Child type="Button" offset="4 4 248 20" align="ALIGN_HSTRETCH ALIGN_TOP" name="Action">
|
||||||
|
<Property key="Scale" value = "1 1 0 0"/>
|
||||||
|
</Child>
|
||||||
|
</Skin>
|
||||||
|
|
||||||
<Skin name = "MW_Window_Pinnable" size = "256 54">
|
<Skin name = "MW_Window_Pinnable" size = "256 54">
|
||||||
<Property key="FontName" value = "Default" />
|
<Property key="FontName" value = "Default" />
|
||||||
<Property key="TextAlign" value = "ALIGN_CENTER" />
|
<Property key="TextAlign" value = "ALIGN_CENTER" />
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
# Defines plugins to load
|
|
||||||
|
|
||||||
# Define plugin folder
|
|
||||||
PluginFolder=${OGRE_PLUGIN_DIR_REL}
|
|
||||||
|
|
||||||
# Define plugins
|
|
||||||
Plugin=RenderSystem_GL${DEBUG_SUFFIX}
|
|
||||||
Plugin=Plugin_ParticleFX${DEBUG_SUFFIX}
|
|
||||||
Plugin=Plugin_OctreeSceneManager${DEBUG_SUFFIX}
|
|
||||||
Plugin=Plugin_CgProgramManager${DEBUG_SUFFIX}
|
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
# Defines plugins to load
|
|
||||||
|
|
||||||
# Define plugin folder
|
|
||||||
PluginFolder=${OGRE_PLUGIN_DIR}
|
|
||||||
|
|
||||||
# Define plugins
|
|
||||||
Plugin=RenderSystem_GL${DEBUG_SUFFIX}.1.8.0
|
|
||||||
Plugin=Plugin_ParticleFX${DEBUG_SUFFIX}.1.8.0
|
|
||||||
Plugin=Plugin_OctreeSceneManager${DEBUG_SUFFIX}.1.8.0
|
|
||||||
Plugin=Plugin_CgProgramManager${DEBUG_SUFFIX}.1.8.0
|
|
||||||
|
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
# Defines plugins to load
|
|
||||||
|
|
||||||
# Define plugin folder
|
|
||||||
PluginFolder=.\
|
|
||||||
|
|
||||||
# Define plugins
|
|
||||||
Plugin=RenderSystem_Direct3D9${DEBUG_SUFFIX}
|
|
||||||
Plugin=RenderSystem_GL${DEBUG_SUFFIX}
|
|
||||||
Plugin=Plugin_ParticleFX${DEBUG_SUFFIX}
|
|
||||||
Plugin=Plugin_OctreeSceneManager${DEBUG_SUFFIX}
|
|
||||||
Plugin=Plugin_CgProgramManager${DEBUG_SUFFIX}
|
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,8 @@ anisotropy = 4
|
||||||
# Number of texture mipmaps to generate
|
# Number of texture mipmaps to generate
|
||||||
num mipmaps = 5
|
num mipmaps = 5
|
||||||
|
|
||||||
|
shader mode =
|
||||||
|
|
||||||
[Shadows]
|
[Shadows]
|
||||||
# Shadows are only supported when object shaders are on!
|
# Shadows are only supported when object shaders are on!
|
||||||
enabled = false
|
enabled = false
|
||||||
|
@ -74,6 +76,8 @@ statics shadows = true
|
||||||
# Fraction of the total shadow distance after which the shadow starts to fade out
|
# Fraction of the total shadow distance after which the shadow starts to fade out
|
||||||
fade start = 0.8
|
fade start = 0.8
|
||||||
|
|
||||||
|
debug = false
|
||||||
|
|
||||||
[HUD]
|
[HUD]
|
||||||
# FPS counter
|
# FPS counter
|
||||||
# 0: not visible
|
# 0: not visible
|
||||||
|
|
|
@ -1,51 +0,0 @@
|
||||||
void main_vp(
|
|
||||||
float4 position : POSITION,
|
|
||||||
float2 uv : TEXCOORD0,
|
|
||||||
|
|
||||||
out float4 oPosition : POSITION,
|
|
||||||
out float2 oDepth : TEXCOORD0,
|
|
||||||
out float2 oUv : TEXCOORD1,
|
|
||||||
|
|
||||||
uniform float4x4 wvpMat)
|
|
||||||
{
|
|
||||||
// this is the view space position
|
|
||||||
oPosition = mul(wvpMat, position);
|
|
||||||
|
|
||||||
// depth info for the fragment.
|
|
||||||
oDepth.x = oPosition.z;
|
|
||||||
oDepth.y = oPosition.w;
|
|
||||||
|
|
||||||
// clamp z to zero. seem to do the trick. :-/
|
|
||||||
oPosition.z = max(oPosition.z, 0);
|
|
||||||
|
|
||||||
oUv = uv;
|
|
||||||
}
|
|
||||||
|
|
||||||
void main_fp(
|
|
||||||
float2 depth : TEXCOORD0,
|
|
||||||
float2 uv : TEXCOORD1,
|
|
||||||
uniform sampler2D texture1 : register(s0),
|
|
||||||
|
|
||||||
out float4 oColour : COLOR)
|
|
||||||
{
|
|
||||||
float finalDepth = depth.x / depth.y;
|
|
||||||
|
|
||||||
// use alpha channel of the first texture
|
|
||||||
float alpha = tex2D(texture1, uv).a;
|
|
||||||
|
|
||||||
// discard if alpha is less than 0.5
|
|
||||||
clip((alpha >= 0.5) ? 1 : -1);
|
|
||||||
|
|
||||||
oColour = float4(finalDepth, finalDepth, finalDepth, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void main_fp_noalpha(
|
|
||||||
float2 depth : TEXCOORD0,
|
|
||||||
float2 uv : TEXCOORD1,
|
|
||||||
|
|
||||||
out float4 oColour : COLOR)
|
|
||||||
{
|
|
||||||
float finalDepth = depth.x / depth.y;
|
|
||||||
|
|
||||||
oColour = float4(finalDepth, finalDepth, finalDepth, 1);
|
|
||||||
}
|
|
|
@ -1,73 +0,0 @@
|
||||||
vertex_program depth_shadow_caster_vs cg
|
|
||||||
{
|
|
||||||
source depthshadowcaster.cg
|
|
||||||
profiles vs_1_1 arbvp1
|
|
||||||
entry_point main_vp
|
|
||||||
|
|
||||||
default_params
|
|
||||||
{
|
|
||||||
param_named_auto wvpMat worldviewproj_matrix
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fragment_program depth_shadow_caster_ps cg
|
|
||||||
{
|
|
||||||
source depthshadowcaster.cg
|
|
||||||
profiles ps_2_0 arbfp1
|
|
||||||
entry_point main_fp
|
|
||||||
|
|
||||||
default_params
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fragment_program depth_shadow_caster_ps_noalpha cg
|
|
||||||
{
|
|
||||||
source depthshadowcaster.cg
|
|
||||||
profiles ps_2_0 arbfp1
|
|
||||||
entry_point main_fp_noalpha
|
|
||||||
|
|
||||||
default_params
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
material depth_shadow_caster
|
|
||||||
{
|
|
||||||
technique
|
|
||||||
{
|
|
||||||
pass
|
|
||||||
{
|
|
||||||
// force-disable fog (relevant for DirectX profiles below SM3 that always apply fixed function fog)
|
|
||||||
fog_override true
|
|
||||||
|
|
||||||
vertex_program_ref depth_shadow_caster_vs
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
fragment_program_ref depth_shadow_caster_ps
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
material depth_shadow_caster_noalpha
|
|
||||||
{
|
|
||||||
technique
|
|
||||||
{
|
|
||||||
pass
|
|
||||||
{
|
|
||||||
// force-disable fog (relevant for DirectX profiles below SM3 that always apply fixed function fog)
|
|
||||||
fog_override true
|
|
||||||
|
|
||||||
vertex_program_ref depth_shadow_caster_vs
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
fragment_program_ref depth_shadow_caster_ps_noalpha
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Binary file not shown.
Before Width: | Height: | Size: 192 KiB |
Binary file not shown.
Before Width: | Height: | Size: 34 KiB |
Binary file not shown.
|
@ -1,61 +0,0 @@
|
||||||
void main_vp
|
|
||||||
(
|
|
||||||
in float4 inPos : POSITION,
|
|
||||||
|
|
||||||
out float4 pos : POSITION,
|
|
||||||
out float2 uv0 : TEXCOORD0,
|
|
||||||
out float4 noiseCoord : TEXCOORD1,
|
|
||||||
|
|
||||||
uniform float4x4 worldViewProj,
|
|
||||||
uniform float timeVal,
|
|
||||||
uniform float scale
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// Use standardise transform, so work accord with render system specific (RS depth, requires texture flipping, etc)
|
|
||||||
pos = mul(worldViewProj, inPos);
|
|
||||||
|
|
||||||
// The input positions adjusted by texel offsets, so clean up inaccuracies
|
|
||||||
inPos.xy = sign(inPos.xy);
|
|
||||||
|
|
||||||
// Convert to image-space
|
|
||||||
uv0 = (float2(inPos.x, -inPos.y) + 1.0f) * 0.5f;
|
|
||||||
noiseCoord = (pos + timeVal) * scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
float4 main_fp_nomrt (float2 iTexCoord : TEXCOORD0,
|
|
||||||
float3 noiseCoord : TEXCOORD1,
|
|
||||||
uniform sampler2D RT : register(s0),
|
|
||||||
uniform sampler2D NormalMap : register(s1),
|
|
||||||
uniform sampler2D CausticMap : register(s2)) : COLOR
|
|
||||||
{
|
|
||||||
float4 normal = tex2D(NormalMap, noiseCoord) * 2 - 1;
|
|
||||||
|
|
||||||
float4 col = tex2D(RT, iTexCoord + normal.xy * 0.015) +
|
|
||||||
(tex2D(CausticMap, noiseCoord) / 5);
|
|
||||||
col.xyz = lerp(col.xyz, float3(0.15, 0.40, 0.40), 0.4);
|
|
||||||
return col;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
float4 main_fp (float2 iTexCoord : TEXCOORD0,
|
|
||||||
float3 noiseCoord : TEXCOORD1,
|
|
||||||
uniform float far,
|
|
||||||
uniform sampler2D RT : register(s0),
|
|
||||||
uniform sampler2D NormalMap : register(s1),
|
|
||||||
uniform sampler2D CausticMap : register(s2),
|
|
||||||
uniform sampler2D DepthMap : register(s3)) : COLOR
|
|
||||||
{
|
|
||||||
float4 normal = tex2D(NormalMap, noiseCoord) * 2 - 1;
|
|
||||||
|
|
||||||
float depth = tex2D(DepthMap, iTexCoord + normal.xy * 0.015).r * far;
|
|
||||||
depth = saturate(depth / 2000.f);
|
|
||||||
|
|
||||||
float4 color = tex2D(RT, iTexCoord + normal.xy * 0.015) +
|
|
||||||
(tex2D(CausticMap, noiseCoord) / 5);
|
|
||||||
color.xyz = lerp(color.xyz, float3(0.15, 0.40, 0.40), 0.4);
|
|
||||||
|
|
||||||
return lerp(color, float4(0.15, 0.40, 0.40, 1), depth);
|
|
||||||
}
|
|
BIN
files/water/underwater_dome.mesh
Normal file
BIN
files/water/underwater_dome.mesh
Normal file
Binary file not shown.
|
@ -1,121 +0,0 @@
|
||||||
void main_vp
|
|
||||||
(
|
|
||||||
in float4 iPos : POSITION
|
|
||||||
, in float2 iUv : TEXCOORD0
|
|
||||||
|
|
||||||
, out float4 oPos : POSITION
|
|
||||||
, out float3 oScreenCoords : TEXCOORD0
|
|
||||||
, out float2 oUv : TEXCOORD1
|
|
||||||
, out float oDepth : TEXCOORD2
|
|
||||||
, out float4 oEyeVector : TEXCOORD3
|
|
||||||
|
|
||||||
, uniform float4x4 wvpMat
|
|
||||||
, uniform float4 camPosObjSpace
|
|
||||||
)
|
|
||||||
{
|
|
||||||
oPos = mul(wvpMat, iPos);
|
|
||||||
|
|
||||||
oUv = iUv * 10; // uv scale
|
|
||||||
oDepth = oPos.z;
|
|
||||||
|
|
||||||
float4x4 scalemat = float4x4( 0.5, 0, 0, 0.5,
|
|
||||||
0, -0.5, 0, 0.5,
|
|
||||||
0, 0, 0.5, 0.5,
|
|
||||||
0, 0, 0, 1 );
|
|
||||||
float4 texcoordProj = mul(scalemat, oPos);
|
|
||||||
oScreenCoords = float3(texcoordProj.x, texcoordProj.y, texcoordProj.w);
|
|
||||||
|
|
||||||
oEyeVector = camPosObjSpace - iPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
void main_fp
|
|
||||||
(
|
|
||||||
out float4 oColor : COLOR
|
|
||||||
|
|
||||||
, in float3 iScreenCoords : TEXCOORD0
|
|
||||||
, in float2 iUv : TEXCOORD1
|
|
||||||
, in float iDepth : TEXCOORD2
|
|
||||||
, in float4 iEyeVector : TEXCOORD3
|
|
||||||
, uniform float renderTargetFlipping
|
|
||||||
, uniform float4 lightPosObjSpace0
|
|
||||||
, uniform float4 lightSpecularColour0
|
|
||||||
|
|
||||||
, uniform sampler2D reflectionMap : register(s0)
|
|
||||||
, uniform sampler2D refractionMap : register(s1)
|
|
||||||
, uniform sampler2D depthMap : register(s2)
|
|
||||||
, uniform sampler2D normalMap : register(s3)
|
|
||||||
, uniform float time
|
|
||||||
, uniform float far
|
|
||||||
, uniform float4 fogParams
|
|
||||||
, uniform float4 fogColour
|
|
||||||
, uniform float isUnderwater
|
|
||||||
)
|
|
||||||
{
|
|
||||||
|
|
||||||
float2 screenCoords = iScreenCoords.xy / iScreenCoords.z;
|
|
||||||
screenCoords.y = (1-saturate(renderTargetFlipping))+renderTargetFlipping*screenCoords.y;
|
|
||||||
|
|
||||||
// No need for transparency since we are using a refraction map
|
|
||||||
oColor.a = 1;
|
|
||||||
|
|
||||||
// Sample screen-space depth map and subtract pixel depth to get the real water depth
|
|
||||||
float depthTex = tex2D(depthMap, screenCoords).r;
|
|
||||||
float depth1 = depthTex * far - iDepth;
|
|
||||||
depth1 = saturate(depth1 / 500.f);
|
|
||||||
|
|
||||||
// Simple wave effect. to be replaced by something better
|
|
||||||
float2 uv1 = iUv + time * float2(0.5, 0);
|
|
||||||
float2 uv2 = iUv + time * float2(0, 0.5);
|
|
||||||
float2 uv3 = iUv + time * float2(-0.5, 0);
|
|
||||||
float2 uv4 = iUv + time * float2(0, -0.5);
|
|
||||||
float4 normal = tex2D(normalMap, uv1) + tex2D(normalMap, uv2) + tex2D(normalMap, uv3) + tex2D(normalMap, uv4);
|
|
||||||
normal = normal / 4.f;
|
|
||||||
normal = 2*normal - 1;
|
|
||||||
|
|
||||||
float2 screenCoords_reflect = screenCoords + normal.yx * 0.05;
|
|
||||||
float2 screenCoords_refract = screenCoords + normal.yx * 0.05 * depth1;
|
|
||||||
|
|
||||||
// Sample depth again with the refracted coordinates
|
|
||||||
depthTex = tex2D(depthMap, screenCoords_refract).r;
|
|
||||||
float depth2 = (depthTex * far - iDepth) / 500.f;
|
|
||||||
depth2 = (depthTex == 0 ? 1 : depth2);
|
|
||||||
// if depth2 is less than 0, this means we would refract something which is above water,
|
|
||||||
// which we don't want to - so in that case, don't refract
|
|
||||||
if (depth2 < 0.25) // delta due to inaccuracies
|
|
||||||
{
|
|
||||||
screenCoords_refract = screenCoords;
|
|
||||||
depth2 = depth1;
|
|
||||||
}
|
|
||||||
depth2 = saturate(depth2);
|
|
||||||
|
|
||||||
float4 reflection = tex2D(reflectionMap, screenCoords_reflect);
|
|
||||||
float4 refraction = tex2D(refractionMap, screenCoords_refract);
|
|
||||||
|
|
||||||
// tangent to object space
|
|
||||||
normal.xyz = normal.xzy;
|
|
||||||
|
|
||||||
iEyeVector.xyz = normalize(iEyeVector.xyz);
|
|
||||||
|
|
||||||
// fresnel
|
|
||||||
float facing = 1.0 - max(abs(dot(iEyeVector.xyz, normal.xyz)), 0);
|
|
||||||
float reflectionFactor = saturate(0.35 + 0.65 * pow(facing, 2));
|
|
||||||
|
|
||||||
// specular
|
|
||||||
float3 lightDir = normalize(lightPosObjSpace0.xyz); // assumes that light 0 is a directional light
|
|
||||||
float3 halfVector = normalize(iEyeVector + lightDir);
|
|
||||||
float specular = pow(max(dot(normal.xyz, halfVector.xyz), 0), 64);
|
|
||||||
|
|
||||||
float opacity = depth2 * saturate(reflectionFactor + specular);
|
|
||||||
opacity *= (1-isUnderwater);
|
|
||||||
|
|
||||||
reflection.xyz += lightSpecularColour0.xyz * specular;
|
|
||||||
|
|
||||||
oColor.xyz = lerp(refraction.xyz, reflection.xyz, opacity);
|
|
||||||
|
|
||||||
oColor.xyz = lerp(oColor.xyz, float3(0.15, 0.40, 0.40), isUnderwater*0.6); // underwater tint color
|
|
||||||
oColor.xyz = lerp(oColor.xyz, float3(0.15, 0.40, 0.40), saturate(isUnderwater * (iDepth / 2000.f))); // underwater fog
|
|
||||||
|
|
||||||
// add fog
|
|
||||||
//float fogValue = saturate((iDepth - fogParams.y) * fogParams.w);
|
|
||||||
//oColor.xyz = lerp(oColor.xyz, fogColour, fogValue);
|
|
||||||
}
|
|
|
@ -1,46 +0,0 @@
|
||||||
compositor UnderwaterNoMRT
|
|
||||||
{
|
|
||||||
technique
|
|
||||||
{
|
|
||||||
texture rt0 target_width target_height PF_R8G8B8
|
|
||||||
|
|
||||||
target rt0 { input previous }
|
|
||||||
|
|
||||||
target_output
|
|
||||||
{
|
|
||||||
// Start with clear output
|
|
||||||
input none
|
|
||||||
|
|
||||||
pass render_quad
|
|
||||||
{
|
|
||||||
material Water/CompositorNoMRT
|
|
||||||
input 0 rt0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
compositor Underwater
|
|
||||||
{
|
|
||||||
technique
|
|
||||||
{
|
|
||||||
texture_ref scene gbuffer mrt_output
|
|
||||||
texture rt0 target_width target_height PF_R8G8B8
|
|
||||||
|
|
||||||
target rt0 { input previous }
|
|
||||||
|
|
||||||
target_output
|
|
||||||
{
|
|
||||||
// Start with clear output
|
|
||||||
input none
|
|
||||||
|
|
||||||
pass render_quad
|
|
||||||
{
|
|
||||||
material Water/Compositor
|
|
||||||
input 0 rt0
|
|
||||||
input 3 scene 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,221 +0,0 @@
|
||||||
vertex_program UnderwaterEffectVP cg
|
|
||||||
{
|
|
||||||
source underwater.cg
|
|
||||||
entry_point main_vp
|
|
||||||
profiles vs_1_1 arbvp1
|
|
||||||
|
|
||||||
default_params
|
|
||||||
{
|
|
||||||
param_named_auto worldViewProj worldviewproj_matrix
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fragment_program UnderwaterEffectFP_NoMRT cg
|
|
||||||
{
|
|
||||||
source underwater.cg
|
|
||||||
entry_point main_fp_nomrt
|
|
||||||
profiles ps_2_0 arbfp1
|
|
||||||
}
|
|
||||||
|
|
||||||
fragment_program UnderwaterEffectFP cg
|
|
||||||
{
|
|
||||||
source underwater.cg
|
|
||||||
entry_point main_fp
|
|
||||||
profiles ps_2_0 arbfp1
|
|
||||||
}
|
|
||||||
|
|
||||||
vertex_program Water_VP cg
|
|
||||||
{
|
|
||||||
source water.cg
|
|
||||||
entry_point main_vp
|
|
||||||
profiles vs_2_x arbvp1
|
|
||||||
|
|
||||||
default_params
|
|
||||||
{
|
|
||||||
param_named_auto wvpMat worldviewproj_matrix
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fragment_program Water_FP cg
|
|
||||||
{
|
|
||||||
source water.cg
|
|
||||||
entry_point main_fp
|
|
||||||
profiles ps_2_x arbfp1
|
|
||||||
}
|
|
||||||
|
|
||||||
material Water
|
|
||||||
{
|
|
||||||
technique
|
|
||||||
{
|
|
||||||
pass
|
|
||||||
{
|
|
||||||
cull_hardware none
|
|
||||||
|
|
||||||
vertex_program_ref Water_VP
|
|
||||||
{
|
|
||||||
param_named_auto camPosObjSpace camera_position_object_space
|
|
||||||
}
|
|
||||||
fragment_program_ref Water_FP
|
|
||||||
{
|
|
||||||
param_named_auto time time 0.1
|
|
||||||
//param_named_auto fogColour fog_colour
|
|
||||||
//param_named_auto fogParams fog_params
|
|
||||||
param_named_auto renderTargetFlipping render_target_flipping
|
|
||||||
param_named_auto far far_clip_distance
|
|
||||||
param_named_auto lightPosObjSpace0 light_position_object_space 0
|
|
||||||
param_named_auto lightSpecularColour0 light_specular_colour 0
|
|
||||||
param_named isUnderwater float 0
|
|
||||||
}
|
|
||||||
|
|
||||||
texture_unit reflectionMap
|
|
||||||
{
|
|
||||||
texture WaterReflection
|
|
||||||
tex_address_mode clamp
|
|
||||||
}
|
|
||||||
|
|
||||||
texture_unit refractionMap
|
|
||||||
{
|
|
||||||
tex_address_mode clamp
|
|
||||||
}
|
|
||||||
|
|
||||||
texture_unit depthMap
|
|
||||||
{
|
|
||||||
tex_address_mode clamp
|
|
||||||
}
|
|
||||||
|
|
||||||
texture_unit normalMap
|
|
||||||
{
|
|
||||||
texture WaterNormal2.tga
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
technique
|
|
||||||
{
|
|
||||||
scheme Fallback
|
|
||||||
pass
|
|
||||||
{
|
|
||||||
cull_hardware none
|
|
||||||
scene_blend alpha_blend
|
|
||||||
depth_write off
|
|
||||||
diffuse 0 0 0 1
|
|
||||||
emissive 0.6 0.7 1.0
|
|
||||||
ambient 0 0 0
|
|
||||||
texture_unit
|
|
||||||
{
|
|
||||||
// texture names set via code
|
|
||||||
scale 0.1 0.1
|
|
||||||
alpha_op_ex source1 src_manual src_current 0.7
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
material Water_Fallback
|
|
||||||
{
|
|
||||||
technique
|
|
||||||
{
|
|
||||||
scheme Fallback
|
|
||||||
pass
|
|
||||||
{
|
|
||||||
cull_hardware none
|
|
||||||
scene_blend alpha_blend
|
|
||||||
depth_write off
|
|
||||||
diffuse 0 0 0 1
|
|
||||||
emissive 0.6 0.7 1.0
|
|
||||||
ambient 0 0 0
|
|
||||||
texture_unit
|
|
||||||
{
|
|
||||||
// texture names set via code
|
|
||||||
scale 0.1 0.1
|
|
||||||
alpha_op_ex source1 src_manual src_current 0.7
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
material Water/CompositorNoMRT
|
|
||||||
{
|
|
||||||
technique
|
|
||||||
{
|
|
||||||
pass
|
|
||||||
{
|
|
||||||
depth_check off
|
|
||||||
vertex_program_ref UnderwaterEffectVP
|
|
||||||
{
|
|
||||||
param_named_auto timeVal time 0.25
|
|
||||||
param_named scale float 0.1
|
|
||||||
}
|
|
||||||
|
|
||||||
fragment_program_ref UnderwaterEffectFP_NoMRT
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
texture_unit RT
|
|
||||||
{
|
|
||||||
tex_coord_set 0
|
|
||||||
tex_address_mode clamp
|
|
||||||
filtering linear linear linear
|
|
||||||
}
|
|
||||||
|
|
||||||
texture_unit
|
|
||||||
{
|
|
||||||
texture WaterNormal2.tga 2d
|
|
||||||
tex_coord_set 1
|
|
||||||
//tex_address_mode clamp
|
|
||||||
filtering linear linear linear
|
|
||||||
}
|
|
||||||
texture_unit
|
|
||||||
{
|
|
||||||
texture caustic_0.png 2d
|
|
||||||
tex_coord_set 2
|
|
||||||
//tex_address_mode clamp
|
|
||||||
filtering linear linear linear
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
material Water/Compositor
|
|
||||||
{
|
|
||||||
technique
|
|
||||||
{
|
|
||||||
pass
|
|
||||||
{
|
|
||||||
depth_check off
|
|
||||||
vertex_program_ref UnderwaterEffectVP
|
|
||||||
{
|
|
||||||
param_named_auto timeVal time 0.25
|
|
||||||
param_named scale float 0.1
|
|
||||||
}
|
|
||||||
|
|
||||||
fragment_program_ref UnderwaterEffectFP
|
|
||||||
{
|
|
||||||
param_named_auto far far_clip_distance
|
|
||||||
}
|
|
||||||
|
|
||||||
texture_unit RT
|
|
||||||
{
|
|
||||||
tex_coord_set 0
|
|
||||||
tex_address_mode clamp
|
|
||||||
}
|
|
||||||
|
|
||||||
texture_unit
|
|
||||||
{
|
|
||||||
texture WaterNormal2.tga 2d
|
|
||||||
tex_coord_set 2
|
|
||||||
}
|
|
||||||
texture_unit
|
|
||||||
{
|
|
||||||
texture caustic_0.png 2d
|
|
||||||
tex_coord_set 3
|
|
||||||
}
|
|
||||||
|
|
||||||
texture_unit DepthMap
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
BIN
files/water/water_nm.png
Normal file
BIN
files/water/water_nm.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 24 KiB |
|
@ -9,7 +9,10 @@
|
||||||
#include "OgreTexture.h"
|
#include "OgreTexture.h"
|
||||||
#include "OgreHardwarePixelBuffer.h"
|
#include "OgreHardwarePixelBuffer.h"
|
||||||
|
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <cstdlib>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
using namespace Ogre;
|
using namespace Ogre;
|
||||||
|
@ -70,7 +73,6 @@ float OgreRenderer::getFPS()
|
||||||
}
|
}
|
||||||
|
|
||||||
void OgreRenderer::configure(const std::string &logPath,
|
void OgreRenderer::configure(const std::string &logPath,
|
||||||
const std::string &pluginCfg,
|
|
||||||
const std::string& renderSystem,
|
const std::string& renderSystem,
|
||||||
bool _logging)
|
bool _logging)
|
||||||
{
|
{
|
||||||
|
@ -86,13 +88,41 @@ void OgreRenderer::configure(const std::string &logPath,
|
||||||
// Disable logging
|
// Disable logging
|
||||||
log->setDebugOutputEnabled(false);
|
log->setDebugOutputEnabled(false);
|
||||||
|
|
||||||
#if defined(ENABLE_PLUGIN_GL) || defined(ENABLE_PLUGIN_Direct3D9) || defined(ENABLE_PLUGIN_CgProgramManager) || defined(ENABLE_PLUGIN_OctreeSceneManager) || defined(ENABLE_PLUGIN_ParticleFX)
|
|
||||||
mRoot = new Root("", "", "");
|
mRoot = new Root("", "", "");
|
||||||
|
|
||||||
|
#if defined(ENABLE_PLUGIN_GL) || defined(ENABLE_PLUGIN_Direct3D9) || defined(ENABLE_PLUGIN_CgProgramManager) || defined(ENABLE_PLUGIN_OctreeSceneManager) || defined(ENABLE_PLUGIN_ParticleFX)
|
||||||
loadPlugins();
|
loadPlugins();
|
||||||
#else
|
|
||||||
mRoot = new Root(pluginCfg, "", "");
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
std::string pluginDir;
|
||||||
|
const char* pluginEnv = getenv("OPENMW_OGRE_PLUGIN_DIR");
|
||||||
|
if (pluginEnv)
|
||||||
|
pluginDir = pluginEnv;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
|
||||||
|
pluginDir = ".\\";
|
||||||
|
#endif
|
||||||
|
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
|
||||||
|
pluginDir = OGRE_PLUGIN_DIR;
|
||||||
|
#endif
|
||||||
|
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
|
||||||
|
pluginDir = OGRE_PLUGIN_DIR_REL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string glPlugin = std::string(pluginDir) + "/RenderSystem_GL" + OGRE_PLUGIN_DEBUG_SUFFIX;
|
||||||
|
if (boost::filesystem::exists(glPlugin + ".so") || boost::filesystem::exists(glPlugin + ".dll"))
|
||||||
|
mRoot->loadPlugin (glPlugin);
|
||||||
|
|
||||||
|
std::string dxPlugin = std::string(pluginDir) + "/RenderSystem_Direct3D9" + OGRE_PLUGIN_DEBUG_SUFFIX;
|
||||||
|
if (boost::filesystem::exists(dxPlugin + ".so") || boost::filesystem::exists(dxPlugin + ".dll"))
|
||||||
|
mRoot->loadPlugin (dxPlugin);
|
||||||
|
|
||||||
|
std::string cgPlugin = std::string(pluginDir) + "/Plugin_CgProgramManager" + OGRE_PLUGIN_DEBUG_SUFFIX;
|
||||||
|
if (boost::filesystem::exists(cgPlugin + ".so") || boost::filesystem::exists(cgPlugin + ".dll"))
|
||||||
|
mRoot->loadPlugin (cgPlugin);
|
||||||
|
|
||||||
RenderSystem* rs = mRoot->getRenderSystemByName(renderSystem);
|
RenderSystem* rs = mRoot->getRenderSystemByName(renderSystem);
|
||||||
if (rs == 0)
|
if (rs == 0)
|
||||||
throw std::runtime_error ("RenderSystem with name " + renderSystem + " not found, make sure the plugins are loaded");
|
throw std::runtime_error ("RenderSystem with name " + renderSystem + " not found, make sure the plugins are loaded");
|
||||||
|
|
|
@ -110,7 +110,6 @@ namespace OEngine
|
||||||
set up the Root and logging classes. */
|
set up the Root and logging classes. */
|
||||||
void configure(
|
void configure(
|
||||||
const std::string &logPath, // Path to directory where to store log files
|
const std::string &logPath, // Path to directory where to store log files
|
||||||
const std::string &pluginCfg, // plugin.cfg file
|
|
||||||
const std::string &renderSystem,
|
const std::string &renderSystem,
|
||||||
bool _logging); // Enable or disable logging
|
bool _logging); // Enable or disable logging
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue