fix parenthesis error

This commit is contained in:
Ian Curtis 2016-03-22 21:59:51 +00:00
parent e7eb912eaa
commit 8ea5978093
3 changed files with 195 additions and 195 deletions

View file

@ -581,7 +581,7 @@ static bool IsDynamicModel(const UINT32 *data)
unsigned numVerts = (data[0]&0x40 ? 4 : 3); unsigned numVerts = (data[0]&0x40 ? 4 : 3);
// Deduct number of reused verts // Deduct number of reused verts
numVerts -= sharedVerts[data[0]&0xf]; numVerts -= sharedVerts[data[0]&0xf];
done = data[1] & 4 > 0; done = (data[1] & 4) > 0;
// Skip header and vertices to next polygon // Skip header and vertices to next polygon
data += 7 + numVerts * 4; data += 7 + numVerts * 4;
} }

View file

@ -753,7 +753,7 @@ 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

View file

@ -1,194 +1,194 @@
/** /**
** Supermodel ** Supermodel
** A Sega Model 3 Arcade Emulator. ** A Sega Model 3 Arcade Emulator.
** Copyright 2011-2012 Bart Trzynadlowski, Nik Henson ** Copyright 2011-2012 Bart Trzynadlowski, Nik Henson
** **
** This file is part of Supermodel. ** This file is part of Supermodel.
** **
** Supermodel is free software: you can redistribute it and/or modify it under ** Supermodel is free software: you can redistribute it and/or modify it under
** the terms of the GNU General Public License as published by the Free ** the terms of the GNU General Public License as published by the Free
** Software Foundation, either version 3 of the License, or (at your option) ** Software Foundation, either version 3 of the License, or (at your option)
** any later version. ** any later version.
** **
** Supermodel is distributed in the hope that it will be useful, but WITHOUT ** Supermodel is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
** more details. ** more details.
** **
** You should have received a copy of the GNU General Public License along ** You should have received a copy of the GNU General Public License along
** with Supermodel. If not, see <http://www.gnu.org/licenses/>. ** with Supermodel. If not, see <http://www.gnu.org/licenses/>.
**/ **/
/* /*
* Fragment.glsl * Fragment.glsl
* *
* Fragment shader for 3D rendering. * Fragment shader for 3D rendering.
*/ */
#version 120 #version 120
// Global uniforms // Global uniforms
uniform sampler2D textureMap; // complete texture map, 2048x2048 texels uniform sampler2D textureMap; // complete texture map, 2048x2048 texels
uniform vec4 spotEllipse; // spotlight ellipse position: .x=X position (screen coordinates), .y=Y position, .z=half-width, .w=half-height) uniform vec4 spotEllipse; // spotlight ellipse position: .x=X position (screen coordinates), .y=Y position, .z=half-width, .w=half-height)
uniform vec2 spotRange; // spotlight Z range: .x=start (viewspace coordinates), .y=limit uniform vec2 spotRange; // spotlight Z range: .x=start (viewspace coordinates), .y=limit
uniform vec3 spotColor; // spotlight RGB color uniform vec3 spotColor; // spotlight RGB color
uniform vec3 lighting[2]; // lighting state (lighting[0] = sun direction, lighting[1].x,y = diffuse, ambient intensities from 0-1.0) uniform vec3 lighting[2]; // lighting state (lighting[0] = sun direction, lighting[1].x,y = diffuse, ambient intensities from 0-1.0)
uniform float mapSize; // texture map size (2048,4096,6144 etc) uniform float mapSize; // texture map size (2048,4096,6144 etc)
// Inputs from vertex shader // Inputs from vertex shader
varying vec4 fsSubTexture; // .x=texture X, .y=texture Y, .z=texture width, .w=texture height (all in texels) varying vec4 fsSubTexture; // .x=texture X, .y=texture Y, .z=texture width, .w=texture height (all in texels)
varying vec4 fsTexParams; // .x=texture enable (if 1, else 0), .y=use transparency (if > 0), .z=U wrap mode (1=mirror, 0=repeat), .w=V wrap mode varying vec4 fsTexParams; // .x=texture enable (if 1, else 0), .y=use transparency (if > 0), .z=U wrap mode (1=mirror, 0=repeat), .w=V wrap mode
varying float fsTexFormat; // T1RGB5 contour texture (if > 0) varying float fsTexFormat; // T1RGB5 contour texture (if > 0)
varying float fsTexMap; // texture map number varying float fsTexMap; // texture map number
varying float fsTransLevel; // translucence level, 0.0 (transparent) to 1.0 (opaque) varying float fsTransLevel; // translucence level, 0.0 (transparent) to 1.0 (opaque)
varying vec3 fsLightIntensity; // lighting intensity varying vec3 fsLightIntensity; // lighting intensity
varying float fsSpecularTerm; // specular highlight varying float fsSpecularTerm; // specular highlight
varying float fsFogFactor; // fog factor varying float fsFogFactor; // fog factor
varying float fsViewZ; // Z distance to fragment from viewpoint at origin varying float fsViewZ; // Z distance to fragment from viewpoint at origin
/* /*
* WrapTexelCoords(): * WrapTexelCoords():
* *
* Computes the normalized OpenGL S,T coordinates within the 2048x2048 texture * Computes the normalized OpenGL S,T coordinates within the 2048x2048 texture
* sheet, taking into account wrapping behavior. * sheet, taking into account wrapping behavior.
* *
* Computing normalized OpenGL texture coordinates (0 to 1) within the * Computing normalized OpenGL texture coordinates (0 to 1) within the
* Real3D texture sheet: * Real3D texture sheet:
* *
* If the texture is not mirrored, we simply have to clamp the * If the texture is not mirrored, we simply have to clamp the
* coordinates to fit within the texture dimensions, add the texture * coordinates to fit within the texture dimensions, add the texture
* X, Y position to select the appropriate one, and normalize by 2048 * X, Y position to select the appropriate one, and normalize by 2048
* (the dimensions of the Real3D texture sheet). * (the dimensions of the Real3D texture sheet).
* *
* = [(u,v)%(w,h)+(x,y)]/(2048,2048) * = [(u,v)%(w,h)+(x,y)]/(2048,2048)
* *
* If mirroring is enabled, textures are mirrored every odd multiple of * If mirroring is enabled, textures are mirrored every odd multiple of
* the original texture. To detect whether we are in an odd multiple, * the original texture. To detect whether we are in an odd multiple,
* simply divide the coordinate by the texture dimension and check * simply divide the coordinate by the texture dimension and check
* whether the result is odd. Then, clamp the coordinates as before but * whether the result is odd. Then, clamp the coordinates as before but
* subtract from the last texel to mirror them: * subtract from the last texel to mirror them:
* *
* = [M*((w-1,h-1)-(u,v)%(w,h)) + (1-M)*(u,v)%(w,h) + (x,y)]/(2048,2048) * = [M*((w-1,h-1)-(u,v)%(w,h)) + (1-M)*(u,v)%(w,h) + (x,y)]/(2048,2048)
* where M is 1.0 if the texture must be mirrored. * where M is 1.0 if the texture must be mirrored.
* *
* As an optimization, this function computes TWO texture coordinates * As an optimization, this function computes TWO texture coordinates
* simultaneously. The first is texCoord.xy, the second is in .zw. The other * simultaneously. The first is texCoord.xy, the second is in .zw. The other
* parameters must have .xy = .zw. * parameters must have .xy = .zw.
*/ */
vec4 WrapTexelCoords(vec4 texCoord, vec4 texOffset, vec4 texSize, vec4 mirrorEnable) vec4 WrapTexelCoords(vec4 texCoord, vec4 texOffset, vec4 texSize, vec4 mirrorEnable)
{ {
vec4 clampedCoord, mirror, glTexCoord; vec4 clampedCoord, mirror, glTexCoord;
clampedCoord = mod(texCoord,texSize); // clamp coordinates to within texture size clampedCoord = mod(texCoord,texSize); // clamp coordinates to within texture size
mirror = mirrorEnable * mod(floor(texCoord/texSize),2.0); // whether this texel needs to be mirrored mirror = mirrorEnable * mod(floor(texCoord/texSize),2.0); // whether this texel needs to be mirrored
glTexCoord = ( mirror*(texSize-clampedCoord) + glTexCoord = ( mirror*(texSize-clampedCoord) +
(vec4(1.0,1.0,1.0,1.0)-mirror)*clampedCoord + (vec4(1.0,1.0,1.0,1.0)-mirror)*clampedCoord +
texOffset texOffset
) / mapSize; ) / mapSize;
return glTexCoord; return glTexCoord;
} }
/* /*
* main(): * main():
* *
* Fragment shader entry point. * Fragment shader entry point.
*/ */
void main(void) void main(void)
{ {
vec4 uv_top, uv_bot, c[4]; vec4 uv_top, uv_bot, c[4];
vec2 r; vec2 r;
vec4 fragColor; vec4 fragColor;
vec2 ellipse; vec2 ellipse;
vec3 lightIntensity; vec3 lightIntensity;
float insideSpot; float insideSpot;
int x; int x;
// Get polygon color for untextured polygons (textured polygons will overwrite) // Get polygon color for untextured polygons (textured polygons will overwrite)
if (fsTexParams.x < 0.5) if (fsTexParams.x < 0.5)
fragColor = gl_Color; fragColor = gl_Color;
else else
// Textured polygons: set fragment color to texel value // Textured polygons: set fragment color to texel value
{ {
/* /*
* Bilinear Filtering * Bilinear Filtering
* *
* In order to get this working on ATI, the number of operations is * In order to get this working on ATI, the number of operations is
* reduced by putting everything into vec4s. uv_top holds the UV * reduced by putting everything into vec4s. uv_top holds the UV
* coordinates for the top two texels (.xy=left, .zw=right) and uv_bot * coordinates for the top two texels (.xy=left, .zw=right) and uv_bot
* is for the lower two. * is for the lower two.
*/ */
// Compute fractional blending factor, r, and lower left corner of texel 0 // Compute fractional blending factor, r, and lower left corner of texel 0
uv_bot.xy = gl_TexCoord[0].st-vec2(0.5,0.5); // move into the lower left blending texel uv_bot.xy = gl_TexCoord[0].st-vec2(0.5,0.5); // move into the lower left blending texel
r = uv_bot.xy-floor(uv_bot.xy); // fractional part r = uv_bot.xy-floor(uv_bot.xy); // fractional part
uv_bot.xy = floor(uv_bot.xy); // integral part uv_bot.xy = floor(uv_bot.xy); // integral part
// Compute texel coordinates // Compute texel coordinates
uv_bot.xy += vec2(0.5,0.5); // offset to center of pixel (should not be needed but it fixes a lot of glitches, esp. on Nvidia) uv_bot.xy += vec2(0.5,0.5); // offset to center of pixel (should not be needed but it fixes a lot of glitches, esp. on Nvidia)
uv_bot.zw = uv_bot.xy + vec2(1.0,0.0); // compute coordinates of the other three neighbors uv_bot.zw = uv_bot.xy + vec2(1.0,0.0); // compute coordinates of the other three neighbors
uv_top = uv_bot + vec4(0.0,1.0,0.0,1.0); uv_top = uv_bot + vec4(0.0,1.0,0.0,1.0);
// Compute the properly wrapped texel coordinates // Compute the properly wrapped texel coordinates
uv_top = WrapTexelCoords(uv_top,vec4(fsSubTexture.xy,fsSubTexture.xy),vec4(fsSubTexture.zw,fsSubTexture.zw), vec4(fsTexParams.zw,fsTexParams.zw)); uv_top = WrapTexelCoords(uv_top,vec4(fsSubTexture.xy,fsSubTexture.xy),vec4(fsSubTexture.zw,fsSubTexture.zw), vec4(fsTexParams.zw,fsTexParams.zw));
uv_bot = WrapTexelCoords(uv_bot,vec4(fsSubTexture.xy,fsSubTexture.xy),vec4(fsSubTexture.zw,fsSubTexture.zw), vec4(fsTexParams.zw,fsTexParams.zw)); uv_bot = WrapTexelCoords(uv_bot,vec4(fsSubTexture.xy,fsSubTexture.xy),vec4(fsSubTexture.zw,fsSubTexture.zw), vec4(fsTexParams.zw,fsTexParams.zw));
// Fetch the texels // Fetch the texels
c[0]=texture2D(textureMap,uv_bot.xy); // bottom-left (base texel) c[0]=texture2D(textureMap,uv_bot.xy); // bottom-left (base texel)
c[1]=texture2D(textureMap,uv_bot.zw); // bottom-right c[1]=texture2D(textureMap,uv_bot.zw); // bottom-right
c[2]=texture2D(textureMap,uv_top.xy); // top-left c[2]=texture2D(textureMap,uv_top.xy); // top-left
c[3]=texture2D(textureMap,uv_top.zw); // top-right c[3]=texture2D(textureMap,uv_top.zw); // top-right
// Interpolate texels and blend result with material color to determine final (unlit) fragment color // Interpolate texels and blend result with material color to determine final (unlit) fragment color
// fragColor = (c[0]*(1.0-r.s)*(1.0-r.t) + c[1]*r.s*(1.0-r.t) + c[2]*(1.0-r.s)*r.t + c[3]*r.s*r.t); // fragColor = (c[0]*(1.0-r.s)*(1.0-r.t) + c[1]*r.s*(1.0-r.t) + c[2]*(1.0-r.s)*r.t + c[3]*r.s*r.t);
// Faster method: // Faster method:
c[0] += (c[1]-c[0])*r.s; // 2 alu c[0] += (c[1]-c[0])*r.s; // 2 alu
c[2] += (c[3]-c[2])*r.s; // 2 alu c[2] += (c[3]-c[2])*r.s; // 2 alu
fragColor = c[0]+(c[2]-c[0])*r.t; //2 alu fragColor = c[0]+(c[2]-c[0])*r.t; //2 alu
/* /*
* T1RGB5: * T1RGB5:
* *
* The transparency bit determines whether to discard pixels (if set). * The transparency bit determines whether to discard pixels (if set).
* What is unknown is how this bit behaves when interpolated. OpenGL * What is unknown is how this bit behaves when interpolated. OpenGL
* processes it as an alpha value, so it might concievably be blended * processes it as an alpha value, so it might concievably be blended
* with neighbors. Here, an arbitrary threshold is chosen. * with neighbors. Here, an arbitrary threshold is chosen.
* *
* To-do: blending could probably enabled and this would work even * To-do: blending could probably enabled and this would work even
* better with a hard threshold. * better with a hard threshold.
* *
* Countour processing also seems to be enabled for RGBA4 textures. * Countour processing also seems to be enabled for RGBA4 textures.
* When the alpha value is 0.0 (or close), pixels are discarded * When the alpha value is 0.0 (or close), pixels are discarded
* entirely. * entirely.
*/ */
if (fsTexParams.y > 0.5) // contour processing enabled if (fsTexParams.y > 0.5) // contour processing enabled
{ {
if (fragColor.a < 0.01) // discard anything with alpha == 0 if (fragColor.a < 0.01) // discard anything with alpha == 0
discard; discard;
} }
// If contour texture and not discarded, force alpha to 1.0 because will later be modified by polygon translucency // If contour texture and not discarded, force alpha to 1.0 because will later be modified by polygon translucency
if (fsTexFormat < 0.5) // contour (T1RGB5) texture if (fsTexFormat < 0.5) // contour (T1RGB5) texture
fragColor.a = 1.0; fragColor.a = 1.0;
} }
// Compute spotlight and apply lighting // Compute spotlight and apply lighting
ellipse = (gl_FragCoord.xy-spotEllipse.xy)/spotEllipse.zw; ellipse = (gl_FragCoord.xy-spotEllipse.xy)/spotEllipse.zw;
insideSpot = dot(ellipse,ellipse); insideSpot = dot(ellipse,ellipse);
if ((insideSpot <= 1.0) && (fsViewZ>=spotRange.x) && (fsViewZ<spotRange.y)) if ((insideSpot <= 1.0) && (fsViewZ>=spotRange.x) && (fsViewZ<spotRange.y))
lightIntensity = fsLightIntensity+(1.0-insideSpot)*spotColor; lightIntensity = fsLightIntensity+(1.0-insideSpot)*spotColor;
else else
lightIntensity = fsLightIntensity; lightIntensity = fsLightIntensity;
fragColor.rgb *= lightIntensity; fragColor.rgb *= lightIntensity;
fragColor.rgb += vec3(fsSpecularTerm,fsSpecularTerm,fsSpecularTerm); fragColor.rgb += vec3(fsSpecularTerm,fsSpecularTerm,fsSpecularTerm);
// Translucency (modulates existing alpha channel for RGBA4 texels) // Translucency (modulates existing alpha channel for RGBA4 texels)
fragColor.a *= fsTransLevel; fragColor.a *= fsTransLevel;
// Apply fog under the control of fog factor setting from polygon header // Apply fog under the control of fog factor setting from polygon header
fragColor.rgb = mix(gl_Fog.color.rgb, fragColor.rgb, fsFogFactor); fragColor.rgb = mix(gl_Fog.color.rgb, fragColor.rgb, fsFogFactor);
// Store final color // Store final color
gl_FragColor = fragColor; gl_FragColor = fragColor;
} }