1 registered members (AbrahamR),
717
guests, and 4
spiders. |
Key:
Admin,
Global Mod,
Mod
|
|
|
Re: Water reflections - possible memory leak?
[Re: Stansmedia]
#445310
09/03/14 08:57
09/03/14 08:57
|
Joined: Mar 2011
Posts: 3,150 Budapest
sivan
Expert
|
Expert
Joined: Mar 2011
Posts: 3,150
Budapest
|
I had no problems with it but since the last release I rewrote it, here is the updated unpublished version (for safety you can ptr_remove the water entity before another level load, but in theory it should work without it, I never remove it): include MBmwater.h and MBmwater.c in your project, put it in water entity action (tested and probably works only with one water entity!): MBmwater.h
#ifndef MBmwater_h
#define MBmwater_h
//////////////////////////////////////////////////////////////////////
// defines
//#define MIRROR_DEBUG
//////////////////////////////////////////////////////////////////////
// variables
var mwater_speedx = 10;
var mwater_speedy = 25;
var mwater_ripple = 50;
var mwater_scale = 100;
var mwater_mirrorvisible = 0;
//////////////////////////////////////////////////////////////////////
// views
#ifdef MIRROR_DEBUG
VIEW* mw_view_mirror = { layer = 1; }
#else
VIEW* mw_view_mirror = { layer = -1; } // render mirror view before camera view
#endif
//////////////////////////////////////////////////////////////////////
// bmaps
BMAP* mw_bmap_mirrortarget = NULL;
BMAP* mw_bmap_water_uv = NULL;
//////////////////////////////////////////////////////////////////////
// materials
MATERIAL* mtl_mirrorWaterMB =
{
ambient_blue = 50; ambient_green = 50; ambient_red = 50;
diffuse_blue = 200; diffuse_green = 200; diffuse_red = 200;
specular_blue = 0; specular_green = 0; specular_red = 0;
emissive_blue = 0; emissive_green = 0; emissive_red = 0;
power = 5;
albedo = 100;
effect = "mirrorWaterMB.fx";
}
//////////////////////////////////////////////////////////////////////
// functions
void Mwater_Init(ENTITY* ent);
//////////////////////////////////////////////////////////////////////
#endif
MBmwater.c
#ifndef MBmwater_c
#define MBmwater_c
//////////////////////////////////////////////////////////////////////
// code
void Mwater_Init(ENTITY* ent)
{
//------------------------------------------------------------------
my = ent;
//------------------------------------------------------------------
my.material = mtl_mirrorWaterMB;
//------------------------------------------------------------------
if (mw_bmap_water_uv)
{
ptr_remove(mw_bmap_water_uv); // *** correct mirror shift on multiple level loads
mw_bmap_water_uv = NULL;
}
// mw_bmap_water_uv = bmap_to_uv(bmap_create("water.dds")); // orig - results in mirror offset
// mw_bmap_water_uv = bmap_to_normals(bmap_create("water.dds"), 50); // *** - no mirror offset error !
mw_bmap_water_uv = bmap_to_normals(bmap_for_entity(my,1), 50); // *** use 1st skin, okay
my.material.skin1 = mw_bmap_water_uv;
my.material.flags |= TRANSLUCENT;
//------------------------------------------------------------------
if (mw_bmap_mirrortarget)
{
// my.material.skin2 = mw_bmap_mirrortarget;
// return;
ptr_remove(mw_bmap_mirrortarget); // *** correct mirror shift on multiple level loads
mw_bmap_mirrortarget = NULL;
}
//------------------------------------------------------------------
mw_bmap_mirrortarget = bmap_createblack(256,256,888);
my.material.skin2 = mw_bmap_mirrortarget;
mw_view_mirror.bmap = mw_bmap_mirrortarget;
mw_view_mirror.size_x = bmap_width(mw_view_mirror.bmap);
mw_view_mirror.size_y = bmap_height(mw_view_mirror.bmap);
vec_set(mw_view_mirror.pnormal_x,vector(0,0,1.0)); // reflect upwards
set(mw_view_mirror,NOCULL|PORTALCLIP); // *** NOSHADOW| - to get proper decal shadows - engine bug to be fixed
#ifdef ENGINE_BUG_DECAL_A840
if ((shadow_stencil < (var)0 ) || (shadow_stencil > (var)2)) // *** because of an engine bug below A8.45.1
#endif
{
set(mw_view_mirror, NOSHADOW); // *** needed by pssm, not needed by decal/stencil shadows
}
set(mw_view_mirror,NOFLAG1); // suppress all entities with flag1 set
set(mw_view_mirror,NOPARTICLE); // requird by PORTALCLIP
set(mw_view_mirror,NOSHADER); // requird by PORTALCLIP
//------------------------------------------------------------------
while ((mw_bmap_mirrortarget) && (me)) // ¤¤¤
{
proc_mode = PROC_LATE; // camera must be moved before
if (!is(my,CLIPPED))
{
// place the mirror plane at the topmost entity polygon
vec_for_max(mw_view_mirror.portal_x,my); // without taking into account scale
// vec_mul(view_mirror.portal_x, my.scale_x); // *** multiply with scale
vec_add(mw_view_mirror.portal_x,my.x); // offset by position
// view_mirror.portal_z = my.z; // ***to avoid errors because of vertex movements
mwater_mirrorvisible = 1;
}
if (mwater_mirrorvisible)
{
set(mw_view_mirror,SHOW);
mw_view_mirror.genius = camera.genius;
mw_view_mirror.aspect = (screen_size.x / screen_size.y) * camera.aspect; // screen aspect, independent of render target
mw_view_mirror.arc = camera.arc;
mw_view_mirror.fog_start = camera.fog_start;
mw_view_mirror.fog_end = camera.fog_end;
mw_view_mirror.clip_far = camera.clip_far * 0.5;
mw_view_mirror.clip_near = camera.clip_near * 2;
mw_view_mirror.x = camera.x;
mw_view_mirror.y = camera.y;
mw_view_mirror.z = 2 * mw_view_mirror.portal_z - camera.z; // move the camera at its mirror position
mw_view_mirror.pan = camera.pan;
mw_view_mirror.tilt = -camera.tilt; // flip the vertical camera angle
mw_view_mirror.roll = -camera.roll;
}
else
{
// switch rendering off when all mirror objects are outside the frustum
reset(mw_view_mirror, SHOW);
}
// reset
mwater_mirrorvisible = 0;
#ifdef MIRROR_DEBUG
if (key_f11)
{
// debugging - make mirror visible onscreen
mw_view_mirror.bmap = NULL;
}
else
{
mw_view_mirror.bmap = mw_bmap_mirrortarget;
}
#endif
wait(1);
}
//------------------------------------------------------------------
// ¤¤¤
ptr_remove(mw_bmap_mirrortarget); // *** correct mirror shift on multiple level loads
mw_bmap_mirrortarget = NULL;
//------------------------------------------------------------------
}
#endif
the shader mirrorWaterMB.fx:
bool AUTORELOAD;
/////////////////////////////////////////////////////////////////////////////
#define FRESNEL_TRANSPARENCY
/////////////////////////////////////////////////////////////////////////////
#include <transform>
#include <fog>
#include <pos>
#include <normal>
//#include <vecskill> // use global variables instead of skills
/////////////////////////////////////////////////////////////////////////////
float4 vecTime;
float4 vecSunColor;
float4 vecColor;
float fAlbedo;
float fAlpha;
/////////////////////////////////////////////////////////////////////////////
texture entSkin1;
texture mtlSkin1;
texture mtlSkin2;
// my.skill41 = floatv(10); // 10 speed x
// my.skill42 = floatv(25); // 25 speed y
// my.skill43 = floatv(25); // 25 ripple - waves
// my.skill44 = floatv(75); // 100 scale
float mwater_speedx_var = 10.0;
float mwater_speedy_var = 25.0;
float mwater_ripple_var = 50.0;
float mwater_scale_var = 100.0;
/////////////////////////////////////////////////////////////////////////////
sampler sBumpTex = sampler_state
{
Texture = <mtlSkin1>;
MipFilter = Linear;
MinFilter = Linear;
MagFilter = Linear;
AddressU = Wrap;
Addressv = Wrap;
};
sampler sMirrorTex = sampler_state
{
Texture = <mtlSkin2>;
MipFilter = Linear;
MinFilter = Linear;
MagFilter = Linear;
AddressU = Clamp;
Addressv = Clamp;
};
/////////////////////////////////////////////////////////////////////////////
struct out_mirror // Output to the pixelshader fragment
{
float4 Pos : POSITION;
float Fog : FOG;
float4 Color: COLOR0;
float2 Tex0 : TEXCOORD0;
float3 Tex1 : TEXCOORD1;
float3 Albedo: TEXCOORD2;
};
/////////////////////////////////////////////////////////////////////////////
out_mirror vs_water_mirror
(
in float4 inPos : POSITION,
in float3 inNormal : NORMAL,
in float4 inTex0 : TEXCOORD0
)
{
out_mirror Out;
Out.Pos = DoTransform(inPos); // transform to screen coordinates
Out.Fog = DoFog(inPos);
// bump and reflection coordinates
float2 Speed;
Speed.x = (mwater_speedx_var * 0.000002);
Speed.y = (mwater_speedy_var * 0.000002);
Out.Tex0 = (inTex0 + Speed*vecTime.w) * (mwater_scale_var*0.05);
Out.Tex1 = Out.Pos.xyw;
// color and transparency
Out.Albedo.x = 0;
Out.Albedo.y = 0;
Out.Albedo.z = (mwater_ripple_var * 0.001); // ripple
Out.Color = float4(vecColor.xyz + vecSunColor.xyz, fAlpha);
{}
#ifdef FRESNEL_TRANSPARENCY
float4 P = DoPos(inPos); // vector world position
float3 vecToView = normalize(vecViewPos-P); // direction towards camera
float3 N = DoNormal(inNormal); // normal world orientation
Out.Color.a = 0.67 + fAlpha * (1.0 - dot(vecToView,N));
#endif
return Out;
}
/////////////////////////////////////////////////////////////////////////////
float4 ps_water_mirror(out_mirror In): COLOR
{
float4 Bump = tex2D(sBumpTex,In.Tex0)*2-1;
float2 Coord = 0.5 * (1.0 + In.Tex1.xy/In.Tex1.z) + Bump.xy * In.Albedo.z;
float4 ColorMod = In.Color;
ColorMod.a = 1;
return tex2D(sMirrorTex,Coord) * In.Color * ColorMod; // ***
}
//////////////////////////////////////////////////////////////////
technique water_mirror
{
pass one
{
AlphaBlendEnable = True;
VertexShader = compile vs_2_0 vs_water_mirror();
PixelShader = compile ps_2_0 ps_water_mirror();
}
}
technique fallback { pass one { } }
to be honest I don't really use it. it has better performance than my other water shaders based on shade-c, but they are also rewritten since last release, providing several options for quality/performance considerations (no foam, no refraction, no dynamic depth).
|
|
|
Re: Water reflections - possible memory leak?
[Re: Iglarion]
#445326
09/03/14 19:25
09/03/14 19:25
|
Joined: Mar 2003
Posts: 1,524 Canada
Stansmedia
OP
Serious User
|
OP
Serious User
Joined: Mar 2003
Posts: 1,524
Canada
|
... it doesn't seem to be doing it now. I... uh... need to go have a smoke before I explode.
This is getting brutal. I'm very close to having this game done, and ironing out bugs is literally the most tedious process.
Last edited by Stansmedia; 09/03/14 19:27.
|
|
|
|