Water is in ECS; water material is created in code

This commit is contained in:
2025-09-03 05:31:13 +03:00
parent 847aab6ed0
commit aca04ff621
8 changed files with 324 additions and 168 deletions

View File

@@ -445,6 +445,8 @@ public:
}
void locateResources() override
{
Ogre::ResourceGroupManager::getSingleton().createResourceGroup(
"Water", true);
OgreBites::ApplicationContext::locateResources();
}
void loadResources() override

View File

@@ -22,7 +22,6 @@ FileSystem=skybox
FileSystem=resources/buildings
FileSystem=resources/vehicles
FileSystem=resources/debug
FileSystem=water
# PBR media must come before the scripts that reference it
#FileSystem=./Media/PBR
#FileSystem=./Media/PBR/filament
@@ -77,3 +76,5 @@ FileSystem=./characters/female
[Audio]
FileSystem=./audio/gui
[Water]
FileSystem=water

View File

@@ -1,4 +1,8 @@
#include <Ogre.h>
#include <OgreColourValue.h>
#include <OgreShaderSubRenderState.h>
#include <OgreShaderGenerator.h>
#include <OgreRTShaderSystem.h>
#include "GameData.h"
#include "Components.h"
#include "WaterModule.h"
@@ -10,7 +14,7 @@ WaterModule::WaterModule(flecs::world &ecs)
ecs.module<WaterModule>();
ecs.component<WaterSurface>().add(flecs::Singleton);
ecs.component<WaterBody>().add(flecs::Singleton);
ecs.set<WaterSurface>({ nullptr, nullptr });
ecs.set<WaterSurface>({ nullptr, nullptr, nullptr });
ecs.set<WaterBody>({ nullptr });
ecs.system<const EngineData, const Camera, WaterSurface>("UpdateWater")
.kind(flecs::OnUpdate)
@@ -18,15 +22,171 @@ WaterModule::WaterModule(flecs::world &ecs)
WaterSurface &water) {
float delta = eng.delta;
if (!water.mWaterEnt || !water.mWaterNode) {
water.mAbove = false;
water.mInRefTexUpdate = false;
water.mRenderTargetListener.mSurface = &water;
const Ogre::String renderTargetName =
"ReflectionRefractionTexture";
water.mWaterPlane =
Ogre::Plane(Ogre::Vector3::UNIT_Y, 0);
water.mReflectionPlane = Ogre::Plane(
Ogre::Vector3(0.0, 1.0, 0.0),
0.0f /* water height */);
water.mReflectionClipPlaneAbove = Ogre::Plane(
Ogre::Vector3(0.0, 1.0, 0.0),
0.0f /* water height */ - 2.0f);
water.mReflectionClipPlaneBelow = Ogre::Plane(
Ogre::Vector3(0.0, -1.0, 0.0),
-(0.0f /* water height */ + 2.0));
water.mRefractionClipPlaneAbove = Ogre::Plane(
Ogre::Vector3(0.0, -1.0, 0.0),
-(0.0f /* water height */ + 2.0));
water.mRefractionClipPlaneBelow = Ogre::Plane(
Ogre::Vector3(0.0, 1.0, 0.0),
0.0f /* water height */ - 2.0);
#if 0
if (Ogre::TextureManager::getSingleton()
.resourceExists(renderTargetName))
Ogre::TextureManager::getSingleton()
.remove(renderTargetName);
#endif
Ogre::TexturePtr reflectionTexture =
Ogre::TextureManager::getSingleton().createManual(
renderTargetName,
Ogre::ResourceGroupManager::
DEFAULT_RESOURCE_GROUP_NAME,
Ogre::TEX_TYPE_2D, 512, 512, 0,
Ogre::PF_R8G8B8A8,
Ogre::TU_RENDERTARGET);
water.mReflectionTexture =
reflectionTexture->getBuffer()
->getRenderTarget();
water.mReflectionTexture->setAutoUpdated(false);
water.mWaterNode =
eng.mScnMgr->getRootSceneNode()
->createChildSceneNode("Water");
Ogre::MaterialPtr mat =
Ogre::MaterialManager::getSingleton()
.getByName("Water/Above",
"Water");
if (!mat) {
mat = Ogre::MaterialManager::getSingleton()
.create("Water/Above",
"Water");
Ogre::Technique *tech =
mat->getTechnique(0);
Ogre::Pass *pass = tech->getPass(0);
pass->setLightingEnabled(true);
pass->setAmbient(
Ogre::ColourValue(1, 1, 1, 1));
pass->setDiffuse(Ogre::ColourValue(
0.0f, 0.2f, 0.5f, 1.0f));
pass->setCullingMode(Ogre::CULL_NONE);
pass->setManualCullingMode(
Ogre::MANUAL_CULL_NONE);
pass->setVertexProgram(
"Water/water_vp");
pass->setFragmentProgram(
"Water/water_fp");
#if 0
Ogre::GpuProgramPtr water_vp =
Ogre::GpuProgramManager::getSingleton()
.getByName(
"Water/water_vp",
Ogre::RGN_AUTODETECT);
OgreAssert(water_vp != nullptr,
"VP failed");
pass->setGpuProgram(
Ogre::GPT_VERTEX_PROGRAM,
water_vp);
OgreAssert(water_vp->isSupported(),
"VP not supported");
Ogre::GpuProgramPtr water_fp =
Ogre::GpuProgramManager::getSingleton()
.getByName(
"Water/water_fp",
Ogre::RGN_AUTODETECT);
OgreAssert(water_vp != nullptr,
"FP failed");
pass->setGpuProgram(
Ogre::GPT_FRAGMENT_PROGRAM,
water_fp);
OgreAssert(water_fp->isSupported(),
"FP not supported");
Ogre::GpuProgramParametersSharedPtr paramsVP =
water_vp->getDefaultParameters();
paramsVP->setNamedAutoConstant(
"world",
Ogre::GpuProgramParameters::
ACT_WORLD_MATRIX);
paramsVP->setNamedAutoConstant(
"worldViewProj",
Ogre::GpuProgramParameters::
ACT_WORLDVIEWPROJ_MATRIX);
paramsVP->setNamedAutoConstant(
"textureProjMatrix",
Ogre::GpuProgramParameters::
ACT_TEXTURE_WORLDVIEWPROJ_MATRIX);
paramsVP->setNamedAutoConstant(
"eyePosition",
Ogre::GpuProgramParameters::
ACT_CAMERA_POSITION_OBJECT_SPACE);
paramsVP->setNamedAutoConstant(
"normalMatrix",
Ogre::GpuProgramParameters::
ACT_NORMAL_MATRIX);
paramsVP->setNamedAutoConstant(
"worldView",
Ogre::GpuProgramParameters::
ACT_WORLDVIEW_MATRIX);
paramsVP->setNamedAutoConstant(
"viewProj",
Ogre::GpuProgramParameters::
ACT_VIEWPROJ_MATRIX);
Ogre::GpuProgramParametersSharedPtr paramsFP =
water_fp->getDefaultParameters();
#endif
Ogre::TextureUnitState *texture_unit =
pass->createTextureUnitState();
texture_unit->setTextureName(
"ReflectionRefractionTexture");
Ogre::Sampler::UVWAddressingMode uvw;
uvw.u = Ogre::TextureUnitState::TAM_MIRROR;
uvw.v = Ogre::TextureUnitState::TAM_MIRROR;
uvw.w = Ogre::TextureUnitState::TAM_MIRROR;
texture_unit->setTextureAddressingMode(
uvw);
texture_unit->setTextureFiltering(
Ogre::FT_MIN, Ogre::FO_LINEAR);
texture_unit->setTextureFiltering(
Ogre::FT_MAG, Ogre::FO_LINEAR);
texture_unit->setTextureFiltering(
Ogre::FT_MIP, Ogre::FO_LINEAR);
#if 0
Ogre::RTShader::RenderState *renderState =
Ogre::RTShader::ShaderGenerator::
getSingletonPtr()
->createOrRetrieveRenderState(
Ogre::MSN_SHADERGEN)
.first;
Ogre::RTShader::SubRenderState *perPixelLightModel =
Ogre::RTShader::ShaderGenerator::getSingletonPtr()
->createSubRenderState(
Ogre::RTShader::
SRS_PER_PIXEL_LIGHTING);
renderState->addTemplateSubRenderState(
perPixelLightModel);
#endif
}
/*
auto mat = Ogre::MaterialManager::getSingleton()
#if 0
mat = Ogre::MaterialManager::getSingleton()
.getByName("Water/Above");
mat->load();
#endif
mat->setReceiveShadows(false);
/*
auto mat2 =
Ogre::MaterialManager::getSingleton()
.getByName("Water/Below");
@@ -39,11 +199,68 @@ WaterModule::WaterModule(flecs::world &ecs)
"Ocean", "sea.glb");
water.mWaterEnt->setVisibilityFlags(WATER_MASK);
water.mWaterEnt->setCastShadows(true);
// water.mWaterEnt->setMaterialName("Water/Above");
// water.mWaterEnt->setMaterial(mat);
// water.mWaterEnt->setMaterialName("Water/Above");
water.mWaterEnt->setMaterial(mat);
water.mWaterNode->attachObject(water.mWaterEnt);
// mDynWorld->attachCollisionObject(
// mWaterBody, water_ent, 1, 0x7FFFFFFF);
water.mReflectionTexture->addListener(
&water.mRenderTargetListener);
water.mReflectionCamera =
eng.mScnMgr->createCamera(
"ReflectionCamera");
camera.mCamera->getParentSceneNode()
->attachObject(water.mReflectionCamera);
water.mReflectionCamera->setAspectRatio(
camera.mCamera->getAspectRatio());
water.mReflectionCamera->setNearClipDistance(
camera.mCamera->getNearClipDistance());
water.mReflectionCamera->setFarClipDistance(
camera.mCamera->getFarClipDistance());
water.mReflectionCamera
->enableCustomNearClipPlane(
water.mReflectionClipPlaneAbove);
water.mReflectionCamera->enableReflection(
water.mReflectionPlane);
Ogre::Viewport *reflectionViewport =
water.mReflectionTexture->addViewport(
water.mReflectionCamera, 0, 0,
0, 0.5f, 1.0f);
reflectionViewport->setClearEveryFrame(true);
reflectionViewport->setBackgroundColour(
Ogre::ColourValue(0.0, 0.0, 1.0, 1.0));
reflectionViewport->setOverlaysEnabled(false);
reflectionViewport->setSkiesEnabled(true);
reflectionViewport->setAutoUpdated(false);
water.mViewports[0] = reflectionViewport;
water.mRefractionCamera =
eng.mScnMgr->createCamera(
"RefractionCamera");
camera.mCamera->getParentSceneNode()
->attachObject(water.mRefractionCamera);
water.mRefractionCamera->setAspectRatio(
camera.mCamera->getAspectRatio());
water.mRefractionCamera->setNearClipDistance(
camera.mCamera->getNearClipDistance());
water.mRefractionCamera->setFarClipDistance(
camera.mCamera->getFarClipDistance());
water.mRefractionCamera
->enableCustomNearClipPlane(
water.mRefractionClipPlaneAbove);
Ogre::Viewport *refractionViewport =
water.mReflectionTexture->addViewport(
water.mRefractionCamera, 1, 0.5,
0, 0.5f, 1.0f);
refractionViewport->setClearEveryFrame(true);
refractionViewport->setBackgroundColour(
Ogre::ColourValue(0.0, 0.5, 1.0, 1.0));
refractionViewport->setOverlaysEnabled(false);
refractionViewport->setSkiesEnabled(false);
refractionViewport->setAutoUpdated(false);
water.mViewports[1] = refractionViewport;
}
Ogre::Vector3 mCameraPos =
camera.mCameraNode->_getDerivedPosition();
@@ -58,6 +275,10 @@ WaterModule::WaterModule(flecs::world &ecs)
water.mWaterNode->translate(d * 3.0f * delta);
else
water.mWaterNode->translate(d);
water.mWaterEnt->setVisible(false);
water.mViewports[0]->update();
water.mViewports[1]->update();
water.mWaterEnt->setVisible(true);
});
ecs.system<const EngineData, const WaterSurface, WaterBody>(
"UpdateWaterBody")
@@ -84,4 +305,24 @@ WaterModule::WaterModule(flecs::world &ecs)
}
});
}
void WaterSurface::RenderTextureListener::preRenderTargetUpdate(
const Ogre::RenderTargetEvent &evt)
{
int i;
if (evt.source == mSurface->mReflectionTexture) {
mSurface->mWaterEnt->setVisible(false);
if (evt.source == mSurface->mReflectionTexture)
mSurface->mInRefTexUpdate = true;
} else {
mSurface->mWaterEnt->setVisible(true);
mSurface->mInRefTexUpdate = false;
}
}
void WaterSurface::RenderTextureListener::postRenderTargetUpdate(
const Ogre::RenderTargetEvent &evt)
{
int i;
mSurface->mWaterEnt->setVisible(true);
mSurface->mInRefTexUpdate = false;
}
}

View File

@@ -1,11 +1,28 @@
#ifndef WATER_MODULE_H
#define WATER_MODULE_H
#include <vector>
#include <flecs.h>
namespace ECS
{
struct WaterSurface {
Ogre::SceneNode *mWaterNode;
Ogre::Entity *mWaterEnt;
Ogre::RenderTexture *mReflectionTexture;
Ogre::Camera *mReflectionCamera, *mRefractionCamera;
bool mInRefTexUpdate;
bool mAbove;
struct RenderTextureListener : public Ogre::RenderTargetListener {
WaterSurface *mSurface;
void preRenderTargetUpdate(
const Ogre::RenderTargetEvent &evt) override;
void postRenderTargetUpdate(
const Ogre::RenderTargetEvent &evt) override;
};
RenderTextureListener mRenderTargetListener;
Ogre::Plane mWaterPlane, mReflectionPlane, mReflectionClipPlaneAbove,
mReflectionClipPlaneBelow, mRefractionClipPlaneAbove,
mRefractionClipPlaneBelow;
Ogre::Viewport *mViewports[2];
};
struct WaterBody {
btGhostObject *mWaterBody;

14
water/depth.frag Normal file
View File

@@ -0,0 +1,14 @@
OGRE_NATIVE_GLSL_VERSION_DIRECTIVE
#include <OgreUnifiedShader.h>
OGRE_UNIFORMS(
uniform vec3 cameraPosition;
)
MAIN_PARAMETERS
IN(vec4 position, POSITION)
IN(vec3 positionWS, TEXCOORD0)
MAIN_DECLARATION
{
vec4 depth = vec4(length(positionWS - cameraPosition), 0.0, 0.0, 1.0);
gl_FragColor = depth;
}

20
water/depth.vert Normal file
View File

@@ -0,0 +1,20 @@
OGRE_NATIVE_GLSL_VERSION_DIRECTIVE
#include <OgreUnifiedShader.h>
OGRE_UNIFORMS(
uniform mat4 world;
uniform mat4 worldViewProj;
)
MAIN_PARAMETERS
IN(vec4 vertex, POSITION);
OUT(vec4 vposition, POSITION);
OUT(vec3 positionWS, TEXCOORD0);
MAIN_DECLARATION
{
vposition = mul(worldViewProj, vertex);
positionWS = mul(world, vertex).xyz;
gl_Position = vposition;
}

View File

@@ -1,25 +1,4 @@
/*
//----------------------------
// Distortion effects
//----------------------------
vertex_program Examples/FresnelRefractReflectVP glsl glsles glslang hlsl
{
source Example_FresnelVp.glsl
}
fragment_program Examples/FresnelRefractReflectFP glsl glsles glslang hlsl
{
source Example_FresnelFp.glsl
default_params
{
// assign samplers as required by GLSL
param_named noiseMap int 0
param_named reflectMap int 1
param_named refractMap int 2
}
}
*/
material Water/Above
{
technique
@@ -31,82 +10,18 @@ material Water/Above
diffuse 0.0 0.2 0.5 1.0
cull_hardware none
cull_software none
/*
vertex_program_ref Examples/FresnelRefractReflectVP
{
param_named_auto worldViewProjMatrix worldviewproj_matrix
param_named_auto textureProjMatrix texture_worldviewproj_matrix 0
param_named_auto eyePosition camera_position_object_space
param_named_auto timeVal time 0.05
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 Examples/FresnelRefractReflectFP
{
param_named fresnelBias float -0.1
param_named fresnelScale float 1.8
param_named fresnelPower float 8
param_named tintColour float4 0 0.05 0.05 1
param_named noiseScale float 0.05
}
*/
vertex_program_ref Water/water_vp
{
}
fragment_program_ref Water/water_fp
{
}
/*
// Noise
texture_unit
{
// Perlin noise volume
texture waves2.png
// min / mag filtering, no mip
filtering linear linear none
tex_address_mode mirror
}
// Reflection
texture_unit
{
content_type compositor Fresnel reflection
tex_address_mode mirror
}
// Refraction
texture_unit
{
content_type compositor Fresnel refraction
tex_address_mode mirror
}
// Normal
texture_unit
{
texture waves2.png
sampler_ref RTSS/NormalMapSampler
// RT Shader system section.
rtshader_system
{
normal_map tangent_space
}
tex_address_mode mirror
}
*/
texture_unit
{
texture ReflectionRefractionTexture
tex_address_mode mirror
filtering linear linear linear
}
/*
texture_unit
{
texture RefractionTexture
tex_address_mode mirror
filtering linear linear linear
}
*/
}
}
rtshader_system
@@ -134,43 +49,12 @@ material Water/Below
fragment_program_ref Water/water_fp
{
}
/*
// Noise
texture_unit
{
// Perlin noise volume
texture waves2.png
// min / mag filtering, no mip
filtering linear linear none
tex_address_mode mirror
}
// Reflection
texture_unit
{
content_type compositor Fresnel reflection
tex_address_mode mirror
}
// Refraction
texture_unit
{
content_type compositor Fresnel refraction
tex_address_mode mirror
}
*/
texture_unit
{
texture ReflectionRefractionTexture
tex_address_mode mirror
filtering linear linear linear
}
/*
texture_unit
{
texture RefractionTexture
tex_address_mode mirror
filtering linear linear linear
}
*/
}
}
rtshader_system
@@ -179,28 +63,5 @@ material Water/Below
lighting_stage per_pixel
}
}
/*
material Water/Depth
{
technique
{
pass
{
cull_hardware none
alpha_rejection greater_equal 0.5
vertex_program_ref Water/depth_vp
{
param_named_auto world world_matrix
param_named_auto worldViewProj worldviewproj_matrix
}
fragment_program_ref Water/depth_fp
{
param_named_auto cameraPosition camera_position
}
}
}
}
*/

View File

@@ -24,32 +24,32 @@ fragment_program Water/water_fp glsl glsles glslang hlsl
{
param_named_auto renderTargetFlipping render_target_flipping
param_named_auto cameraPosition camera_position
param_named_auto ambient surface_ambient_colour
param_named_auto diffuse surface_diffuse_colour
// param_named_auto ambient surface_ambient_colour
// param_named_auto diffuse surface_diffuse_colour
param_named_auto viewportSize viewport_size
param_named_auto time time
// param_named NormalMap int 0
// param_named EnvironmentMap int 1
param_named deepColor float4 0 0.2 0.5 1.0
param_named shallowColor float4 0 0.8 1 1.0
param_named reflectionColor float4 0.95 1 1 1.0
param_named reflectionAmount float 0.5
param_named reflectionBlur float 0.0
param_named waterAmount float 0.5
// param_named fresnelPower float 5.0
// param_named fresnelPower float 8.0
param_named fresnelPower float 2.0
//// param_named_auto time time
//// param_named NormalMap int 0
//// param_named EnvironmentMap int 1
// param_named deepColor float4 0 0.2 0.5 1.0
// param_named shallowColor float4 0 0.8 1 1.0
// param_named reflectionColor float4 0.95 1 1 1.0
// param_named reflectionAmount float 0.5
// param_named reflectionBlur float 0.0
// param_named waterAmount float 0.5
//// param_named fresnelPower float 5.0
//// param_named fresnelPower float 8.0
// param_named fresnelPower float 2.0
//// param_named fresnelBias float 0.328
// param_named fresnelBias float 0.328
param_named fresnelBias float 0.328
// param_named fresnelScale float 1.8
// param_named fresnelScale float 1.8
param_named fresnelScale float 1.0
param_named hdrMultiplier float 0.471
param_named tintColour float4 0 0.05 0.05 1
param_named noiseScale float 0.03
// param_named noiseMap int 0
//// param_named fresnelScale float 1.8
//// param_named fresnelScale float 1.8
// param_named fresnelScale float 1.0
// param_named hdrMultiplier float 0.471
// param_named tintColour float4 0 0.05 0.05 1
// param_named noiseScale float 0.03
//// param_named noiseMap int 0
param_named reflectMap int 0
// param_named refractMap int 1
//// param_named refractMap int 1
}
}