mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2025-04-10 19:15:14 +00:00
Legacy renderer changes:
- Updated shading model. Unfortunately, it is far from perfect but it seems to be the best I can do for now. Not really much of a difference from before except that the Scud Race castle is fixed at the expense of the Yosemite level in LA Machineguns being too bright. - Added lots of notes in the shading code. - Passing both specular coefficient and shininess to shader. This will probably break specular lighting for now until the shader is updated to use the shininess correctly. - Color table address in polygon RAM is now obtained from culling nodes as they are traversed (found this in the Pro-1000 SDK).
This commit is contained in:
parent
147faf37c9
commit
897b1acb21
|
@ -661,6 +661,13 @@ void CLegacy3D::DescendCullingNode(UINT32 addr)
|
||||||
--stackDepth;
|
--stackDepth;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set color table address, if one is specified
|
||||||
|
if ((node[0x00] & 0x04))
|
||||||
|
{
|
||||||
|
m_colorTableAddr = ((node[0x03-offset] >> 19) << 0) | ((node[0x07-offset] >> 28) << 13) | ((node[0x08-offset] >> 25) << 17);
|
||||||
|
m_colorTableAddr &= 0x000FFFFF; // clamp to 4MB (in words) range
|
||||||
|
}
|
||||||
|
|
||||||
//printf("%08x NODE %d\n", addr, stackDepth);
|
//printf("%08x NODE %d\n", addr, stackDepth);
|
||||||
//for (int i = 0; i < 8; i++)
|
//for (int i = 0; i < 8; i++)
|
||||||
|
@ -990,6 +997,7 @@ void CLegacy3D::RenderFrame(void)
|
||||||
if (texMapLoc != -1) glEnableVertexAttribArray(texMapLoc);
|
if (texMapLoc != -1) glEnableVertexAttribArray(texMapLoc);
|
||||||
if (transLevelLoc != -1) glEnableVertexAttribArray(transLevelLoc);
|
if (transLevelLoc != -1) glEnableVertexAttribArray(transLevelLoc);
|
||||||
if (lightEnableLoc != -1) glEnableVertexAttribArray(lightEnableLoc);
|
if (lightEnableLoc != -1) glEnableVertexAttribArray(lightEnableLoc);
|
||||||
|
if (specularLoc != -1) glEnableVertexAttribArray(specularLoc);
|
||||||
if (shininessLoc != -1) glEnableVertexAttribArray(shininessLoc);
|
if (shininessLoc != -1) glEnableVertexAttribArray(shininessLoc);
|
||||||
if (fogIntensityLoc != -1) glEnableVertexAttribArray(fogIntensityLoc);
|
if (fogIntensityLoc != -1) glEnableVertexAttribArray(fogIntensityLoc);
|
||||||
|
|
||||||
|
@ -1016,6 +1024,7 @@ void CLegacy3D::RenderFrame(void)
|
||||||
// Disable VBO client states
|
// Disable VBO client states
|
||||||
if (fogIntensityLoc != -1) glDisableVertexAttribArray(fogIntensityLoc);
|
if (fogIntensityLoc != -1) glDisableVertexAttribArray(fogIntensityLoc);
|
||||||
if (shininessLoc != -1) glDisableVertexAttribArray(shininessLoc);
|
if (shininessLoc != -1) glDisableVertexAttribArray(shininessLoc);
|
||||||
|
if (specularLoc != -1) glDisableVertexAttribArray(specularLoc);
|
||||||
if (lightEnableLoc != -1) glDisableVertexAttribArray(lightEnableLoc);
|
if (lightEnableLoc != -1) glDisableVertexAttribArray(lightEnableLoc);
|
||||||
if (transLevelLoc != -1) glDisableVertexAttribArray(transLevelLoc);
|
if (transLevelLoc != -1) glDisableVertexAttribArray(transLevelLoc);
|
||||||
if (texMapLoc != -1) glDisableVertexAttribArray(texMapLoc);
|
if (texMapLoc != -1) glDisableVertexAttribArray(texMapLoc);
|
||||||
|
@ -1261,6 +1270,7 @@ bool CLegacy3D::Init(unsigned xOffset, unsigned yOffset, unsigned xRes, unsigned
|
||||||
texMapLoc = glGetAttribLocation(shaderProgram,"texMap");
|
texMapLoc = glGetAttribLocation(shaderProgram,"texMap");
|
||||||
transLevelLoc = glGetAttribLocation(shaderProgram,"transLevel");
|
transLevelLoc = glGetAttribLocation(shaderProgram,"transLevel");
|
||||||
lightEnableLoc = glGetAttribLocation(shaderProgram,"lightEnable");
|
lightEnableLoc = glGetAttribLocation(shaderProgram,"lightEnable");
|
||||||
|
specularLoc = glGetAttribLocation(shaderProgram,"specular");
|
||||||
shininessLoc = glGetAttribLocation(shaderProgram,"shininess");
|
shininessLoc = glGetAttribLocation(shaderProgram,"shininess");
|
||||||
fogIntensityLoc = glGetAttribLocation(shaderProgram,"fogIntensity");
|
fogIntensityLoc = glGetAttribLocation(shaderProgram,"fogIntensity");
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,7 @@ struct Vertex
|
||||||
struct Poly
|
struct Poly
|
||||||
{
|
{
|
||||||
Vertex Vert[4];
|
Vertex Vert[4];
|
||||||
GLfloat n[3]; // polygon normal (used for backface culling)
|
GLfloat n[3]; // polygon normal (used for backface culling and flat shading)
|
||||||
POLY_STATE state; // alpha or normal?
|
POLY_STATE state; // alpha or normal?
|
||||||
unsigned numVerts; // triangle (3) or quad (4)
|
unsigned numVerts; // triangle (3) or quad (4)
|
||||||
const UINT32 *header; // pointer to Real3D 7-word polygon header
|
const UINT32 *header; // pointer to Real3D 7-word polygon header
|
||||||
|
@ -425,13 +425,12 @@ private:
|
||||||
GLint viewportX, viewportY;
|
GLint viewportX, viewportY;
|
||||||
GLint viewportWidth, viewportHeight;
|
GLint viewportWidth, viewportHeight;
|
||||||
|
|
||||||
// Scene graph stack
|
// Scene graph processing
|
||||||
int listDepth; // how many lists have we recursed into
|
int listDepth; // how many lists have we recursed into
|
||||||
int stackDepth; // for debugging and error handling purposes
|
int stackDepth; // for debugging and error handling purposes
|
||||||
|
GLfloat texOffsetXY[2]; // decoded texture X, Y offsets
|
||||||
// Texture offset (during scene graph processing)
|
UINT16 texOffset; // raw texture offset data as it appears in culling node
|
||||||
GLfloat texOffsetXY[2]; // decoded X, Y offsets
|
UINT32 m_colorTableAddr = 0x400; // address of color table in polygon RAM
|
||||||
UINT16 texOffset; // raw texture offset data as it appears in culling node
|
|
||||||
|
|
||||||
// Resolution and scaling factors (to support resolutions higher than 496x384) and offsets
|
// Resolution and scaling factors (to support resolutions higher than 496x384) and offsets
|
||||||
GLfloat xRatio, yRatio;
|
GLfloat xRatio, yRatio;
|
||||||
|
@ -465,6 +464,7 @@ private:
|
||||||
GLint texMapLoc; // attribute
|
GLint texMapLoc; // attribute
|
||||||
GLint transLevelLoc; // attribute
|
GLint transLevelLoc; // attribute
|
||||||
GLint lightEnableLoc; // attribute
|
GLint lightEnableLoc; // attribute
|
||||||
|
GLint specularLoc; // attribute
|
||||||
GLint shininessLoc; // attribute
|
GLint shininessLoc; // attribute
|
||||||
GLint fogIntensityLoc; // attribute
|
GLint fogIntensityLoc; // attribute
|
||||||
|
|
||||||
|
|
|
@ -112,21 +112,22 @@ namespace Legacy3D {
|
||||||
#define VBO_VERTEX_OFFSET_B 8 // color and material B
|
#define VBO_VERTEX_OFFSET_B 8 // color and material B
|
||||||
#define VBO_VERTEX_OFFSET_TRANSLUCENCE 9 // translucence level (0.0 fully transparent, 1.0 opaque)
|
#define VBO_VERTEX_OFFSET_TRANSLUCENCE 9 // translucence level (0.0 fully transparent, 1.0 opaque)
|
||||||
#define VBO_VERTEX_OFFSET_LIGHTENABLE 10 // lighting enabled (0.0 luminous, 1.0 light enabled)
|
#define VBO_VERTEX_OFFSET_LIGHTENABLE 10 // lighting enabled (0.0 luminous, 1.0 light enabled)
|
||||||
#define VBO_VERTEX_OFFSET_SHININESS 11 // shininess (if negative, disables specular lighting)
|
#define VBO_VERTEX_OFFSET_SPECULAR 11 // specular coefficient (0.0 if disabled)
|
||||||
#define VBO_VERTEX_OFFSET_FOGINTENSITY 12 // fog intensity (0.0 no fog applied, 1.0 all fog applied)
|
#define VBO_VERTEX_OFFSET_SHININESS 12 // shininess (specular power)
|
||||||
#define VBO_VERTEX_OFFSET_U 13 // texture U coordinate (in texels, relative to sub-texture)
|
#define VBO_VERTEX_OFFSET_FOGINTENSITY 13 // fog intensity (0.0 no fog applied, 1.0 all fog applied)
|
||||||
#define VBO_VERTEX_OFFSET_V 14 // texture V coordinate
|
#define VBO_VERTEX_OFFSET_U 14 // texture U coordinate (in texels, relative to sub-texture)
|
||||||
#define VBO_VERTEX_OFFSET_TEXTURE_X 15 // sub-texture parameters, X (position in overall texture map, in texels)
|
#define VBO_VERTEX_OFFSET_V 15 // texture V coordinate
|
||||||
#define VBO_VERTEX_OFFSET_TEXTURE_Y 16 // "" Y ""
|
#define VBO_VERTEX_OFFSET_TEXTURE_X 16 // sub-texture parameters, X (position in overall texture map, in texels)
|
||||||
#define VBO_VERTEX_OFFSET_TEXTURE_W 17 // sub-texture parameters, width of texture in texels
|
#define VBO_VERTEX_OFFSET_TEXTURE_Y 17 // "" Y ""
|
||||||
#define VBO_VERTEX_OFFSET_TEXTURE_H 18 // "" height of texture in texels
|
#define VBO_VERTEX_OFFSET_TEXTURE_W 18 // sub-texture parameters, width of texture in texels
|
||||||
#define VBO_VERTEX_OFFSET_TEXPARAMS_EN 19 // texture parameter: ==1 texturing enabled, ==0 disabled (per-polygon)
|
#define VBO_VERTEX_OFFSET_TEXTURE_H 19 // "" height of texture in texels
|
||||||
#define VBO_VERTEX_OFFSET_TEXPARAMS_TRANS 20 // texture parameter: >=0 use transparency bit, <0 no transparency (per-polygon)
|
#define VBO_VERTEX_OFFSET_TEXPARAMS_EN 20 // texture parameter: ==1 texturing enabled, ==0 disabled (per-polygon)
|
||||||
#define VBO_VERTEX_OFFSET_TEXPARAMS_UWRAP 21 // texture parameters: U wrap mode: ==1 mirrored repeat, ==0 normal repeat
|
#define VBO_VERTEX_OFFSET_TEXPARAMS_TRANS 21 // texture parameter: >=0 use transparency bit, <0 no transparency (per-polygon)
|
||||||
#define VBO_VERTEX_OFFSET_TEXPARAMS_VWRAP 22 // "" V wrap mode ""
|
#define VBO_VERTEX_OFFSET_TEXPARAMS_UWRAP 22 // texture parameters: U wrap mode: ==1 mirrored repeat, ==0 normal repeat
|
||||||
#define VBO_VERTEX_OFFSET_TEXFORMAT 23 // texture format 0-7 (also ==0 indicates contour texture - see also texParams.trans)
|
#define VBO_VERTEX_OFFSET_TEXPARAMS_VWRAP 23 // "" V wrap mode ""
|
||||||
#define VBO_VERTEX_OFFSET_TEXMAP 24 // texture map number
|
#define VBO_VERTEX_OFFSET_TEXFORMAT 24 // texture format 0-7 (also ==0 indicates contour texture - see also texParams.trans)
|
||||||
#define VBO_VERTEX_SIZE 25 // total size (may include padding for alignment)
|
#define VBO_VERTEX_OFFSET_TEXMAP 25 // texture map number
|
||||||
|
#define VBO_VERTEX_SIZE 26 // total size (may include padding for alignment)
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
@ -216,6 +217,7 @@ void CLegacy3D::DrawDisplayList(ModelCache *Cache, POLY_STATE state)
|
||||||
if (transLevelLoc != -1) glVertexAttribPointer(transLevelLoc, 1, GL_FLOAT, GL_FALSE, VBO_VERTEX_SIZE*sizeof(GLfloat), (GLvoid *) (VBO_VERTEX_OFFSET_TRANSLUCENCE*sizeof(GLfloat)));
|
if (transLevelLoc != -1) glVertexAttribPointer(transLevelLoc, 1, GL_FLOAT, GL_FALSE, VBO_VERTEX_SIZE*sizeof(GLfloat), (GLvoid *) (VBO_VERTEX_OFFSET_TRANSLUCENCE*sizeof(GLfloat)));
|
||||||
if (lightEnableLoc != -1) glVertexAttribPointer(lightEnableLoc, 1, GL_FLOAT, GL_FALSE, VBO_VERTEX_SIZE*sizeof(GLfloat), (GLvoid *) (VBO_VERTEX_OFFSET_LIGHTENABLE*sizeof(GLfloat)));
|
if (lightEnableLoc != -1) glVertexAttribPointer(lightEnableLoc, 1, GL_FLOAT, GL_FALSE, VBO_VERTEX_SIZE*sizeof(GLfloat), (GLvoid *) (VBO_VERTEX_OFFSET_LIGHTENABLE*sizeof(GLfloat)));
|
||||||
if (shininessLoc != -1) glVertexAttribPointer(shininessLoc, 1, GL_FLOAT, GL_FALSE, VBO_VERTEX_SIZE*sizeof(GLfloat), (GLvoid *) (VBO_VERTEX_OFFSET_SHININESS*sizeof(GLfloat)));
|
if (shininessLoc != -1) glVertexAttribPointer(shininessLoc, 1, GL_FLOAT, GL_FALSE, VBO_VERTEX_SIZE*sizeof(GLfloat), (GLvoid *) (VBO_VERTEX_OFFSET_SHININESS*sizeof(GLfloat)));
|
||||||
|
if (specularLoc != -1) glVertexAttribPointer(specularLoc, 1, GL_FLOAT, GL_FALSE, VBO_VERTEX_SIZE*sizeof(GLfloat), (GLvoid *) (VBO_VERTEX_OFFSET_SPECULAR*sizeof(GLfloat)));
|
||||||
if (fogIntensityLoc != -1) glVertexAttribPointer(fogIntensityLoc, 1, GL_FLOAT, GL_FALSE, VBO_VERTEX_SIZE*sizeof(GLfloat), (GLvoid *) (VBO_VERTEX_OFFSET_FOGINTENSITY*sizeof(GLfloat)));
|
if (fogIntensityLoc != -1) glVertexAttribPointer(fogIntensityLoc, 1, GL_FLOAT, GL_FALSE, VBO_VERTEX_SIZE*sizeof(GLfloat), (GLvoid *) (VBO_VERTEX_OFFSET_FOGINTENSITY*sizeof(GLfloat)));
|
||||||
|
|
||||||
// Set up state
|
// Set up state
|
||||||
|
@ -470,12 +472,11 @@ void CLegacy3D::InsertVertex(ModelCache *Cache, const Vertex *V, const Poly *P,
|
||||||
GLfloat b = 1.0;
|
GLfloat b = 1.0;
|
||||||
if ((P->header[1]&2) == 0)
|
if ((P->header[1]&2) == 0)
|
||||||
{
|
{
|
||||||
size_t base = 0x400;
|
//size_t sensorColorIdx = ((P->header[4]>>20)&0x7FF) - 0; // works for Scud
|
||||||
//size_t colorIdx = ((P->header[4]>>20)&0x7FF) - 0; // works for Scud
|
|
||||||
size_t colorIdx = ((P->header[4]>>8)&0x7FF) - 0; // works for Daytona2 lights and Scud
|
size_t colorIdx = ((P->header[4]>>8)&0x7FF) - 0; // works for Daytona2 lights and Scud
|
||||||
b = (GLfloat) (polyRAM[base+colorIdx]&0xFF) * (1.0f/255.0f);
|
b = (GLfloat) (polyRAM[m_colorTableAddr+colorIdx]&0xFF) * (1.0f/255.0f);
|
||||||
g = (GLfloat) ((polyRAM[base+colorIdx]>>8)&0xFF) * (1.0f/255.0f);
|
g = (GLfloat) ((polyRAM[m_colorTableAddr+colorIdx]>>8)&0xFF) * (1.0f/255.0f);
|
||||||
r = (GLfloat) ((polyRAM[base+colorIdx]>>16)&0xFF) * (1.0f/255.0f);
|
r = (GLfloat) ((polyRAM[m_colorTableAddr+colorIdx]>>16)&0xFF) * (1.0f/255.0f);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -486,6 +487,10 @@ void CLegacy3D::InsertVertex(ModelCache *Cache, const Vertex *V, const Poly *P,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* These observations are somewhat out of date now that we know the polygon
|
||||||
|
* header layout from the Pro-1000 SDK. However, there are some important
|
||||||
|
* regressions to keep an eye out for.
|
||||||
|
*
|
||||||
* Color Modulation Observations
|
* Color Modulation Observations
|
||||||
* -----------------------------
|
* -----------------------------
|
||||||
*
|
*
|
||||||
|
@ -533,44 +538,149 @@ void CLegacy3D::InsertVertex(ModelCache *Cache, const Vertex *V, const Poly *P,
|
||||||
* - Fighting Vipers 2 shadows are not black anymore.
|
* - Fighting Vipers 2 shadows are not black anymore.
|
||||||
* - More to follow...
|
* - More to follow...
|
||||||
*/
|
*/
|
||||||
/*
|
|
||||||
unsigned modulate = (step >= 0x20) ? !(P->header[4]&0x80) : (P->header[3]&0x80 && lightEnable);
|
|
||||||
if (texEnable)
|
|
||||||
{
|
|
||||||
// When textures enabled, modulation can apparently be disabled
|
|
||||||
if (!modulate)
|
|
||||||
r = g = b = 1.0f;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
// Shading bits
|
||||||
* When fixed shading is enabled, header[1] & 0x08 == 0 (always?) Perhaps
|
int fixedShading = (P->header[1] & 0x20);
|
||||||
* some combination of these two bits also selects between smooth and flat
|
int smoothShading = (P->header[1] & 0x08);
|
||||||
* shading when fixed shading is off? Should check to see if 0x08 is the
|
|
||||||
* flat shading bit.
|
// Color modulation here means multiplication of texel by polygon color
|
||||||
*/
|
int modulate = true;
|
||||||
int modulate = !(P->header[4] & 0x80);
|
|
||||||
int fixedShading = (P->header[1] & 0x20);// && !(P->header[1] & 0x08);
|
// Source of normal vector depends on shading mode
|
||||||
if (texEnable)
|
float nx = 0.0f;
|
||||||
|
float ny = 0.0f;
|
||||||
|
float nz = 0.0f;
|
||||||
|
|
||||||
|
float intensity = 1.0f;
|
||||||
|
|
||||||
|
// Lighting/shading modes
|
||||||
|
if (lightEnable)
|
||||||
{
|
{
|
||||||
if (!modulate)
|
if (smoothShading)
|
||||||
r = g = b = 1.0f;
|
{
|
||||||
|
// Vertex normals present: smooth shading only. Fixed shading never
|
||||||
|
// observed to be enabled with light and smooth shading in any game.
|
||||||
|
nx = V->n[0];
|
||||||
|
ny = V->n[1];
|
||||||
|
nz = V->n[2];
|
||||||
|
modulate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Vertex normals absent: fixed or flat shading only
|
||||||
|
if (fixedShading)
|
||||||
|
{
|
||||||
|
// LA Machineguns Vegas street pulsating color effect requires modulation
|
||||||
|
intensity = V->intensity;
|
||||||
|
lightEnable = 0; // this breaks Yosemite level of LA Machineguns but fixes Scud castle
|
||||||
|
modulate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Flat shading occurs rarely. It can be observed in LA Machineguns (LA
|
||||||
|
// mission, parking lot). A fixed shading intensity seems to be provided
|
||||||
|
// but is presumably unused.
|
||||||
|
nx = P->n[0];
|
||||||
|
ny = P->n[1];
|
||||||
|
nz = P->n[2];
|
||||||
|
modulate = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (fixedShading && lightEnable)
|
else
|
||||||
{
|
{
|
||||||
//lightEnable = 0; // is this needed?
|
// Here things get tricky...
|
||||||
r *= V->intensity;
|
if (smoothShading)
|
||||||
g *= V->intensity;
|
{
|
||||||
b *= V->intensity;
|
/*
|
||||||
|
* Vertex normals don't matter because lighting is disabled.
|
||||||
|
* So does the smooth shading bit convey any meaning?
|
||||||
|
*
|
||||||
|
* Cases of interest:
|
||||||
|
*
|
||||||
|
* - Sega Rally 2: menu has lightEnable = 0, smoothShading = 1,
|
||||||
|
* fixedShading = 0. Color modulation must occur.
|
||||||
|
* - LA Machineguns: this setting occurs for enemy blue flames and
|
||||||
|
* flashing missile warheads. Only the latter require modulation. Blue
|
||||||
|
* flames look wrong if either fixed shading or modulation is applied.
|
||||||
|
* However, this is inconclusive because these and most other polygons
|
||||||
|
* in the game have the "translator map" feature enabled. Perhaps this
|
||||||
|
* compensates somehow?
|
||||||
|
* - LA Machineguns is the primary reason for disabling modulation
|
||||||
|
* whenever tranlator map is enabled.
|
||||||
|
*/
|
||||||
|
modulate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (fixedShading)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Fixed intensities are sometimes observed in the normal area (e.g.,
|
||||||
|
* normal=0x3f,0,0, which cannot be a vertex normal because magnitude <
|
||||||
|
* 1) but often, all three components are just 0, indicating that fixed
|
||||||
|
* shading is indeed unused here.
|
||||||
|
*
|
||||||
|
* This is one of the most problematic settings:
|
||||||
|
*
|
||||||
|
* - Scud Race waterfalls, totem poles (near waterfalls at check-
|
||||||
|
* point), orange guard rail lamps, sky, and beginner level tunnels
|
||||||
|
* all look correct with color modulation disabled. Fixed shading
|
||||||
|
* and polygon color values are simply too dark and there does not
|
||||||
|
* appear to be a plausible combination of the two that works.
|
||||||
|
* - Scud Race blinking traffic signals, blue arrow signs at entrance
|
||||||
|
* to Colosseum, all expect modulation to be on. Palette vs. RGB
|
||||||
|
* polygon color seems to make no difference.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// TODO: check color table address?
|
||||||
|
modulate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* No vertex normals or intensity. Almost never happens. Only a single,
|
||||||
|
* untextured HUD triangle uses this mode in Scud Race.
|
||||||
|
*/
|
||||||
|
modulate = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Translator map probably affects shading. Used extensively in LA
|
||||||
|
// Machineguns. Here, we disable it to fix that game, otherwise polygon
|
||||||
|
// colors and modulation make everything too dark.
|
||||||
|
// TODO: search for translator map by looking for 128*4 byte block xfers? May
|
||||||
|
// be in VROM, though...
|
||||||
|
if ((P->header[4] & 0x80))
|
||||||
|
modulate = false;
|
||||||
|
|
||||||
|
// Untextured polygons always use polygon color. Make sure we pass it to
|
||||||
|
// shader!
|
||||||
|
if (!texEnable)
|
||||||
|
modulate = true;
|
||||||
|
|
||||||
|
// This removes the effect of polygon color
|
||||||
|
if (!modulate)
|
||||||
|
{
|
||||||
|
r = 1.0f;
|
||||||
|
g = 1.0f;
|
||||||
|
b = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assemble final shading color and intensity
|
||||||
|
r *= intensity;
|
||||||
|
g *= intensity;
|
||||||
|
b *= intensity;
|
||||||
|
|
||||||
// Specular shininess
|
// Specular shininess
|
||||||
int shininess = (P->header[0]>>26)&0x3F;
|
GLfloat specularCoefficient = (GLfloat) ((P->header[0]>>26) & 0x3F) * (1.0f/63.0f);
|
||||||
//shininess = (P->header[0]>>28)&0xF;
|
int shininess = (P->header[6] >> 5) & 3;
|
||||||
//if (shininess)
|
if (!(P->header[0]&0x80)) //|| (shininess == 0)) // bit 0x80 seems to enable specular lighting
|
||||||
// printf("%X\n", shininess);
|
{
|
||||||
if (!(P->header[0]&0x80) || (shininess == 0)) // bit 0x80 seems to enable specular lighting
|
specularCoefficient = 0.; // disable
|
||||||
shininess = -1; // disable
|
shininess = -1;
|
||||||
|
}
|
||||||
|
|
||||||
// Determine whether polygon is translucent
|
// Determine whether polygon is translucent
|
||||||
GLfloat translucence = (GLfloat) ((P->header[6]>>18)&0x1F) * (1.0f/31.0f);
|
GLfloat translucence = (GLfloat) ((P->header[6]>>18)&0x1F) * (1.0f/31.0f);
|
||||||
|
@ -626,12 +736,13 @@ void CLegacy3D::InsertVertex(ModelCache *Cache, const Vertex *V, const Poly *P,
|
||||||
Cache->verts[s][baseIdx + VBO_VERTEX_OFFSET_B] = b;
|
Cache->verts[s][baseIdx + VBO_VERTEX_OFFSET_B] = b;
|
||||||
Cache->verts[s][baseIdx + VBO_VERTEX_OFFSET_TRANSLUCENCE] = translucence;
|
Cache->verts[s][baseIdx + VBO_VERTEX_OFFSET_TRANSLUCENCE] = translucence;
|
||||||
Cache->verts[s][baseIdx + VBO_VERTEX_OFFSET_LIGHTENABLE] = lightEnable ? 1.0f : 0.0f;
|
Cache->verts[s][baseIdx + VBO_VERTEX_OFFSET_LIGHTENABLE] = lightEnable ? 1.0f : 0.0f;
|
||||||
|
Cache->verts[s][baseIdx + VBO_VERTEX_OFFSET_SPECULAR] = specularCoefficient;
|
||||||
Cache->verts[s][baseIdx + VBO_VERTEX_OFFSET_SHININESS] = (GLfloat) shininess;
|
Cache->verts[s][baseIdx + VBO_VERTEX_OFFSET_SHININESS] = (GLfloat) shininess;
|
||||||
Cache->verts[s][baseIdx + VBO_VERTEX_OFFSET_FOGINTENSITY] = fogIntensity;
|
Cache->verts[s][baseIdx + VBO_VERTEX_OFFSET_FOGINTENSITY] = fogIntensity;
|
||||||
|
|
||||||
Cache->verts[s][baseIdx + VBO_VERTEX_OFFSET_NX] = V->n[0]*normFlip;
|
Cache->verts[s][baseIdx + VBO_VERTEX_OFFSET_NX] = fixedShading ? 0. : nx*normFlip;
|
||||||
Cache->verts[s][baseIdx + VBO_VERTEX_OFFSET_NY] = V->n[1]*normFlip;
|
Cache->verts[s][baseIdx + VBO_VERTEX_OFFSET_NY] = fixedShading ? 0. : ny*normFlip;
|
||||||
Cache->verts[s][baseIdx + VBO_VERTEX_OFFSET_NZ] = V->n[2]*normFlip;
|
Cache->verts[s][baseIdx + VBO_VERTEX_OFFSET_NZ] = fixedShading ? 0. : nz*normFlip;
|
||||||
|
|
||||||
Cache->verts[s][baseIdx + VBO_VERTEX_OFFSET_U] = V->u;
|
Cache->verts[s][baseIdx + VBO_VERTEX_OFFSET_U] = V->u;
|
||||||
Cache->verts[s][baseIdx + VBO_VERTEX_OFFSET_V] = V->v;
|
Cache->verts[s][baseIdx + VBO_VERTEX_OFFSET_V] = V->v;
|
||||||
|
@ -678,9 +789,9 @@ bool CLegacy3D::InsertPolygon(ModelCache *Cache, const Poly *P)
|
||||||
* to do with using the correct Z convention to identify a vector pointing
|
* to do with using the correct Z convention to identify a vector pointing
|
||||||
* toward or away from the screen.
|
* toward or away from the screen.
|
||||||
*/
|
*/
|
||||||
GLfloat v1[3];
|
GLfloat v1[3];
|
||||||
GLfloat v2[3];
|
GLfloat v2[3];
|
||||||
GLfloat n[3];
|
GLfloat n[3];
|
||||||
v1[0] = P->Vert[0].x-P->Vert[1].x;
|
v1[0] = P->Vert[0].x-P->Vert[1].x;
|
||||||
v1[1] = P->Vert[0].y-P->Vert[1].y;
|
v1[1] = P->Vert[0].y-P->Vert[1].y;
|
||||||
v1[2] = P->Vert[0].z-P->Vert[1].z;
|
v1[2] = P->Vert[0].z-P->Vert[1].z;
|
||||||
|
@ -850,7 +961,7 @@ struct VBORef *CLegacy3D::CacheModel(ModelCache *Cache, int lutIdx, UINT16 texOf
|
||||||
Poly P; // current polygon
|
Poly P; // current polygon
|
||||||
P.header = data;
|
P.header = data;
|
||||||
data += 7; // data will now point to first vertex
|
data += 7; // data will now point to first vertex
|
||||||
if (P.header[6]==0)// || P.header[0]==0)
|
if (P.header[6]==0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Sega Rally 2: dust trails often have polygons with seemingly invalid
|
// Sega Rally 2: dust trails often have polygons with seemingly invalid
|
||||||
|
@ -860,11 +971,11 @@ struct VBORef *CLegacy3D::CacheModel(ModelCache *Cache, int lutIdx, UINT16 texOf
|
||||||
bool validPoly = (P.header[0] & 0x300) != 0x300;
|
bool validPoly = (P.header[0] & 0x300) != 0x300;
|
||||||
|
|
||||||
// Obtain basic polygon parameters
|
// Obtain basic polygon parameters
|
||||||
done = (P.header[1] & 4) > 0; // last polygon?
|
done = (P.header[1] & 4) > 0; // last polygon?
|
||||||
P.numVerts = (P.header[0]&0x40)?4:3;
|
P.numVerts = (P.header[0]&0x40)?4:3;
|
||||||
|
|
||||||
// Texture data
|
// Texture data
|
||||||
int texEnable = P.header[6]&0x04000000;
|
int texEnable = P.header[6]&0x400;
|
||||||
int texFormat = (P.header[6]>>7)&7;
|
int texFormat = (P.header[6]>>7)&7;
|
||||||
int texWidth = (32<<((P.header[3]>>3)&7));
|
int texWidth = (32<<((P.header[3]>>3)&7));
|
||||||
int texHeight = (32<<((P.header[3]>>0)&7));
|
int texHeight = (32<<((P.header[3]>>0)&7));
|
||||||
|
@ -947,11 +1058,15 @@ struct VBORef *CLegacy3D::CacheModel(ModelCache *Cache, int lutIdx, UINT16 texOf
|
||||||
P.Vert[j].n[0] = (GLfloat)(INT8)(ix&0xFF);
|
P.Vert[j].n[0] = (GLfloat)(INT8)(ix&0xFF);
|
||||||
P.Vert[j].n[1] = (GLfloat)(INT8)(iy&0xFF);
|
P.Vert[j].n[1] = (GLfloat)(INT8)(iy&0xFF);
|
||||||
P.Vert[j].n[2] = (GLfloat)(INT8)(iz&0xFF);
|
P.Vert[j].n[2] = (GLfloat)(INT8)(iz&0xFF);
|
||||||
P.Vert[j].u = (GLfloat) ((UINT16)(it>>16)) * uvScale; // TO-DO: might these be signed?
|
P.Vert[j].u = (GLfloat) ((UINT16)(it>>16)) * uvScale;
|
||||||
P.Vert[j].v = (GLfloat) ((UINT16)(it&0xFFFF)) * uvScale;
|
P.Vert[j].v = (GLfloat) ((UINT16)(it&0xFFFF)) * uvScale;
|
||||||
P.Vert[j].intensity = GLfloat((ix + 128) & 0xFF) / 255.0f; // signed (-0.5 -> black, +0.5 -> white)
|
P.Vert[j].intensity = GLfloat((ix + 128) & 0xFF) / 255.0f; // signed (-0.5 -> black, +0.5 -> white)
|
||||||
//if ((P.header[1] & 0x20) && !(P.header[1] & 0x08))
|
//P.Vert[j].intensity_7u = GLfloat(ix & 0x7F) / 127.0f;
|
||||||
// printf("%02x %02x %02x\n", ix&0xff, iy&0xff, iz&0xff);
|
//if ((P.header[1] & 0x20) && j == 0)
|
||||||
|
//if (!(P.header[1] & 0x20) && !(P.header[1] & 0x08) && !(P.header[6] & 0x10000))
|
||||||
|
//{
|
||||||
|
// printf("%06X: le=%d fx=%d sm=%d %02x %02x %02x\tcolor=%06x (%s)\tambient=%1.2f\n", lutIdx, !!!(P.header[6] & 0x10000), !!(P.header[1] & 0x20), !!(P.header[1] & 0x08), ix&0xff, iy&0xff, iz&0xff, P.header[4]>>8, (P.header[1]&2) ? "rgb" : "pal", lightingParams[4]);
|
||||||
|
//}
|
||||||
data += 4;
|
data += 4;
|
||||||
|
|
||||||
// Normalize the vertex normal
|
// Normalize the vertex normal
|
||||||
|
|
Loading…
Reference in a new issue