mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2024-11-22 13:55:38 +00:00
Smooth texture repeat makes no sense for alpha/contour textures with pixel dilate. HW seems to treat them as non smooth anyway. Also implement some line of sight stuff, used by Scud. Really need to check the threading/synchronisation of the register reads but it basically works.
This commit is contained in:
parent
df02d6a753
commit
bf4d725970
|
@ -20,6 +20,7 @@ public:
|
|||
virtual bool Init(unsigned xOffset, unsigned yOffset, unsigned xRes, unsigned yRes, unsigned totalXRes, unsigned totalYRes) = 0;
|
||||
virtual void SetSunClamp(bool enable) = 0;
|
||||
virtual void SetSignedShade(bool enable) = 0;
|
||||
virtual float GetLosValue(int layer) = 0;
|
||||
|
||||
virtual ~IRender3D()
|
||||
{
|
||||
|
|
|
@ -1305,6 +1305,11 @@ void CLegacy3D::SetSignedShade(bool enable)
|
|||
{
|
||||
}
|
||||
|
||||
float CLegacy3D::GetLosValue(int layer)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
CLegacy3D::CLegacy3D(const Util::Config::Node &config)
|
||||
: m_config(config)
|
||||
{
|
||||
|
|
|
@ -348,6 +348,16 @@ public:
|
|||
*/
|
||||
void SetSignedShade(bool enable);
|
||||
|
||||
/*
|
||||
* GetLosValue(int layer);
|
||||
*
|
||||
* Gets the line of sight value for the priority layer
|
||||
*
|
||||
* Parameters:
|
||||
* layer Priority layer to read from
|
||||
*/
|
||||
float GetLosValue(int layer);
|
||||
|
||||
/*
|
||||
* CLegacy3D(void):
|
||||
* ~CLegacy3D(void):
|
||||
|
|
|
@ -297,6 +297,10 @@ void CNew3D::RenderFrame(void)
|
|||
m_nfPairs[i].zFar = std::numeric_limits<float>::max();
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
m_lineOfSight[i] = 0;
|
||||
}
|
||||
|
||||
// release any resources from last frame
|
||||
m_polyBufferRam.clear(); // clear dyanmic model memory buffer
|
||||
m_nodes.clear(); // memory will grow during the object life time, that's fine, no need to shrink to fit
|
||||
|
@ -351,6 +355,10 @@ void CNew3D::RenderFrame(void)
|
|||
m_r3dFrameBuffers.SetFBO(Layer::colour);
|
||||
hasOverlay = RenderScene(pri, renderOverlay, Layer::colour);
|
||||
|
||||
if (!renderOverlay && ProcessLos(pri)) {
|
||||
ProcessLos(pri);
|
||||
}
|
||||
|
||||
glDepthFunc(GL_LESS); // alpha polys seem to use gl_less (ocean hunter)
|
||||
|
||||
m_r3dShader.DiscardAlpha(false); // render only translucent pixels
|
||||
|
@ -370,7 +378,6 @@ void CNew3D::RenderFrame(void)
|
|||
}
|
||||
|
||||
m_r3dFrameBuffers.DisableFBO(); // draw to back buffer normally
|
||||
|
||||
}
|
||||
|
||||
void CNew3D::BeginFrame(void)
|
||||
|
@ -1010,6 +1017,11 @@ void CNew3D::SetMeshValues(SortingMesh *currentMesh, PolyHeader &ph)
|
|||
bool smoothU = ph.TexSmoothU();
|
||||
bool smoothV = ph.TexSmoothV();
|
||||
|
||||
if (ph.AlphaTest()) {
|
||||
smoothU = false; // smooth wrap makes no sense for alpha tested polys with pixel dilate
|
||||
smoothV = false;
|
||||
}
|
||||
|
||||
if (ph.TexUMirror()) {
|
||||
if (smoothU) currentMesh->wrapModeU = Mesh::TexWrapMode::mirror;
|
||||
else currentMesh->wrapModeU = Mesh::TexWrapMode::mirrorClamp;
|
||||
|
@ -1643,4 +1655,49 @@ void CNew3D::SetSignedShade(bool enable)
|
|||
m_shadeIsSigned = enable;
|
||||
}
|
||||
|
||||
float CNew3D::GetLosValue(int layer)
|
||||
{
|
||||
return m_lineOfSight[layer];
|
||||
}
|
||||
|
||||
void CNew3D::TranslateLosPosition(int inX, int inY, int& outX, int& outY)
|
||||
{
|
||||
// remap real3d 496x384 to our new viewport
|
||||
inY = 384 - inY;
|
||||
|
||||
outX = m_xOffs + int(inX * m_xRatio);
|
||||
outY = m_yOffs + int(inY * m_yRatio);
|
||||
}
|
||||
|
||||
bool CNew3D::ProcessLos(int priority)
|
||||
{
|
||||
for (const auto &n : m_nodes) {
|
||||
if (n.viewport.priority == priority) {
|
||||
if (n.viewport.losPosX || n.viewport.losPosY) {
|
||||
|
||||
int losX, losY;
|
||||
TranslateLosPosition(n.viewport.losPosX, n.viewport.losPosY, losX, losY);
|
||||
|
||||
float depth;
|
||||
glReadPixels(losX, losY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
|
||||
|
||||
if (depth < 0.99f || depth == 1.0f) { // kinda guess work but when depth = 1, haven't drawn anything, when 0.99~ drawing sky somewhere far
|
||||
return false;
|
||||
}
|
||||
|
||||
depth = 2.0f * depth - 1.0f;
|
||||
|
||||
float zNear = m_nfPairs[priority].zNear;
|
||||
float zFar = m_nfPairs[priority].zFar;
|
||||
float zVal = 2.0f * zNear * zFar / (zFar + zNear - depth * (zFar - zNear));
|
||||
|
||||
m_lineOfSight[priority] = zVal;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // New3D
|
||||
|
|
|
@ -163,6 +163,16 @@ public:
|
|||
*/
|
||||
void SetSignedShade(bool enable);
|
||||
|
||||
/*
|
||||
* GetLosValue(int layer);
|
||||
*
|
||||
* Gets the line of sight value for the priority layer
|
||||
*
|
||||
* Parameters:
|
||||
* layer Priority layer to read from
|
||||
*/
|
||||
float GetLosValue(int layer);
|
||||
|
||||
/*
|
||||
* CRender3D(config):
|
||||
* ~CRender3D(void):
|
||||
|
@ -207,6 +217,8 @@ private:
|
|||
bool SkipLayer(int layer);
|
||||
void SetRenderStates();
|
||||
void DisableRenderStates();
|
||||
void TranslateLosPosition(int inX, int inY, int& outX, int& outY);
|
||||
bool ProcessLos(int priority);
|
||||
|
||||
void CalcTexOffset(int offX, int offY, int page, int x, int y, int& newX, int& newY);
|
||||
|
||||
|
@ -250,6 +262,8 @@ private:
|
|||
NodeAttributes m_nodeAttribs;
|
||||
Mat4 m_modelMat; // current modelview matrix
|
||||
|
||||
float m_lineOfSight[4];
|
||||
|
||||
Vertex m_prev[4]; // these are class variables because sega bass fishing starts meshes with shared vertices from the previous one
|
||||
UINT16 m_prevTexCoords[4][2]; // basically relying on undefined behavour
|
||||
|
||||
|
|
|
@ -174,6 +174,11 @@ bool PolyHeader::SmoothShading()
|
|||
return (header[1] & 0x8) > 0;
|
||||
}
|
||||
|
||||
bool PolyHeader::NoLosReturn()
|
||||
{
|
||||
return (header[1] & 0x1) > 0;
|
||||
}
|
||||
|
||||
//
|
||||
// header 2
|
||||
//
|
||||
|
|
|
@ -105,6 +105,7 @@ public:
|
|||
bool PolyColor(); // if false uses LUT from ram
|
||||
bool FixedShading();
|
||||
bool SmoothShading();
|
||||
bool NoLosReturn(); // no line of sight return (still not exactly how sure this attribute is used yet)
|
||||
|
||||
//header 2
|
||||
bool TexUMirror();
|
||||
|
|
|
@ -771,6 +771,20 @@ uint32_t CReal3D::ReadRegister(unsigned reg)
|
|||
return 0xfdffffff | m_pingPong;
|
||||
#endif
|
||||
}
|
||||
|
||||
else if (reg >= 20 && reg<=32) { // line of sight registers
|
||||
|
||||
int index = (reg - 20) / 4;
|
||||
float val = Render3D->GetLosValue(index);
|
||||
|
||||
if (val) {
|
||||
//val = 1.0f / val; // test program indicate z values are 1 over
|
||||
return 0xffffffff; // infinity
|
||||
}
|
||||
|
||||
return *(uint32_t*)(&val);
|
||||
}
|
||||
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue