mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2024-11-22 22:05:38 +00:00
Prior scroll fog logic was nearly correct. For scroll fogging to draw it needs either a start value or a fog density value, but these can come from a different viewport if they have the same colour fog set. This fixes the credits in vf3 which sets scroll fog, but it never draws on the original hardware.
For a long time we've had bug reports that in vf3 the background in the Dural levels was the wrong colour, it should have been much darker. We thought it was again missing scroll fog, but gm_mathew worked out it was actually coming from the fogAmbient paramater. Not only does it darken the fog, but it also has an effect on the 2d background from the tilegen, similar to scroll fog. This also fixes the sky in lemans24.
This commit is contained in:
parent
2af0787279
commit
a214c6dae8
|
@ -161,6 +161,7 @@ void CNew3D::DrawScrollFog()
|
||||||
// I think the basic logic is this: the real3d picks the highest scroll fog value, starting from the lowest priority layer.
|
// I think the basic logic is this: the real3d picks the highest scroll fog value, starting from the lowest priority layer.
|
||||||
// If it finds a value for priority layer 0 for example, it then bails out looking for any more.
|
// If it finds a value for priority layer 0 for example, it then bails out looking for any more.
|
||||||
// Fogging seems to be constrained to whatever the viewport is that is set.
|
// Fogging seems to be constrained to whatever the viewport is that is set.
|
||||||
|
// Scroll fog needs a density or start value to work, but these can come from another viewport if the fog colour is the same
|
||||||
|
|
||||||
Node* nodePtr = nullptr;
|
Node* nodePtr = nullptr;
|
||||||
|
|
||||||
|
@ -185,6 +186,20 @@ void CNew3D::DrawScrollFog()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nodePtr) {
|
if (nodePtr) {
|
||||||
|
|
||||||
|
// interate nodes to see if any viewports with that fog colour actually set a fog density or start value
|
||||||
|
// if both of these are zero fogging is effectively disabled
|
||||||
|
|
||||||
|
for (auto& n : m_nodes) {
|
||||||
|
|
||||||
|
if (nodePtr->viewport.fogParams[0] == n.viewport.fogParams[0] &&
|
||||||
|
nodePtr->viewport.fogParams[1] == n.viewport.fogParams[1] &&
|
||||||
|
nodePtr->viewport.fogParams[2] == n.viewport.fogParams[2])
|
||||||
|
{
|
||||||
|
// check to see if we have a fog start or density value
|
||||||
|
|
||||||
|
if (n.viewport.fogParams[3] > 0.0f || n.viewport.fogParams[4] > 0.0f) {
|
||||||
|
|
||||||
float rgba[4];
|
float rgba[4];
|
||||||
auto& vp = nodePtr->viewport;
|
auto& vp = nodePtr->viewport;
|
||||||
rgba[0] = vp.fogParams[0];
|
rgba[0] = vp.fogParams[0];
|
||||||
|
@ -194,6 +209,37 @@ void CNew3D::DrawScrollFog()
|
||||||
glViewport(vp.x, vp.y, vp.width, vp.height);
|
glViewport(vp.x, vp.y, vp.width, vp.height);
|
||||||
m_r3dScrollFog.DrawScrollFog(rgba, vp.scrollAtt, vp.fogParams[6], vp.spotFogColor, vp.spotEllipse);
|
m_r3dScrollFog.DrawScrollFog(rgba, vp.scrollAtt, vp.fogParams[6], vp.spotFogColor, vp.spotEllipse);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CNew3D::DrawAmbientFog()
|
||||||
|
{
|
||||||
|
// logic here is still not totally understood
|
||||||
|
// some games are setting fog ambient which seems to darken the 2d background layer too when scroll fogging is not set
|
||||||
|
// The logic is something like tileGenColour * fogAmbient
|
||||||
|
// If fogAmbient = 1.0 it's a no-op. Lower values darken the image
|
||||||
|
// Does this work with scroll fog? Well technically scroll fog already takes into account the fog ambient as it darkens the fog colour
|
||||||
|
|
||||||
|
// Let's pick the lowest fog ambient value
|
||||||
|
|
||||||
|
float fogAmbient = 1.0f;
|
||||||
|
Node* nodePtr = nullptr;
|
||||||
|
|
||||||
|
for (auto& n : m_nodes) {
|
||||||
|
if (n.viewport.fogParams[6] < fogAmbient) {
|
||||||
|
nodePtr = &n;
|
||||||
|
fogAmbient = n.viewport.fogParams[6];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fogAmbient < 1.0f) {
|
||||||
|
auto& vp = nodePtr->viewport;
|
||||||
|
float rgba[] = { 0.0f, 0.0f, 0.0f, 1.0f - fogAmbient };
|
||||||
|
glViewport(vp.x, vp.y, vp.width, vp.height);
|
||||||
|
m_r3dScrollFog.DrawScrollFog(rgba, vp.scrollAtt, vp.fogParams[6], vp.spotFogColor, vp.spotEllipse);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CNew3D::RenderScene(int priority, bool renderOverlay, Layer layer)
|
bool CNew3D::RenderScene(int priority, bool renderOverlay, Layer layer)
|
||||||
|
@ -339,6 +385,7 @@ void CNew3D::RenderFrame(void)
|
||||||
m_r3dFrameBuffers.SetFBO(Layer::colour); // colour will draw to all 3 buffers. For regular opaque pixels the transparent layers will be essentially masked
|
m_r3dFrameBuffers.SetFBO(Layer::colour); // colour will draw to all 3 buffers. For regular opaque pixels the transparent layers will be essentially masked
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
DrawAmbientFog();
|
||||||
DrawScrollFog(); // fog layer if applicable must be drawn here
|
DrawScrollFog(); // fog layer if applicable must be drawn here
|
||||||
|
|
||||||
for (int pri = 0; pri <= 3; pri++) {
|
for (int pri = 0; pri <= 3; pri++) {
|
||||||
|
|
|
@ -217,6 +217,7 @@ private:
|
||||||
bool IsDynamicModel(UINT32 *data); // check if the model has a colour palette
|
bool IsDynamicModel(UINT32 *data); // check if the model has a colour palette
|
||||||
bool IsVROMModel(UINT32 modelAddr);
|
bool IsVROMModel(UINT32 modelAddr);
|
||||||
void DrawScrollFog();
|
void DrawScrollFog();
|
||||||
|
void DrawAmbientFog();
|
||||||
bool SkipLayer(int layer);
|
bool SkipLayer(int layer);
|
||||||
void SetRenderStates();
|
void SetRenderStates();
|
||||||
void DisableRenderStates();
|
void DisableRenderStates();
|
||||||
|
|
Loading…
Reference in a new issue