Remove double copy of shaders

This commit is contained in:
Ian Curtis 2016-03-22 11:40:24 +00:00
parent 5b3eea25fb
commit ce99c47f8a
8 changed files with 0 additions and 1036 deletions

View file

@ -1,2 +0,0 @@
Shader source files go here. Completed versions of the shader files should be
copied into Src/Graphics/Shaders3D.h and Src/Graphics/Shaders2D.h.

View file

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

View file

@ -1,42 +0,0 @@
/**
** Supermodel
** A Sega Model 3 Arcade Emulator.
** Copyright 2011-2012 Bart Trzynadlowski, Nik Henson
**
** This file is part of Supermodel.
**
** 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
** Software Foundation, either version 3 of the License, or (at your option)
** any later version.
**
** Supermodel is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
** more details.
**
** You should have received a copy of the GNU General Public License along
** with Supermodel. If not, see <http://www.gnu.org/licenses/>.
**/
/*
* Fragment2D.glsl
*
* Fragment shader for 2D tilemap rendering.
*/
#version 120
// Global uniforms
uniform sampler2D textureMap; // 512x512 layer surface
/*
* main():
*
* Fragment shader entry point.
*/
void main(void)
{
gl_FragColor = texture2D(textureMap, gl_TexCoord[0].st);
}

View file

@ -1,142 +0,0 @@
/**
** Supermodel
** A Sega Model 3 Arcade Emulator.
** Copyright 2011 Bart Trzynadlowski, Nik Henson
**
** This file is part of Supermodel.
**
** 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
** Software Foundation, either version 3 of the License, or (at your option)
** any later version.
**
** Supermodel is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
** more details.
**
** You should have received a copy of the GNU General Public License along
** with Supermodel. If not, see <http://www.gnu.org/licenses/>.
**/
/*
* Fragment_NoSpotlight.glsl
*
* Fragment shader for 3D rendering. Spotlight effect removed. Fixes fragment
* shader link errors on older ATI Radeon GPUs.
*
* To load external fragment shaders, use the -frag-shader=<file> option when
* starting Supermodel.
*/
#version 120
// Global uniforms
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 vec2 spotRange; // spotlight Z range: .x=start (viewspace coordinates), .y=limit
uniform vec3 spotColor; // spotlight RGB color
uniform float mapSize; // texture map size (2048,4096,6144 etc)
// Inputs from vertex shader
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 float fsTexFormat; // .x=T1RGB5 contour texture (if > 0)
varying float fsTransLevel; // translucence level, 0.0 (transparent) to 1.0 (opaque)
varying vec3 fsLightIntensity; // lighting intensity
varying float fsFogFactor; // fog factor
varying float fsViewZ; // Z distance to fragment from viewpoint at origin
/*
* WrapTexelCoords():
*
* Computes the normalized OpenGL S,T coordinates within the 2048x2048 texture
* sheet, taking into account wrapping behavior.
*
* Computing normalized OpenGL texture coordinates (0 to 1) within the
* Real3D texture sheet:
*
* If the texture is not mirrored, we simply have to clamp the
* coordinates to fit within the texture dimensions, add the texture
* X, Y position to select the appropriate one, and normalize by 2048
* (the dimensions of the Real3D texture sheet).
*
* = [(u,v)%(w,h)+(x,y)]/(2048,2048)
*
* If mirroring is enabled, textures are mirrored every odd multiple of
* the original texture. To detect whether we are in an odd multiple,
* simply divide the coordinate by the texture dimension and check
* whether the result is odd. Then, clamp the coordinates as before but
* 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)
* where M is 1.0 if the texture must be mirrored.
*
* As an optimization, this function computes TWO texture coordinates
* simultaneously. The first is texCoord.xy, the second is in .zw. The other
* parameters must have .xy = .zw.
*/
vec4 WrapTexelCoords(vec4 texCoord, vec4 texOffset, vec4 texSize, vec4 mirrorEnable)
{
vec4 clampedCoord, mirror, glTexCoord;
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
glTexCoord = ( mirror*(texSize-clampedCoord) +
(vec4(1.0,1.0,1.0,1.0)-mirror)*clampedCoord +
texOffset
) / mapSize;
/*
glTexCoord = ( mirror*(texSize-vec4(1.0,1.0,1.0,1.0)-clampedCoord) +
(vec4(1.0,1.0,1.0,1.0)-mirror)*clampedCoord +
texOffset
) / mapSize;
*/
return glTexCoord;
}
/*
* main():
*
* Fragment shader entry point.
*/
void main(void)
{
vec4 uv_top, uv_bot, c[4];
vec2 r;
vec4 fragColor;
vec2 ellipse;
vec3 lightIntensity;
float insideSpot;
// Get polygon color for untextured polygons (textured polygons will overwrite)
if (fsTexParams.x < 0.5)
fragColor = gl_Color;
else
// Textured polygons: set fragment color to texel value
{
fragColor = texture2D(textureMap,(fsSubTexture.xy+fsSubTexture.zw/2.0)/mapSize);
//fragColor += texture2D(textureMap,(fsSubTexture.xy+fsSubTexture.zw)/mapSize);
}
// Compute spotlight and apply lighting
ellipse = (gl_FragCoord.xy-spotEllipse.xy)/spotEllipse.zw;
insideSpot = dot(ellipse,ellipse);
if ((insideSpot <= 1.0) && (fsViewZ>=spotRange.x) && (fsViewZ<spotRange.y))
lightIntensity = fsLightIntensity+(1.0-insideSpot)*spotColor;
else
lightIntensity = fsLightIntensity;
fragColor.rgb *= lightIntensity;
// Translucency (modulates existing alpha channel for RGBA4 texels)
fragColor.a *= fsTransLevel;
// Apply fog under the control of fog factor setting from polygon header
fragColor.rgb = mix(gl_Fog.color.rgb, fragColor.rgb, fsFogFactor );
// Store final color
gl_FragColor = fragColor;
}

View file

@ -1,239 +0,0 @@
/**
** Supermodel
** A Sega Model 3 Arcade Emulator.
** Copyright 2011-2012 Bart Trzynadlowski, Nik Henson
**
** This file is part of Supermodel.
**
** 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
** Software Foundation, either version 3 of the License, or (at your option)
** any later version.
**
** Supermodel is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
** more details.
**
** You should have received a copy of the GNU General Public License along
** with Supermodel. If not, see <http://www.gnu.org/licenses/>.
**/
/*
* Fragment_MultiSheet.glsl
*
* Fragment shader for 3D rendering. Uses 8 texture sheets to decode the
* different possible formats.
*/
#version 120
// Global uniforms
uniform sampler2D textureMap0; // complete texture map (fmt 0), 2048x2048 texels
uniform sampler2D textureMap1; // complete texture map (fmt 1), 2048x2048 texels
uniform sampler2D textureMap2; // complete texture map (fmt 2), 2048x2048 texels
uniform sampler2D textureMap3; // complete texture map (fmt 3), 2048x2048 texels
uniform sampler2D textureMap4; // complete texture map (fmt 4), 2048x2048 texels
uniform sampler2D textureMap5; // complete texture map (fmt 5), 2048x2048 texels
uniform sampler2D textureMap6; // complete texture map (fmt 6), 2048x2048 texels
uniform sampler2D textureMap7; // complete texture map (fmt 7), 2048x2048 texels
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 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 float mapSize; // texture map size (2048,4096,6144 etc)
// Inputs from vertex shader
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 float fsTexFormat; // T1RGB5 contour texture (if > 0)
varying float fsTexMap; // texture map number
varying float fsTransLevel; // translucence level, 0.0 (transparent) to 1.0 (opaque)
varying vec3 fsLightIntensity; // lighting intensity
varying float fsSpecularTerm; // specular highlight
varying float fsFogFactor; // fog factor
varying float fsViewZ; // Z distance to fragment from viewpoint at origin
/*
* WrapTexelCoords():
*
* Computes the normalized OpenGL S,T coordinates within the 2048x2048 texture
* sheet, taking into account wrapping behavior.
*
* Computing normalized OpenGL texture coordinates (0 to 1) within the
* Real3D texture sheet:
*
* If the texture is not mirrored, we simply have to clamp the
* coordinates to fit within the texture dimensions, add the texture
* X, Y position to select the appropriate one, and normalize by 2048
* (the dimensions of the Real3D texture sheet).
*
* = [(u,v)%(w,h)+(x,y)]/(2048,2048)
*
* If mirroring is enabled, textures are mirrored every odd multiple of
* the original texture. To detect whether we are in an odd multiple,
* simply divide the coordinate by the texture dimension and check
* whether the result is odd. Then, clamp the coordinates as before but
* 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)
* where M is 1.0 if the texture must be mirrored.
*
* As an optimization, this function computes TWO texture coordinates
* simultaneously. The first is texCoord.xy, the second is in .zw. The other
* parameters must have .xy = .zw.
*/
vec4 WrapTexelCoords(vec4 texCoord, vec4 texOffset, vec4 texSize, vec4 mirrorEnable)
{
vec4 clampedCoord, mirror, glTexCoord;
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
glTexCoord = ( mirror*(texSize-clampedCoord) +
(vec4(1.0,1.0,1.0,1.0)-mirror)*clampedCoord +
texOffset
) / mapSize;
return glTexCoord;
}
/*
* main():
*
* Fragment shader entry point.
*/
void main(void)
{
vec4 uv_top, uv_bot, c[4];
vec2 r;
vec4 fragColor;
vec2 ellipse;
vec3 lightIntensity;
float insideSpot;
int x;
// Get polygon color for untextured polygons (textured polygons will overwrite)
if (fsTexParams.x < 0.5)
fragColor = gl_Color;
else
// Textured polygons: set fragment color to texel value
{
/*
* Bilinear Filtering
*
* In order to get this working on ATI, the number of operations is
* reduced by putting everything into vec4s. uv_top holds the UV
* coordinates for the top two texels (.xy=left, .zw=right) and uv_bot
* is for the lower two.
*/
// 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
r = uv_bot.xy-floor(uv_bot.xy); // fractional part
uv_bot.xy = floor(uv_bot.xy); // integral part
// 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.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);
// 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_bot = WrapTexelCoords(uv_bot,vec4(fsSubTexture.xy,fsSubTexture.xy),vec4(fsSubTexture.zw,fsSubTexture.zw), vec4(fsTexParams.zw,fsTexParams.zw));
// Fetch the texels from the given texture map
if (fsTexMap < 0.5f) {
c[0]=texture2D(textureMap0, uv_bot.xy); // bottom-left (base texel)
c[1]=texture2D(textureMap0, uv_bot.zw); // bottom-right
c[2]=texture2D(textureMap0, uv_top.xy); // top-left
c[3]=texture2D(textureMap0, uv_top.zw); // top-right
} else if (fsTexMap < 1.5f) {
c[0]=texture2D(textureMap1, uv_bot.xy); // bottom-left (base texel)
c[1]=texture2D(textureMap1, uv_bot.zw); // bottom-right
c[2]=texture2D(textureMap1, uv_top.xy); // top-left
c[3]=texture2D(textureMap1, uv_top.zw); // top-right
} else if (fsTexMap < 2.5f) {
c[0]=texture2D(textureMap2, uv_bot.xy); // bottom-left (base texel)
c[1]=texture2D(textureMap2, uv_bot.zw); // bottom-right
c[2]=texture2D(textureMap2, uv_top.xy); // top-left
c[3]=texture2D(textureMap2, uv_top.zw); // top-right
} else if (fsTexMap < 3.5f) {
c[0]=texture2D(textureMap3, uv_bot.xy); // bottom-left (base texel)
c[1]=texture2D(textureMap3, uv_bot.zw); // bottom-right
c[2]=texture2D(textureMap3, uv_top.xy); // top-left
c[3]=texture2D(textureMap3, uv_top.zw); // top-right
} else if (fsTexMap < 4.5f) {
c[0]=texture2D(textureMap4, uv_bot.xy); // bottom-left (base texel)
c[1]=texture2D(textureMap4, uv_bot.zw); // bottom-right
c[2]=texture2D(textureMap4, uv_top.xy); // top-left
c[3]=texture2D(textureMap4, uv_top.zw); // top-right
} else if (fsTexMap < 5.5f) {
c[0]=texture2D(textureMap5, uv_bot.xy); // bottom-left (base texel)
c[1]=texture2D(textureMap5, uv_bot.zw); // bottom-right
c[2]=texture2D(textureMap5, uv_top.xy); // top-left
c[3]=texture2D(textureMap5, uv_top.zw); // top-right
} else if (fsTexMap < 6.5f) {
c[0]=texture2D(textureMap6, uv_bot.xy); // bottom-left (base texel)
c[1]=texture2D(textureMap6, uv_bot.zw); // bottom-right
c[2]=texture2D(textureMap6, uv_top.xy); // top-left
c[3]=texture2D(textureMap6, uv_top.zw); // top-right
} else {
c[0]=texture2D(textureMap7, uv_bot.xy); // bottom-left (base texel)
c[1]=texture2D(textureMap7, uv_bot.zw); // bottom-right
c[2]=texture2D(textureMap7, uv_top.xy); // top-left
c[3]=texture2D(textureMap7, uv_top.zw); // top-right
}
// 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);
// Faster method:
c[0] += (c[1]-c[0])*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
/*
* T1RGB5:
*
* The transparency bit determines whether to discard pixels (if set).
* What is unknown is how this bit behaves when interpolated. OpenGL
* processes it as an alpha value, so it might concievably be blended
* with neighbors. Here, an arbitrary threshold is chosen.
*
* To-do: blending could probably enabled and this would work even
* better with a hard threshold.
*
* Countour processing also seems to be enabled for RGBA4 textures.
* When the alpha value is 0.0 (or close), pixels are discarded
* entirely.
*/
if (fsTexParams.y > 0.5) // contour processing enabled
{
if (fragColor.a < 0.01) // discard anything with alpha == 0
discard;
}
// 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 map
fragColor.a = 1.0;
}
// Compute spotlight and apply lighting
ellipse = (gl_FragCoord.xy-spotEllipse.xy)/spotEllipse.zw;
insideSpot = dot(ellipse,ellipse);
if ((insideSpot <= 1.0) && (fsViewZ>=spotRange.x) && (fsViewZ<spotRange.y))
lightIntensity = fsLightIntensity+(1.0-insideSpot)*spotColor;
else
lightIntensity = fsLightIntensity;
fragColor.rgb *= lightIntensity;
fragColor.rgb += vec3(fsSpecularTerm,fsSpecularTerm,fsSpecularTerm);
// Translucency (modulates existing alpha channel for RGBA4 texels)
fragColor.a *= fsTransLevel;
// Apply fog under the control of fog factor setting from polygon header
fragColor.rgb = mix(gl_Fog.color.rgb, fragColor.rgb, fsFogFactor);
// Store final color
gl_FragColor = fragColor;
}

View file

@ -1,202 +0,0 @@
/**
** Supermodel
** A Sega Model 3 Arcade Emulator.
** Copyright 2011 Bart Trzynadlowski, Nik Henson
**
** This file is part of Supermodel.
**
** 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
** Software Foundation, either version 3 of the License, or (at your option)
** any later version.
**
** Supermodel is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
** more details.
**
** You should have received a copy of the GNU General Public License along
** with Supermodel. If not, see <http://www.gnu.org/licenses/>.
**/
/*
* Fragment_NoSpotlight.glsl
*
* Fragment shader for 3D rendering. Spotlight effect removed. Fixes fragment
* shader link errors on older ATI Radeon GPUs.
*
* To load external fragment shaders, use the -frag-shader=<file> option when
* starting Supermodel.
*/
#version 120
// Global uniforms
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 vec2 spotRange; // spotlight Z range: .x=start (viewspace coordinates), .y=limit
uniform vec3 spotColor; // spotlight RGB color
uniform float mapSize; // texture map size (2048,4096,6144 etc)
// Inputs from vertex shader
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 float fsTexFormat; // .x=T1RGB5 contour texture (if > 0)
varying float fsTransLevel; // translucence level, 0.0 (transparent) to 1.0 (opaque)
varying vec3 fsLightIntensity; // lighting intensity
varying float fsFogFactor; // fog factor
varying float fsViewZ; // Z distance to fragment from viewpoint at origin
/*
* WrapTexelCoords():
*
* Computes the normalized OpenGL S,T coordinates within the 2048x2048 texture
* sheet, taking into account wrapping behavior.
*
* Computing normalized OpenGL texture coordinates (0 to 1) within the
* Real3D texture sheet:
*
* If the texture is not mirrored, we simply have to clamp the
* coordinates to fit within the texture dimensions, add the texture
* X, Y position to select the appropriate one, and normalize by 2048
* (the dimensions of the Real3D texture sheet).
*
* = [(u,v)%(w,h)+(x,y)]/(2048,2048)
*
* If mirroring is enabled, textures are mirrored every odd multiple of
* the original texture. To detect whether we are in an odd multiple,
* simply divide the coordinate by the texture dimension and check
* whether the result is odd. Then, clamp the coordinates as before but
* 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)
* where M is 1.0 if the texture must be mirrored.
*
* As an optimization, this function computes TWO texture coordinates
* simultaneously. The first is texCoord.xy, the second is in .zw. The other
* parameters must have .xy = .zw.
*/
vec4 WrapTexelCoords(vec4 texCoord, vec4 texOffset, vec4 texSize, vec4 mirrorEnable)
{
vec4 clampedCoord, mirror, glTexCoord;
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
glTexCoord = ( mirror*(texSize-clampedCoord) +
(vec4(1.0,1.0,1.0,1.0)-mirror)*clampedCoord +
texOffset
) / mapSize;
/*
glTexCoord = ( mirror*(texSize-vec4(1.0,1.0,1.0,1.0)-clampedCoord) +
(vec4(1.0,1.0,1.0,1.0)-mirror)*clampedCoord +
texOffset
) / mapSize;
*/
return glTexCoord;
}
/*
* main():
*
* Fragment shader entry point.
*/
void main(void)
{
vec4 uv_top, uv_bot, c[4];
vec2 r;
vec4 fragColor;
vec2 ellipse;
vec3 lightIntensity;
float insideSpot;
// Get polygon color for untextured polygons (textured polygons will overwrite)
if (fsTexParams.x < 0.5)
fragColor = gl_Color;
else
// Textured polygons: set fragment color to texel value
{
/*
* Bilinear Filtering
*
* In order to get this working on ATI, the number of operations is
* reduced by putting everything into vec4s. uv_top holds the UV
* coordinates for the top two texels (.xy=left, .zw=right) and uv_bot
* is for the lower two.
*/
// 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
r = uv_bot.xy-floor(uv_bot.xy); // fractional part
uv_bot.xy = floor(uv_bot.xy); // integral part
// 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.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);
// 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_bot = WrapTexelCoords(uv_bot,vec4(fsSubTexture.xy,fsSubTexture.xy),vec4(fsSubTexture.zw,fsSubTexture.zw), vec4(fsTexParams.zw,fsTexParams.zw));
// Fetch the texels
c[0]=texture2D(textureMap,uv_bot.xy); // bottom-left (base texel)
c[1]=texture2D(textureMap,uv_bot.zw); // bottom-right
c[2]=texture2D(textureMap,uv_top.xy); // top-left
c[3]=texture2D(textureMap,uv_top.zw); // top-right
// 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);
// Faster method:
c[0] += (c[1]-c[0])*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
/*
* T1RGB5:
*
* The transparency bit determines whether to discard pixels (if set).
* What is unknown is how this bit behaves when interpolated. OpenGL
* processes it as an alpha value, so it might concievably be blended
* with neighbors. Here, an arbitrary threshold is chosen.
*
* To-do: blending could probably enabled and this would work even
* better with a hard threshold.
*
* Countour processing also seems to be enabled for RGBA4 textures.
* When the alpha value is 0.0 (or close), pixels are discarded
* entirely.
*/
if (fsTexParams.y > 0.5) // contour processing enabled
{
if (fragColor.a < 0.01) // discard anything with alpha == 0
discard;
}
// 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 map
fragColor.a = 1.0;
}
// Compute spotlight and apply lighting
/***
ellipse = (gl_FragCoord.xy-spotEllipse.xy)/spotEllipse.zw;
insideSpot = dot(ellipse,ellipse);
if ((insideSpot <= 1.0) && (fsViewZ>=spotRange.x) && (fsViewZ<spotRange.y))
lightIntensity = fsLightIntensity+(1.0-insideSpot)*spotColor;
else
lightIntensity = fsLightIntensity;
fragColor.rgb *= lightIntensity;
***/
fragColor.rgb *= fsLightIntensity;
// Translucency (modulates existing alpha channel for RGBA4 texels)
fragColor.a *= fsTransLevel;
// Apply fog under the control of fog factor setting from polygon header
fragColor.rgb = mix(gl_Fog.color.rgb, fragColor.rgb, fsFogFactor );
// Store final color
gl_FragColor = fragColor;
}

View file

@ -1,181 +0,0 @@
/**
** Supermodel
** A Sega Model 3 Arcade Emulator.
** Copyright 2011-2012 Bart Trzynadlowski, Nik Henson
**
** This file is part of Supermodel.
**
** 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
** Software Foundation, either version 3 of the License, or (at your option)
** any later version.
**
** Supermodel is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
** more details.
**
** You should have received a copy of the GNU General Public License along
** with Supermodel. If not, see <http://www.gnu.org/licenses/>.
**/
/*
* Vertex.glsl
*
* Vertex shader for 3D rendering.
*/
#version 120
// Global uniforms
uniform mat4 modelViewMatrix; // model -> view space matrix
uniform mat4 projectionMatrix; // view space -> screen space matrix
uniform vec3 lighting[2]; // lighting state (lighting[0] = sun direction, lighting[1].x,y = diffuse, ambient intensities from 0-1.0)
uniform vec4 spotEllipse; // spotlight ellipse position: .x=X position (normalized device coordinates), .y=Y position, .z=half-width, .w=half-height)
uniform vec2 spotRange; // spotlight Z range: .x=start (viewspace coordinates), .y=limit
uniform vec3 spotColor; // spotlight RGB color
// Custom vertex attributes
attribute vec4 subTexture; // .x=texture X, .y=texture Y, .z=texture width, .w=texture height (all in texels)
attribute vec4 texParams; // .x=texture enable (if 1, else 0), .y=use transparency (if >=0), .z=U wrap mode (1=mirror, 0=repeat), .w=V wrap mode
attribute float texFormat; // T1RGB5 contour texture (if > 0)
attribute float texMap; // texture map number
attribute float transLevel; // translucence level, 0.0 (transparent) to 1.0 (opaque). if less than 1.0, replace alpha value
attribute float lightEnable; // lighting enabled (1.0) or luminous (0.0), drawn at full intensity
attribute float shininess; // specular shininess (if >= 0.0) or disable specular lighting (negative)
attribute float fogIntensity; // fog intensity (1.0, full fog effect, 0.0, no fog)
// Custom outputs to fragment shader
varying vec4 fsSubTexture;
varying vec4 fsTexParams;
varying float fsTexFormat;
varying float fsTexMap;
varying float fsTransLevel;
varying vec3 fsLightIntensity; // total light intensity for this vertex
varying float fsSpecularTerm; // specular light term (additive)
varying float fsFogFactor; // fog factor
varying float fsViewZ;
// Gets the 3x3 matrix out of a 4x4 (because mat3(mat4matrix) does not work on ATI!)
mat3 GetLinearPart( mat4 m )
{
mat3 result;
result[0][0] = m[0][0];
result[0][1] = m[0][1];
result[0][2] = m[0][2];
result[1][0] = m[1][0];
result[1][1] = m[1][1];
result[1][2] = m[1][2];
result[2][0] = m[2][0];
result[2][1] = m[2][1];
result[2][2] = m[2][2];
return result;
}
void main(void)
{
vec3 viewVertex; // vertex coordinates in view space
vec3 viewNormal; // vertex normal in view space
vec3 sunVector; // sun lighting vector (as reflecting away from vertex)
float sunFactor; // sun light projection along vertex normal (0.0 to 1.0)
vec3 halfway;
float specFactor;
// Transform vertex
gl_Position = projectionMatrix * modelViewMatrix * gl_Vertex;
viewVertex = vec3(modelViewMatrix * gl_Vertex);
/*
* Modulation
*
* Polygon color serves as material color (modulating the light intensity)
* for textured polygons. The fragment shader will ignore (overwrite) the
* the color passed to it if the fragment is textured.
*
* Untextured fragments must be set to the polygon color and the light
* intensity is initialized to 1.0 here. Alpha must be set to 1.0 because
* the fragment shader multiplies it by the polygon translucency setting.
*
* TO-DO: Does OpenGL set alpha to 1.0 by default if no alpha is specified
* for the vertex? If so, we can remove that line from here.
*/
gl_FrontColor = gl_Color; // untextured polygons will use this
gl_FrontColor.a = 1.0;
fsLightIntensity = vec3(1.0,1.0,1.0);
if (texParams.x > 0.5) // textured
fsLightIntensity *= gl_Color.rgb;
/*
* Sun Light
*
* Parallel light source and ambient lighting are only applied for non-
* luminous polygons.
*/
fsSpecularTerm = 0.0;
if (lightEnable > 0.5) // not luminous
{
// Normal -> view space
viewNormal = normalize(GetLinearPart(modelViewMatrix)*gl_Normal);
// Real3D -> OpenGL view space convention (TO-DO: do this outside of shader)
sunVector = lighting[0]*vec3(1.0,-1.0,-1.0);
// Compute diffuse factor for sunlight
sunFactor = max(dot(sunVector,viewNormal),0.0);
// Total light intensity: sum of all components
fsLightIntensity *= (sunFactor*lighting[1].x+lighting[1].y);
/*
* Specular Lighting
*
* The specular term is treated similarly to the "separate specular
* color" functionality of OpenGL: it is added as a highlight in the
* fragment shader. This allows even black textures to be lit.
*
* TO-DO: Ambient intensity viewport parameter is known but what about
* the intensity of the specular term? Always applied with full
* intensity here but this is unlikely to be correct.
*/
if (shininess >= 0.0)
{
// Standard specular lighting equation
vec3 V = normalize(-viewVertex);
vec3 H = normalize(sunVector+V); // halfway vector
float s = max(10.0,64.0-shininess); // seems to look nice, but probably not correct
fsSpecularTerm = pow(max(dot(viewNormal,H),0.0),s);
if (sunFactor <= 0.0) fsSpecularTerm = 0.0;
// Faster approximation
//float temp = max(dot(viewNormal,H),0.0);
//float s = 64.0-shininess;
//fsSpecularTerm = temp/(s-temp*s+temp);
// Phong formula
//vec3 R = normalize(2.0*dot(sunVector,viewNormal)*viewNormal - sunVector);
//vec3 V = normalize(-viewVertex);
//float s = max(2.0,64.0-shininess);
//fsSpecularTerm = pow(max(dot(R,V),0.0),s);
}
}
// Fog
float z = length(viewVertex);
fsFogFactor = clamp(1.0-fogIntensity*(gl_Fog.start+z*gl_Fog.density), 0.0, 1.0);
// Pass viewspace Z coordinate (for spotlight)
fsViewZ = -viewVertex.z; // convert Z from GL->Real3D convention (want +Z to be further into screen)
// Pass remaining parameters to fragment shader
gl_TexCoord[0] = gl_MultiTexCoord0;
fsSubTexture = subTexture;
fsTexParams = texParams;
fsTransLevel = transLevel;
fsTexFormat = texFormat;
fsTexMap = texMap;
}

View file

@ -1,34 +0,0 @@
/**
** Supermodel
** A Sega Model 3 Arcade Emulator.
** Copyright 2011-2012 Bart Trzynadlowski, Nik Henson
**
** This file is part of Supermodel.
**
** 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
** Software Foundation, either version 3 of the License, or (at your option)
** any later version.
**
** Supermodel is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
** more details.
**
** You should have received a copy of the GNU General Public License along
** with Supermodel. If not, see <http://www.gnu.org/licenses/>.
**/
/*
* Vertex2D.glsl
*
* Vertex shader for 2D tilemap rendering.
*/
#version 120
void main(void)
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = gl_ModelViewProjectionMatrix*gl_Vertex;
}