mirror of https://github.com/AxioDL/metaforce.git
Implement non-rippling CFluidPlaneCPU render path
This commit is contained in:
parent
ea2fdc939b
commit
fd7589afd5
|
@ -12,9 +12,9 @@ struct ITweakGame : ITweak
|
|||
virtual bool GetSplashScreensDisabled() const = 0;
|
||||
virtual float GetFirstPersonFOV() const = 0;
|
||||
virtual float GetPressStartDelay() const = 0;
|
||||
virtual float GetRippleSideLengthNormal() const = 0;
|
||||
virtual float GetRippleSideLengthPoison() const = 0;
|
||||
virtual float GetRippleSideLengthLava() const = 0;
|
||||
virtual float GetWavecapIntensityNormal() const = 0;
|
||||
virtual float GetWavecapIntensityPoison() const = 0;
|
||||
virtual float GetWavecapIntensityLava() const = 0;
|
||||
virtual float GetFluidEnvBumpScale() const = 0;
|
||||
virtual float GetHardModeDamageMultiplier() const = 0;
|
||||
virtual float GetHardModeWeaponMultiplier() const = 0;
|
||||
|
|
|
@ -20,9 +20,9 @@ struct CTweakGame : ITweakGame
|
|||
Value<bool> x2b_splashScreensDisabled;
|
||||
Value<float> x2c_unknown5;
|
||||
Value<float> x30_pressStartDelay;
|
||||
Value<float> x34_rippleSideLenNormal;
|
||||
Value<float> x38_rippleSideLenPoison;
|
||||
Value<float> x3c_rippleSideLenLava;
|
||||
Value<float> x34_wavecapIntensityNormal;
|
||||
Value<float> x38_wavecapIntensityPoison;
|
||||
Value<float> x3c_wavecapIntensityLava;
|
||||
Value<float> x40_unknown10;
|
||||
Value<float> x44_unknown11;
|
||||
Value<float> x48_unknown12;
|
||||
|
@ -38,9 +38,9 @@ struct CTweakGame : ITweakGame
|
|||
bool GetSplashScreensDisabled() const { return x2b_splashScreensDisabled; }
|
||||
float GetFirstPersonFOV() const { return x24_fov; }
|
||||
float GetPressStartDelay() const { return x30_pressStartDelay; }
|
||||
float GetRippleSideLengthNormal() const { return x34_rippleSideLenNormal; }
|
||||
float GetRippleSideLengthPoison() const { return x38_rippleSideLenPoison; }
|
||||
float GetRippleSideLengthLava() const { return x3c_rippleSideLenLava; }
|
||||
float GetWavecapIntensityNormal() const { return x34_wavecapIntensityNormal; }
|
||||
float GetWavecapIntensityPoison() const { return x38_wavecapIntensityPoison; }
|
||||
float GetWavecapIntensityLava() const { return x3c_wavecapIntensityLava; }
|
||||
float GetFluidEnvBumpScale() const { return x4c_fluidEnvBumpScale; }
|
||||
float GetHardModeDamageMultiplier() const { return x60_hardmodeDamageMult; }
|
||||
float GetHardModeWeaponMultiplier() const { return x64_hardmodeWeaponMult; }
|
||||
|
|
|
@ -178,7 +178,8 @@ CFluidPlaneShader::CFluidPlaneShader(CFluidPlane::EFluidType type,
|
|||
}
|
||||
|
||||
void CFluidPlaneShader::draw(const zeus::CMatrix4f texMtxs[6], const zeus::CMatrix4f& normMtx, float indScale,
|
||||
const std::vector<CLight>& lights, const zeus::CColor kColors[4])
|
||||
const std::vector<CLight>& lights, const zeus::CColor kColors[4],
|
||||
const std::vector<Vertex>& verts)
|
||||
{
|
||||
Uniform& uni = *reinterpret_cast<Uniform*>(m_uniBuf->map(sizeof(Uniform)));
|
||||
uni.m_mv = CGraphics::g_GXModelView.toMatrix4f();
|
||||
|
@ -192,8 +193,11 @@ void CFluidPlaneShader::draw(const zeus::CMatrix4f texMtxs[6], const zeus::CMatr
|
|||
uni.m_lighting.mulColor = kColors[3];
|
||||
uni.m_lighting.fog.m_rangeScale = indScale;
|
||||
m_uniBuf->unmap();
|
||||
|
||||
m_vbo->load(verts.data(), verts.size() * sizeof(Vertex));
|
||||
|
||||
CGraphics::SetShaderDataBinding(m_dataBind);
|
||||
CGraphics::DrawArray(0, 0);
|
||||
CGraphics::DrawArray(0, verts.size());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -37,6 +37,29 @@ struct SFluidPlaneShaderInfo
|
|||
|
||||
class CFluidPlaneShader
|
||||
{
|
||||
public:
|
||||
struct Vertex
|
||||
{
|
||||
zeus::CVector3f m_pos;
|
||||
zeus::CVector3f m_norm;
|
||||
zeus::CVector3f m_binorm;
|
||||
zeus::CVector3f m_tangent;
|
||||
zeus::CColor m_color;
|
||||
|
||||
Vertex() = default;
|
||||
Vertex(const zeus::CVector3f& position) : m_pos(position) {}
|
||||
Vertex(const zeus::CVector3f& position, const zeus::CColor& color)
|
||||
: m_pos(position), m_color(color) {}
|
||||
Vertex(const zeus::CVector3f& position, const zeus::CVector3f& normal,
|
||||
const zeus::CColor& color)
|
||||
: m_pos(position), m_norm(normal), m_color(color) {}
|
||||
Vertex(const zeus::CVector3f& position, const zeus::CVector3f& normal,
|
||||
const zeus::CVector3f& binormal, const zeus::CVector3f& tangent,
|
||||
const zeus::CColor& color)
|
||||
: m_pos(position), m_norm(normal), m_binorm(binormal), m_tangent(tangent), m_color(color) {}
|
||||
};
|
||||
|
||||
private:
|
||||
class Cache
|
||||
{
|
||||
std::pair<boo::GraphicsDataToken, boo::IShaderPipeline*> m_cache[1024] = {};
|
||||
|
@ -46,15 +69,6 @@ class CFluidPlaneShader
|
|||
};
|
||||
static Cache _cache;
|
||||
|
||||
struct Vertex
|
||||
{
|
||||
zeus::CVector3f m_pos;
|
||||
zeus::CVector3f m_norm;
|
||||
zeus::CVector3f m_binorm;
|
||||
zeus::CVector3f m_tangent;
|
||||
zeus::CColor m_color;
|
||||
};
|
||||
|
||||
struct Uniform
|
||||
{
|
||||
zeus::CMatrix4f m_mv;
|
||||
|
@ -102,7 +116,8 @@ public:
|
|||
const std::experimental::optional<TLockedToken<CTexture>>& lightmap,
|
||||
bool doubleLightmapBlend, bool additive);
|
||||
void draw(const zeus::CMatrix4f texMtxs[6], const zeus::CMatrix4f& normMtx, float indScale,
|
||||
const std::vector<CLight>& lights, const zeus::CColor kColors[4]);
|
||||
const std::vector<CLight>& lights, const zeus::CColor kColors[4],
|
||||
const std::vector<Vertex>& verts);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ public:
|
|||
CScriptWater& water, CStateManager& mgr);
|
||||
virtual void Update();
|
||||
virtual void Render(const CStateManager& mgr, float alpha, const zeus::CAABox& aabb, const zeus::CTransform& xf,
|
||||
const zeus::CTransform& areaXf, bool noSubdiv, const zeus::CFrustum& frustum,
|
||||
const zeus::CTransform& areaXf, bool noNormals, const zeus::CFrustum& frustum,
|
||||
const std::experimental::optional<CRippleManager>& rippleManager, TUniqueId waterId,
|
||||
const bool* gridFlags, u32 gridDimX, u32 gridDimY, const zeus::CVector3f& areaCenter) const {}
|
||||
float GetAlpha() const { return x40_alpha; }
|
||||
|
|
|
@ -281,12 +281,12 @@ CFluidPlaneCPU::RenderSetup(const CStateManager& mgr, float alpha, const zeus::C
|
|||
class CFluidPlaneCPURender
|
||||
{
|
||||
public:
|
||||
enum class RenderMode
|
||||
enum class NormalMode
|
||||
{
|
||||
None,
|
||||
Normal,
|
||||
Subdivided,
|
||||
BumpMapped
|
||||
NoNormals,
|
||||
Normals,
|
||||
NBT
|
||||
};
|
||||
|
||||
static int numTilesInHField;
|
||||
|
@ -297,52 +297,52 @@ public:
|
|||
{
|
||||
u8 x0_xSubdivs, x1_ySubdivs;
|
||||
zeus::CVector2f x4_localMin, xc_globalMin;
|
||||
float x14_rippleSideLen;
|
||||
float x14_tileSize;
|
||||
float x18_rippleResolution;
|
||||
float x1c_rippleHypRadius;
|
||||
float x20_ooRippleSideLen;
|
||||
float x1c_tileHypRadius;
|
||||
float x20_ooTileSize;
|
||||
float x24_ooRippleResolution;
|
||||
u16 x28_tileX;
|
||||
u16 x2a_gridDimX;
|
||||
u16 x2c_gridDimY;
|
||||
u16 x2e_tileY;
|
||||
const bool* x30_gridFlags;
|
||||
bool x34_r14;
|
||||
u8 x35_r22;
|
||||
u8 x36_r23;
|
||||
RenderMode x37_renderMode;
|
||||
float x38_tileSize;
|
||||
u8 x34_redShift;
|
||||
u8 x35_greenShift;
|
||||
u8 x36_blueShift;
|
||||
NormalMode x37_normalMode;
|
||||
float x38_wavecapIntensityScale;
|
||||
public:
|
||||
SPatchInfo(const zeus::CVector3f& localMin, const zeus::CVector3f& localMax, const zeus::CVector3f& pos,
|
||||
float rippleResolution, float rippleSideLen, float tileSize, int numSubdivisionsInHField,
|
||||
RenderMode renderMode, bool r14, int r22, int r23, u32 tileX, u32 gridDimX, u32 gridDimY,
|
||||
u32 tileY, const bool* gridFlags)
|
||||
float rippleResolution, float tileSize, float wavecapIntensityScale, int numSubdivisionsInHField,
|
||||
NormalMode normalMode, int redShift, int greenShift, int blueShift, u32 tileX, u32 gridDimX,
|
||||
u32 gridDimY, u32 tileY, const bool* gridFlags)
|
||||
{
|
||||
x0_xSubdivs = std::min(s16((localMax.x - localMin.x) / rippleResolution + 1.f - FLT_EPSILON) + 2,
|
||||
numSubdivisionsInHField + 2);
|
||||
x1_ySubdivs = std::min(s16((localMax.y - localMin.y) / rippleResolution + 1.f - FLT_EPSILON) + 2,
|
||||
numSubdivisionsInHField + 2);
|
||||
float rippleHypRadius = rippleSideLen * rippleSideLen * 2 * 0.25f;
|
||||
float tileHypRadius = tileSize * tileSize * 2 * 0.25f;
|
||||
x4_localMin.x = localMin.x;
|
||||
x4_localMin.y = localMin.y;
|
||||
xc_globalMin = x4_localMin + zeus::CVector2f(pos.x, pos.y);
|
||||
x14_rippleSideLen = rippleSideLen;
|
||||
x14_tileSize = tileSize;
|
||||
x18_rippleResolution = rippleResolution;
|
||||
if (rippleHypRadius != 0.f)
|
||||
rippleHypRadius = std::sqrt(rippleHypRadius);
|
||||
x1c_rippleHypRadius = rippleHypRadius;
|
||||
x20_ooRippleSideLen = 1.f / x14_rippleSideLen;
|
||||
if (tileHypRadius != 0.f)
|
||||
tileHypRadius = std::sqrt(tileHypRadius);
|
||||
x1c_tileHypRadius = tileHypRadius;
|
||||
x20_ooTileSize = 1.f / x14_tileSize;
|
||||
x24_ooRippleResolution = 1.f / x18_rippleResolution;
|
||||
x28_tileX = u16(tileX);
|
||||
x2a_gridDimX = u16(gridDimX);
|
||||
x2c_gridDimY = u16(gridDimY);
|
||||
x2e_tileY = u16(tileY);
|
||||
x30_gridFlags = gridFlags;
|
||||
x34_r14 = r14;
|
||||
x35_r22 = u8(r22);
|
||||
x36_r23 = u8(r23);
|
||||
x37_renderMode = renderMode;
|
||||
x38_tileSize = tileSize;
|
||||
x34_redShift = u8(redShift);
|
||||
x35_greenShift = u8(greenShift);
|
||||
x36_blueShift = u8(blueShift);
|
||||
x37_normalMode = normalMode;
|
||||
x38_wavecapIntensityScale = wavecapIntensityScale;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -364,8 +364,11 @@ public:
|
|||
|
||||
struct SHFieldSample
|
||||
{
|
||||
float f1;
|
||||
u8 f2;
|
||||
float height;
|
||||
s8 nx;
|
||||
s8 ny;
|
||||
s8 nz;
|
||||
u8 wavecapIntensity;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -424,7 +427,7 @@ static void ApplyTurbulence(float t, CFluidPlaneCPURender::SHFieldSample (&heigh
|
|||
float distFac = curX * curX + curYSq;
|
||||
if (distFac != 0.f)
|
||||
distFac = std::sqrt(distFac);
|
||||
heights[i][j].f1 = fluidPane.GetTurbulenceHeight(fluidPane.GetOOTurbulenceDistance() * distFac + scaledT);
|
||||
heights[i][j].height = fluidPane.GetTurbulenceHeight(fluidPane.GetOOTurbulenceDistance() * distFac + scaledT);
|
||||
curX += info.x18_rippleResolution;
|
||||
}
|
||||
curY += info.x18_rippleResolution;
|
||||
|
@ -457,27 +460,27 @@ static void ApplyRipple(const CFluidPlaneCPURender::SRippleInfo& rippleInfo,
|
|||
CFluidPlaneCPURender::numSubdivisionsInTile;
|
||||
|
||||
float curY = rippleInfo.x0_ripple.GetCenter().y - info.xc_globalMin.y -
|
||||
(0.5f * info.x14_rippleSideLen + (fromY - 1) * info.x14_rippleSideLen);
|
||||
(0.5f * info.x14_tileSize + (fromY - 1) * info.x14_tileSize);
|
||||
int curGridY = info.x2a_gridDimX * (info.x2e_tileY + fromY - 1);
|
||||
int startGridX = (info.x28_tileX + fromX - 1);
|
||||
int gridCells = info.x2a_gridDimX * info.x2c_gridDimY;
|
||||
float f11 = 64.f * rippleInfo.x0_ripple.GetOODistanceFalloff();
|
||||
int curYDiv = rippleInfo.xc_fromY;
|
||||
|
||||
for (int i=fromY ; i<=toY ; ++i, curY -= info.x14_rippleSideLen)
|
||||
for (int i=fromY ; i<=toY ; ++i, curY -= info.x14_tileSize)
|
||||
{
|
||||
int nextYDiv = (i+1) * CFluidPlaneCPURender::numSubdivisionsInTile;
|
||||
float curYSq = curY * curY;
|
||||
int curGridX = startGridX;
|
||||
int curXDiv = rippleInfo.x4_fromX;
|
||||
float curX = rippleInfo.x0_ripple.GetCenter().x - info.xc_globalMin.x -
|
||||
(0.5f * info.x14_rippleSideLen + (fromX - 1) * info.x14_rippleSideLen);
|
||||
for (int j=fromX ; j<=toX ; ++j, curX -= info.x14_rippleSideLen, ++curGridX)
|
||||
(0.5f * info.x14_tileSize + (fromX - 1) * info.x14_tileSize);
|
||||
for (int j=fromX ; j<=toX ; ++j, curX -= info.x14_tileSize, ++curGridX)
|
||||
{
|
||||
float dist = curX * curX + curYSq;
|
||||
if (dist != 0.f)
|
||||
dist = std::sqrt(dist);
|
||||
if (maxDist < dist - info.x1c_rippleHypRadius || minDist > dist + info.x1c_rippleHypRadius)
|
||||
if (maxDist < dist - info.x1c_tileHypRadius || minDist > dist + info.x1c_tileHypRadius)
|
||||
continue;
|
||||
|
||||
bool addedRipple = false;
|
||||
|
@ -504,12 +507,12 @@ static void ApplyRipple(const CFluidPlaneCPURender::SRippleInfo& rippleInfo,
|
|||
float divDist = (divDistSq != 0.f) ? std::sqrt(divDistSq) : 0.f;
|
||||
if (u8 val = CFluidPlaneManager::RippleValues[lifeIdx][int(divDist * f11)])
|
||||
{
|
||||
heights[k][l].f1 += val * rippleInfo.x0_ripple.GetAmplitude() *
|
||||
heights[k][l].height += val * rippleInfo.x0_ripple.GetAmplitude() *
|
||||
sineWave[int(divDist * rippleInfo.x0_ripple.GetLookupPhase() + lookupT)];
|
||||
}
|
||||
else
|
||||
{
|
||||
heights[k][l].f1 += 0.f;
|
||||
heights[k][l].height += 0.f;
|
||||
}
|
||||
addedRipple = true;
|
||||
}
|
||||
|
@ -557,12 +560,12 @@ static void ApplyRipple(const CFluidPlaneCPURender::SRippleInfo& rippleInfo,
|
|||
float divDist = (divDistSq != 0.f) ? std::sqrt(divDistSq) : 0.f;
|
||||
if (u8 val = CFluidPlaneManager::RippleValues[lifeIdx][int(divDist * f11)])
|
||||
{
|
||||
heights[k][l].f1 += val * rippleInfo.x0_ripple.GetAmplitude() *
|
||||
heights[k][l].height += val * rippleInfo.x0_ripple.GetAmplitude() *
|
||||
sineWave[int(divDist * rippleInfo.x0_ripple.GetLookupPhase() + lookupT)];
|
||||
}
|
||||
else
|
||||
{
|
||||
heights[k][l].f1 += 0.f;
|
||||
heights[k][l].height += 0.f;
|
||||
}
|
||||
addedRipple = true;
|
||||
}
|
||||
|
@ -597,7 +600,7 @@ static void ApplyRipples(const rstl::reserved_vector<CFluidPlaneCPURender::SRipp
|
|||
flags[CFluidPlaneCPURender::numTilesInHField+1][i+1] |= 2;
|
||||
}
|
||||
|
||||
static void UpdatePatchNormal(CFluidPlaneCPURender::SHFieldSample (&heights)[45][45], const u8 (&flags)[9][9],
|
||||
static void UpdatePatchNoNormals(CFluidPlaneCPURender::SHFieldSample (& heights)[45][45], const u8 (& flags)[9][9],
|
||||
const CFluidPlaneCPURender::SPatchInfo& info)
|
||||
{
|
||||
for (int i=1 ; i <= (info.x1_ySubdivs + CFluidPlaneCPURender::numSubdivisionsInTile - 2) /
|
||||
|
@ -619,35 +622,38 @@ static void UpdatePatchNormal(CFluidPlaneCPURender::SHFieldSample (&heights)[45]
|
|||
for (int l=r11 ; l<x28 ; ++l)
|
||||
{
|
||||
CFluidPlaneCPURender::SHFieldSample& sample = heights[k][l];
|
||||
if (sample.f1 > 0.f)
|
||||
sample.f2 = u8(std::min(255, int(info.x38_tileSize * sample.f1)));
|
||||
if (sample.height > 0.f)
|
||||
sample.wavecapIntensity =
|
||||
u8(std::min(255, int(info.x38_wavecapIntensityScale * sample.height)));
|
||||
else
|
||||
sample.f2 = 0;
|
||||
sample.wavecapIntensity = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (i > 0 && i < CFluidPlaneCPURender::numTilesInHField + 1 &&
|
||||
r10 > 0 && r10 < CFluidPlaneCPURender::numTilesInHField + 1)
|
||||
j > 0 && j < CFluidPlaneCPURender::numTilesInHField + 1)
|
||||
{
|
||||
int halfSubdivs = CFluidPlaneCPURender::numSubdivisionsInTile / 2;
|
||||
CFluidPlaneCPURender::SHFieldSample& sample = heights[halfSubdivs + r9][halfSubdivs + r11];
|
||||
if (sample.f1 > 0.f)
|
||||
sample.f2 = u8(std::min(255, int(info.x38_tileSize * sample.f1)));
|
||||
if (sample.height > 0.f)
|
||||
sample.wavecapIntensity =
|
||||
u8(std::min(255, int(info.x38_wavecapIntensityScale * sample.height)));
|
||||
else
|
||||
sample.f2 = 0;
|
||||
sample.wavecapIntensity = 0;
|
||||
}
|
||||
|
||||
if (i != 0)
|
||||
{
|
||||
for (int k=r11 ; k<x28 ; ++k)
|
||||
for (int l=r11 ; l<x28 ; ++l)
|
||||
{
|
||||
CFluidPlaneCPURender::SHFieldSample& sample = heights[i][k];
|
||||
if (sample.f1 > 0.f)
|
||||
sample.f2 = u8(std::min(255, int(info.x38_tileSize * sample.f1)));
|
||||
CFluidPlaneCPURender::SHFieldSample& sample = heights[r9][l];
|
||||
if (sample.height > 0.f)
|
||||
sample.wavecapIntensity =
|
||||
u8(std::min(255, int(info.x38_wavecapIntensityScale * sample.height)));
|
||||
else
|
||||
sample.f2 = 0;
|
||||
sample.wavecapIntensity = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -656,10 +662,11 @@ static void UpdatePatchNormal(CFluidPlaneCPURender::SHFieldSample (&heights)[45]
|
|||
for (int k=r9+1 ; k<x24 ; ++k)
|
||||
{
|
||||
CFluidPlaneCPURender::SHFieldSample& sample = heights[k][r11];
|
||||
if (sample.f1 > 0.f)
|
||||
sample.f2 = u8(std::min(255, int(info.x38_tileSize * sample.f1)));
|
||||
if (sample.height > 0.f)
|
||||
sample.wavecapIntensity =
|
||||
u8(std::min(255, int(info.x38_wavecapIntensityScale * sample.height)));
|
||||
else
|
||||
sample.f2 = 0;
|
||||
sample.wavecapIntensity = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -667,14 +674,166 @@ static void UpdatePatchNormal(CFluidPlaneCPURender::SHFieldSample (&heights)[45]
|
|||
}
|
||||
}
|
||||
|
||||
static void UpdatePatchSubdivided(const CFluidPlaneCPURender::SHFieldSample (&heights)[45][45], const u8 (&flags)[9][9],
|
||||
static void UpdatePatchWithNormals(CFluidPlaneCPURender::SHFieldSample (& heights)[45][45], const u8 (& flags)[9][9],
|
||||
const CFluidPlaneCPURender::SPatchInfo& info)
|
||||
{
|
||||
|
||||
float normalScale = -(2.f * info.x18_rippleResolution);
|
||||
float nz = 0.25f * 2.f * info.x18_rippleResolution;
|
||||
int curGridY = info.x2e_tileY * info.x2a_gridDimX - 1 + info.x28_tileX;
|
||||
for (int i=1 ; i <= (info.x1_ySubdivs + CFluidPlaneCPURender::numSubdivisionsInTile - 2) /
|
||||
CFluidPlaneCPURender::numSubdivisionsInTile ; ++i, curGridY += info.x2a_gridDimX)
|
||||
{
|
||||
int r11 = i * CFluidPlaneCPURender::numSubdivisionsInTile + 1;
|
||||
int r9 = std::max(0, r11 - CFluidPlaneCPURender::numSubdivisionsInTile);
|
||||
int x38 = std::min(r11, info.x1_ySubdivs + 1);
|
||||
for (int j=1 ; j <= (info.x0_xSubdivs + CFluidPlaneCPURender::numSubdivisionsInTile - 2) /
|
||||
CFluidPlaneCPURender::numSubdivisionsInTile ; ++j)
|
||||
{
|
||||
int r12 = j * CFluidPlaneCPURender::numSubdivisionsInTile + 1;
|
||||
int x3c = std::min(r12, info.x0_xSubdivs + 1);
|
||||
r12 -= CFluidPlaneCPURender::numSubdivisionsInTile;
|
||||
if ((flags[i][j] & 0x1f) == 0x1f)
|
||||
{
|
||||
for (int k=r9 ; k<x38 ; ++k)
|
||||
{
|
||||
for (int l=r12 ; l<x3c ; ++l)
|
||||
{
|
||||
CFluidPlaneCPURender::SHFieldSample& sample = heights[k][l];
|
||||
CFluidPlaneCPURender::SHFieldSample& up = heights[k+1][l];
|
||||
CFluidPlaneCPURender::SHFieldSample& down = heights[k-1][l];
|
||||
CFluidPlaneCPURender::SHFieldSample& right = heights[k][l+1];
|
||||
CFluidPlaneCPURender::SHFieldSample& left = heights[k][l-1];
|
||||
float nx = (right.height - left.height) * normalScale;
|
||||
float ny = (up.height - down.height) * normalScale;
|
||||
float normalizer = ny * ny + nx * nx + nz * nz;
|
||||
if (normalizer != 0.f)
|
||||
normalizer = std::sqrt(normalizer);
|
||||
normalizer = 63.f / normalizer;
|
||||
sample.nx = s8(nx * normalizer);
|
||||
sample.ny = s8(ny * normalizer);
|
||||
sample.nz = s8(nz * normalizer);
|
||||
if (sample.height > 0.f)
|
||||
sample.wavecapIntensity =
|
||||
u8(std::min(255, int(info.x38_wavecapIntensityScale * sample.height)));
|
||||
else
|
||||
sample.wavecapIntensity = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!info.x30_gridFlags || info.x30_gridFlags[curGridY+j])
|
||||
{
|
||||
if (i > 0 && i < CFluidPlaneCPURender::numTilesInHField + 1 &&
|
||||
j > 0 && j < CFluidPlaneCPURender::numTilesInHField + 1)
|
||||
{
|
||||
int halfSubdivs = CFluidPlaneCPURender::numSubdivisionsInTile / 2;
|
||||
int k = halfSubdivs + r9;
|
||||
int l = halfSubdivs + r12;
|
||||
CFluidPlaneCPURender::SHFieldSample& sample = heights[k][l];
|
||||
CFluidPlaneCPURender::SHFieldSample& up = heights[k+1][l];
|
||||
CFluidPlaneCPURender::SHFieldSample& down = heights[k-1][l];
|
||||
CFluidPlaneCPURender::SHFieldSample& right = heights[k][l+1];
|
||||
CFluidPlaneCPURender::SHFieldSample& left = heights[k][l-1];
|
||||
float nx = (right.height - left.height) * normalScale;
|
||||
float ny = (up.height - down.height) * normalScale;
|
||||
float normalizer = ny * ny + nx * nx + nz * nz;
|
||||
if (normalizer != 0.f)
|
||||
normalizer = std::sqrt(normalizer);
|
||||
normalizer = 63.f / normalizer;
|
||||
sample.nx = s8(nx * normalizer);
|
||||
sample.ny = s8(ny * normalizer);
|
||||
sample.nz = s8(nz * normalizer);
|
||||
if (sample.height > 0.f)
|
||||
sample.wavecapIntensity =
|
||||
u8(std::min(255, int(info.x38_wavecapIntensityScale * sample.height)));
|
||||
else
|
||||
sample.wavecapIntensity = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static bool UpdatePatch(float time, const CFluidPlaneCPURender::SPatchInfo& info, const CFluidPlaneCPU& fluidPane,
|
||||
const zeus::CVector3f& areaCenter,
|
||||
if (j != 0 && i != 0)
|
||||
{
|
||||
if ((flags[i][j] & 2) != 0 || (flags[i-1][j] & 1) != 0 ||
|
||||
(flags[i][j] & 4) != 0 || (flags[i][j-1] & 8) != 0)
|
||||
{
|
||||
for (int l=r12 ; l<x3c ; ++l)
|
||||
{
|
||||
CFluidPlaneCPURender::SHFieldSample& sample = heights[r9][l];
|
||||
CFluidPlaneCPURender::SHFieldSample& up = heights[r9+1][l];
|
||||
CFluidPlaneCPURender::SHFieldSample& down = heights[r9-1][l];
|
||||
CFluidPlaneCPURender::SHFieldSample& right = heights[r9][l+1];
|
||||
CFluidPlaneCPURender::SHFieldSample& left = heights[r9][l-1];
|
||||
float nx = (right.height - left.height) * normalScale;
|
||||
float ny = (up.height - down.height) * normalScale;
|
||||
float normalizer = ny * ny + nx * nx + nz * nz;
|
||||
if (normalizer != 0.f)
|
||||
normalizer = std::sqrt(normalizer);
|
||||
normalizer = 63.f / normalizer;
|
||||
sample.nx = s8(nx * normalizer);
|
||||
sample.ny = s8(ny * normalizer);
|
||||
sample.nz = s8(nz * normalizer);
|
||||
if (sample.height > 0.f)
|
||||
sample.wavecapIntensity =
|
||||
u8(std::min(255, int(info.x38_wavecapIntensityScale * sample.height)));
|
||||
else
|
||||
sample.wavecapIntensity = 0;
|
||||
}
|
||||
|
||||
for (int k=r9 ; k<x38 ; ++k)
|
||||
{
|
||||
CFluidPlaneCPURender::SHFieldSample& sample = heights[k][r12];
|
||||
CFluidPlaneCPURender::SHFieldSample& up = heights[k+1][r12];
|
||||
CFluidPlaneCPURender::SHFieldSample& down = heights[k-1][r12];
|
||||
CFluidPlaneCPURender::SHFieldSample& right = heights[k][r12+1];
|
||||
CFluidPlaneCPURender::SHFieldSample& left = heights[k][r12-1];
|
||||
float nx = (right.height - left.height) * normalScale;
|
||||
float ny = (up.height - down.height) * normalScale;
|
||||
float normalizer = ny * ny + nx * nx + nz * nz;
|
||||
if (normalizer != 0.f)
|
||||
normalizer = std::sqrt(normalizer);
|
||||
normalizer = 63.f / normalizer;
|
||||
sample.nx = s8(nx * normalizer);
|
||||
sample.ny = s8(ny * normalizer);
|
||||
sample.nz = s8(nz * normalizer);
|
||||
if (sample.height > 0.f)
|
||||
sample.wavecapIntensity =
|
||||
u8(std::min(255, int(info.x38_wavecapIntensityScale * sample.height)));
|
||||
else
|
||||
sample.wavecapIntensity = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CFluidPlaneCPURender::SHFieldSample& sample = heights[r9][r12];
|
||||
CFluidPlaneCPURender::SHFieldSample& up = heights[r9+1][r12];
|
||||
CFluidPlaneCPURender::SHFieldSample& down = heights[r9-1][r12];
|
||||
CFluidPlaneCPURender::SHFieldSample& right = heights[r9][r12+1];
|
||||
CFluidPlaneCPURender::SHFieldSample& left = heights[r9][r12-1];
|
||||
float nx = (right.height - left.height) * normalScale;
|
||||
float ny = (up.height - down.height) * normalScale;
|
||||
float normalizer = ny * ny + nx * nx + nz * nz;
|
||||
if (normalizer != 0.f)
|
||||
normalizer = std::sqrt(normalizer);
|
||||
normalizer = 63.f / normalizer;
|
||||
sample.nx = s8(nx * normalizer);
|
||||
sample.ny = s8(ny * normalizer);
|
||||
sample.nz = s8(nz * normalizer);
|
||||
if (sample.height > 0.f)
|
||||
sample.wavecapIntensity =
|
||||
u8(std::min(255, int(info.x38_wavecapIntensityScale * sample.height)));
|
||||
else
|
||||
sample.wavecapIntensity = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool UpdatePatch(float time, const CFluidPlaneCPURender::SPatchInfo& info,
|
||||
CFluidPlaneCPURender::SHFieldSample (&heights)[45][45], u8 (&flags)[9][9],
|
||||
const CFluidPlaneCPU& fluidPane, const zeus::CVector3f& areaCenter,
|
||||
const std::experimental::optional<CRippleManager>& rippleManager,
|
||||
int fromX, int toX, int fromY, int toY)
|
||||
{
|
||||
|
@ -694,47 +853,246 @@ static bool UpdatePatch(float time, const CFluidPlaneCPURender::SPatchInfo& info
|
|||
if (rippleInfos.empty())
|
||||
return true;
|
||||
|
||||
CFluidPlaneCPURender::SHFieldSample heights[45][45];
|
||||
u8 flags[9][9] = {};
|
||||
ApplyTurbulence(time, heights, flags, sGlobalSineWave, info, fluidPane, areaCenter);
|
||||
ApplyRipples(rippleInfos, heights, flags, sGlobalSineWave, info);
|
||||
if (info.x37_renderMode == CFluidPlaneCPURender::RenderMode::Normal)
|
||||
UpdatePatchNormal(heights, flags, info);
|
||||
if (info.x37_normalMode == CFluidPlaneCPURender::NormalMode::NoNormals)
|
||||
UpdatePatchNoNormals(heights, flags, info);
|
||||
else
|
||||
UpdatePatchSubdivided(heights, flags, info);
|
||||
UpdatePatchWithNormals(heights, flags, info);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void RenderPatch(const CFluidPlaneCPURender::SPatchInfo& info, bool updateResult)
|
||||
static void RenderStripWithRipples(float curY, const CFluidPlaneCPURender::SHFieldSample (&heights)[45][45],
|
||||
const u8 (&flags)[9][9], int startYDiv,
|
||||
const CFluidPlaneCPURender::SPatchInfo& info,
|
||||
std::vector<CFluidPlaneShader::Vertex>& vOut)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void RenderPatch(const CFluidPlaneCPURender::SPatchInfo& info,
|
||||
const CFluidPlaneCPURender::SHFieldSample (&heights)[45][45],
|
||||
const u8 (&flags)[9][9], bool noRipples, bool flagIs1,
|
||||
std::vector<CFluidPlaneShader::Vertex>& vOut)
|
||||
{
|
||||
if (noRipples)
|
||||
{
|
||||
float xMin = info.x4_localMin.x;
|
||||
float yMin = info.x4_localMin.y;
|
||||
float xMax = info.x18_rippleResolution * (info.x0_xSubdivs - 2) + xMin;
|
||||
float yMax = info.x18_rippleResolution * (info.x1_ySubdivs - 2) + yMin;
|
||||
|
||||
switch (info.x37_normalMode)
|
||||
{
|
||||
case CFluidPlaneCPURender::NormalMode::None:
|
||||
vOut.emplace_back(zeus::CVector3f(xMin, yMin, 0.f));
|
||||
vOut.emplace_back(zeus::CVector3f(xMin, yMax, 0.f));
|
||||
vOut.emplace_back(zeus::CVector3f(xMax, yMin, 0.f));
|
||||
vOut.emplace_back(zeus::CVector3f(xMax, yMax, 0.f));
|
||||
break;
|
||||
case CFluidPlaneCPURender::NormalMode::NoNormals:
|
||||
vOut.emplace_back(zeus::CVector3f(xMin, yMin, 0.f), zeus::CColor::skBlack);
|
||||
vOut.emplace_back(zeus::CVector3f(xMin, yMax, 0.f), zeus::CColor::skBlack);
|
||||
vOut.emplace_back(zeus::CVector3f(xMax, yMin, 0.f), zeus::CColor::skBlack);
|
||||
vOut.emplace_back(zeus::CVector3f(xMax, yMax, 0.f), zeus::CColor::skBlack);
|
||||
break;
|
||||
case CFluidPlaneCPURender::NormalMode::Normals:
|
||||
{
|
||||
int yTiles = (info.x1_ySubdivs - 3) / CFluidPlaneCPURender::numSubdivisionsInTile + 1;
|
||||
int xTiles = (info.x0_xSubdivs - 3) / CFluidPlaneCPURender::numSubdivisionsInTile + 1;
|
||||
int xTileStart = info.x28_tileX + info.x2e_tileY * info.x2a_gridDimX;
|
||||
for (int curYTile=yTiles ; curYTile>0 ; --curYTile,
|
||||
yMax += info.x14_tileSize, xTileStart += info.x2a_gridDimX)
|
||||
{
|
||||
xMax = xMin;
|
||||
int nextXTile;
|
||||
for (int curXTile=0 ; curXTile<xTiles ; curXTile=nextXTile)
|
||||
{
|
||||
if (!info.x30_gridFlags || info.x30_gridFlags[xTileStart+curXTile])
|
||||
{
|
||||
if (curYTile == yTiles || curYTile == 1 || curXTile == 0 || xTiles - 1 == curXTile)
|
||||
{
|
||||
vOut.emplace_back(zeus::CVector3f(xMax + 0.5f * info.x14_tileSize,
|
||||
yMax + 0.5f * info.x14_tileSize, 0.f),
|
||||
zeus::CVector3f::skUp, zeus::CColor::skBlack);
|
||||
|
||||
float tmp = xMax;
|
||||
for (int v=0 ; v<((curYTile == 1) ?
|
||||
CFluidPlaneCPURender::numSubdivisionsInTile : 1) ; ++v)
|
||||
{
|
||||
vOut.emplace_back(zeus::CVector3f(tmp, yMax + info.x14_tileSize, 0.f),
|
||||
zeus::CVector3f::skUp, zeus::CColor::skBlack);
|
||||
tmp += info.x18_rippleResolution;
|
||||
}
|
||||
|
||||
tmp = yMax + info.x14_tileSize;
|
||||
for (int v=0 ; v<((xTiles - 1 == curXTile) ?
|
||||
CFluidPlaneCPURender::numSubdivisionsInTile : 1) ; ++v)
|
||||
{
|
||||
vOut.emplace_back(zeus::CVector3f(xMax + info.x14_tileSize, tmp, 0.f),
|
||||
zeus::CVector3f::skUp, zeus::CColor::skBlack);
|
||||
tmp -= info.x18_rippleResolution;
|
||||
}
|
||||
|
||||
tmp = xMax + info.x14_tileSize;
|
||||
for (int v=0 ; v<((curYTile == yTiles) ?
|
||||
CFluidPlaneCPURender::numSubdivisionsInTile : 1) ; ++v)
|
||||
{
|
||||
vOut.emplace_back(zeus::CVector3f(tmp, yMax, 0.f),
|
||||
zeus::CVector3f::skUp, zeus::CColor::skBlack);
|
||||
tmp -= info.x18_rippleResolution;
|
||||
}
|
||||
|
||||
tmp = yMax;
|
||||
for (int v=0 ; v<((curXTile == 0) ?
|
||||
CFluidPlaneCPURender::numSubdivisionsInTile : 1) ; ++v)
|
||||
{
|
||||
vOut.emplace_back(zeus::CVector3f(xMax, tmp, 0.f),
|
||||
zeus::CVector3f::skUp, zeus::CColor::skBlack);
|
||||
tmp += info.x18_rippleResolution;
|
||||
}
|
||||
|
||||
vOut.emplace_back(zeus::CVector3f(xMax, yMax + info.x14_tileSize, 0.f),
|
||||
zeus::CVector3f::skUp, zeus::CColor::skBlack);
|
||||
|
||||
nextXTile = curXTile + 1;
|
||||
xMax += info.x14_tileSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
nextXTile = curXTile + 1;
|
||||
while (nextXTile < xTiles - 1 &&
|
||||
(!info.x30_gridFlags || info.x30_gridFlags[xTileStart+nextXTile]))
|
||||
++nextXTile;
|
||||
|
||||
for (int v = 0 ; v < nextXTile - curXTile + 1 ; ++v)
|
||||
{
|
||||
vOut.emplace_back(zeus::CVector3f(xMax, yMax, 0.f), zeus::CColor::skBlack);
|
||||
vOut.emplace_back(zeus::CVector3f(xMax, yMax + info.x14_tileSize, 0.f),
|
||||
zeus::CColor::skBlack);
|
||||
xMax += info.x14_tileSize;
|
||||
}
|
||||
|
||||
++nextXTile;
|
||||
if (nextXTile == xTiles)
|
||||
{
|
||||
--nextXTile;
|
||||
xMax -= info.x14_tileSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nextXTile = curXTile + 1;
|
||||
xMax += info.x14_tileSize;
|
||||
while (nextXTile < xTiles && !info.x30_gridFlags[xTileStart+nextXTile])
|
||||
{
|
||||
xMax += info.x14_tileSize;
|
||||
++nextXTile;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CFluidPlaneCPURender::NormalMode::NBT:
|
||||
{
|
||||
if (flagIs1 || !info.x30_gridFlags)
|
||||
{
|
||||
vOut.emplace_back(zeus::CVector3f(xMin, yMin, 0.f), zeus::CVector3f::skUp,
|
||||
zeus::CVector3f::skForward, zeus::CVector3f::skRight, zeus::CColor::skBlack);
|
||||
vOut.emplace_back(zeus::CVector3f(xMin, yMax, 0.f), zeus::CVector3f::skUp,
|
||||
zeus::CVector3f::skForward, zeus::CVector3f::skRight, zeus::CColor::skBlack);
|
||||
vOut.emplace_back(zeus::CVector3f(xMax, yMin, 0.f), zeus::CVector3f::skUp,
|
||||
zeus::CVector3f::skForward, zeus::CVector3f::skRight, zeus::CColor::skBlack);
|
||||
vOut.emplace_back(zeus::CVector3f(xMax, yMax, 0.f), zeus::CVector3f::skUp,
|
||||
zeus::CVector3f::skForward, zeus::CVector3f::skRight, zeus::CColor::skBlack);
|
||||
}
|
||||
else
|
||||
{
|
||||
int xTiles = (info.x0_xSubdivs - 3) / CFluidPlaneCPURender::numSubdivisionsInTile + 1;
|
||||
int yTiles = (info.x1_ySubdivs - 3) / CFluidPlaneCPURender::numSubdivisionsInTile + 1;
|
||||
int xTileStart = info.x28_tileX + info.x2e_tileY * info.x2a_gridDimX;
|
||||
for (; yTiles>0 ; --yTiles, yMin += info.x14_tileSize, xTileStart += info.x2a_gridDimX)
|
||||
{
|
||||
xMax = xMin;
|
||||
int nextXTile;
|
||||
for (int curXTile=0 ; curXTile<xTiles ; curXTile=nextXTile)
|
||||
{
|
||||
if (info.x30_gridFlags[xTileStart+curXTile])
|
||||
{
|
||||
nextXTile = curXTile + 1;
|
||||
int tile = xTileStart + nextXTile;
|
||||
while (nextXTile < xTiles && info.x30_gridFlags[tile])
|
||||
{
|
||||
++nextXTile;
|
||||
++tile;
|
||||
}
|
||||
|
||||
for (int v = 0 ; v < nextXTile - curXTile + 1 ; ++v)
|
||||
{
|
||||
vOut.emplace_back(zeus::CVector3f(xMax, yMin, 0.f), zeus::CVector3f::skUp,
|
||||
zeus::CVector3f::skForward, zeus::CVector3f::skRight,
|
||||
zeus::CColor::skBlack);
|
||||
vOut.emplace_back(zeus::CVector3f(xMax, yMin + info.x14_tileSize, 0.f),
|
||||
zeus::CVector3f::skUp, zeus::CVector3f::skForward,
|
||||
zeus::CVector3f::skRight, zeus::CColor::skBlack);
|
||||
xMax += info.x14_tileSize;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nextXTile = curXTile + 1;
|
||||
xMax += info.x14_tileSize;
|
||||
int tile = xTileStart + nextXTile;
|
||||
while (nextXTile < xTiles && !info.x30_gridFlags[tile])
|
||||
{
|
||||
xMax += info.x14_tileSize;
|
||||
++nextXTile;
|
||||
++tile;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float curY = info.x4_localMin.y;
|
||||
for (int startYDiv=1 ; startYDiv<info.x1_ySubdivs-2 ;
|
||||
startYDiv += CFluidPlaneCPURender::numSubdivisionsInTile, curY += info.x14_tileSize)
|
||||
RenderStripWithRipples(curY, heights, flags, startYDiv, info, vOut);
|
||||
}
|
||||
}
|
||||
|
||||
void CFluidPlaneCPU::Render(const CStateManager& mgr, float alpha, const zeus::CAABox& aabb, const zeus::CTransform& xf,
|
||||
const zeus::CTransform& areaXf, bool noSubdiv, const zeus::CFrustum& frustum,
|
||||
const zeus::CTransform& areaXf, bool noNormals, const zeus::CFrustum& frustum,
|
||||
const std::experimental::optional<CRippleManager>& rippleManager, TUniqueId waterId,
|
||||
const bool* gridFlags, u32 gridDimX, u32 gridDimY, const zeus::CVector3f& areaCenter) const
|
||||
{
|
||||
TCastToConstPtr<CScriptWater> water = mgr.GetObjectById(waterId);
|
||||
RenderSetupInfo setupInfo = RenderSetup(mgr, alpha, xf, areaXf, aabb, water.GetPtr());
|
||||
|
||||
CFluidPlaneCPURender::RenderMode renderMode;
|
||||
CFluidPlaneCPURender::NormalMode normalMode;
|
||||
if (xb0_bumpMap && kEnableWaterBumpMaps)
|
||||
renderMode = CFluidPlaneCPURender::RenderMode::BumpMapped;
|
||||
else if (!noSubdiv)
|
||||
renderMode = CFluidPlaneCPURender::RenderMode::Subdivided;
|
||||
normalMode = CFluidPlaneCPURender::NormalMode::NBT;
|
||||
else if (!noNormals)
|
||||
normalMode = CFluidPlaneCPURender::NormalMode::Normals;
|
||||
else
|
||||
renderMode = CFluidPlaneCPURender::RenderMode::Normal;
|
||||
normalMode = CFluidPlaneCPURender::NormalMode::NoNormals;
|
||||
|
||||
// Set Position and color format
|
||||
|
||||
switch (renderMode)
|
||||
switch (normalMode)
|
||||
{
|
||||
case CFluidPlaneCPURender::RenderMode::BumpMapped:
|
||||
case CFluidPlaneCPURender::NormalMode::NBT:
|
||||
// Set NBT format
|
||||
break;
|
||||
case CFluidPlaneCPURender::RenderMode::Subdivided:
|
||||
case CFluidPlaneCPURender::NormalMode::Normals:
|
||||
// Set Normal format
|
||||
break;
|
||||
default:
|
||||
|
@ -751,22 +1109,23 @@ void CFluidPlaneCPU::Render(const CStateManager& mgr, float alpha, const zeus::C
|
|||
zeus::CVector2f center2D(aabbCenter.x, aabbCenter.y);
|
||||
zeus::CVector2f ripplePitch(x108_rippleResolution * CFluidPlaneCPURender::numSubdivisionsInHField);
|
||||
|
||||
bool r14 = false;
|
||||
int r22 = 0;
|
||||
int r23 = 0;
|
||||
float rippleSideLen = g_tweakGame->GetRippleSideLengthNormal();
|
||||
// Amount to shift intensity values right (for added wavecap color)
|
||||
int redShift = 0;
|
||||
int greenShift = 0;
|
||||
int blueShift = 0;
|
||||
float wavecapIntensityScale = g_tweakGame->GetWavecapIntensityNormal();
|
||||
switch (x44_fluidType)
|
||||
{
|
||||
case EFluidType::PoisonWater:
|
||||
rippleSideLen = g_tweakGame->GetRippleSideLengthPoison();
|
||||
r14 = true;
|
||||
r23 = 1;
|
||||
wavecapIntensityScale = g_tweakGame->GetWavecapIntensityPoison();
|
||||
redShift = 1;
|
||||
blueShift = 1;
|
||||
break;
|
||||
case EFluidType::Lava:
|
||||
case EFluidType::Five:
|
||||
rippleSideLen = g_tweakGame->GetRippleSideLengthLava();
|
||||
r23 = 8;
|
||||
r22 = 8;
|
||||
wavecapIntensityScale = g_tweakGame->GetWavecapIntensityLava();
|
||||
blueShift = 8;
|
||||
greenShift = 8;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -777,12 +1136,14 @@ void CFluidPlaneCPU::Render(const CStateManager& mgr, float alpha, const zeus::C
|
|||
float cameraPenetration =
|
||||
mgr.GetCameraManager()->GetCurrentCamera(mgr)->GetTranslation().dot(zeus::CVector3f::skUp) -
|
||||
water->GetTriggerBoundsWR().max.z;
|
||||
rippleSideLen *= (cameraPenetration >= 0.5f || cameraPenetration < 0.f) ? 1.f : 2.f * cameraPenetration;
|
||||
wavecapIntensityScale *= (cameraPenetration >= 0.5f || cameraPenetration < 0.f) ? 1.f : 2.f * cameraPenetration;
|
||||
}
|
||||
|
||||
u32 patchDimX = (water && water->GetPatchDimensionX()) ? water->GetPatchDimensionX() : 128;
|
||||
u32 patchDimY = (water && water->GetPatchDimensionY()) ? water->GetPatchDimensionY() : 128;
|
||||
|
||||
m_verts.clear();
|
||||
|
||||
u32 tileY = 0;
|
||||
float curY = aabb.min.y;
|
||||
for (int i=0 ; curY < aabb.max.y && i<patchDimY ; ++i)
|
||||
|
@ -792,7 +1153,7 @@ void CFluidPlaneCPU::Render(const CStateManager& mgr, float alpha, const zeus::C
|
|||
float _remDivsY = (aabb.max.y - curY) * rippleResolutionRecip;
|
||||
for (int j=0 ; curX < aabb.max.x && j<patchDimX ; ++j)
|
||||
{
|
||||
if (water->CanRenderPatch(j, i))
|
||||
if (u8 renderFlags = water->GetPatchRenderFlags(j, i))
|
||||
{
|
||||
s16 remDivsX = std::min(s16((aabb.max.x - curX) * rippleResolutionRecip),
|
||||
s16(CFluidPlaneCPURender::numSubdivisionsInHField));
|
||||
|
@ -804,9 +1165,10 @@ void CFluidPlaneCPU::Render(const CStateManager& mgr, float alpha, const zeus::C
|
|||
if (frustum.aabbFrustumTest(testaabb))
|
||||
{
|
||||
CFluidPlaneCPURender::SPatchInfo info(localMin, localMax, xf.origin, x108_rippleResolution,
|
||||
rippleSideLen, x100_tileSize,
|
||||
CFluidPlaneCPURender::numSubdivisionsInHField, renderMode,
|
||||
r14, r22, r23, tileX, gridDimX, gridDimY, tileY, gridFlags);
|
||||
x100_tileSize, wavecapIntensityScale,
|
||||
CFluidPlaneCPURender::numSubdivisionsInHField, normalMode,
|
||||
redShift, greenShift, blueShift, tileX, gridDimX, gridDimY,
|
||||
tileY, gridFlags);
|
||||
|
||||
int fromX = tileX != 0 ? (2 - CFluidPlaneCPURender::numSubdivisionsInTile) : 0;
|
||||
int toX;
|
||||
|
@ -822,9 +1184,12 @@ void CFluidPlaneCPU::Render(const CStateManager& mgr, float alpha, const zeus::C
|
|||
else
|
||||
toY = info.x1_ySubdivs;
|
||||
|
||||
bool result = UpdatePatch(mgr.GetFluidPlaneManager()->GetUVT(), info, *this, areaCenter,
|
||||
rippleManager, fromX, toX, fromY, toY);
|
||||
RenderPatch(info, result);
|
||||
CFluidPlaneCPURender::SHFieldSample heights[45][45];
|
||||
u8 flags[9][9] = {};
|
||||
|
||||
bool noRipples = UpdatePatch(mgr.GetFluidPlaneManager()->GetUVT(), info, heights, flags,
|
||||
*this, areaCenter, rippleManager, fromX, toX, fromY, toY);
|
||||
RenderPatch(info, heights, flags, noRipples, renderFlags == 1, m_verts);
|
||||
}
|
||||
}
|
||||
curX += ripplePitch.x;
|
||||
|
@ -834,7 +1199,8 @@ void CFluidPlaneCPU::Render(const CStateManager& mgr, float alpha, const zeus::C
|
|||
tileY += CFluidPlaneCPURender::numTilesInHField;
|
||||
}
|
||||
|
||||
//m_shader->draw(setupInfo.texMtxs, setupInfo.normMtx, setupInfo.indScale, setupInfo.lights, setupInfo.kColors);
|
||||
m_shader->draw(setupInfo.texMtxs, setupInfo.normMtx, setupInfo.indScale,
|
||||
setupInfo.lights, setupInfo.kColors, m_verts);
|
||||
}
|
||||
|
||||
void CFluidPlaneCPU::RenderCleanup() const
|
||||
|
|
|
@ -54,6 +54,8 @@ class CFluidPlaneCPU : public CFluidPlane
|
|||
float x118_reflectionSize;
|
||||
float x11c_unitsPerLightmapTexel;
|
||||
CTurbulence x120_turbulence;
|
||||
|
||||
mutable std::vector<CFluidPlaneShader::Vertex> m_verts;
|
||||
mutable std::experimental::optional<CFluidPlaneShader> m_shader;
|
||||
|
||||
struct RenderSetupInfo
|
||||
|
@ -79,7 +81,7 @@ public:
|
|||
const zeus::CTransform& areaXf, const zeus::CAABox& aabb,
|
||||
const CScriptWater* water) const;
|
||||
void Render(const CStateManager& mgr, float alpha, const zeus::CAABox& aabb, const zeus::CTransform& xf,
|
||||
const zeus::CTransform& areaXf, bool noSubdiv, const zeus::CFrustum& frustum,
|
||||
const zeus::CTransform& areaXf, bool noNormals, const zeus::CFrustum& frustum,
|
||||
const std::experimental::optional<CRippleManager>& rippleManager, TUniqueId waterId,
|
||||
const bool* gridFlags, u32 gridDimX, u32 gridDimY, const zeus::CVector3f& areaCenter) const;
|
||||
void RenderCleanup() const;
|
||||
|
|
|
@ -100,9 +100,9 @@ void CScriptWater::SetupGrid(bool b)
|
|||
for (int j=0 ; j<x2c4_gridDimX ; ++j)
|
||||
x2d8_gridFlags[i * x2c4_gridDimX + j] = true;
|
||||
if (!x2e0_patchFlags || x2d0_patchDimX != 0 || x2d4_patchDimY != 0)
|
||||
x2e0_patchFlags.reset(new bool[32]);
|
||||
x2e0_patchFlags.reset(new u8[32]);
|
||||
for (int i=0 ; i<32 ; ++i)
|
||||
x2e0_patchFlags[i] = true;
|
||||
x2e0_patchFlags[i] = 1;
|
||||
x2d4_patchDimY = 0;
|
||||
x2d0_patchDimX = 0;
|
||||
x2e8_28 = b;
|
||||
|
|
|
@ -58,7 +58,7 @@ private:
|
|||
u32 x2d4_patchDimY = 0;
|
||||
std::unique_ptr<bool[]> x2d8_gridFlags;
|
||||
std::unique_ptr<bool[]> x2dc_;
|
||||
std::unique_ptr<bool[]> x2e0_patchFlags;
|
||||
std::unique_ptr<u8[]> x2e0_patchFlags;
|
||||
u32 x2e4_gridCellCount2 = 0;
|
||||
union
|
||||
{
|
||||
|
@ -123,7 +123,7 @@ public:
|
|||
u16 GetVisorRunoffSfx() const { return x262_visorRunoffSfx; }
|
||||
const CScriptWater* GetNextConnectedWater(const CStateManager& mgr) const;
|
||||
float GetLightmapDoubleBlendFactor() const { return x1f8_lightmapDoubleBlendFactor; }
|
||||
bool CanRenderPatch(int x, int y) const { return x2e0_patchFlags[y * x2d0_patchDimX + x]; }
|
||||
u8 GetPatchRenderFlags(int x, int y) const { return x2e0_patchFlags[y * x2d0_patchDimX + x]; }
|
||||
u32 GetPatchDimensionX() const { return x2d0_patchDimX; }
|
||||
u32 GetPatchDimensionY() const { return x2d4_patchDimY; }
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue