diff --git a/Src/Graphics/Shaders/DIR.txt b/Src/Graphics/Shaders/DIR.txt deleted file mode 100644 index fca6919..0000000 --- a/Src/Graphics/Shaders/DIR.txt +++ /dev/null @@ -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. \ No newline at end of file diff --git a/Src/Graphics/Shaders/Fragment.glsl b/Src/Graphics/Shaders/Fragment.glsl deleted file mode 100644 index fb2804e..0000000 --- a/Src/Graphics/Shaders/Fragment.glsl +++ /dev/null @@ -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 . - **/ - -/* - * 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. - **/ - -/* - * 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); -} diff --git a/Src/Graphics/Shaders/Fragment_Flat.glsl b/Src/Graphics/Shaders/Fragment_Flat.glsl deleted file mode 100644 index d1af1c4..0000000 --- a/Src/Graphics/Shaders/Fragment_Flat.glsl +++ /dev/null @@ -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 . - **/ - -/* - * 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= 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. - **/ - -/* - * 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. - **/ - -/* - * 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= 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. - **/ - -/* - * 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; -} diff --git a/Src/Graphics/Shaders/Vertex2D.glsl b/Src/Graphics/Shaders/Vertex2D.glsl deleted file mode 100644 index 3c286df..0000000 --- a/Src/Graphics/Shaders/Vertex2D.glsl +++ /dev/null @@ -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 . - **/ - -/* - * Vertex2D.glsl - * - * Vertex shader for 2D tilemap rendering. - */ - -#version 120 - -void main(void) -{ - gl_TexCoord[0] = gl_MultiTexCoord0; - gl_Position = gl_ModelViewProjectionMatrix*gl_Vertex; -} \ No newline at end of file