mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2025-04-10 19:15:14 +00:00
We were force normalising the result of matrix * normal, which looked correct in most cases. But this didn't preserve the scaling of the matrix, or the scaling of the model normals which resulted in many over bright areas. On it's own this generally worked, but games like Star Wars looked quite broken. Harry correctly figured out if you scale these normals by the scaling value that is sometimes present in the culling nodes the lighting looks correct. Still more work to do to correctly figure out the model3's lighting model.
This commit is contained in:
parent
a9b49c1676
commit
9aa3f13777
|
@ -8,6 +8,7 @@ NodeAttributes::NodeAttributes()
|
||||||
currentTexOffsetY = 0;
|
currentTexOffsetY = 0;
|
||||||
currentPage = 0;
|
currentPage = 0;
|
||||||
currentClipStatus = Clip::INTERCEPT;
|
currentClipStatus = Clip::INTERCEPT;
|
||||||
|
currentModelScale = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NodeAttributes::Push()
|
bool NodeAttributes::Push()
|
||||||
|
@ -25,8 +26,9 @@ bool NodeAttributes::Push()
|
||||||
na.texOffsetX = currentTexOffsetX;
|
na.texOffsetX = currentTexOffsetX;
|
||||||
na.texOffsetY = currentTexOffsetY;
|
na.texOffsetY = currentTexOffsetY;
|
||||||
na.clip = currentClipStatus;
|
na.clip = currentClipStatus;
|
||||||
|
na.modelScale = currentModelScale;
|
||||||
|
|
||||||
m_vecAttribs.push_back(na);
|
m_vecAttribs.emplace_back(na);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -37,12 +39,13 @@ bool NodeAttributes::Pop()
|
||||||
return false; // check for underflow
|
return false; // check for underflow
|
||||||
}
|
}
|
||||||
|
|
||||||
auto last = &m_vecAttribs.back();
|
auto &last = m_vecAttribs.back();
|
||||||
|
|
||||||
currentPage = last->page;
|
currentPage = last.page;
|
||||||
currentTexOffsetX = last->texOffsetX;
|
currentTexOffsetX = last.texOffsetX;
|
||||||
currentTexOffsetY = last->texOffsetY;
|
currentTexOffsetY = last.texOffsetY;
|
||||||
currentClipStatus = last->clip;
|
currentClipStatus = last.clip;
|
||||||
|
currentModelScale = last.modelScale;
|
||||||
|
|
||||||
m_vecAttribs.pop_back();
|
m_vecAttribs.pop_back();
|
||||||
|
|
||||||
|
@ -60,6 +63,7 @@ void NodeAttributes::Reset()
|
||||||
currentTexOffsetX = 0;
|
currentTexOffsetX = 0;
|
||||||
currentTexOffsetY = 0;
|
currentTexOffsetY = 0;
|
||||||
currentClipStatus = Clip::INTERCEPT;
|
currentClipStatus = Clip::INTERCEPT;
|
||||||
|
currentModelScale = 1.0f;
|
||||||
|
|
||||||
m_vecAttribs.clear();
|
m_vecAttribs.clear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,6 +118,9 @@ struct Model
|
||||||
//matrices
|
//matrices
|
||||||
float modelMat[16];
|
float modelMat[16];
|
||||||
float determinant; // we check if the determinant of the matrix is negative, if it is, the matrix will swap the axis order
|
float determinant; // we check if the determinant of the matrix is negative, if it is, the matrix will swap the axis order
|
||||||
|
|
||||||
|
//model scale step 1.5+
|
||||||
|
float scale = 1.0f;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Viewport
|
struct Viewport
|
||||||
|
@ -166,6 +169,7 @@ public:
|
||||||
int currentTexOffsetY;
|
int currentTexOffsetY;
|
||||||
int currentPage;
|
int currentPage;
|
||||||
Clip currentClipStatus;
|
Clip currentClipStatus;
|
||||||
|
float currentModelScale;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -175,6 +179,7 @@ private:
|
||||||
int texOffsetY;
|
int texOffsetY;
|
||||||
int page;
|
int page;
|
||||||
Clip clip;
|
Clip clip;
|
||||||
|
float modelScale;
|
||||||
};
|
};
|
||||||
std::vector<NodeAttribs> m_vecAttribs;
|
std::vector<NodeAttribs> m_vecAttribs;
|
||||||
};
|
};
|
||||||
|
|
|
@ -409,6 +409,7 @@ bool CNew3D::DrawModel(UINT32 modelAddr)
|
||||||
m->textureOffsetX = m_nodeAttribs.currentTexOffsetX;
|
m->textureOffsetX = m_nodeAttribs.currentTexOffsetX;
|
||||||
m->textureOffsetY = m_nodeAttribs.currentTexOffsetY;
|
m->textureOffsetY = m_nodeAttribs.currentTexOffsetY;
|
||||||
m->page = m_nodeAttribs.currentPage;
|
m->page = m_nodeAttribs.currentPage;
|
||||||
|
m->scale = m_nodeAttribs.currentModelScale;
|
||||||
|
|
||||||
if (!cached) {
|
if (!cached) {
|
||||||
CacheModel(m, modelAddress);
|
CacheModel(m, modelAddress);
|
||||||
|
@ -463,6 +464,12 @@ void CNew3D::DescendCullingNode(UINT32 addr)
|
||||||
m_nodeAttribs.Push(); // save current attribs
|
m_nodeAttribs.Push(); // save current attribs
|
||||||
|
|
||||||
if (!m_offset) { // Step 1.5+
|
if (!m_offset) { // Step 1.5+
|
||||||
|
|
||||||
|
float modelScale = *(float *)&node[1];
|
||||||
|
if (modelScale) {
|
||||||
|
m_nodeAttribs.currentModelScale = modelScale;
|
||||||
|
}
|
||||||
|
|
||||||
// apply texture offsets, else retain current ones
|
// apply texture offsets, else retain current ones
|
||||||
if ((node[0x02] & 0x8000)) {
|
if ((node[0x02] & 0x8000)) {
|
||||||
int tx = 32 * ((node[0x02] >> 7) & 0x3F);
|
int tx = 32 * ((node[0x02] >> 7) & 0x3F);
|
||||||
|
@ -477,7 +484,7 @@ void CNew3D::DescendCullingNode(UINT32 addr)
|
||||||
m_modelMat.PushMatrix();
|
m_modelMat.PushMatrix();
|
||||||
|
|
||||||
// apply translation vector
|
// apply translation vector
|
||||||
if ((node[0x00] & 0x10)) {
|
if (node[0x00] & 0x10) {
|
||||||
float x = *(float *)&node[0x04 - m_offset];
|
float x = *(float *)&node[0x04 - m_offset];
|
||||||
float y = *(float *)&node[0x05 - m_offset];
|
float y = *(float *)&node[0x05 - m_offset];
|
||||||
float z = *(float *)&node[0x06 - m_offset];
|
float z = *(float *)&node[0x06 - m_offset];
|
||||||
|
|
|
@ -9,6 +9,7 @@ static const char *vertexShaderR3D = R"glsl(
|
||||||
uniform float fogIntensity;
|
uniform float fogIntensity;
|
||||||
uniform float fogDensity;
|
uniform float fogDensity;
|
||||||
uniform float fogStart;
|
uniform float fogStart;
|
||||||
|
uniform float modelScale;
|
||||||
|
|
||||||
//outputs to fragment shader
|
//outputs to fragment shader
|
||||||
varying float fsFogFactor;
|
varying float fsFogFactor;
|
||||||
|
@ -19,7 +20,7 @@ varying vec4 fsColor;
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
fsViewVertex = vec3(gl_ModelViewMatrix * gl_Vertex);
|
fsViewVertex = vec3(gl_ModelViewMatrix * gl_Vertex);
|
||||||
fsViewNormal = normalize(gl_NormalMatrix * gl_Normal);
|
fsViewNormal = (mat3(gl_ModelViewMatrix) * gl_Normal) / modelScale;
|
||||||
float z = length(fsViewVertex);
|
float z = length(fsViewVertex);
|
||||||
fsFogFactor = fogIntensity * clamp(fogStart + z * fogDensity, 0.0, 1.0);
|
fsFogFactor = fogIntensity * clamp(fogStart + z * fogDensity, 0.0, 1.0);
|
||||||
|
|
||||||
|
@ -193,6 +194,7 @@ void R3DShader::Start()
|
||||||
m_lightEnabled = false;
|
m_lightEnabled = false;
|
||||||
m_layered = false;
|
m_layered = false;
|
||||||
m_textureInverted = false;
|
m_textureInverted = false;
|
||||||
|
m_modelScale = 1.0f;
|
||||||
|
|
||||||
m_baseTexSize[0] = 0;
|
m_baseTexSize[0] = 0;
|
||||||
m_baseTexSize[1] = 0;
|
m_baseTexSize[1] = 0;
|
||||||
|
@ -255,6 +257,7 @@ bool R3DShader::LoadShader(const char* vertexShader, const char* fragmentShader)
|
||||||
m_locSpotRange = glGetUniformLocation(m_shaderProgram, "spotRange");
|
m_locSpotRange = glGetUniformLocation(m_shaderProgram, "spotRange");
|
||||||
m_locSpotColor = glGetUniformLocation(m_shaderProgram, "spotColor");
|
m_locSpotColor = glGetUniformLocation(m_shaderProgram, "spotColor");
|
||||||
m_locSpotFogColor = glGetUniformLocation(m_shaderProgram, "spotFogColor");
|
m_locSpotFogColor = glGetUniformLocation(m_shaderProgram, "spotFogColor");
|
||||||
|
m_locModelScale = glGetUniformLocation(m_shaderProgram, "modelScale");
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
@ -414,6 +417,11 @@ void R3DShader::SetModelStates(const Model* model)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_dirtyModel || model->scale != m_modelScale) {
|
||||||
|
glUniform1f(m_locModelScale, model->scale);
|
||||||
|
m_modelScale = model->scale;
|
||||||
|
}
|
||||||
|
|
||||||
m_matDet = test;
|
m_matDet = test;
|
||||||
m_dirtyModel = false;
|
m_dirtyModel = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,7 @@ private:
|
||||||
// cached model values
|
// cached model values
|
||||||
enum class MatDet { notset, negative, positive, zero };
|
enum class MatDet { notset, negative, positive, zero };
|
||||||
MatDet m_matDet;
|
MatDet m_matDet;
|
||||||
|
float m_modelScale;
|
||||||
|
|
||||||
// are our cache values dirty
|
// are our cache values dirty
|
||||||
bool m_dirtyMesh;
|
bool m_dirtyMesh;
|
||||||
|
@ -67,7 +68,7 @@ private:
|
||||||
GLint m_locFogAttenuation;
|
GLint m_locFogAttenuation;
|
||||||
GLint m_locFogAmbient;
|
GLint m_locFogAmbient;
|
||||||
|
|
||||||
// lighting
|
// lighting / other
|
||||||
GLint m_locLighting;
|
GLint m_locLighting;
|
||||||
GLint m_locLightEnable;
|
GLint m_locLightEnable;
|
||||||
GLint m_locLightClamp;
|
GLint m_locLightClamp;
|
||||||
|
@ -77,6 +78,9 @@ private:
|
||||||
GLint m_locSpotRange;
|
GLint m_locSpotRange;
|
||||||
GLint m_locSpotColor;
|
GLint m_locSpotColor;
|
||||||
GLint m_locSpotFogColor;
|
GLint m_locSpotFogColor;
|
||||||
|
|
||||||
|
// model uniforms
|
||||||
|
GLint m_locModelScale;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // New3D
|
} // New3D
|
||||||
|
|
Loading…
Reference in a new issue