mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2024-11-22 13:55:38 +00:00
The translator map seems to work with paletted colour values too, and the result is not clamped. Colours are passed to the GPU as unsigned bytes to multiplying by 16 will overflow, so we do the logic in the shader. If we passed floats we could skip the shader logic.
This commit is contained in:
parent
e2ad593e88
commit
6f6c98c671
|
@ -150,6 +150,7 @@ struct Mesh
|
||||||
bool layered = false; // stencil poly
|
bool layered = false; // stencil poly
|
||||||
bool highPriority = false; // rendered over the top
|
bool highPriority = false; // rendered over the top
|
||||||
bool transLSelect = false; // actually the transparency layer, false = layer 0, true = layer 1
|
bool transLSelect = false; // actually the transparency layer, false = layer 0, true = layer 1
|
||||||
|
bool translatorMap = false; // colours are multiplied by 16
|
||||||
|
|
||||||
// lighting
|
// lighting
|
||||||
bool fixedShading = false;
|
bool fixedShading = false;
|
||||||
|
|
|
@ -994,6 +994,7 @@ void CNew3D::SetMeshValues(SortingMesh *currentMesh, PolyHeader &ph)
|
||||||
currentMesh->shininess = ph.Shininess();
|
currentMesh->shininess = ph.Shininess();
|
||||||
currentMesh->specularValue = ph.SpecularValue();
|
currentMesh->specularValue = ph.SpecularValue();
|
||||||
currentMesh->fogIntensity = ph.LightModifier();
|
currentMesh->fogIntensity = ph.LightModifier();
|
||||||
|
currentMesh->translatorMap = ph.TranslatorMap();
|
||||||
|
|
||||||
if (currentMesh->textured) {
|
if (currentMesh->textured) {
|
||||||
|
|
||||||
|
@ -1135,16 +1136,9 @@ void CNew3D::CacheModel(Model *m, const UINT32 *data)
|
||||||
p.faceColour[0] = ((m_polyRAM[m_colorTableAddr + colorIdx] >> 16) & 0xFF);
|
p.faceColour[0] = ((m_polyRAM[m_colorTableAddr + colorIdx] >> 16) & 0xFF);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
p.faceColour[0] = ((ph.header[4] >> 24));
|
p.faceColour[0] = ((ph.header[4] >> 24));
|
||||||
p.faceColour[1] = ((ph.header[4] >> 16) & 0xFF);
|
p.faceColour[1] = ((ph.header[4] >> 16) & 0xFF);
|
||||||
p.faceColour[2] = ((ph.header[4] >> 8) & 0xFF);
|
p.faceColour[2] = ((ph.header[4] >> 8) & 0xFF);
|
||||||
|
|
||||||
if (ph.TranslatorMap()) {
|
|
||||||
p.faceColour[0] = std::min((p.faceColour[0] * 255) / 16, 255); // When the translator map is enabled, max colour seems to be 16. Why not 4 bits?
|
|
||||||
p.faceColour[1] = std::min((p.faceColour[1] * 255) / 16, 255); // We clamp the result because virtua on will overflow for only the smoke effects
|
|
||||||
p.faceColour[2] = std::min((p.faceColour[2] * 255) / 16, 255); // It's passing 33 instead of a max of 16.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
p.faceColour[3] = ph.Transparency();
|
p.faceColour[3] = ph.Transparency();
|
||||||
|
|
|
@ -398,16 +398,16 @@ UINT64 PolyHeader::Hash()
|
||||||
hash |= (UINT64)(header[3] & 0xFF); // bits 0-7 tex width / height / uv smooth
|
hash |= (UINT64)(header[3] & 0xFF); // bits 0-7 tex width / height / uv smooth
|
||||||
hash |= (UINT64)(((header[4] & 0x1F) << 1) | ((header[5] >> 7) & 1)) << 8; // bits 8-13 x offset
|
hash |= (UINT64)(((header[4] & 0x1F) << 1) | ((header[5] >> 7) & 1)) << 8; // bits 8-13 x offset
|
||||||
hash |= (UINT64)(header[5] & 0x1F) << 14; // bits 14-18 y offset
|
hash |= (UINT64)(header[5] & 0x1F) << 14; // bits 14-18 y offset
|
||||||
hash |= (UINT64)Page() << 19; // bits 19 page
|
hash |= (UINT64)((header[4] & 0xC0) >> 6) << 19; // bits 19-20 page / translatormap
|
||||||
hash |= (UINT64)DoubleSided() << 20; // bits 20 double sided
|
hash |= (UINT64)DoubleSided() << 21; // bits 21 double sided
|
||||||
hash |= (UINT64)AlphaTest() << 21; // bits 21 contour processing
|
hash |= (UINT64)AlphaTest() << 22; // bits 22 contour processing
|
||||||
hash |= (UINT64)PolyAlpha() << 22; // bits 22 poly alpha processing
|
hash |= (UINT64)PolyAlpha() << 23; // bits 23 poly alpha processing
|
||||||
hash |= (UINT64)(header[2] & 0xFF) << 23; // bits 23-30 microtexture / uv mirror
|
hash |= (UINT64)(header[2] & 0xFF) << 24; // bits 24-31 microtexture / uv mirror
|
||||||
hash |= (UINT64)SpecularEnabled() << 31; // bits 31 enable specular reflection
|
hash |= (UINT64)SpecularEnabled() << 32; // bits 32 enable specular reflection
|
||||||
hash |= (UINT64)SmoothShading() << 32; // bits 32 smooth shading
|
hash |= (UINT64)SmoothShading() << 33; // bits 33 smooth shading
|
||||||
hash |= (UINT64)FixedShading() << 33; // bits 33 fixed shading
|
hash |= (UINT64)FixedShading() << 34; // bits 34 fixed shading
|
||||||
hash |= (UINT64)(header[0] >> 26) << 34; // bits 34-39 specular coefficient (opacity)
|
hash |= (UINT64)(header[0] >> 26) << 35; // bits 35-40 specular coefficient (opacity)
|
||||||
hash |= (UINT64)(header[6] & 0x3FFFF) << 40; // bits 40-57 Translucency pattern select / disable lighting / Polygon light modifier / Texture enable / Texture format / Shininess / High priority / Layered polygon / Translucency mode
|
hash |= (UINT64)(header[6] & 0x3FFFF) << 41; // bits 41-58 Translucency pattern select / disable lighting / Polygon light modifier / Texture enable / Texture format / Shininess / High priority / Layered polygon / Translucency mode
|
||||||
|
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ void R3DShader::Start()
|
||||||
m_layered = false;
|
m_layered = false;
|
||||||
m_textureInverted = false;
|
m_textureInverted = false;
|
||||||
m_fixedShading = false;
|
m_fixedShading = false;
|
||||||
|
m_translatorMap = false;
|
||||||
m_modelScale = 1.0f;
|
m_modelScale = 1.0f;
|
||||||
m_shininess = 0;
|
m_shininess = 0;
|
||||||
m_specularValue = 0;
|
m_specularValue = 0;
|
||||||
|
@ -111,6 +112,7 @@ bool R3DShader::LoadShader(const char* vertexShader, const char* fragmentShader)
|
||||||
m_locSpecularValue = glGetUniformLocation(m_shaderProgram, "specularValue");
|
m_locSpecularValue = glGetUniformLocation(m_shaderProgram, "specularValue");
|
||||||
m_locSpecularEnabled = glGetUniformLocation(m_shaderProgram, "specularEnabled");
|
m_locSpecularEnabled = glGetUniformLocation(m_shaderProgram, "specularEnabled");
|
||||||
m_locFixedShading = glGetUniformLocation(m_shaderProgram, "fixedShading");
|
m_locFixedShading = glGetUniformLocation(m_shaderProgram, "fixedShading");
|
||||||
|
m_locTranslatorMap = glGetUniformLocation(m_shaderProgram, "translatorMap");
|
||||||
|
|
||||||
m_locSpotEllipse = glGetUniformLocation(m_shaderProgram, "spotEllipse");
|
m_locSpotEllipse = glGetUniformLocation(m_shaderProgram, "spotEllipse");
|
||||||
m_locSpotRange = glGetUniformLocation(m_shaderProgram, "spotRange");
|
m_locSpotRange = glGetUniformLocation(m_shaderProgram, "spotRange");
|
||||||
|
@ -226,6 +228,11 @@ void R3DShader::SetMeshUniforms(const Mesh* m)
|
||||||
m_fixedShading = m->fixedShading;
|
m_fixedShading = m->fixedShading;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_dirtyMesh || m->translatorMap != m_translatorMap) {
|
||||||
|
glUniform1i(m_locTranslatorMap, m->translatorMap);
|
||||||
|
m_translatorMap = m->translatorMap;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_dirtyMesh || m->wrapModeU != m_texWrapMode[0] || m->wrapModeV != m_texWrapMode[1]) {
|
if (m_dirtyMesh || m->wrapModeU != m_texWrapMode[0] || m->wrapModeV != m_texWrapMode[1]) {
|
||||||
m_texWrapMode[0] = m->wrapModeU;
|
m_texWrapMode[0] = m->wrapModeU;
|
||||||
m_texWrapMode[1] = m->wrapModeV;
|
m_texWrapMode[1] = m->wrapModeV;
|
||||||
|
|
|
@ -48,6 +48,7 @@ private:
|
||||||
GLint m_locBaseTexSize;
|
GLint m_locBaseTexSize;
|
||||||
GLint m_locTextureInverted;
|
GLint m_locTextureInverted;
|
||||||
GLint m_locTexWrapMode;
|
GLint m_locTexWrapMode;
|
||||||
|
GLint m_locTranslatorMap;
|
||||||
|
|
||||||
// cached mesh values
|
// cached mesh values
|
||||||
bool m_textured1;
|
bool m_textured1;
|
||||||
|
@ -60,6 +61,7 @@ private:
|
||||||
float m_specularValue;
|
float m_specularValue;
|
||||||
bool m_specularEnabled;
|
bool m_specularEnabled;
|
||||||
bool m_fixedShading;
|
bool m_fixedShading;
|
||||||
|
bool m_translatorMap;
|
||||||
|
|
||||||
bool m_layered;
|
bool m_layered;
|
||||||
float m_microTexScale;
|
float m_microTexScale;
|
||||||
|
|
|
@ -9,6 +9,7 @@ static const char *vertexShaderR3DQuads = R"glsl(
|
||||||
uniform float modelScale;
|
uniform float modelScale;
|
||||||
uniform mat4 modelMat;
|
uniform mat4 modelMat;
|
||||||
uniform mat4 projMat;
|
uniform mat4 projMat;
|
||||||
|
uniform bool translatorMap;
|
||||||
|
|
||||||
// attributes
|
// attributes
|
||||||
in vec4 inVertex;
|
in vec4 inVertex;
|
||||||
|
@ -30,6 +31,17 @@ out VS_OUT
|
||||||
float discardPoly; // can't have varying bool (glsl spec)
|
float discardPoly; // can't have varying bool (glsl spec)
|
||||||
} vs_out;
|
} vs_out;
|
||||||
|
|
||||||
|
vec4 GetColour(vec4 colour)
|
||||||
|
{
|
||||||
|
vec4 c = colour;
|
||||||
|
|
||||||
|
if(translatorMap) {
|
||||||
|
c.rgb *= 16.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
float CalcBackFace(in vec3 viewVertex)
|
float CalcBackFace(in vec3 viewVertex)
|
||||||
{
|
{
|
||||||
vec3 vt = viewVertex - vec3(0.0);
|
vec3 vt = viewVertex - vec3(0.0);
|
||||||
|
@ -44,7 +56,7 @@ void main(void)
|
||||||
vs_out.viewVertex = vec3(modelMat * inVertex);
|
vs_out.viewVertex = vec3(modelMat * inVertex);
|
||||||
vs_out.viewNormal = (mat3(modelMat) * inNormal) / modelScale;
|
vs_out.viewNormal = (mat3(modelMat) * inNormal) / modelScale;
|
||||||
vs_out.discardPoly = CalcBackFace(vs_out.viewVertex);
|
vs_out.discardPoly = CalcBackFace(vs_out.viewVertex);
|
||||||
vs_out.color = inColour;
|
vs_out.color = GetColour(inColour);
|
||||||
vs_out.texCoord = inTexCoord;
|
vs_out.texCoord = inTexCoord;
|
||||||
vs_out.fixedShade = inFixedShade;
|
vs_out.fixedShade = inFixedShade;
|
||||||
gl_Position = projMat * modelMat * inVertex;
|
gl_Position = projMat * modelMat * inVertex;
|
||||||
|
|
|
@ -9,6 +9,7 @@ static const char *vertexShaderR3D = R"glsl(
|
||||||
uniform float modelScale;
|
uniform float modelScale;
|
||||||
uniform mat4 modelMat;
|
uniform mat4 modelMat;
|
||||||
uniform mat4 projMat;
|
uniform mat4 projMat;
|
||||||
|
uniform bool translatorMap;
|
||||||
|
|
||||||
// attributes
|
// attributes
|
||||||
attribute vec4 inVertex;
|
attribute vec4 inVertex;
|
||||||
|
@ -26,6 +27,17 @@ varying vec4 fsColor;
|
||||||
varying float fsDiscard; // can't have varying bool (glsl spec)
|
varying float fsDiscard; // can't have varying bool (glsl spec)
|
||||||
varying float fsFixedShade;
|
varying float fsFixedShade;
|
||||||
|
|
||||||
|
vec4 GetColour(vec4 colour)
|
||||||
|
{
|
||||||
|
vec4 c = colour;
|
||||||
|
|
||||||
|
if(translatorMap) {
|
||||||
|
c.rgb *= 16.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
float CalcBackFace(in vec3 viewVertex)
|
float CalcBackFace(in vec3 viewVertex)
|
||||||
{
|
{
|
||||||
vec3 vt = viewVertex - vec3(0.0);
|
vec3 vt = viewVertex - vec3(0.0);
|
||||||
|
@ -40,7 +52,7 @@ void main(void)
|
||||||
fsViewVertex = vec3(modelMat * inVertex);
|
fsViewVertex = vec3(modelMat * inVertex);
|
||||||
fsViewNormal = (mat3(modelMat) * inNormal) / modelScale;
|
fsViewNormal = (mat3(modelMat) * inNormal) / modelScale;
|
||||||
fsDiscard = CalcBackFace(fsViewVertex);
|
fsDiscard = CalcBackFace(fsViewVertex);
|
||||||
fsColor = inColour;
|
fsColor = GetColour(inColour);
|
||||||
fsTexCoord = inTexCoord;
|
fsTexCoord = inTexCoord;
|
||||||
fsFixedShade = inFixedShade;
|
fsFixedShade = inFixedShade;
|
||||||
gl_Position = projMat * modelMat * inVertex;
|
gl_Position = projMat * modelMat * inVertex;
|
||||||
|
|
Loading…
Reference in a new issue