mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-03-03 21:49:41 +00:00
Bringing in some of Azathoth's work
This commit is contained in:
parent
7385948056
commit
8798f7dd40
17 changed files with 661 additions and 92 deletions
|
@ -202,6 +202,7 @@ link_directories(${Boost_LIBRARY_DIRS} ${OGRE_LIB_DIR})
|
||||||
|
|
||||||
add_subdirectory( extern/caelum )
|
add_subdirectory( extern/caelum )
|
||||||
add_subdirectory( extern/mygui_3.0.1 )
|
add_subdirectory( extern/mygui_3.0.1 )
|
||||||
|
add_subdirectory( files/)
|
||||||
|
|
||||||
# Make sure that certain libraries are used as static libraries
|
# Make sure that certain libraries are used as static libraries
|
||||||
# This is in effect turns off __declspec (dllexport) for windows
|
# This is in effect turns off __declspec (dllexport) for windows
|
||||||
|
|
|
@ -16,7 +16,7 @@ set(GAME_HEADER
|
||||||
source_group(game FILES ${GAME} ${GAME_HEADER})
|
source_group(game FILES ${GAME} ${GAME_HEADER})
|
||||||
|
|
||||||
add_openmw_dir (mwrender
|
add_openmw_dir (mwrender
|
||||||
renderingmanager debugging sky player npcs creatures objects renderinginterface
|
renderingmanager debugging sky player npcs creatures objects renderinginterface water
|
||||||
)
|
)
|
||||||
|
|
||||||
add_openmw_dir (mwinput
|
add_openmw_dir (mwinput
|
||||||
|
|
104
apps/openmw/mwrender/water.cpp
Normal file
104
apps/openmw/mwrender/water.cpp
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
#include "water.hpp"
|
||||||
|
|
||||||
|
namespace MWRender {
|
||||||
|
Water::Water (Ogre::Camera *camera) : mCamera (camera), mViewport (camera->getViewport()), mSceneManager (camera->getSceneManager()) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
Ogre::CompositorManager::getSingleton().addCompositor(mViewport, "Water", -1);
|
||||||
|
Ogre::CompositorManager::getSingleton().setCompositorEnabled(mViewport, "Water", false);
|
||||||
|
} catch(...) {
|
||||||
|
}
|
||||||
|
mIsUnderwater = false;
|
||||||
|
|
||||||
|
mCamera->addListener(this);
|
||||||
|
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < 2; i++) {
|
||||||
|
Ogre::TexturePtr tex = Ogre::TextureManager::getSingleton().createManual(i == 0 ? "refraction" : "reflection", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, 512, 512, 0, Ogre::PF_R8G8B8, Ogre::TU_RENDERTARGET);
|
||||||
|
|
||||||
|
Ogre::RenderTarget* rtt = tex->getBuffer()->getRenderTarget();
|
||||||
|
rtt->addViewport(mCamera)->setOverlaysEnabled(false);
|
||||||
|
rtt->addListener(this);
|
||||||
|
|
||||||
|
if (i == 0) mRefractionTarget = rtt;
|
||||||
|
else mReflectionTarget = rtt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
mWaterPlane = Ogre::Plane(Ogre::Vector3::UNIT_Y, 0);
|
||||||
|
Ogre::MeshManager::getSingleton().createPlane("water", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, mWaterPlane, 7000, 7000, 10, 10, true, 1, 3, 5, Ogre::Vector3::UNIT_Z);
|
||||||
|
|
||||||
|
|
||||||
|
mWater = mSceneManager->createEntity("Water", "water");
|
||||||
|
mWater->setMaterialName("Water/ReflectionRefraction");
|
||||||
|
mWaterNode = mSceneManager->getRootSceneNode()->createChildSceneNode();
|
||||||
|
mWaterNode->attachObject(mWater);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Water::~Water() {
|
||||||
|
Ogre::MeshManager::getSingleton().remove("water");
|
||||||
|
Ogre::TextureManager::getSingleton().remove("refraction");
|
||||||
|
Ogre::TextureManager::getSingleton().remove("reflection");
|
||||||
|
Ogre::CompositorManager::getSingleton().removeCompositorChain(mViewport);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Water::preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt) {
|
||||||
|
mWater->setVisible(false);
|
||||||
|
|
||||||
|
if (evt.source == mReflectionTarget) {
|
||||||
|
mCamera->enableReflection(mWaterPlane);
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Water::postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt) {
|
||||||
|
mWater->setVisible(true);
|
||||||
|
|
||||||
|
if (evt.source == mReflectionTarget) {
|
||||||
|
mCamera->disableReflection();
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Water::checkUnderwater() {
|
||||||
|
Ogre::Vector3 pos = mCamera->getPosition();
|
||||||
|
if (mIsUnderwater && pos.y > 0) {
|
||||||
|
try {
|
||||||
|
Ogre::CompositorManager::getSingleton().setCompositorEnabled(mViewport, "Water", false);
|
||||||
|
} catch(...) {
|
||||||
|
}
|
||||||
|
std::cout << "Removing water compositor" << "\n";
|
||||||
|
mIsUnderwater = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mIsUnderwater && pos.y < 0) {
|
||||||
|
try {
|
||||||
|
Ogre::CompositorManager::getSingleton().setCompositorEnabled(mViewport, "Water", true);
|
||||||
|
} catch(...) {
|
||||||
|
}
|
||||||
|
mIsUnderwater = true;
|
||||||
|
std::cout << "Adding water compositor" << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Water::cameraPreRenderScene(Ogre::Camera *cam) {
|
||||||
|
Ogre::Vector3 pos = cam->getPosition();
|
||||||
|
|
||||||
|
if (pos != mOldCameraPos) {
|
||||||
|
mWaterNode->setPosition(pos.x, 0, pos.z);
|
||||||
|
|
||||||
|
mOldCameraPos = pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Water::cameraPostRenderScene(Ogre::Camera *cam) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void Water::cameraDestroyed(Ogre::Camera *cam) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
45
apps/openmw/mwrender/water.hpp
Normal file
45
apps/openmw/mwrender/water.hpp
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
#ifndef GAME_MWRENDER_WATER_H
|
||||||
|
#define GAME_MWRENDER_WATER_H
|
||||||
|
|
||||||
|
#include <Ogre.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace MWRender {
|
||||||
|
|
||||||
|
/// Water rendering
|
||||||
|
class Water : Ogre::RenderTargetListener, Ogre::Camera::Listener {
|
||||||
|
Ogre::Camera *mCamera;
|
||||||
|
Ogre::SceneManager *mSceneManager;
|
||||||
|
Ogre::Viewport *mViewport;
|
||||||
|
|
||||||
|
Ogre::RenderTarget *mRefractionTarget;
|
||||||
|
Ogre::RenderTarget *mReflectionTarget;
|
||||||
|
|
||||||
|
Ogre::Plane mWaterPlane;
|
||||||
|
Ogre::SceneNode *mWaterNode;
|
||||||
|
Ogre::Entity *mWater;
|
||||||
|
|
||||||
|
Ogre::Vector3 mOldCameraPos;
|
||||||
|
bool mIsUnderwater;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void preRenderTargetUpdate(const Ogre::RenderTargetEvent&);
|
||||||
|
void postRenderTargetUpdate(const Ogre::RenderTargetEvent&);
|
||||||
|
|
||||||
|
void cameraPreRenderScene(Ogre::Camera *cam);
|
||||||
|
void cameraPostRenderScene(Ogre::Camera *cam);
|
||||||
|
void cameraDestroyed(Ogre::Camera *cam);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Water (Ogre::Camera *camera);
|
||||||
|
~Water();
|
||||||
|
|
||||||
|
void checkUnderwater();
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -15,30 +15,6 @@
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void insertCellRefList (T& cellRefList, ESMS::CellStore<MWWorld::RefData> &cell)
|
|
||||||
{
|
|
||||||
if (!cellRefList.list.empty())
|
|
||||||
{
|
|
||||||
//const MWWorld::Class& class_ = MWWorld::Class::get (MWWorld::Ptr (&*cellRefList.list.begin(), &cell));
|
|
||||||
|
|
||||||
for (typename T::List::iterator it = cellRefList.list.begin();
|
|
||||||
it != cellRefList.list.end(); it++)
|
|
||||||
{
|
|
||||||
if (it->mData.getCount() || it->mData.isEnabled())
|
|
||||||
{
|
|
||||||
MWWorld::Ptr ptr (&*it, &cell);
|
|
||||||
/* TODO: call
|
|
||||||
* RenderingManager.insertObject
|
|
||||||
* class_.insertObjectPhysic
|
|
||||||
* class_.insertObjectMechanics
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void insertCellRefList(MWRender::RenderingManager& rendering, MWWorld::Environment& environment,
|
void insertCellRefList(MWRender::RenderingManager& rendering, MWWorld::Environment& environment,
|
||||||
T& cellRefList, ESMS::CellStore<MWWorld::RefData> &cell, MWWorld::PhysicsSystem& physics)
|
T& cellRefList, ESMS::CellStore<MWWorld::RefData> &cell, MWWorld::PhysicsSystem& physics)
|
||||||
|
@ -79,11 +55,13 @@ namespace MWWorld
|
||||||
|
|
||||||
void Scene::unloadCell (CellStoreCollection::iterator iter)
|
void Scene::unloadCell (CellStoreCollection::iterator iter)
|
||||||
{
|
{
|
||||||
|
std::cout << "Unloading cell\n";
|
||||||
ListHandles functor;
|
ListHandles functor;
|
||||||
|
|
||||||
MWWorld::Ptr::CellStore* active = *iter;
|
MWWorld::Ptr::CellStore* active = *iter;
|
||||||
mRendering.removeCell(active);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
active->forEach<ListHandles>(functor);
|
active->forEach<ListHandles>(functor);
|
||||||
|
|
||||||
|
@ -97,10 +75,13 @@ namespace MWWorld
|
||||||
mPhysics->removeObject (node->getName());
|
mPhysics->removeObject (node->getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mRendering.removeCell(active);
|
||||||
|
//mPhysics->removeObject("Unnamed_43");
|
||||||
mWorld->getLocalScripts().clearCell (active);
|
mWorld->getLocalScripts().clearCell (active);
|
||||||
mEnvironment.mMechanicsManager->dropActors (active);
|
mEnvironment.mMechanicsManager->dropActors (active);
|
||||||
mEnvironment.mSoundManager->stopSound (active);
|
mEnvironment.mSoundManager->stopSound (active);
|
||||||
mActiveCells.erase (iter);
|
mActiveCells.erase(active);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::loadCell (Ptr::CellStore *cell)
|
void Scene::loadCell (Ptr::CellStore *cell)
|
||||||
|
@ -114,7 +95,7 @@ namespace MWWorld
|
||||||
mActiveCells.insert(cell);
|
mActiveCells.insert(cell);
|
||||||
if(result.second){
|
if(result.second){
|
||||||
insertCell(*cell, mEnvironment);
|
insertCell(*cell, mEnvironment);
|
||||||
mRendering.getObjects().buildStaticGeometry(*cell);
|
//mRendering.cellAdded (cell);
|
||||||
mRendering.configureAmbient(*cell);
|
mRendering.configureAmbient(*cell);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -140,15 +121,13 @@ namespace MWWorld
|
||||||
mEnvironment.mMechanicsManager->removeActor (mWorld->getPlayer().getPlayer());
|
mEnvironment.mMechanicsManager->removeActor (mWorld->getPlayer().getPlayer());
|
||||||
|
|
||||||
CellStoreCollection::iterator active = mActiveCells.begin();
|
CellStoreCollection::iterator active = mActiveCells.begin();
|
||||||
Ptr::CellStore* cellstore = *active;
|
|
||||||
|
|
||||||
while (active!=mActiveCells.end())
|
while (active!=mActiveCells.end())
|
||||||
{
|
{
|
||||||
cellstore = *active;
|
if (!((*active)->cell->data.flags & ESM::Cell::Interior))
|
||||||
if (!(cellstore->cell->data.flags & ESM::Cell::Interior))
|
|
||||||
{
|
{
|
||||||
if (std::abs (X-cellstore->cell->data.gridX)<=1 &&
|
if (std::abs (X-(*active)->cell->data.gridX)<=1 &&
|
||||||
std::abs (Y-cellstore->cell->data.gridY)<=1)
|
std::abs (Y-(*active)->cell->data.gridY)<=1)
|
||||||
{
|
{
|
||||||
// keep cells within the new 3x3 grid
|
// keep cells within the new 3x3 grid
|
||||||
++active;
|
++active;
|
||||||
|
@ -165,14 +144,12 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
CellStoreCollection::iterator iter = mActiveCells.begin();
|
CellStoreCollection::iterator iter = mActiveCells.begin();
|
||||||
|
|
||||||
|
|
||||||
while (iter!=mActiveCells.end())
|
while (iter!=mActiveCells.end())
|
||||||
{
|
{
|
||||||
cellstore = *iter;
|
assert (!((*iter)->cell->data.flags & ESM::Cell::Interior));
|
||||||
assert (!(cellstore->cell->data.flags & ESM::Cell::Interior));
|
|
||||||
|
|
||||||
if (x==cellstore->cell->data.gridX &&
|
if (x==(*iter)->cell->data.gridX &&
|
||||||
y==cellstore->cell->data.gridY)
|
y==(*iter)->cell->data.gridY)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
++iter;
|
++iter;
|
||||||
|
@ -189,14 +166,12 @@ namespace MWWorld
|
||||||
// find current cell
|
// find current cell
|
||||||
CellStoreCollection::iterator iter = mActiveCells.begin();
|
CellStoreCollection::iterator iter = mActiveCells.begin();
|
||||||
|
|
||||||
|
|
||||||
while (iter!=mActiveCells.end())
|
while (iter!=mActiveCells.end())
|
||||||
{
|
{
|
||||||
cellstore = *iter;
|
assert (!((*iter)->cell->data.flags & ESM::Cell::Interior));
|
||||||
assert (!(iter->first->cell->data.flags & ESM::Cell::Interior));
|
|
||||||
|
|
||||||
if (X==cellstore->cell->data.gridX &&
|
if (X==(*iter)->cell->data.gridX &&
|
||||||
Y==cellstore->cell->data.gridY)
|
Y==(*iter)->cell->data.gridY)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
++iter;
|
++iter;
|
||||||
|
@ -204,7 +179,7 @@ namespace MWWorld
|
||||||
|
|
||||||
assert (iter!=mActiveCells.end());
|
assert (iter!=mActiveCells.end());
|
||||||
|
|
||||||
mCurrentCell = cellstore;
|
mCurrentCell = *iter;
|
||||||
|
|
||||||
// adjust player
|
// adjust player
|
||||||
playerCellChange (mWorld->getExterior(X, Y), position, adjustPlayerPos);
|
playerCellChange (mWorld->getExterior(X, Y), position, adjustPlayerPos);
|
||||||
|
@ -217,8 +192,8 @@ namespace MWWorld
|
||||||
|
|
||||||
//We need the ogre renderer and a scene node.
|
//We need the ogre renderer and a scene node.
|
||||||
Scene::Scene (Environment& environment, World *world, MWRender::RenderingManager& rendering, PhysicsSystem *physics)
|
Scene::Scene (Environment& environment, World *world, MWRender::RenderingManager& rendering, PhysicsSystem *physics)
|
||||||
: mRendering(rendering), mCurrentCell (0),
|
: mCurrentCell (0), mCellChanged (false), mEnvironment (environment), mWorld(world),
|
||||||
mCellChanged (false), mEnvironment (environment), mWorld(world), mPhysics(physics)
|
mPhysics(physics), mRendering(rendering)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,7 +216,7 @@ namespace MWWorld
|
||||||
std::cout << "Changing to interior\n";
|
std::cout << "Changing to interior\n";
|
||||||
// remove active
|
// remove active
|
||||||
CellStoreCollection::iterator active = mActiveCells.begin();
|
CellStoreCollection::iterator active = mActiveCells.begin();
|
||||||
std::cout << "Size: " << mActiveCells.size() << "\n";
|
|
||||||
while (active!=mActiveCells.end())
|
while (active!=mActiveCells.end())
|
||||||
{
|
{
|
||||||
unloadCell (active++);
|
unloadCell (active++);
|
||||||
|
@ -261,7 +236,6 @@ namespace MWWorld
|
||||||
mWorld->adjustSky();
|
mWorld->adjustSky();
|
||||||
|
|
||||||
mCellChanged = true;
|
mCellChanged = true;
|
||||||
//currentRegion->name = "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::changeToExteriorCell (const ESM::Position& position)
|
void Scene::changeToExteriorCell (const ESM::Position& position)
|
||||||
|
@ -284,38 +258,6 @@ namespace MWWorld
|
||||||
mCellChanged = false;
|
mCellChanged = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*#include <cassert>
|
|
||||||
#include <iostream>
|
|
||||||
#include <exception>
|
|
||||||
|
|
||||||
#include "../mwworld/class.hpp"
|
|
||||||
#include "../mwworld/ptr.hpp"*/
|
|
||||||
|
|
||||||
void Scene::insertCell(ESMS::CellStore<MWWorld::RefData> &cell)
|
|
||||||
{
|
|
||||||
// Loop through all references in the cell
|
|
||||||
insertCellRefList (cell.activators, cell);
|
|
||||||
insertCellRefList (cell.potions, cell);
|
|
||||||
insertCellRefList (cell.appas, cell);
|
|
||||||
insertCellRefList (cell.armors, cell);
|
|
||||||
insertCellRefList (cell.books, cell);
|
|
||||||
insertCellRefList (cell.clothes, cell);
|
|
||||||
insertCellRefList (cell.containers, cell);
|
|
||||||
insertCellRefList (cell.creatures, cell);
|
|
||||||
insertCellRefList (cell.doors, cell);
|
|
||||||
insertCellRefList (cell.ingreds, cell);
|
|
||||||
insertCellRefList (cell.creatureLists, cell);
|
|
||||||
insertCellRefList (cell.itemLists, cell);
|
|
||||||
insertCellRefList (cell.lights, cell);
|
|
||||||
insertCellRefList (cell.lockpicks, cell);
|
|
||||||
insertCellRefList (cell.miscItems, cell);
|
|
||||||
insertCellRefList (cell.npcs, cell);
|
|
||||||
insertCellRefList (cell.probes, cell);
|
|
||||||
insertCellRefList (cell.repairs, cell);
|
|
||||||
insertCellRefList (cell.statics, cell);
|
|
||||||
insertCellRefList(cell.weapons, cell);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Scene::insertCell(ESMS::CellStore<MWWorld::RefData> &cell,
|
void Scene::insertCell(ESMS::CellStore<MWWorld::RefData> &cell,
|
||||||
MWWorld::Environment& environment)
|
MWWorld::Environment& environment)
|
||||||
{
|
{
|
||||||
|
|
12
files/CMakeLists.txt
Normal file
12
files/CMakeLists.txt
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
project(resources)
|
||||||
|
|
||||||
|
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/caustic_0.png "${OpenMW_BINARY_DIR}/resources/water/caustic_0.png" COPYONLY)
|
||||||
|
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/Example_Fresnel.cg "${OpenMW_BINARY_DIR}/resources/water/Example_Fresnel.cg" COPYONLY)
|
||||||
|
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/Example_FresnelPS.asm "${OpenMW_BINARY_DIR}/resources/water/Example_FresnelPS.asm" COPYONLY)
|
||||||
|
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/GlassFP.cg "${OpenMW_BINARY_DIR}/resources/water/GlassFP.cg" COPYONLY)
|
||||||
|
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/GlassVP.cg "${OpenMW_BINARY_DIR}/resources/water/GlassVP.cg" COPYONLY)
|
||||||
|
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/perlinvolume.dds "${OpenMW_BINARY_DIR}/resources/water/perlinvolume.dds" COPYONLY)
|
||||||
|
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/water/Water02.jpg "${OpenMW_BINARY_DIR}/resources/water/Water02.jpg" COPYONLY)
|
||||||
|
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/waves2.dds "${OpenMW_BINARY_DIR}/resources/water/waves2.dds" COPYONLY)
|
|
@ -7,6 +7,6 @@ PluginFolder=${OGRE_PLUGIN_DIR}
|
||||||
Plugin=RenderSystem_GL
|
Plugin=RenderSystem_GL
|
||||||
Plugin=Plugin_ParticleFX
|
Plugin=Plugin_ParticleFX
|
||||||
Plugin=Plugin_OctreeSceneManager
|
Plugin=Plugin_OctreeSceneManager
|
||||||
# Plugin=Plugin_CgProgramManager
|
Plugin=Plugin_CgProgramManager
|
||||||
|
|
||||||
|
|
||||||
|
|
116
files/water/Example_Fresnel.cg
Normal file
116
files/water/Example_Fresnel.cg
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
// Vertex program for fresnel reflections / refractions
|
||||||
|
void main_vp(
|
||||||
|
float4 pos : POSITION,
|
||||||
|
float4 normal : NORMAL,
|
||||||
|
float2 tex : TEXCOORD0,
|
||||||
|
|
||||||
|
out float4 oPos : POSITION,
|
||||||
|
out float3 noiseCoord : TEXCOORD0,
|
||||||
|
out float4 projectionCoord : TEXCOORD1,
|
||||||
|
out float3 oEyeDir : TEXCOORD2,
|
||||||
|
out float3 oNormal : TEXCOORD3,
|
||||||
|
|
||||||
|
uniform float4x4 worldViewProjMatrix,
|
||||||
|
uniform float3 eyePosition, // object space
|
||||||
|
uniform float timeVal,
|
||||||
|
uniform float scale, // the amount to scale the noise texture by
|
||||||
|
uniform float scroll, // the amount by which to scroll the noise
|
||||||
|
uniform float noise // the noise perturb as a factor of the time
|
||||||
|
)
|
||||||
|
{
|
||||||
|
oPos = mul(worldViewProjMatrix, pos);
|
||||||
|
// Projective texture coordinates, adjust for mapping
|
||||||
|
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);
|
||||||
|
projectionCoord = mul(scalemat, oPos);
|
||||||
|
// Noise map coords
|
||||||
|
noiseCoord.xy = (tex + (timeVal * scroll)) * scale;
|
||||||
|
noiseCoord.z = noise * timeVal;
|
||||||
|
|
||||||
|
oEyeDir = normalize(pos.xyz - eyePosition);
|
||||||
|
oNormal = normal.rgb;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fragment program for distorting a texture using a 3D noise texture
|
||||||
|
void main_fp(
|
||||||
|
float3 noiseCoord : TEXCOORD0,
|
||||||
|
float4 projectionCoord : TEXCOORD1,
|
||||||
|
float3 eyeDir : TEXCOORD2,
|
||||||
|
float3 normal : TEXCOORD3,
|
||||||
|
|
||||||
|
out float4 col : COLOR,
|
||||||
|
|
||||||
|
uniform float4 tintColour,
|
||||||
|
uniform float noiseScale,
|
||||||
|
uniform float fresnelBias,
|
||||||
|
uniform float fresnelScale,
|
||||||
|
uniform float fresnelPower,
|
||||||
|
uniform sampler2D waterTex : register(s0),
|
||||||
|
uniform sampler2D noiseMap : register(s1),
|
||||||
|
uniform sampler2D reflectMap : register(s2),
|
||||||
|
uniform sampler2D refractMap : register(s3)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Do the tex projection manually so we can distort _after_
|
||||||
|
float2 final = projectionCoord.xy / projectionCoord.w;
|
||||||
|
|
||||||
|
// Noise
|
||||||
|
float3 noiseNormal = (tex2D(noiseMap, (noiseCoord.xy / 5)).rgb - 0.5).rbg * noiseScale;
|
||||||
|
final += noiseNormal.xz;
|
||||||
|
|
||||||
|
// Fresnel
|
||||||
|
//normal = normalize(normal + noiseNormal.xz);
|
||||||
|
float fresnel = fresnelBias + fresnelScale * pow(1 + dot(eyeDir, normal), fresnelPower);
|
||||||
|
|
||||||
|
// Reflection / refraction
|
||||||
|
float4 reflectionColour = tex2D(reflectMap, final);
|
||||||
|
float4 refractionColour = tex2D(refractMap, final) + tintColour;
|
||||||
|
|
||||||
|
// Final colour
|
||||||
|
col = lerp(refractionColour, reflectionColour, fresnel) * tex2D(waterTex, noiseNormal) / 3 ;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Old version to match ATI PS 1.3 implementation
|
||||||
|
void main_vp_old(
|
||||||
|
float4 pos : POSITION,
|
||||||
|
float4 normal : NORMAL,
|
||||||
|
float2 tex : TEXCOORD0,
|
||||||
|
|
||||||
|
out float4 oPos : POSITION,
|
||||||
|
out float fresnel : COLOR,
|
||||||
|
out float3 noiseCoord : TEXCOORD0,
|
||||||
|
out float4 projectionCoord : TEXCOORD1,
|
||||||
|
|
||||||
|
uniform float4x4 worldViewProjMatrix,
|
||||||
|
uniform float3 eyePosition, // object space
|
||||||
|
uniform float fresnelBias,
|
||||||
|
uniform float fresnelScale,
|
||||||
|
uniform float fresnelPower,
|
||||||
|
uniform float timeVal,
|
||||||
|
uniform float scale, // the amount to scale the noise texture by
|
||||||
|
uniform float scroll, // the amount by which to scroll the noise
|
||||||
|
uniform float noise // the noise perturb as a factor of the time
|
||||||
|
)
|
||||||
|
{
|
||||||
|
oPos = mul(worldViewProjMatrix, pos);
|
||||||
|
// Projective texture coordinates, adjust for mapping
|
||||||
|
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);
|
||||||
|
projectionCoord = mul(scalemat, oPos);
|
||||||
|
// Noise map coords
|
||||||
|
noiseCoord.xy = (tex + (timeVal * scroll)) * scale;
|
||||||
|
noiseCoord.z = noise * timeVal;
|
||||||
|
|
||||||
|
// calc fresnel factor (reflection coefficient)
|
||||||
|
float3 eyeDir = normalize(pos.xyz - eyePosition);
|
||||||
|
fresnel = fresnelBias + fresnelScale * pow(1 + dot(eyeDir, normal), fresnelPower);
|
||||||
|
|
||||||
|
}
|
72
files/water/Example_FresnelPS.asm
Normal file
72
files/water/Example_FresnelPS.asm
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
ps.1.4
|
||||||
|
// conversion from Cg generated ARB_fragment_program to ps.1.4 by NFZ
|
||||||
|
// command line args: -profile arbfp1 -entry main_fp
|
||||||
|
// program main_fp
|
||||||
|
// c0 : distortionRange
|
||||||
|
// c1 : tintColour
|
||||||
|
// testure 0 : noiseMap
|
||||||
|
// texture 1 : reflectMap
|
||||||
|
// texture 2 : refractMap
|
||||||
|
// v0.x : fresnel
|
||||||
|
// t0.xyz : noiseCoord
|
||||||
|
// t1.xyw : projectionCoord
|
||||||
|
|
||||||
|
def c2, 2, 1, 0, 0
|
||||||
|
|
||||||
|
// Cg: distort.x = tex3D(noiseMap, noiseCoord).x;
|
||||||
|
// arbfp1: TEX R0.x, fragment.texcoord[0], texture[0], 3D;
|
||||||
|
// sample noise map using noiseCoord in TEX unit 0
|
||||||
|
|
||||||
|
texld r0, t0.xyz
|
||||||
|
|
||||||
|
// get projected texture coordinates from TEX coord 1
|
||||||
|
// will be used in phase 2
|
||||||
|
|
||||||
|
texcrd r1.xy, t1_dw.xyw
|
||||||
|
mov r1.z, c2.y
|
||||||
|
|
||||||
|
// Cg: distort.y = tex3D(noiseMap, noiseCoord + yoffset).x;
|
||||||
|
// arbfp1: ADD R1.xyz, fragment.texcoord[0], c1;
|
||||||
|
// arbfp1: TEX R1.x, R1, texture[0], 3D;
|
||||||
|
// arbfp1: MOV R0.y, R1.x;
|
||||||
|
|
||||||
|
// Cg: distort = (distort * 2 - 1) * distortionRange;
|
||||||
|
// arbfp1: MAD R0.xy, R0, c0.x, -c0.y;
|
||||||
|
// arbfp1: MUL R0.xy, R0, u0.x;
|
||||||
|
// (distort * 2 - 1) same as 2*(distort -.5) so use _bx2
|
||||||
|
|
||||||
|
|
||||||
|
// Cg: final = projectionCoord.xy / projectionCoord.w;
|
||||||
|
// Cg: final += distort;
|
||||||
|
// arbfp1: RCP R0.w, fragment.texcoord[1].w;
|
||||||
|
// arbfp1: MAD R0.xy, fragment.texcoord[1], R0.w, R0;
|
||||||
|
// final = (distort * projectionCoord.w) + projectionCoord.xy
|
||||||
|
// for ps.1.4 have to re-arrange things a bit to perturb projected texture coordinates
|
||||||
|
|
||||||
|
mad r0.xyz, r0_bx2, c0.x, r1
|
||||||
|
|
||||||
|
phase
|
||||||
|
|
||||||
|
// do dependant texture reads
|
||||||
|
// Cg: reflectionColour = tex2D(reflectMap, final);
|
||||||
|
// arbfp1: TEX R0, R0, texture[1], 2D;
|
||||||
|
// sampe reflectMap using dependant read : texunit 1
|
||||||
|
|
||||||
|
texld r1, r0.xyz
|
||||||
|
|
||||||
|
// Cg: refractionColour = tex2D(refractMap, final) + tintColour;
|
||||||
|
// arbfp1: TEX R1, R0, texture[2], 2D;
|
||||||
|
// sample refractMap : texunit 2
|
||||||
|
|
||||||
|
texld r2, r0.xyz
|
||||||
|
|
||||||
|
// adding tintColour that is in global c1
|
||||||
|
// arbfp1: ADD R1, R1, u1;
|
||||||
|
|
||||||
|
add r2, r2, c1
|
||||||
|
|
||||||
|
// Cg: col = lerp(refractionColour, reflectionColour, fresnel);
|
||||||
|
// arbfp1: ADD R0, R0, -R1;
|
||||||
|
// arbfp1: MAD result.color, fragment.color.primary.x, R0, R1;
|
||||||
|
|
||||||
|
lrp r0, v0.x, r1, r2
|
15
files/water/GlassFP.cg
Normal file
15
files/water/GlassFP.cg
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
sampler RT : register(s0);
|
||||||
|
sampler NormalMap : register(s1);
|
||||||
|
sampler CausticMap : register(s2);
|
||||||
|
|
||||||
|
float4 main_ps(float2 iTexCoord : TEXCOORD0,
|
||||||
|
float3 noiseCoord : TEXCOORD1,
|
||||||
|
uniform float4 tintColour) : COLOR
|
||||||
|
{
|
||||||
|
float4 normal = tex2D(NormalMap, noiseCoord);
|
||||||
|
|
||||||
|
|
||||||
|
return tex2D(RT, iTexCoord + normal.xy * 0.05) +
|
||||||
|
(tex2D(CausticMap, noiseCoord) / 5) +
|
||||||
|
tintColour ;
|
||||||
|
}
|
24
files/water/GlassVP.cg
Normal file
24
files/water/GlassVP.cg
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
void glass_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;
|
||||||
|
}
|
||||||
|
|
BIN
files/water/Water02.jpg
Normal file
BIN
files/water/Water02.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 182 KiB |
BIN
files/water/caustic_0.png
Normal file
BIN
files/water/caustic_0.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 34 KiB |
BIN
files/water/perlinvolume.dds
Normal file
BIN
files/water/perlinvolume.dds
Normal file
Binary file not shown.
21
files/water/water.compositor
Normal file
21
files/water/water.compositor
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
compositor Water
|
||||||
|
{
|
||||||
|
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/Compositor
|
||||||
|
input 0 rt0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
217
files/water/water.material
Normal file
217
files/water/water.material
Normal file
|
@ -0,0 +1,217 @@
|
||||||
|
// Derived from ogre samples
|
||||||
|
|
||||||
|
|
||||||
|
vertex_program Water/GlassVP cg
|
||||||
|
{
|
||||||
|
source GlassVP.cg
|
||||||
|
entry_point glass_vp
|
||||||
|
profiles vs_1_1 arbvp1
|
||||||
|
|
||||||
|
default_params
|
||||||
|
{
|
||||||
|
param_named_auto worldViewProj worldviewproj_matrix
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fragment_program Water/GlassFP cg
|
||||||
|
{
|
||||||
|
source GlassFP.cg
|
||||||
|
entry_point main_ps
|
||||||
|
profiles ps_2_0 arbfp1
|
||||||
|
}
|
||||||
|
|
||||||
|
material Water/Compositor
|
||||||
|
{
|
||||||
|
technique
|
||||||
|
{
|
||||||
|
pass
|
||||||
|
{
|
||||||
|
depth_check off
|
||||||
|
|
||||||
|
vertex_program_ref Water/GlassVP
|
||||||
|
{
|
||||||
|
param_named_auto timeVal time 0.25
|
||||||
|
param_named scale float 0.1
|
||||||
|
}
|
||||||
|
|
||||||
|
fragment_program_ref Water/GlassFP
|
||||||
|
{
|
||||||
|
param_named tintColour float4 0 0.35 0.35 1
|
||||||
|
}
|
||||||
|
|
||||||
|
texture_unit RT
|
||||||
|
{
|
||||||
|
tex_coord_set 0
|
||||||
|
tex_address_mode clamp
|
||||||
|
filtering linear linear linear
|
||||||
|
}
|
||||||
|
|
||||||
|
texture_unit
|
||||||
|
{
|
||||||
|
texture WaterNormal1.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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
vertex_program Water/RefractReflectVP cg
|
||||||
|
{
|
||||||
|
source Example_Fresnel.cg
|
||||||
|
entry_point main_vp
|
||||||
|
profiles vs_1_1 arbvp1
|
||||||
|
}
|
||||||
|
vertex_program Water/RefractReflectVPold cg
|
||||||
|
{
|
||||||
|
source Example_Fresnel.cg
|
||||||
|
entry_point main_vp_old
|
||||||
|
profiles vs_1_1 arbvp1
|
||||||
|
}
|
||||||
|
|
||||||
|
fragment_program Water/RefractReflectFP cg
|
||||||
|
{
|
||||||
|
source Example_Fresnel.cg
|
||||||
|
entry_point main_fp
|
||||||
|
// sorry, ps_1_1 and fp20 can't do this
|
||||||
|
profiles ps_2_0 arbfp1
|
||||||
|
}
|
||||||
|
|
||||||
|
fragment_program Water/RefractReflectPS asm
|
||||||
|
{
|
||||||
|
source Example_FresnelPS.asm
|
||||||
|
// sorry, only for ps_1_4 :)
|
||||||
|
syntax ps_1_4
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
material Water/ReflectionRefraction
|
||||||
|
{
|
||||||
|
// ps_2_0 / arbfp1
|
||||||
|
technique
|
||||||
|
{
|
||||||
|
pass
|
||||||
|
{
|
||||||
|
|
||||||
|
vertex_program_ref Water/RefractReflectVP
|
||||||
|
{
|
||||||
|
param_named_auto worldViewProjMatrix worldviewproj_matrix
|
||||||
|
param_named_auto eyePosition camera_position_object_space
|
||||||
|
param_named_auto timeVal time 0.15
|
||||||
|
param_named scroll float 1
|
||||||
|
param_named scale float 1
|
||||||
|
param_named noise float 1
|
||||||
|
// scroll and noisePos will need updating per frame
|
||||||
|
}
|
||||||
|
fragment_program_ref Water/RefractReflectFP
|
||||||
|
{
|
||||||
|
param_named fresnelBias float -0.1
|
||||||
|
param_named fresnelScale float 0.8
|
||||||
|
param_named fresnelPower float 20
|
||||||
|
param_named tintColour float4 0 0.15 0.15 1
|
||||||
|
param_named noiseScale float 0.05
|
||||||
|
}
|
||||||
|
// Water
|
||||||
|
texture_unit
|
||||||
|
{
|
||||||
|
// Water texture
|
||||||
|
texture Water02.jpg
|
||||||
|
// min / mag filtering, no mip
|
||||||
|
filtering linear linear none
|
||||||
|
}
|
||||||
|
// Noise
|
||||||
|
texture_unit
|
||||||
|
{
|
||||||
|
// Perlin noise volume
|
||||||
|
texture waves2.dds
|
||||||
|
// min / mag filtering, no mip
|
||||||
|
filtering linear linear none
|
||||||
|
}
|
||||||
|
// Reflection
|
||||||
|
texture_unit
|
||||||
|
{
|
||||||
|
// Will be filled in at runtime
|
||||||
|
texture reflection
|
||||||
|
tex_address_mode clamp
|
||||||
|
}
|
||||||
|
// Refraction
|
||||||
|
texture_unit
|
||||||
|
{
|
||||||
|
// Will be filled in at runtime
|
||||||
|
texture refraction
|
||||||
|
tex_address_mode clamp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// ATI 8500 +
|
||||||
|
technique
|
||||||
|
{
|
||||||
|
pass
|
||||||
|
{
|
||||||
|
vertex_program_ref Water/RefractReflectVPold
|
||||||
|
{
|
||||||
|
param_named_auto worldViewProjMatrix worldviewproj_matrix
|
||||||
|
param_named_auto eyePosition camera_position_object_space
|
||||||
|
param_named fresnelBias float -0.3
|
||||||
|
param_named fresnelScale float 1.4
|
||||||
|
param_named fresnelPower float 8
|
||||||
|
param_named_auto timeVal time_0_1 20
|
||||||
|
param_named scroll float 1
|
||||||
|
param_named scale float 4
|
||||||
|
param_named noise float 1
|
||||||
|
// scroll and noisePos will need updating per frame
|
||||||
|
}
|
||||||
|
|
||||||
|
// for ATI RADEON 8500 - 9200
|
||||||
|
fragment_program_ref Water/RefractReflectPS
|
||||||
|
{
|
||||||
|
// distortionRange
|
||||||
|
param_indexed 0 float 0.025
|
||||||
|
// tintColour
|
||||||
|
param_indexed 1 float4 0.05 0.12 0.15 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Noise
|
||||||
|
texture_unit
|
||||||
|
{
|
||||||
|
// Perlin noise volume
|
||||||
|
texture perlinvolume.dds 3d
|
||||||
|
// min / mag filtering, no mip
|
||||||
|
filtering linear linear none
|
||||||
|
}
|
||||||
|
// Reflection
|
||||||
|
texture_unit
|
||||||
|
{
|
||||||
|
// Will be filled in at runtime
|
||||||
|
texture Reflection
|
||||||
|
tex_address_mode clamp
|
||||||
|
}
|
||||||
|
// Refraction
|
||||||
|
texture_unit
|
||||||
|
{
|
||||||
|
// Will be filled in at runtime
|
||||||
|
texture Refraction
|
||||||
|
tex_address_mode clamp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
BIN
files/water/waves2.dds
Normal file
BIN
files/water/waves2.dds
Normal file
Binary file not shown.
Loading…
Reference in a new issue