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:
Ian Curtis 2020-05-11 09:05:46 +00:00
parent e2ad593e88
commit 6f6c98c671
7 changed files with 47 additions and 19 deletions

View file

@ -150,6 +150,7 @@ struct Mesh
bool layered = false; // stencil poly
bool highPriority = false; // rendered over the top
bool transLSelect = false; // actually the transparency layer, false = layer 0, true = layer 1
bool translatorMap = false; // colours are multiplied by 16
// lighting
bool fixedShading = false;

View file

@ -994,6 +994,7 @@ void CNew3D::SetMeshValues(SortingMesh *currentMesh, PolyHeader &ph)
currentMesh->shininess = ph.Shininess();
currentMesh->specularValue = ph.SpecularValue();
currentMesh->fogIntensity = ph.LightModifier();
currentMesh->translatorMap = ph.TranslatorMap();
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);
}
else {
p.faceColour[0] = ((ph.header[4] >> 24));
p.faceColour[1] = ((ph.header[4] >> 16) & 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();

View file

@ -398,16 +398,16 @@ UINT64 PolyHeader::Hash()
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[5] & 0x1F) << 14; // bits 14-18 y offset
hash |= (UINT64)Page() << 19; // bits 19 page
hash |= (UINT64)DoubleSided() << 20; // bits 20 double sided
hash |= (UINT64)AlphaTest() << 21; // bits 21 contour processing
hash |= (UINT64)PolyAlpha() << 22; // bits 22 poly alpha processing
hash |= (UINT64)(header[2] & 0xFF) << 23; // bits 23-30 microtexture / uv mirror
hash |= (UINT64)SpecularEnabled() << 31; // bits 31 enable specular reflection
hash |= (UINT64)SmoothShading() << 32; // bits 32 smooth shading
hash |= (UINT64)FixedShading() << 33; // bits 33 fixed shading
hash |= (UINT64)(header[0] >> 26) << 34; // bits 34-39 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[4] & 0xC0) >> 6) << 19; // bits 19-20 page / translatormap
hash |= (UINT64)DoubleSided() << 21; // bits 21 double sided
hash |= (UINT64)AlphaTest() << 22; // bits 22 contour processing
hash |= (UINT64)PolyAlpha() << 23; // bits 23 poly alpha processing
hash |= (UINT64)(header[2] & 0xFF) << 24; // bits 24-31 microtexture / uv mirror
hash |= (UINT64)SpecularEnabled() << 32; // bits 32 enable specular reflection
hash |= (UINT64)SmoothShading() << 33; // bits 33 smooth shading
hash |= (UINT64)FixedShading() << 34; // bits 34 fixed shading
hash |= (UINT64)(header[0] >> 26) << 35; // bits 35-40 specular coefficient (opacity)
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;
}

View file

@ -29,6 +29,7 @@ void R3DShader::Start()
m_layered = false;
m_textureInverted = false;
m_fixedShading = false;
m_translatorMap = false;
m_modelScale = 1.0f;
m_shininess = 0;
m_specularValue = 0;
@ -111,6 +112,7 @@ bool R3DShader::LoadShader(const char* vertexShader, const char* fragmentShader)
m_locSpecularValue = glGetUniformLocation(m_shaderProgram, "specularValue");
m_locSpecularEnabled = glGetUniformLocation(m_shaderProgram, "specularEnabled");
m_locFixedShading = glGetUniformLocation(m_shaderProgram, "fixedShading");
m_locTranslatorMap = glGetUniformLocation(m_shaderProgram, "translatorMap");
m_locSpotEllipse = glGetUniformLocation(m_shaderProgram, "spotEllipse");
m_locSpotRange = glGetUniformLocation(m_shaderProgram, "spotRange");
@ -226,6 +228,11 @@ void R3DShader::SetMeshUniforms(const Mesh* m)
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]) {
m_texWrapMode[0] = m->wrapModeU;
m_texWrapMode[1] = m->wrapModeV;

View file

@ -48,6 +48,7 @@ private:
GLint m_locBaseTexSize;
GLint m_locTextureInverted;
GLint m_locTexWrapMode;
GLint m_locTranslatorMap;
// cached mesh values
bool m_textured1;
@ -60,6 +61,7 @@ private:
float m_specularValue;
bool m_specularEnabled;
bool m_fixedShading;
bool m_translatorMap;
bool m_layered;
float m_microTexScale;

View file

@ -9,6 +9,7 @@ static const char *vertexShaderR3DQuads = R"glsl(
uniform float modelScale;
uniform mat4 modelMat;
uniform mat4 projMat;
uniform bool translatorMap;
// attributes
in vec4 inVertex;
@ -30,6 +31,17 @@ out VS_OUT
float discardPoly; // can't have varying bool (glsl spec)
} vs_out;
vec4 GetColour(vec4 colour)
{
vec4 c = colour;
if(translatorMap) {
c.rgb *= 16.0;
}
return c;
}
float CalcBackFace(in vec3 viewVertex)
{
vec3 vt = viewVertex - vec3(0.0);
@ -44,7 +56,7 @@ void main(void)
vs_out.viewVertex = vec3(modelMat * inVertex);
vs_out.viewNormal = (mat3(modelMat) * inNormal) / modelScale;
vs_out.discardPoly = CalcBackFace(vs_out.viewVertex);
vs_out.color = inColour;
vs_out.color = GetColour(inColour);
vs_out.texCoord = inTexCoord;
vs_out.fixedShade = inFixedShade;
gl_Position = projMat * modelMat * inVertex;

View file

@ -9,6 +9,7 @@ static const char *vertexShaderR3D = R"glsl(
uniform float modelScale;
uniform mat4 modelMat;
uniform mat4 projMat;
uniform bool translatorMap;
// attributes
attribute vec4 inVertex;
@ -26,6 +27,17 @@ varying vec4 fsColor;
varying float fsDiscard; // can't have varying bool (glsl spec)
varying float fsFixedShade;
vec4 GetColour(vec4 colour)
{
vec4 c = colour;
if(translatorMap) {
c.rgb *= 16.0;
}
return c;
}
float CalcBackFace(in vec3 viewVertex)
{
vec3 vt = viewVertex - vec3(0.0);
@ -40,7 +52,7 @@ void main(void)
fsViewVertex = vec3(modelMat * inVertex);
fsViewNormal = (mat3(modelMat) * inNormal) / modelScale;
fsDiscard = CalcBackFace(fsViewVertex);
fsColor = inColour;
fsColor = GetColour(inColour);
fsTexCoord = inTexCoord;
fsFixedShade = inFixedShade;
gl_Position = projMat * modelMat * inVertex;