Merge pull request #724 from ImJezze/master

HLSL refactoring
This commit is contained in:
Scott Stone 2016-03-17 20:27:10 -04:00
commit ba499f3860
29 changed files with 1032 additions and 1306 deletions

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

View File

@ -8,8 +8,6 @@ yiq_enable 0/1 Enables YIQ-colorspace post-processing.
NTSC TV appearance on TV-based systems when configured
properly.
hlslpath [path] Path to the .fx files that are in use. (default: hlsl)
hlsl_prescale_x [horizontal] HLSL pre-scale override factor for X. (0 for auto)
hlsl_prescale_y [vertical] HLSL pre-scale override factor for Y. (0 for auto)
hlsl_write [filename] Enables HLSL AVI writing. (huge disk bandwidth suggested)
hlsl_snap_width [width] HLSL upscaled-snapshot width. (default: 2048)
hlsl_snap_height [height] HLSL upscaled-snapshot height. (default: 1536)
@ -104,17 +102,17 @@ vector_length_ratio 500.0 Vector fade length (4.0 - vectors fade t
Bloom Post-Processing Options
-----------------------------
Name Default Values Description
bloom_blend_mode 0 or 1 0 for addition blend mode or 1 for darken blend mode.
bloom_scale 0.500 Bloom intensity factor. (0.000-2.000)
bloom_overdrive 0.00,0.00,0.00 Bloom overdrive factor to bright full saturated colors. (0.000-2.000)
bloom_blend_mode 0 or 1 0 for brighten blend mode or 1 for darken blend mode.
bloom_scale 0.0 Bloom intensity factor. (0.000-2.000)
bloom_overdrive 0.0,0.0,0.0 Bloom overdrive factor to bright full saturated colors. (0.000-2.000)
bloom_lvl0_weight 1.00 Bloom level 0 (full-size target) weight. (0.00-1.00)
bloom_lvl1_weight 0.21 Bloom level 1 (half-size target) weight. (0.00-1.00)
bloom_lvl2_weight 0.19 Bloom level 2 (quarter-size target) weight. (0.00-1.00)
bloom_lvl3_weight 0.17 Bloom level 3 (.) weight. (0.00-1.00)
bloom_lvl4_weight 0.14 Bloom level 4 (.) weight. (0.00-1.00)
bloom_lvl5_weight 0.14 Bloom level 5 (.) weight. (0.00-1.00)
bloom_lvl6_weight 0.13 Bloom level 6 (.) weight. (0.00-1.00)
bloom_lvl7_weight 0.12 Bloom level 7 (.) weight. (0.00-1.00)
bloom_lvl8_weight 0.11 Bloom level 8 (.) weight. (0.00-1.00)
bloom_lvl9_weight 0.10 Bloom level 9 (.) weight. (0.00-1.00)
bloom_lvl10_weight 0.09 Bloom level 10 (1x1 target) weight. (0.00-1.00)
bloom_lvl1_weight 0.64 Bloom level 1 (1/2-size target) weight. (0.00-1.00)
bloom_lvl2_weight 0.32 Bloom level 2 (1/4-size target) weight. (0.00-1.00)
bloom_lvl3_weight 0.16 Bloom level 3 (1/8-size target) weight. (0.00-1.00)
bloom_lvl4_weight 0.08 Bloom level 4 (1/16-size target) weight. (0.00-1.00)
bloom_lvl5_weight 0.04 Bloom level 5 (1/32-size target) weight. (0.00-1.00)
bloom_lvl6_weight 0.04 Bloom level 6 (1/64-size target) weight. (0.00-1.00)
bloom_lvl7_weight 0.02 Bloom level 7 (1/128-size target) weight. (0.00-1.00)
bloom_lvl8_weight 0.02 Bloom level 8 (1/256-size target) weight. (0.00-1.00)
bloom_lvl9_weight 0.01 Bloom level 9 (1/512-size target) weight. (0.00-1.00)
bloom_lvl10_weight 0.01 Bloom level 10 (1/1024-size target) weight. (0.00-1.00)

View File

@ -1,101 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:ImJezze
//-----------------------------------------------------------------------------
// Distortion Effect
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Sampler Definitions
//-----------------------------------------------------------------------------
texture DiffuseTexture;
sampler DiffuseSampler = sampler_state
{
Texture = <DiffuseTexture>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
AddressU = CLAMP;
AddressV = CLAMP;
AddressW = CLAMP;
};
//-----------------------------------------------------------------------------
// Vertex Definitions
//-----------------------------------------------------------------------------
struct VS_INPUT
{
float4 Position : POSITION;
float4 Color : COLOR0;
float2 TexCoord : TEXCOORD0;
};
struct VS_OUTPUT
{
float4 Position : POSITION;
float4 Color : COLOR0;
float2 TexCoord : TEXCOORD0;
};
struct PS_INPUT
{
float4 Color : COLOR0;
float2 TexCoord : TEXCOORD0;
};
//-----------------------------------------------------------------------------
// Distortion Vertex Shader
//-----------------------------------------------------------------------------
uniform float2 ScreenDims; // size of the window or fullscreen
uniform float2 TargetDims;
VS_OUTPUT vs_main(VS_INPUT Input)
{
VS_OUTPUT Output = (VS_OUTPUT)0;
Output.Position = float4(Input.Position.xyz, 1.0f);
Output.Position.xy /= ScreenDims;
Output.Position.y = 1.0f - Output.Position.y; // flip y
Output.Position.xy -= 0.5f; // center
Output.Position.xy *= 2.0f; // zoom
Output.Color = Input.Color;
Output.TexCoord = Input.Position.xy / ScreenDims;
Output.TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9)
return Output;
}
//-----------------------------------------------------------------------------
// Post-Processing Pixel Shader
//-----------------------------------------------------------------------------
float4 ps_main(PS_INPUT Input) : COLOR
{
float2 BaseCoord = Input.TexCoord;
// Color
float4 BaseColor = tex2D(DiffuseSampler, BaseCoord);
BaseColor.a = 1.0f;
return BaseColor;
}
//-----------------------------------------------------------------------------
// Distortion Effect
//-----------------------------------------------------------------------------
technique DefaultTechnique
{
pass Pass0
{
Lighting = FALSE;
VertexShader = compile vs_3_0 vs_main();
PixelShader = compile ps_3_0 ps_main();
}
}

View File

@ -1,535 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz,ImJezze
//-----------------------------------------------------------------------------
// Scanline, Shadowmask & Distortion Effect
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Sampler Definitions
//-----------------------------------------------------------------------------
texture DiffuseTexture;
sampler DiffuseSampler = sampler_state
{
Texture = <DiffuseTexture>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
AddressU = CLAMP;
AddressV = CLAMP;
AddressW = CLAMP;
};
texture ShadowTexture;
sampler ShadowSampler = sampler_state
{
Texture = <ShadowTexture>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
AddressU = WRAP;
AddressV = WRAP;
AddressW = WRAP;
};
//-----------------------------------------------------------------------------
// Vertex Definitions
//-----------------------------------------------------------------------------
struct VS_INPUT
{
float4 Position : POSITION;
float4 Color : COLOR0;
float2 TexCoord : TEXCOORD0;
};
struct VS_OUTPUT
{
float4 Position : POSITION;
float4 Color : COLOR0;
float2 TexCoord : TEXCOORD0;
float2 ScreenCoord : TEXCOORD1;
};
struct PS_INPUT
{
float4 Color : COLOR0;
float2 TexCoord : TEXCOORD0;
float2 ScreenCoord : TEXCOORD1;
};
//-----------------------------------------------------------------------------
// Constants
//-----------------------------------------------------------------------------
static const float Epsilon = 1.0e-7f;
static const float PI = 3.1415927f;
static const float PHI = 1.618034f;
static const float E = 2.7182817f;
static const float Gelfond = 23.140692f; // e^pi (Gelfond constant)
static const float GelfondSchneider = 2.6651442f; // 2^sqrt(2) (Gelfond-Schneider constant)
//-----------------------------------------------------------------------------
// Functions
//-----------------------------------------------------------------------------
// www.stackoverflow.com/questions/5149544/can-i-generate-a-random-number-inside-a-pixel-shader/
float random(float2 seed)
{
// irrationals for pseudo randomness
float2 i = float2(Gelfond, GelfondSchneider);
return frac(cos(dot(seed, i)) * 123456.0f);
}
// www.dinodini.wordpress.com/2010/04/05/normalized-tunable-sigmoid-functions/
float normalizedSigmoid(float n, float k)
{
// valid for n and k in range of -1.0 and 1.0
return (n - n * k) / (k - abs(n) * 2.0f * k + 1);
}
// www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
float roundBox(float2 p, float2 b, float r)
{
return length(max(abs(p) - b + r, 0.0f)) - r;
}
//-----------------------------------------------------------------------------
// Scanline, Shadowmask & Distortion Vertex Shader
//-----------------------------------------------------------------------------
uniform float2 ScreenDims; // size of the window or fullscreen
uniform float2 SourceDims; // size of the texture in power-of-two size
uniform float2 SourceRect; // size of the uv rectangle
uniform float2 TargetDims; // size of the target surface
uniform float2 QuadDims; // size of the screen quad
uniform float2 ShadowDims = float2(32.0f, 32.0f); // size of the shadow texture (extended to power-of-two size)
uniform float2 ShadowUVOffset = float2(0.0f, 0.0f);
uniform bool SwapXY = false;
uniform int RotationType = 0; // 0 = 0°, 1 = 90°, 2 = 180°, 3 = 270°
uniform bool PrepareBloom = false; // disables some effects for rendering bloom textures
uniform bool PrepareVector = false;
VS_OUTPUT vs_main(VS_INPUT Input)
{
VS_OUTPUT Output = (VS_OUTPUT)0;
float2 shadowUVOffset = ShadowUVOffset;
shadowUVOffset = SwapXY
? shadowUVOffset.yx
: shadowUVOffset.xy;
float2 ScreenCoordOffset = 0.0f;
ScreenCoordOffset += shadowUVOffset;
Output.ScreenCoord = Input.Position.xy;
Output.ScreenCoord += ScreenCoordOffset;
Output.Position = float4(Input.Position.xyz, 1.0f);
Output.Position.xy /= ScreenDims;
Output.Position.y = 1.0f - Output.Position.y; // flip y
Output.Position.xy -= 0.5f; // center
Output.Position.xy *= 2.0f; // zoom
Output.TexCoord = PrepareVector
? Input.Position.xy / ScreenDims
: Input.TexCoord;
Output.TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9)
Output.Color = Input.Color;
return Output;
}
//-----------------------------------------------------------------------------
// Scanline, Shadowmask & Distortion Pixel Shader
//-----------------------------------------------------------------------------
uniform float HumBarHertzRate = 60.0f / 59.94f - 1.0f; // difference between the 59.94 Hz field rate and 60 Hz line frequency (NTSC)
uniform float HumBarAlpha = 0.0f;
uniform float TimeMilliseconds = 0.0f;
uniform float2 ScreenScale = float2(1.0f, 1.0f);
uniform float2 ScreenOffset = float2(0.0f, 0.0f);
uniform float ScanlineAlpha = 1.0f;
uniform float ScanlineScale = 1.0f;
uniform float ScanlineBrightScale = 1.0f;
uniform float ScanlineBrightOffset = 1.0f;
uniform float ScanlineOffset = 1.0f;
uniform float ScanlineHeight = 1.0f;
uniform float3 BackColor = float3(0.0f, 0.0f, 0.0f);
uniform float CurvatureAmount = 1.0f;
uniform float RoundCornerAmount = 0.0f;
uniform float SmoothBorderAmount = 0.0f;
uniform float VignettingAmount = 0.0f;
uniform float ReflectionAmount = 0.0f;
uniform int ShadowTileMode = 0; // 0 based on screen dimension, 1 based on source dimension
uniform float ShadowAlpha = 0.0f;
uniform float2 ShadowCount = float2(6.0f, 6.0f);
uniform float2 ShadowUV = float2(0.25f, 0.25f);
uniform float3 Power = float3(1.0f, 1.0f, 1.0f);
uniform float3 Floor = float3(0.0f, 0.0f, 0.0f);
float2 GetRatioCorrection()
{
if (PrepareVector)
{
float ScreenRatio = ScreenDims.x / ScreenDims.y;
float QuadRatio = QuadDims.x / QuadDims.y;
float ScreenQuadRatio = QuadRatio / ScreenRatio;
return ScreenQuadRatio > 1.0f
? float2(1.0, 1.0f / ScreenQuadRatio)
: float2(ScreenQuadRatio, 1.0);
}
else
{
return SourceRect;
}
}
float GetNoiseFactor(float n, float random)
{
// smaller n become more noisy
return 1.0f + random * max(0.0f, 0.25f * pow(E, -8 * n));
}
float GetVignetteFactor(float2 coord, float amount)
{
float2 VignetteCoord = coord;
float VignetteLength = length(VignetteCoord);
float VignetteBlur = (amount * 0.75f) + 0.25;
// 0.5 full screen fitting circle
float VignetteRadius = 1.0f - (amount * 0.25f);
float Vignette = smoothstep(VignetteRadius, VignetteRadius - VignetteBlur, VignetteLength);
return saturate(Vignette);
}
float GetSpotAddend(float2 coord, float amount)
{
float2 RatioCorrection = GetRatioCorrection();
// normalized screen canvas ratio
float2 CanvasRatio = PrepareVector
? float2(1.0f, QuadDims.y / QuadDims.x)
: float2(1.0f, SwapXY
? QuadDims.x / QuadDims.y
: QuadDims.y / QuadDims.x);
// upper right quadrant
float2 spotOffset = PrepareVector
? RotationType == 1 // 90°
? float2(-0.25f, -0.25f)
: RotationType == 2 // 180°
? float2(0.25f, -0.25f)
: RotationType == 3 // 270°
? float2(0.25f, 0.25f)
: float2(-0.25f, 0.25f)
: SwapXY
? float2(0.25f, 0.25f)
: float2(-0.25f, 0.25f);
float2 SpotCoord = coord;
SpotCoord += spotOffset * RatioCorrection;
SpotCoord *= CanvasRatio;
SpotCoord /= RatioCorrection;
float SpotBlur = amount;
// 0.5 full screen fitting circle
float SpotRadius = amount * 0.75f;
float Spot = smoothstep(SpotRadius, SpotRadius - SpotBlur, length(SpotCoord));
float SigmoidSpot = amount * normalizedSigmoid(Spot, 0.75);
// increase strength by 100%
SigmoidSpot = SigmoidSpot * 2.0f;
return saturate(SigmoidSpot);
}
float GetRoundCornerFactor(float2 coord, float radiusAmount, float smoothAmount)
{
float2 RatioCorrection = GetRatioCorrection();
// reduce smooth amount down to radius amount
smoothAmount = min(smoothAmount, radiusAmount);
float2 CanvasDims = PrepareVector
? ScreenDims
: SwapXY
? QuadDims.yx / SourceRect
: QuadDims.xy / SourceRect;
coord = PrepareVector
? coord
: coord - 1.0f / SourceDims; // alignment correction (raster graphics)
float range = min(QuadDims.x, QuadDims.y) * 0.5;
float radius = range * max(radiusAmount, 0.0025f);
float smooth = 1.0 / (range * max(smoothAmount, 0.0025f));
// compute box
float box = roundBox(CanvasDims * (coord * 2.0f), CanvasDims * RatioCorrection, radius);
// apply smooth
box *= smooth;
box += 1.0f - pow(smooth * 0.5f, 0.5f);
float border = smoothstep(1.0f, 0.0f, box);
return saturate(border);
}
// www.francois-tarlier.com/blog/cubic-lens-distortion-shader/
float2 GetDistortedCoords(float2 centerCoord, float amount)
{
// lens distortion coefficient
float k = amount;
// cubic distortion value
float kcube = amount * 2.0f;
// compute cubic distortion factor
float r2 = centerCoord.x * centerCoord.x + centerCoord.y * centerCoord.y;
float f = kcube == 0.0f
? 1.0f + r2 * k
: 1.0f + r2 * (k + kcube * sqrt(r2));
// fit screen bounds
f /= 1.0f + amount * 0.5f;
// apply cubic distortion factor
centerCoord *= f;
return centerCoord;
}
float2 GetCoords(float2 coord, float2 centerOffset, float distortionAmount)
{
float2 RatioCorrection = GetRatioCorrection();
// center coordinates
coord -= centerOffset;
// apply ratio difference between screen and quad
coord /= RatioCorrection;
// distort coordinates
coord = GetDistortedCoords(coord, distortionAmount);
// revert ratio difference between screen and quad
coord *= RatioCorrection;
// un-center coordinates
coord += centerOffset;
return coord;
}
float2 GetAdjustedCoords(float2 coord, float2 centerOffset, float distortionAmount)
{
float2 RatioCorrection = GetRatioCorrection();
// center coordinates
coord -= centerOffset;
// apply ratio difference between screen and quad
coord /= RatioCorrection;
// apply screen scale
coord /= ScreenScale;
// distort coordinates
coord = GetDistortedCoords(coord, distortionAmount);
// revert ratio difference between screen and quad
coord *= RatioCorrection;
// un-center coordinates
coord += centerOffset;
// apply screen offset
coord += (centerOffset * 2.0) * ScreenOffset;
return coord;
}
float4 ps_main(PS_INPUT Input) : COLOR
{
float2 ScreenTexelDims = 1.0f / ScreenDims;
float2 SourceTexelDims = 1.0f / SourceDims;
float2 HalfSourceRect = SourceRect * 0.5f;
float2 ScreenCoord = Input.ScreenCoord / ScreenDims;
ScreenCoord = GetCoords(ScreenCoord, float2(0.5f, 0.5f), CurvatureAmount * 0.25f); // reduced amount
float2 DistortionCoord = Input.TexCoord;
DistortionCoord = GetCoords(DistortionCoord, HalfSourceRect, CurvatureAmount * 0.25f); // reduced amount
float2 BaseCoord = Input.TexCoord;
BaseCoord = GetAdjustedCoords(BaseCoord, HalfSourceRect, CurvatureAmount * 0.25f); // reduced amount
float2 DistortionCoordCentered = DistortionCoord;
DistortionCoordCentered -= HalfSourceRect;
float2 BaseCoordCentered = BaseCoord;
BaseCoordCentered -= HalfSourceRect;
float4 BaseColor = tex2D(DiffuseSampler, BaseCoord);
BaseColor.a = 1.0f;
if (BaseCoord.x < 0.0f || BaseCoord.y < 0.0f)
{
BaseColor.rgb = 0.0f;
}
// Mask Simulation (may not affect bloom)
if (!PrepareBloom && ShadowAlpha > 0.0f)
{
float2 shadowDims = ShadowDims;
shadowDims = SwapXY
? shadowDims.yx
: shadowDims.xy;
float2 shadowUV = ShadowUV;
// shadowUV = SwapXY
// ? shadowUV.yx
// : shadowUV.xy;
float2 screenCoord = ShadowTileMode == 0 ? ScreenCoord : BaseCoord;
screenCoord = SwapXY
? screenCoord.yx
: screenCoord.xy;
float2 shadowCount = ShadowCount;
shadowCount = SwapXY
? shadowCount.yx
: shadowCount.xy;
float2 shadowTile = ((ShadowTileMode == 0 ? ScreenTexelDims : SourceTexelDims) * shadowCount);
shadowTile = SwapXY
? shadowTile.yx
: shadowTile.xy;
float2 ShadowFrac = frac(screenCoord / shadowTile);
float2 ShadowCoord = (ShadowFrac * shadowUV);
ShadowCoord += 0.5f / shadowDims; // half texel offset
// ShadowCoord = SwapXY
// ? ShadowCoord.yx
// : ShadowCoord.xy;
float4 ShadowColor = tex2D(ShadowSampler, ShadowCoord);
float3 ShadowMaskColor = lerp(1.0f, ShadowColor.rgb, ShadowAlpha);
float ShadowMaskClear = (1.0f - ShadowColor.a) * ShadowAlpha;
// apply shadow mask color
BaseColor.rgb *= ShadowMaskColor;
// clear shadow mask by background color
BaseColor.rgb = lerp(BaseColor.rgb, BackColor, ShadowMaskClear);
}
// Color Compression (may not affect bloom)
if (!PrepareBloom)
{
// increasing the floor of the signal without affecting the ceiling
BaseColor.rgb = Floor + (1.0f - Floor) * BaseColor.rgb;
}
// Color Power (may affect bloom)
BaseColor.r = pow(BaseColor.r, Power.r);
BaseColor.g = pow(BaseColor.g, Power.g);
BaseColor.b = pow(BaseColor.b, Power.b);
// Scanline Simulation (may not affect bloom)
if (!PrepareBloom)
{
// Scanline Simulation (may not affect vector screen)
if (!PrepareVector && ScanlineAlpha > 0.0f)
{
float ScanCoord = BaseCoord.y * SourceDims.y * ScanlineScale * PI;
float ScanCoordJitter = ScanlineOffset * PHI;
float ScanSine = sin(ScanCoord + ScanCoordJitter);
float ScanSineScaled = pow(ScanSine * ScanSine, ScanlineHeight);
float ScanBrightness = ScanSineScaled * ScanlineBrightScale + 1.0f + ScanlineBrightOffset;
BaseColor.rgb *= lerp(1.0f, ScanBrightness * 0.5f, ScanlineAlpha);
}
// Hum Bar Simulation (may not affect vector screen)
if (!PrepareVector && HumBarAlpha > 0.0f)
{
float HumTimeStep = frac(TimeMilliseconds * HumBarHertzRate);
float HumBrightness = 1.0 - frac(BaseCoord.y / SourceRect.y + HumTimeStep) * HumBarAlpha;
BaseColor.rgb *= HumBrightness;
}
}
// Output
float4 Output = PrepareVector
? BaseColor * (Input.Color + float4(1.0f, 1.0f, 1.0f, 0.0f))
: BaseColor * Input.Color;
Output.a = 1.0f;
// Vignetting Simulation (may not affect bloom)
if (!PrepareBloom)
{
float2 VignetteCoord = DistortionCoordCentered;
float VignetteFactor = GetVignetteFactor(VignetteCoord, VignettingAmount);
Output.rgb *= VignetteFactor;
}
// Light Reflection Simulation (may not affect bloom)
if (!PrepareBloom)
{
float3 LightColor = float3(1.0f, 0.90f, 0.80f);
float2 SpotCoord = DistortionCoordCentered;
float2 NoiseCoord = DistortionCoordCentered;
float SpotAddend = GetSpotAddend(SpotCoord, ReflectionAmount);
float NoiseFactor = GetNoiseFactor(SpotAddend, random(NoiseCoord));
Output.rgb += SpotAddend * NoiseFactor * LightColor;
}
// Round Corners Simulation (may affect bloom)
float2 RoundCornerCoord = DistortionCoordCentered;
float roundCornerFactor = GetRoundCornerFactor(RoundCornerCoord, RoundCornerAmount, SmoothBorderAmount);
Output.rgb *= roundCornerFactor;
return Output;
}
//-----------------------------------------------------------------------------
// Scanline & Shadowmask Effect
//-----------------------------------------------------------------------------
technique DefaultTechnique
{
pass Pass0
{
Lighting = FALSE;
VertexShader = compile vs_3_0 vs_main();
PixelShader = compile ps_3_0 ps_main();
}
}

View File

@ -202,8 +202,9 @@ float random(float2 seed)
uniform float2 ScreenDims;
uniform float2 TargetDims;
uniform float2 SourceRect;
uniform float2 SourceDims;
// level dimensions not necessary anymore?
uniform float2 Level0Size;
uniform float4 Level12Size;
uniform float4 Level34Size;
@ -211,6 +212,8 @@ uniform float4 Level56Size;
uniform float4 Level78Size;
uniform float4 Level9ASize;
uniform bool VectorScreen = false;
VS_OUTPUT vs_main(VS_INPUT Input)
{
VS_OUTPUT Output = (VS_OUTPUT)0;
@ -223,15 +226,20 @@ VS_OUTPUT vs_main(VS_INPUT Input)
Output.Color = Input.Color;
float2 TexCoord = Input.Position.xy / ScreenDims;
float2 TexCoord = Input.TexCoord;
TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9)
Output.TexCoord0 = TexCoord;
Output.TexCoord12 = TexCoord.xyxy + (0.5f / Level12Size);
Output.TexCoord34 = TexCoord.xyxy + (0.5f / Level34Size);
Output.TexCoord56 = TexCoord.xyxy + (0.5f / Level56Size);
Output.TexCoord78 = TexCoord.xyxy + (0.5f / Level78Size);
Output.TexCoord9A = TexCoord.xyxy + (0.5f / Level9ASize);
Output.TexCoord0 = TexCoord.xy; // + (0.5f / Level0Size);
TexCoord += VectorScreen
? 0.5f / TargetDims.xy
: 0.5f / SourceDims.xy;
Output.TexCoord12 = TexCoord.xyxy; // + (0.5f / Level12Size);
Output.TexCoord34 = TexCoord.xyxy; // + (0.5f / Level34Size);
Output.TexCoord56 = TexCoord.xyxy; // + (0.5f / Level56Size);
Output.TexCoord78 = TexCoord.xyxy; // + (0.5f / Level78Size);
Output.TexCoord9A = TexCoord.xyxy; // + (0.5f / Level9ASize);
return Output;
}
@ -247,7 +255,7 @@ uniform float2 Level56Weight;
uniform float2 Level78Weight;
uniform float2 Level9AWeight;
uniform int BloomBlendMode = 0; // 0 addition, 1 darken
uniform int BloomBlendMode = 0; // 0 brighten, 1 darken
uniform float BloomScale;
uniform float3 BloomOverdrive;
@ -273,7 +281,7 @@ float4 ps_main(PS_INPUT Input) : COLOR
float3 blend;
// addition
// brighten
if (BloomBlendMode == 0)
{
texel0 *= Level0Weight;

View File

@ -52,12 +52,7 @@ struct PS_INPUT
//-----------------------------------------------------------------------------
uniform float2 ScreenDims;
uniform float2 SourceDims;
uniform float2 SourceRect;
uniform float2 TargetDims;
uniform float2 QuadDims;
uniform bool SwapXY = false;
uniform float3 ConvergeX = float3(0.0f, 0.0f, 0.0f);
uniform float3 ConvergeY = float3(0.0f, 0.0f, 0.0f);
@ -68,48 +63,41 @@ VS_OUTPUT vs_main(VS_INPUT Input)
{
VS_OUTPUT Output = (VS_OUTPUT)0;
float2 HalfSourceRect = SourceRect * 0.5f;
float2 QuadRatio =
float2(1.0f, SwapXY
? QuadDims.y / QuadDims.x
: QuadDims.x / QuadDims.y);
// imaginary texel dimensions independed from quad dimensions, but dependend on quad ratio
float2 FixedTexelDims = (1.0f / 1024.0) * SourceRect * QuadRatio;
Output.Position = float4(Input.Position.xyz, 1.0f);
Output.Position.xy /= ScreenDims;
Output.Position.y = 1.0f - Output.Position.y; // flip y
Output.Position.xy -= 0.5f; // center
Output.Position.xy *= 2.0f; // toom
Output.Position.xy *= 2.0f; // zoom
float2 TexCoord = Input.TexCoord;
TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9)
Output.Color = Input.Color;
// imaginary texel dimensions independed from screen dimension, but ratio
float2 TexelDims = (1.0f / 1024);
Output.TexCoordX = TexCoord.xxx;
Output.TexCoordY = TexCoord.yyy;
// center coordinates
Output.TexCoordX -= HalfSourceRect.xxx;
Output.TexCoordY -= HalfSourceRect.yyy;
Output.TexCoordX -= 0.5f;
Output.TexCoordY -= 0.5f;
// radial converge offset to "translate" the most outer pixel as thay would be translated by the linar converge with the same amount
float2 radialConvergeOffset = 2.0f / SourceRect;
float2 radialConvergeOffset = 2.0f;
// radial converge
Output.TexCoordX *= 1.0f + RadialConvergeX * FixedTexelDims.xxx * radialConvergeOffset.xxx;
Output.TexCoordY *= 1.0f + RadialConvergeY * FixedTexelDims.yyy * radialConvergeOffset.yyy;
Output.TexCoordX *= 1.0f + RadialConvergeX * TexelDims.xxx * radialConvergeOffset.xxx;
Output.TexCoordY *= 1.0f + RadialConvergeY * TexelDims.yyy * radialConvergeOffset.yyy;
// un-center coordinates
Output.TexCoordX += HalfSourceRect.xxx;
Output.TexCoordY += HalfSourceRect.yyy;
Output.TexCoordX += 0.5f;
Output.TexCoordY += 0.5f;
// linear converge
Output.TexCoordX += ConvergeX * FixedTexelDims.xxx;
Output.TexCoordY += ConvergeY * FixedTexelDims.yyy;
Output.TexCoordX += ConvergeX * TexelDims.xxx;
Output.TexCoordY += ConvergeY * TexelDims.yyy;
Output.Color = Input.Color;
return Output;
}

View File

@ -89,6 +89,8 @@ uniform float2 ScreenDims; // size of the window or fullscreen
uniform float2 TargetDims; // size of the target surface
uniform float2 QuadDims; // size of the screen quad
uniform bool VectorScreen;
VS_OUTPUT vs_main(VS_INPUT Input)
{
VS_OUTPUT Output = (VS_OUTPUT)0;
@ -101,7 +103,7 @@ VS_OUTPUT vs_main(VS_INPUT Input)
Output.Color = Input.Color;
Output.TexCoord = Input.Position.xy / ScreenDims;
Output.TexCoord = Input.TexCoord;
Output.TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9)
return Output;
@ -117,19 +119,9 @@ uniform float SmoothBorderAmount = 0.0f;
uniform float VignettingAmount = 0.0f;
uniform float ReflectionAmount = 0.0f;
uniform bool SwapXY = false;
uniform int RotationType = 0; // 0 = 0°, 1 = 90°, 2 = 180°, 3 = 270°
float2 GetRatioCorrection()
{
float ScreenRatio = ScreenDims.x / ScreenDims.y;
float QuadRatio = QuadDims.x / QuadDims.y;
float ScreenQuadRatio = QuadRatio / ScreenRatio;
return ScreenQuadRatio > 1.0f
? float2(1.0, 1.0f / ScreenQuadRatio)
: float2(ScreenQuadRatio, 1.0);
}
float GetNoiseFactor(float3 n, float random)
{
// smaller n become more noisy
@ -152,25 +144,42 @@ float GetVignetteFactor(float2 coord, float amount)
float GetSpotAddend(float2 coord, float amount)
{
float2 RatioCorrection = GetRatioCorrection();
// normalized screen quad ratio
float2 QuadRatio = float2 (1.0f, QuadDims.y / QuadDims.x);
// upper right quadrant
float2 spotOffset =
RotationType == 1 // 90°
? float2(-0.25f, -0.25f)
: RotationType == 2 // 180°
? float2(0.25f, -0.25f)
: RotationType == 3 // 270°
? float2(0.25f, 0.25f)
: float2(-0.25f, 0.25f);
float2 SpotCoord = coord;
SpotCoord += spotOffset * RatioCorrection;
SpotCoord *= QuadRatio;
SpotCoord /= RatioCorrection;
// hack for vector screen
if (VectorScreen)
{
// upper right quadrant
float2 spotOffset =
RotationType == 1 // 90°
? float2(-0.25f, -0.25f)
: RotationType == 2 // 180°
? float2(0.25f, -0.25f)
: RotationType == 3 // 270° else 0°
? float2(0.25f, 0.25f)
: float2(-0.25f, 0.25f);
// normalized screen canvas ratio
float2 CanvasRatio = SwapXY
? float2(QuadDims.x / QuadDims.y, 1.0f)
: float2(1.0f, QuadDims.y / QuadDims.x);
SpotCoord += spotOffset;
SpotCoord *= CanvasRatio;
}
else
{
// upper right quadrant
float2 spotOffset = float2(-0.25f, 0.25f);
// normalized screen canvas ratio
float2 CanvasRatio = SwapXY
? float2(1.0f, QuadDims.x / QuadDims.y)
: float2(1.0f, QuadDims.y / QuadDims.x);
SpotCoord += spotOffset;
SpotCoord *= CanvasRatio;
}
float SpotBlur = amount;
@ -188,17 +197,20 @@ float GetSpotAddend(float2 coord, float amount)
float GetRoundCornerFactor(float2 coord, float radiusAmount, float smoothAmount)
{
float2 RatioCorrection = GetRatioCorrection();
// reduce smooth amount down to radius amount
smoothAmount = min(smoothAmount, radiusAmount);
float range = min(QuadDims.x, QuadDims.y) * 0.5;
float2 quadDims = QuadDims;
quadDims = !VectorScreen && SwapXY
? quadDims.yx
: quadDims.xy;
float range = min(quadDims.x, quadDims.y) * 0.5;
float radius = range * max(radiusAmount, 0.0025f);
float smooth = 1.0 / (range * max(smoothAmount, 0.0025f));
// compute box
float box = roundBox(ScreenDims * (coord * 2.0f), ScreenDims * RatioCorrection, radius);
float box = roundBox(quadDims * (coord * 2.0f), quadDims, radius);
// apply smooth
box *= smooth;
@ -235,20 +247,12 @@ float2 GetDistortedCoords(float2 centerCoord, float amount)
float2 GetCoords(float2 coord, float distortionAmount)
{
float2 RatioCorrection = GetRatioCorrection();
// center coordinates
coord -= 0.5f;
// apply ratio difference between screen and quad
coord /= RatioCorrection;
// distort coordinates
coord = GetDistortedCoords(coord, distortionAmount);
// revert ratio difference between screen and quad
coord *= RatioCorrection;
// un-center coordinates
coord += 0.5f;
@ -257,21 +261,18 @@ float2 GetCoords(float2 coord, float distortionAmount)
float4 ps_main(PS_INPUT Input) : COLOR
{
float2 TexCoord = Input.TexCoord;
float2 BaseCoord = TexCoord;
// Screen Curvature
BaseCoord = GetCoords(BaseCoord, CurvatureAmount * 0.25f); // reduced amount
float2 TexCoord = GetCoords(Input.TexCoord, CurvatureAmount * 0.25f); // reduced amount
float2 BaseCoordCentered = BaseCoord;
BaseCoordCentered -= 0.5f;
float2 TexCoordCentered = TexCoord;
TexCoordCentered -= 0.5f;
// Color
float4 BaseColor = tex2D(DiffuseSampler, BaseCoord);
float4 BaseColor = tex2D(DiffuseSampler, TexCoord);
BaseColor.a = 1.0f;
// Vignetting Simulation
float2 VignetteCoord = BaseCoordCentered;
float2 VignetteCoord = TexCoordCentered;
float VignetteFactor = GetVignetteFactor(VignetteCoord, VignettingAmount);
BaseColor.rgb *= VignetteFactor;
@ -279,15 +280,15 @@ float4 ps_main(PS_INPUT Input) : COLOR
// Light Reflection Simulation
float3 LightColor = float3(1.0f, 0.90f, 0.80f); // color temperature 5.000 Kelvin
float2 SpotCoord = BaseCoordCentered;
float2 NoiseCoord = BaseCoordCentered;
float2 SpotCoord = TexCoordCentered;
float2 NoiseCoord = TexCoordCentered;
float SpotAddend = GetSpotAddend(SpotCoord, ReflectionAmount);
float NoiseFactor = GetNoiseFactor(SpotAddend, random(NoiseCoord));
BaseColor.rgb += SpotAddend * NoiseFactor * LightColor;
// Round Corners Simulation
float2 RoundCornerCoord = BaseCoordCentered;
float2 RoundCornerCoord = TexCoordCentered;
float roundCornerFactor = GetRoundCornerFactor(RoundCornerCoord, RoundCornerAmount, SmoothBorderAmount);
BaseColor.rgb *= roundCornerFactor;

View File

@ -53,15 +53,25 @@ struct PS_INPUT
uniform float2 ScreenDims;
uniform float2 TargetDims;
uniform float2 SourceRect;
uniform float2 QuadDims;
uniform bool PrepareVector;
uniform int BloomLevel;
uniform bool VectorScreen;
static const float2 Coord0Offset = float2(-0.5f, -0.5f);
static const float2 Coord1Offset = float2( 0.5f, -0.5f);
static const float2 Coord2Offset = float2(-0.5f, 0.5f);
static const float2 Coord3Offset = float2( 0.5f, 0.5f);
VS_OUTPUT vs_main(VS_INPUT Input)
{
VS_OUTPUT Output = (VS_OUTPUT)0;
float2 TargetTexelDims = 1.0f / TargetDims;
float2 HalfTargetTexelDims = 0.5f / TargetDims;
HalfTargetTexelDims *= VectorScreen
? (ScreenDims / QuadDims)
: 1.0f;
Output.Position = float4(Input.Position.xyz, 1.0f);
Output.Position.xy /= ScreenDims;
@ -71,15 +81,13 @@ VS_OUTPUT vs_main(VS_INPUT Input)
Output.Color = Input.Color;
float2 TexCoord = Input.Position.xy / ScreenDims;
TexCoord += PrepareVector
? 0.5f / TargetDims // half texel offset correction (DX9) - only for vector grpahics
: 0.0f;
float2 TexCoord = Input.TexCoord;
TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9)
Output.TexCoord01.xy = TexCoord + float2(-0.5f, -0.5f) * TargetTexelDims;
Output.TexCoord01.zw = TexCoord + float2( 0.5f, -0.5f) * TargetTexelDims;
Output.TexCoord23.xy = TexCoord + float2(-0.5f, 0.5f) * TargetTexelDims;
Output.TexCoord23.zw = TexCoord + float2( 0.5f, 0.5f) * TargetTexelDims;
Output.TexCoord01.xy = TexCoord + Coord0Offset * HalfTargetTexelDims;
Output.TexCoord01.zw = TexCoord + Coord1Offset * HalfTargetTexelDims;
Output.TexCoord23.xy = TexCoord + Coord2Offset * HalfTargetTexelDims;
Output.TexCoord23.zw = TexCoord + Coord3Offset * HalfTargetTexelDims;
return Output;
}

View File

@ -51,8 +51,6 @@ struct PS_INPUT
uniform float2 ScreenDims;
uniform float2 TargetDims;
uniform float2 SourceRect;
uniform float2 QuadDims;
VS_OUTPUT vs_main(VS_INPUT Input)
{
@ -68,7 +66,7 @@ VS_OUTPUT vs_main(VS_INPUT Input)
TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9)
Output.TexCoord = TexCoord;
Output.Color = Input.Color;
return Output;
@ -78,28 +76,21 @@ VS_OUTPUT vs_main(VS_INPUT Input)
// Defocus Pixel Shader
//-----------------------------------------------------------------------------
float2 Coord1Offset = float2( 0.75f, 0.50f);
float2 Coord2Offset = float2( 0.25f, 1.00f);
float2 Coord3Offset = float2(-0.50f, 0.75f);
float2 Coord4Offset = float2(-1.00f, 0.25f);
float2 Coord5Offset = float2(-0.75f, -0.50f);
float2 Coord6Offset = float2(-0.25f, -1.00f);
float2 Coord7Offset = float2( 0.50f, -0.75f);
float2 Coord8Offset = float2( 1.00f, -0.25f);
uniform float2 Defocus = float2(0.0f, 0.0f);
uniform bool SwapXY = false;
static const float2 Coord1Offset = float2( 0.75f, 0.50f);
static const float2 Coord2Offset = float2( 0.25f, 1.00f);
static const float2 Coord3Offset = float2(-0.50f, 0.75f);
static const float2 Coord4Offset = float2(-1.00f, 0.25f);
static const float2 Coord5Offset = float2(-0.75f, -0.50f);
static const float2 Coord6Offset = float2(-0.25f, -1.00f);
static const float2 Coord7Offset = float2( 0.50f, -0.75f);
static const float2 Coord8Offset = float2( 1.00f, -0.25f);
float4 ps_main(PS_INPUT Input) : COLOR
{
float2 QuadRatio =
float2(1.0f, SwapXY
? QuadDims.y / QuadDims.x
: QuadDims.x / QuadDims.y);
// imaginary texel dimensions independed from quad dimensions, but dependend on quad ratio
float2 TexelDims = (1.0f / 1024.0) * SourceRect * QuadRatio;
// imaginary texel dimensions independed from screen dimension, but ratio
float2 TexelDims = (1.0f / 1024);
float2 DefocusTexelDims = Defocus * TexelDims;

View File

@ -44,7 +44,7 @@ struct PS_INPUT
};
//-----------------------------------------------------------------------------
// YIQ Decode Vertex Shader
// YIQ Vertex Shader
//-----------------------------------------------------------------------------
uniform float2 ScreenDims;

View File

@ -49,15 +49,17 @@ struct VS_OUTPUT
{
float4 Position : POSITION;
float4 Color : COLOR0;
float2 TexCoord : TEXCOORD0;
float2 ScreenCoord : TEXCOORD1;
float2 SourceCoord : TEXCOORD0;
float2 TexCoord : TEXCOORD1;
float2 ScreenCoord : TEXCOORD2;
};
struct PS_INPUT
{
float4 Color : COLOR0;
float2 TexCoord : TEXCOORD0;
float2 ScreenCoord : TEXCOORD1;
float2 SourceCoord : TEXCOORD0;
float2 TexCoord : TEXCOORD1;
float2 ScreenCoord : TEXCOORD2;
};
//-----------------------------------------------------------------------------
@ -71,10 +73,10 @@ static const float PHI = 1.618034f;
// Scanline & Shadowmask Vertex Shader
//-----------------------------------------------------------------------------
uniform float2 ScreenDims; // size of the window or fullscreen
uniform float2 SourceDims; // size of the texture in power-of-two size
uniform float2 SourceRect; // size of the uv rectangle
uniform float2 TargetDims; // size of the target surface
uniform float2 ScreenDims;
uniform float2 SourceDims;
uniform float2 TargetDims;
uniform float2 QuadDims;
uniform float2 ShadowDims = float2(32.0f, 32.0f); // size of the shadow texture (extended to power-of-two size)
uniform float2 ShadowUVOffset = float2(0.0f, 0.0f);
@ -82,33 +84,27 @@ uniform float2 ShadowUVOffset = float2(0.0f, 0.0f);
uniform bool SwapXY = false;
uniform bool PrepareBloom = false; // disables some effects for rendering bloom textures
uniform bool PrepareVector = false;
uniform bool VectorScreen = false;
VS_OUTPUT vs_main(VS_INPUT Input)
{
VS_OUTPUT Output = (VS_OUTPUT)0;
float2 shadowUVOffset = ShadowUVOffset;
shadowUVOffset = SwapXY
? shadowUVOffset.yx
: shadowUVOffset.xy;
float2 ScreenCoordOffset = 0.0f;
ScreenCoordOffset += shadowUVOffset;
Output.ScreenCoord = Input.Position.xy;
Output.ScreenCoord += ScreenCoordOffset;
Output.Position = float4(Input.Position.xyz, 1.0f);
Output.Position.xy /= ScreenDims;
Output.Position.y = 1.0f - Output.Position.y; // flip y
Output.Position.xy -= 0.5f; // center
Output.Position.xy *= 2.0f; // zoom
Output.TexCoord = PrepareVector
? Input.Position.xy / ScreenDims
: Input.TexCoord;
Output.TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9)
Output.TexCoord = Input.TexCoord;
Output.TexCoord += PrepareBloom
? 0.0f / TargetDims // use half texel offset (DX9) to do the blur for first bloom layer
: 0.5f / TargetDims; // fix half texel offset correction (DX9)
Output.ScreenCoord = Input.Position.xy / ScreenDims;
Output.SourceCoord = Input.TexCoord;
Output.SourceCoord += 0.5f / TargetDims;
Output.Color = Input.Color;
@ -119,7 +115,7 @@ VS_OUTPUT vs_main(VS_INPUT Input)
// Scanline & Shadowmask Pixel Shader
//-----------------------------------------------------------------------------
uniform float HumBarHertzRate = 60.0f / 59.94f - 1.0f; // difference between the 59.94 Hz field rate and 60 Hz line frequency (NTSC)
uniform float HumBarDesync = 60.0f / 59.94f - 1.0f; // difference between the 59.94 Hz field rate and 60 Hz line frequency (NTSC)
uniform float HumBarAlpha = 0.0f;
uniform float TimeMilliseconds = 0.0f;
@ -129,14 +125,15 @@ uniform float2 ScreenOffset = float2(0.0f, 0.0f);
uniform float ScanlineAlpha = 0.0f;
uniform float ScanlineScale = 1.0f;
uniform float ScanlineHeight = 1.0f;
uniform float ScanlineVariation = 1.0f;
uniform float ScanlineOffset = 1.0f;
uniform float ScanlineBrightScale = 1.0f;
uniform float ScanlineBrightOffset = 1.0f;
uniform float ScanlineOffset = 1.0f;
uniform float ScanlineHeight = 1.0f;
uniform float3 BackColor = float3(0.0f, 0.0f, 0.0f);
uniform int ShadowTileMode = 0; // 0 based on screen dimension, 1 based on source dimension
uniform int ShadowTileMode = 0; // 0 based on screen (quad) dimension, 1 based on source dimension
uniform float ShadowAlpha = 0.0f;
uniform float2 ShadowCount = float2(6.0f, 6.0f);
uniform float2 ShadowUV = float2(0.25f, 0.25f);
@ -161,60 +158,74 @@ float2 GetAdjustedCoords(float2 coord, float2 centerOffset)
return coord;
}
// vector screen has the same quad texture coordinates for every screen orientation, raster screen differs
float2 GetShadowCoord(float2 QuadCoord, float2 SourceCoord)
{
float2 QuadTexel = 1.0f / QuadDims;
float2 SourceTexel = 1.0f / SourceDims;
float2 canvasCoord = ShadowTileMode == 0
? QuadCoord + ShadowUVOffset / QuadDims
: SourceCoord + ShadowUVOffset / SourceDims;
float2 canvasTexelDims = ShadowTileMode == 0
? QuadTexel
: SourceTexel;
float2 shadowDims = ShadowDims;
float2 shadowUV = ShadowUV;
float2 shadowCount = ShadowCount;
// swap x/y vector and raster in screen mode (not source mode)
canvasCoord = ShadowTileMode == 0 && SwapXY
? canvasCoord.yx
: canvasCoord.xy;
// swap x/y vector and raster in screen mode (not source mode)
shadowCount = ShadowTileMode == 0 && SwapXY
? shadowCount.yx
: shadowCount.xy;
float2 shadowTile = canvasTexelDims * shadowCount;
// swap x/y vector in screen mode (not raster and not source mode)
shadowTile = VectorScreen && ShadowTileMode == 0 && SwapXY
? shadowTile.yx
: shadowTile.xy;
float2 shadowFrac = frac(canvasCoord / shadowTile);
// swap x/y raster in screen mode (not vector and not source mode)
shadowFrac = !VectorScreen && ShadowTileMode == 0 && SwapXY
? shadowFrac.yx
: shadowFrac.xy;
float2 shadowCoord = (shadowFrac * shadowUV);
shadowCoord += 0.5f / shadowDims; // half texel offset
return shadowCoord;
}
float4 ps_main(PS_INPUT Input) : COLOR
{
float2 ScreenTexelDims = 1.0f / ScreenDims;
float2 SourceTexelDims = 1.0f / SourceDims;
float2 SourceRes = SourceDims * SourceRect;
float2 HalfSourceRect = SourceRect * 0.5f;
float2 ScreenCoord = Input.ScreenCoord / ScreenDims;
float2 BaseCoord = GetAdjustedCoords(Input.TexCoord, HalfSourceRect);
float2 ScreenCoord = Input.ScreenCoord;
float2 TexCoord = GetAdjustedCoords(Input.TexCoord, 0.5f);
float2 SourceCoord = GetAdjustedCoords(Input.SourceCoord, 0.5f);
// Color
float4 BaseColor = tex2D(DiffuseSampler, BaseCoord);
float4 BaseColor = tex2D(DiffuseSampler, TexCoord);
BaseColor.a = 1.0f;
if (BaseCoord.x < 0.0f || BaseCoord.y < 0.0f)
// keep border
if (!PrepareBloom)
{
BaseColor.rgb = 0.0f;
// clip border
clip(TexCoord < 0.0f || TexCoord > 1.0f ? -1 : 1);
}
// Mask Simulation (may not affect bloom)
if (!PrepareBloom && ShadowAlpha > 0.0f)
{
float2 shadowDims = ShadowDims;
shadowDims = SwapXY
? shadowDims.yx
: shadowDims.xy;
float2 shadowUV = ShadowUV;
// shadowUV = SwapXY
// ? shadowUV.yx
// : shadowUV.xy;
float2 screenCoord = ShadowTileMode == 0 ? ScreenCoord : BaseCoord;
screenCoord = SwapXY
? screenCoord.yx
: screenCoord.xy;
float2 shadowCount = ShadowCount;
shadowCount = SwapXY
? shadowCount.yx
: shadowCount.xy;
float2 shadowTile = ((ShadowTileMode == 0 ? ScreenTexelDims : SourceTexelDims) * shadowCount);
shadowTile = SwapXY
? shadowTile.yx
: shadowTile.xy;
float2 ShadowFrac = frac(screenCoord / shadowTile);
float2 ShadowCoord = (ShadowFrac * shadowUV);
ShadowCoord += 0.5f / shadowDims; // half texel offset
// ShadowCoord = SwapXY
// ? ShadowCoord.yx
// : ShadowCoord.xy;
float2 ShadowCoord = GetShadowCoord(ScreenCoord, SourceCoord);
float4 ShadowColor = tex2D(ShadowSampler, ShadowCoord);
float3 ShadowMaskColor = lerp(1.0f, ShadowColor.rgb, ShadowAlpha);
@ -242,33 +253,33 @@ float4 ps_main(PS_INPUT Input) : COLOR
if (!PrepareBloom)
{
// Scanline Simulation (may not affect vector screen)
if (!PrepareVector && ScanlineAlpha > 0.0f)
if (!VectorScreen && ScanlineAlpha > 0.0f)
{
float ScanCoord = BaseCoord.y * SourceDims.y * ScanlineScale * PI;
float ScanCoordJitter = ScanlineOffset * PHI;
float ScanSine = sin(ScanCoord + ScanCoordJitter);
float ScanSineScaled = pow(ScanSine * ScanSine, ScanlineHeight);
float ScanBrightness = ScanSineScaled * ScanlineBrightScale + 1.0f + ScanlineBrightOffset;
float BrightnessOffset = (ScanlineBrightOffset * ScanlineAlpha);
float BrightnessScale = (ScanlineBrightScale * ScanlineAlpha) + (1.0f - ScanlineAlpha);
BaseColor.rgb *= lerp(1.0f, ScanBrightness * 0.5f, ScanlineAlpha);
float ColorBrightness = 0.299f * BaseColor.r + 0.587f * BaseColor.g + 0.114 * BaseColor.b;
float ScanlineCoord = SourceCoord.y * SourceDims.y * ScanlineScale * PI;
float ScanlineCoordJitter = ScanlineOffset * PHI;
float ScanlineSine = sin(ScanlineCoord + ScanlineCoordJitter);
float ScanlineWide = ScanlineHeight + ScanlineVariation * max(1.0f, ScanlineHeight) * (1.0f - ColorBrightness);
float ScanlineAmount = pow(ScanlineSine * ScanlineSine, ScanlineWide);
float ScanlineBrightness = ScanlineAmount * BrightnessScale + BrightnessOffset * BrightnessScale;
BaseColor.rgb *= lerp(1.0f, ScanlineBrightness, ScanlineAlpha);
}
// Hum Bar Simulation (may not affect vector screen)
if (!PrepareVector && HumBarAlpha > 0.0f)
if (!VectorScreen && HumBarAlpha > 0.0f)
{
float HumTimeStep = frac(TimeMilliseconds * HumBarHertzRate);
float HumBrightness = 1.0 - frac(BaseCoord.y / SourceRect.y + HumTimeStep) * HumBarAlpha;
BaseColor.rgb *= HumBrightness;
float HumBarStep = frac(TimeMilliseconds * HumBarDesync);
float HumBarBrightness = 1.0 - frac(SourceCoord.y + HumBarStep) * HumBarAlpha;
BaseColor.rgb *= HumBarBrightness;
}
}
// Output
float4 Output = PrepareVector
? BaseColor * (Input.Color + float4(1.0f, 1.0f, 1.0f, 0.0f))
: BaseColor * Input.Color;
Output.a = 1.0f;
return Output;
return BaseColor;
}
//-----------------------------------------------------------------------------

View File

@ -1,7 +1,11 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
// copyright-holders:Ryan Holtz,Themaister,ImJezze
//-----------------------------------------------------------------------------
// Prescale Effect
// Pre-scale Effect
//
// Uses the hardware bilinear interpolator to avoid having to sample 4 times manually.
//
// https://github.com/libretro/common-shaders/blob/master/retro/shaders/sharp-bilinear.cg
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
@ -13,9 +17,9 @@ texture Diffuse;
sampler DiffuseSampler = sampler_state
{
Texture = <Diffuse>;
MipFilter = NONE;
MinFilter = NONE;
MagFilter = NONE;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
AddressU = CLAMP;
AddressV = CLAMP;
AddressW = CLAMP;
@ -45,22 +49,23 @@ struct PS_INPUT
};
//-----------------------------------------------------------------------------
// Prescale Vertex Shader
// Pre-scale Vertex Shader
//-----------------------------------------------------------------------------
uniform float2 ScreenDims;
uniform float2 TargetDims;
uniform float2 SourceDims;
VS_OUTPUT vs_main(VS_INPUT Input)
{
VS_OUTPUT Output = (VS_OUTPUT)0;
Output.Position = float4(Input.Position.xyz, 1.0f);
Output.Position.xy /= ScreenDims;
Output.Position.y = 1.0f - Output.Position.y; // flip y
Output.Position.xy -= 0.5f; // center
Output.Position.xy *= 2.0f; // zoom
Output.TexCoord = Input.TexCoord;
Output.TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9)
@ -68,16 +73,29 @@ VS_OUTPUT vs_main(VS_INPUT Input)
}
//-----------------------------------------------------------------------------
// Prescale Pixel Shader
// Pre-scale Pixel Shader
//-----------------------------------------------------------------------------
float4 ps_main(PS_INPUT Input) : COLOR
{
return tex2D(DiffuseSampler, Input.TexCoord);
float2 Scale = TargetDims / SourceDims;
float2 TexelDims = Input.TexCoord * SourceDims;
float2 i = floor(TexelDims);
float2 s = frac(TexelDims);
// Figure out where in the texel to sample to get the correct pre-scaled bilinear.
float2 CenterDistance = s - 0.5f;
float2 RegionRange = 0.5f - 0.5f / Scale;
float2 f = (CenterDistance - clamp(CenterDistance, -RegionRange, RegionRange)) * Scale + 0.5f;
float2 TexCoord = (i + f) / SourceDims;
return tex2D(DiffuseSampler, TexCoord);
}
//-----------------------------------------------------------------------------
// Prescale Technique
// Pre-scale Technique
//-----------------------------------------------------------------------------
technique DefaultTechnique

View File

@ -46,19 +46,18 @@ struct PS_INPUT
};
//-----------------------------------------------------------------------------
// Primary Vertex Shader
// Primary Vertex Shaders
//-----------------------------------------------------------------------------
static const float Epsilon = 1.0e-7f;
uniform float2 ScreenDims;
uniform float2 TargetDims;
uniform float2 QuadDims;
uniform bool PostPass;
uniform bool VectorScreen;
uniform float Brighten;
VS_OUTPUT vs_main(VS_INPUT Input)
VS_OUTPUT vs_screen_main(VS_INPUT Input)
{
VS_OUTPUT Output = (VS_OUTPUT)0;
@ -68,14 +67,44 @@ VS_OUTPUT vs_main(VS_INPUT Input)
Output.Position.xy -= 0.5f; // center
Output.Position.xy *= 2.0f; // zoom
float2 targetDims = TargetDims + Epsilon; // bug: with exact target dimensions the font disappears
Output.TexCoord = Input.TexCoord;
// Output.TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9)
Output.TexCoord = PostPass
? Input.Position.xy / ScreenDims
: Input.TexCoord;
Output.TexCoord += PostPass
? 0.5f / targetDims // half texel offset correction (DX9)
: 0.0f;
Output.Color = Input.Color;
return Output;
}
VS_OUTPUT vs_vector_buffer_main(VS_INPUT Input)
{
VS_OUTPUT Output = (VS_OUTPUT)0;
Output.Position = float4(Input.Position.xyz, 1.0f);
Output.Position.xy /= ScreenDims;
Output.Position.y = 1.0f - Output.Position.y; // flip y
Output.Position.xy -= 0.5f; // center
Output.Position.xy *= 2.0f; // zoom
Output.TexCoord = Input.TexCoord;
Output.TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9)
Output.Color = Input.Color;
return Output;
}
VS_OUTPUT vs_ui_main(VS_INPUT Input)
{
VS_OUTPUT Output = (VS_OUTPUT)0;
Output.Position = float4(Input.Position.xyz, 1.0f);
Output.Position.xy /= ScreenDims;
Output.Position.y = 1.0f - Output.Position.y; // flip y
Output.Position.xy -= 0.5f; // center
Output.Position.xy *= 2.0f; // zoom
Output.TexCoord = Input.TexCoord;
// Output.TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9)
Output.Color = Input.Color;
@ -83,28 +112,64 @@ VS_OUTPUT vs_main(VS_INPUT Input)
}
//-----------------------------------------------------------------------------
// Primary Pixel Shader
// Primary Pixel Shaders
//-----------------------------------------------------------------------------
float4 ps_main(PS_INPUT Input) : COLOR
float4 ps_screen_main(PS_INPUT Input) : COLOR
{
float4 BaseTexel = tex2D(DiffuseSampler, Input.TexCoord);
BaseTexel *= Input.Color + float4(Brighten, Brighten, Brighten, 0.0f);
return BaseTexel;
}
float4 ps_vector_buffer_main(PS_INPUT Input) : COLOR
{
float4 BaseTexel = tex2D(DiffuseSampler, Input.TexCoord);
return BaseTexel;
}
float4 ps_ui_main(PS_INPUT Input) : COLOR
{
float4 BaseTexel = tex2D(DiffuseSampler, Input.TexCoord);
BaseTexel *= Input.Color;
return BaseTexel;
}
//-----------------------------------------------------------------------------
// Primary Technique
// Primary Techniques
//-----------------------------------------------------------------------------
technique DefaultTechnique
technique ScreenTechnique
{
pass Pass0
{
Lighting = FALSE;
VertexShader = compile vs_2_0 vs_main();
PixelShader = compile ps_2_0 ps_main();
VertexShader = compile vs_2_0 vs_screen_main();
PixelShader = compile ps_2_0 ps_screen_main();
}
}
technique VectorBufferTechnique
{
pass Pass0
{
Lighting = FALSE;
VertexShader = compile vs_2_0 vs_vector_buffer_main();
PixelShader = compile ps_2_0 ps_vector_buffer_main();
}
}
technique UiTechnique
{
pass Pass0
{
Lighting = FALSE;
VertexShader = compile vs_2_0 vs_ui_main();
PixelShader = compile ps_2_0 ps_ui_main();
}
}

View File

@ -36,6 +36,8 @@ struct PS_INPUT
//-----------------------------------------------------------------------------
uniform float2 ScreenDims;
uniform float2 QuadDims;
uniform float2 TimeParams;
uniform float3 LengthParams;
@ -47,9 +49,9 @@ VS_OUTPUT vs_main(VS_INPUT Input)
Output.Position.xy /= ScreenDims;
Output.Position.y = 1.0f - Output.Position.y; // flip y
Output.Position.xy -= 0.5f; // center
Output.Position.xy *= 2.0f; // zoom
Output.Position.xy *= 2.0f * (ScreenDims / QuadDims); // zoom
Output.TexCoord = Input.Position.xy / ScreenDims;
Output.TexCoord = Input.TexCoord;
Output.Color = Input.Color;
@ -75,7 +77,9 @@ float4 ps_main(PS_INPUT Input) : COLOR
lengthModulate = lerp(lengthModulate, 4.0f, minLength * 0.5f);
lengthModulate = lerp(1.0f, timeModulate * lengthModulate, LengthParams.y);
float4 outColor = Input.Color * float4(lengthModulate, lengthModulate, lengthModulate, 1.0f);
float4 outColor = float4(lengthModulate, lengthModulate, lengthModulate, 1.0f);
outColor *= Input.Color;
return outColor;
}
@ -90,6 +94,6 @@ technique DefaultTechnique
Lighting = FALSE;
VertexShader = compile vs_2_0 vs_main();
PixelShader = compile ps_2_0 ps_main();
PixelShader = compile ps_2_0 ps_main();
}
}

55
ini/gameboy.ini Normal file
View File

@ -0,0 +1,55 @@
#
# DIRECT3D POST-PROCESSING OPTIONS
#
shadow_mask_tile_mode 1
shadow_mask_alpha 0.25
shadow_mask_texture monochrome-matrix.png
shadow_mask_x_count 2
shadow_mask_y_count 2
shadow_mask_usize 0.5
shadow_mask_vsize 0.5
shadow_mask_uoffset 0.0
shadow_mask_voffset 0.0
curvature 0.0
round_corner 0.0
smooth_border 0.0
reflection 0.0
vignetting 0.0
scanline_alpha 0.0
defocus 0.0,0.0
converge_x 0.0,0.0,0.0
converge_y 0.0,0.0,0.0
radial_converge_x 0.0,0.0,0.0
radial_converge_y 0.0,0.0,0.0
red_ratio 1.0,0.0,0.0
grn_ratio 0.0,1.0,0.0
blu_ratio 0.0,0.0,1.0
saturation 1.0
offset 0.0,0.0,0.0
scale 1.0,1.0,1.0
power 1.0,1.0,1.0
floor 0.0,0.0,0.0
phosphor_life 0.5,0.5,0.5
#
# NTSC POST-PROCESSING OPTIONS
#
yiq_enable 0
#
# BLOOM POST-PROCESSING OPTIONS
#
bloom_blend_mode 1
bloom_scale 1.0
bloom_overdrive 0.0,0.0,0.0
bloom_lvl0_weight 1.0
bloom_lvl1_weight 0.64
bloom_lvl2_weight 0.32
bloom_lvl3_weight 0.16
bloom_lvl4_weight 0.08
bloom_lvl5_weight 0.04
bloom_lvl6_weight 0.04
bloom_lvl7_weight 0.02
bloom_lvl8_weight 0.02
bloom_lvl9_weight 0.01
bloom_lvl10_weight 0.01

55
ini/gba.ini Normal file
View File

@ -0,0 +1,55 @@
#
# DIRECT3D POST-PROCESSING OPTIONS
#
shadow_mask_tile_mode 1
shadow_mask_alpha 0.75
shadow_mask_texture slot-mask-aligned.png
shadow_mask_x_count 2
shadow_mask_y_count 2
shadow_mask_usize 0.1875
shadow_mask_vsize 0.1875
shadow_mask_uoffset 0.0
shadow_mask_voffset 0.0
curvature 0.0
round_corner 0.0
smooth_border 0.0
reflection 0.0
vignetting 0.0
scanline_alpha 0.0
defocus 0.0,0.0
converge_x 0.0,0.0,0.0
converge_y 0.0,0.0,0.0
radial_converge_x 0.0,0.0,0.0
radial_converge_y 0.0,0.0,0.0
red_ratio 1.0,0.0,0.0
grn_ratio 0.0,1.0,0.0
blu_ratio 0.0,0.0,1.0
saturation 1.0
offset 0.0,0.0,0.0
scale 1.0,1.0,1.0
power 1.0,1.0,1.0
floor 0.0,0.0,0.0
phosphor_life 0.5,0.5,0.5
#
# NTSC POST-PROCESSING OPTIONS
#
yiq_enable 0
#
# BLOOM POST-PROCESSING OPTIONS
#
bloom_blend_mode 0
bloom_scale 0.25
bloom_overdrive 0.0,0.0,0.0
bloom_lvl0_weight 1.0
bloom_lvl1_weight 0.64
bloom_lvl2_weight 0.32
bloom_lvl3_weight 0.16
bloom_lvl4_weight 0.08
bloom_lvl5_weight 0.04
bloom_lvl6_weight 0.04
bloom_lvl7_weight 0.02
bloom_lvl8_weight 0.02
bloom_lvl9_weight 0.01
bloom_lvl10_weight 0.01

61
ini/raster.ini Normal file
View File

@ -0,0 +1,61 @@
#
# DIRECT3D POST-PROCESSING OPTIONS
#
shadow_mask_tile_mode 0
shadow_mask_alpha 0.35
shadow_mask_texture shadow-mask.png
shadow_mask_x_count 6
shadow_mask_y_count 4
shadow_mask_usize 0.1875
shadow_mask_vsize 0.25
shadow_mask_uoffset 0.0
shadow_mask_voffset 0.0
curvature 0.0
round_corner 0.0
smooth_border 0.0
reflection 0.0
vignetting 0.0
scanline_alpha 0.50
scanline_size 1.0
scanline_height 1.0
scanline_variation 1.0
scanline_bright_scale 2.0
scanline_bright_offset 0.0
scanline_jitter 0.0
defocus 1.0,0.0
converge_x 0.0,0.0,0.0
converge_y 0.0,0.0,0.0
radial_converge_x 0.0,0.0,0.0
radial_converge_y 0.0,0.0,0.0
red_ratio 1.05,0.00,0.10
grn_ratio -0.10,1.00,0.25
blu_ratio -0.25,0.25,1.25
saturation 1.25
offset -0.30,-0.20,-0.05
scale 1.15,1.05,0.90
power 0.90,0.90,1.15
floor 0.05,0.05,0.05
phosphor_life 0.5,0.5,0.5
#
# NTSC POST-PROCESSING OPTIONS
#
yiq_enable 0
#
# BLOOM POST-PROCESSING OPTIONS
#
bloom_blend_mode 0
bloom_scale 0.35
bloom_overdrive 1.00,1.00,1.00
bloom_lvl0_weight 1.00
bloom_lvl1_weight 0.64
bloom_lvl2_weight 0.32
bloom_lvl3_weight 0.16
bloom_lvl4_weight 0.08
bloom_lvl5_weight 0.04
bloom_lvl6_weight 0.04
bloom_lvl7_weight 0.02
bloom_lvl8_weight 0.02
bloom_lvl9_weight 0.01
bloom_lvl10_weight 0.01

70
ini/vector.ini Normal file
View File

@ -0,0 +1,70 @@
#
# CORE VECTOR OPTIONS
#
antialias 1
beam_width_min 0.50
beam_width_max 4.00
beam_intensity_weight 0.75
flicker 0.15
#
# DIRECT3D POST-PROCESSING OPTIONS
#
shadow_mask_tile_mode 0
shadow_mask_alpha 0.5
shadow_mask_texture shadow-mask.png
shadow_mask_x_count 6
shadow_mask_y_count 4
shadow_mask_usize 0.1875
shadow_mask_vsize 0.25
shadow_mask_uoffset 0.0
shadow_mask_voffset 0.0
curvature 0.0
round_corner 0.0
smooth_border 0.0
reflection 0.0
vignetting 0.0
scanline_alpha 0.0
defocus 0.0,0.0
converge_x 0.0,0.0,0.0
converge_y 0.0,0.0,0.0
radial_converge_x 0.0,0.0,0.0
radial_converge_y 0.0,0.0,0.0
red_ratio 1.0,0.0,0.1
grn_ratio 0.0,1.0,0.0
blu_ratio 0.0,0.0,1.0
saturation 1.0
offset 0.0,0.0,0.0
scale 1.0,1.0,1.0
power 1.0,1.0,1.0
floor 0.0,0.0,0.0
phosphor_life 0.5,0.5,0.5
#
# NTSC POST-PROCESSING OPTIONS
#
yiq_enable 0
#
# VECTOR POST-PROCESSING OPTIONS
#
vector_length_scale 0.8
vector_length_ratio 500.0
#
# BLOOM POST-PROCESSING OPTIONS
#
bloom_blend_mode 0
bloom_scale 1.50
bloom_overdrive 1.50,1.50,1.50
bloom_lvl0_weight 1.00
bloom_lvl1_weight 0.64
bloom_lvl2_weight 0.32
bloom_lvl3_weight 0.16
bloom_lvl4_weight 0.24
bloom_lvl5_weight 0.32
bloom_lvl6_weight 0.48
bloom_lvl7_weight 0.32
bloom_lvl8_weight 0.24
bloom_lvl9_weight 0.16
bloom_lvl10_weight 0.08

View File

@ -1756,29 +1756,39 @@ void render_target::add_container_primitives(render_primitive_list &list, const
// set the palette
prim->texture.palette = curitem->texture()->get_adjusted_palette(container);
// determine UV coordinates and apply clipping
// determine UV coordinates
prim->texcoords = oriented_texcoords[finalorient];
// apply clipping
clipped = render_clip_quad(&prim->bounds, &cliprect, &prim->texcoords);
// apply the final orientation from the quad flags and then build up the final flags
prim->flags = (curitem->flags() & ~(PRIMFLAG_TEXORIENT_MASK | PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK)) |
PRIMFLAG_TEXORIENT(finalorient) |
PRIMFLAG_TEXFORMAT(curitem->texture()->format());
if (blendmode != -1)
prim->flags |= PRIMFLAG_BLENDMODE(blendmode);
else
prim->flags |= PRIMFLAG_BLENDMODE(PRIMFLAG_GET_BLENDMODE(curitem->flags()));
prim->flags = (curitem->flags() & ~(PRIMFLAG_TEXORIENT_MASK | PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK))
| PRIMFLAG_TEXORIENT(finalorient)
| PRIMFLAG_TEXFORMAT(curitem->texture()->format());
prim->flags |= blendmode != -1
? PRIMFLAG_BLENDMODE(blendmode)
: PRIMFLAG_BLENDMODE(PRIMFLAG_GET_BLENDMODE(curitem->flags()));
}
else
{
if (curitem->flags() & PRIMFLAG_VECTORBUF_MASK)
{
// determine UV coordinates
prim->texcoords = oriented_texcoords[0];
}
// adjust the color for brightness/contrast/gamma
prim->color.r = container.apply_brightness_contrast_gamma_fp(prim->color.r);
prim->color.g = container.apply_brightness_contrast_gamma_fp(prim->color.g);
prim->color.b = container.apply_brightness_contrast_gamma_fp(prim->color.b);
// no texture -- set the basic flags
// no texture
prim->texture.base = nullptr;
prim->flags = (curitem->flags() &~ PRIMFLAG_BLENDMODE_MASK) | PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA);
// set the basic flags
prim->flags = (curitem->flags() & ~PRIMFLAG_BLENDMODE_MASK)
| PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA);
// apply clipping
clipped = render_clip_quad(&prim->bounds, &cliprect, nullptr);

View File

@ -329,6 +329,8 @@ public:
// getters
render_primitive *next() const { return m_next; }
bool packable(const INT32 pack_size) const { return (flags & PRIMFLAG_PACKABLE) && texture.base != nullptr && texture.width <= pack_size && texture.height <= pack_size; }
float get_quad_width() const { return bounds.x1 - bounds.x0; }
float get_quad_height() const { return bounds.y1 - bounds.y0; }
// reset to prepare for re-use
void reset();

View File

@ -244,7 +244,7 @@ public:
cache_target() { }
~cache_target();
bool init(renderer_d3d9 *d3d, d3d_base *d3dintf, int width, int height, int prescale_x, int prescale_y);
bool init(renderer_d3d9 *d3d, d3d_base *d3dintf, int source_width, int source_height, int target_width, int target_height);
surface *last_target;
texture *last_texture;
@ -269,31 +269,34 @@ public:
d3d_render_target() { }
~d3d_render_target();
bool init(renderer_d3d9 *d3d, d3d_base *d3dintf, int width, int height, int prescale_x, int prescale_y);
bool init(renderer_d3d9 *d3d, d3d_base *d3dintf, int source_width, int source_height, int target_width, int target_height);
int next_index(int index) { return ++index > 1 ? 0 : index; }
// real target dimension
int target_width;
int target_height;
int prescale_x;
int prescale_y;
// only used to identify/find the render target
int width;
int height;
int screen_index;
int page_index;
surface *prescale_target[2];
texture *prescale_texture[2];
surface *native_target[2];
texture *native_texture[2];
surface *target_surface[2];
texture *target_texture[2];
surface *source_surface[2];
texture *source_texture[2];
d3d_render_target *next;
d3d_render_target *prev;
surface *bloom_target[11];
surface *bloom_surface[11];
texture *bloom_texture[11];
float bloom_dims[11][2];
int bloom_count;
};
#endif

View File

@ -60,7 +60,7 @@ static direct3dx9_loadeffect_ptr g_load_effect = nullptr;
//============================================================
shaders::shaders() :
d3dintf(nullptr), machine(nullptr), d3d(nullptr), num_screens(0), curr_screen(0), curr_frame(0), write_ini(false), read_ini(false), hlsl_prescale_x(0), hlsl_prescale_y(0), bloom_count(0),
d3dintf(nullptr), machine(nullptr), d3d(nullptr), num_screens(0), curr_screen(0), curr_frame(0),
vecbuf_type(), vecbuf_index(0), vecbuf_count(0), avi_output_file(nullptr), avi_frame(0), avi_copy_surface(nullptr), avi_copy_texture(nullptr), avi_final_target(nullptr), avi_final_texture(nullptr),
black_surface(nullptr), black_texture(nullptr), render_snap(false), snap_rendered(false), snap_copy_target(nullptr), snap_copy_texture(nullptr), snap_target(nullptr), snap_texture(nullptr),
snap_width(0), snap_height(0), lines_pending(false), backbuffer(nullptr), curr_effect(nullptr), default_effect(nullptr), prescale_effect(nullptr), post_effect(nullptr), distortion_effect(nullptr),
@ -69,9 +69,6 @@ shaders::shaders() :
{
master_enable = false;
vector_enable = true;
hlsl_prescale_x = 1;
hlsl_prescale_x = 1;
preset = -1;
shadow_texture = nullptr;
options = nullptr;
paused = true;
@ -410,8 +407,6 @@ void shaders::toggle()
{
// free shader resources before renderer resources
delete_resources(false);
g_slider_list = nullptr;
}
master_enable = !master_enable;
@ -436,10 +431,6 @@ void shaders::toggle()
{
master_enable = false;
}
else
{
g_slider_list = init_slider_list();
}
}
}
}
@ -556,9 +547,9 @@ void shaders::remove_render_target(texture_info *texture)
remove_render_target(find_render_target(texture));
}
void shaders::remove_render_target(int width, int height, UINT32 screen_index, UINT32 page_index)
void shaders::remove_render_target(int source_width, int source_height, UINT32 screen_index, UINT32 page_index)
{
d3d_render_target *target = find_render_target(width, height, screen_index, page_index);
d3d_render_target *target = find_render_target(source_width, source_height, screen_index, page_index);
if (target != nullptr)
{
remove_render_target(target);
@ -662,14 +653,17 @@ void shaders::init(d3d_base *d3dintf, running_machine *machine, renderer_d3d9 *r
// check if no driver loaded (not all settings might be loaded yet)
if (&machine->system() == &GAME_NAME(___empty))
{
options->params_init = false;
last_options.params_init = false;
return;
}
enumerate_screens();
windows_options &winoptions = downcast<windows_options &>(machine->options());
master_enable = winoptions.d3d_hlsl_enable();
hlsl_prescale_x = winoptions.d3d_hlsl_prescale_x();
hlsl_prescale_y = winoptions.d3d_hlsl_prescale_y();
snap_width = winoptions.d3d_snap_width();
snap_height = winoptions.d3d_snap_height();
@ -697,6 +691,7 @@ void shaders::init(d3d_base *d3dintf, running_machine *machine, renderer_d3d9 *r
options->scanline_alpha = winoptions.screen_scanline_amount();
options->scanline_scale = winoptions.screen_scanline_scale();
options->scanline_height = winoptions.screen_scanline_height();
options->scanline_variation = winoptions.screen_scanline_variation();
options->scanline_bright_scale = winoptions.screen_scanline_bright_scale();
options->scanline_bright_offset = winoptions.screen_scanline_bright_offset();
options->scanline_jitter = winoptions.screen_scanline_jitter();
@ -749,8 +744,6 @@ void shaders::init(d3d_base *d3dintf, running_machine *machine, renderer_d3d9 *r
}
options->params_dirty = true;
g_slider_list = init_slider_list();
}
@ -957,6 +950,7 @@ int shaders::create_resources(bool reset)
effects[i]->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS);
effects[i]->add_uniform("QuadDims", uniform::UT_VEC2, uniform::CU_QUAD_DIMS);
effects[i]->add_uniform("SwapXY", uniform::UT_BOOL, uniform::CU_SWAP_XY);
effects[i]->add_uniform("VectorScreen", uniform::UT_BOOL, uniform::CU_VECTOR_SCREEN);
}
ntsc_effect->add_uniform("CCValue", uniform::UT_FLOAT, uniform::CU_NTSC_CCFREQ);
@ -986,26 +980,19 @@ int shaders::create_resources(bool reset)
phosphor_effect->add_uniform("Phosphor", uniform::UT_VEC3, uniform::CU_PHOSPHOR_LIFE);
post_effect->add_uniform("VignettingAmount", uniform::UT_FLOAT, uniform::CU_POST_VIGNETTING); // backward compatibility
post_effect->add_uniform("CurvatureAmount", uniform::UT_FLOAT, uniform::CU_POST_CURVATURE); // backward compatibility
post_effect->add_uniform("RoundCornerAmount", uniform::UT_FLOAT, uniform::CU_POST_ROUND_CORNER); // backward compatibility
post_effect->add_uniform("SmoothBorderAmount", uniform::UT_FLOAT, uniform::CU_POST_SMOOTH_BORDER); // backward compatibility
post_effect->add_uniform("ReflectionAmount", uniform::UT_FLOAT, uniform::CU_POST_REFLECTION); // backward compatibility
post_effect->add_uniform("ShadowAlpha", uniform::UT_FLOAT, uniform::CU_POST_SHADOW_ALPHA);
post_effect->add_uniform("ShadowCount", uniform::UT_VEC2, uniform::CU_POST_SHADOW_COUNT);
post_effect->add_uniform("ShadowUV", uniform::UT_VEC2, uniform::CU_POST_SHADOW_UV);
post_effect->add_uniform("ShadowUVOffset", uniform::UT_VEC2, uniform::CU_POST_SHADOW_UV_OFFSET);
post_effect->add_uniform("ShadowDims", uniform::UT_VEC2, uniform::CU_POST_SHADOW_DIMS);
post_effect->add_uniform("ScanlineAlpha", uniform::UT_FLOAT, uniform::CU_POST_SCANLINE_ALPHA);
post_effect->add_uniform("ScanlineScale", uniform::UT_FLOAT, uniform::CU_POST_SCANLINE_SCALE);
post_effect->add_uniform("ScanlineHeight", uniform::UT_FLOAT, uniform::CU_POST_SCANLINE_HEIGHT);
post_effect->add_uniform("ScanlineVariation", uniform::UT_FLOAT, uniform::CU_POST_SCANLINE_VARIATION);
post_effect->add_uniform("ScanlineBrightScale", uniform::UT_FLOAT, uniform::CU_POST_SCANLINE_BRIGHT_SCALE);
post_effect->add_uniform("ScanlineBrightOffset", uniform::UT_FLOAT, uniform::CU_POST_SCANLINE_BRIGHT_OFFSET);
post_effect->add_uniform("Power", uniform::UT_VEC3, uniform::CU_POST_POWER);
post_effect->add_uniform("Floor", uniform::UT_VEC3, uniform::CU_POST_FLOOR);
post_effect->add_uniform("RotationType", uniform::UT_INT, uniform::CU_ROTATION_TYPE);
distortion_effect->add_uniform("VignettingAmount", uniform::UT_FLOAT, uniform::CU_POST_VIGNETTING);
@ -1013,11 +1000,12 @@ int shaders::create_resources(bool reset)
distortion_effect->add_uniform("RoundCornerAmount", uniform::UT_FLOAT, uniform::CU_POST_ROUND_CORNER);
distortion_effect->add_uniform("SmoothBorderAmount", uniform::UT_FLOAT, uniform::CU_POST_SMOOTH_BORDER);
distortion_effect->add_uniform("ReflectionAmount", uniform::UT_FLOAT, uniform::CU_POST_REFLECTION);
distortion_effect->add_uniform("RotationType", uniform::UT_INT, uniform::CU_ROTATION_TYPE);
initialized = true;
init_slider_list();
return 0;
}
@ -1035,7 +1023,7 @@ void shaders::begin_draw()
curr_effect = default_effect;
default_effect->set_technique("DefaultTechnique");
default_effect->set_technique("ScreenTechnique");
post_effect->set_technique("DefaultTechnique");
distortion_effect->set_technique("DefaultTechnique");
prescale_effect->set_technique("DefaultTechnique");
@ -1158,9 +1146,9 @@ void shaders::init_effect_info(poly_info *poly)
// shaders::find_render_target
//============================================================
d3d_render_target* shaders::find_render_target(texture_info *info)
d3d_render_target* shaders::find_render_target(texture_info *texture)
{
UINT32 screen_index_data = (UINT32)info->get_texinfo().osddata;
UINT32 screen_index_data = (UINT32)texture->get_texinfo().osddata;
UINT32 screen_index = screen_index_data >> 1;
UINT32 page_index = screen_index_data & 1;
@ -1168,8 +1156,8 @@ d3d_render_target* shaders::find_render_target(texture_info *info)
while (curr != nullptr && (
curr->screen_index != screen_index ||
curr->page_index != page_index ||
curr->width != info->get_texinfo().width ||
curr->height != info->get_texinfo().height))
curr->width != texture->get_width() ||
curr->height != texture->get_height()))
{
curr = curr->next;
}
@ -1182,12 +1170,12 @@ d3d_render_target* shaders::find_render_target(texture_info *info)
// shaders::find_render_target
//============================================================
d3d_render_target* shaders::find_render_target(int width, int height, UINT32 screen_index, UINT32 page_index)
d3d_render_target* shaders::find_render_target(int source_width, int source_height, UINT32 screen_index, UINT32 page_index)
{
d3d_render_target *curr = targethead;
while (curr != nullptr && (
curr->width != width ||
curr->height != height ||
curr->width != source_width ||
curr->height != source_height ||
curr->screen_index != screen_index ||
curr->page_index != page_index))
{
@ -1236,9 +1224,9 @@ int shaders::ntsc_pass(d3d_render_target *rt, int source_index, poly_info *poly,
curr_effect->set_float("SignalOffset", signal_offset);
next_index = rt->next_index(next_index);
blit(rt->native_target[next_index], true, D3DPT_TRIANGLELIST, 0, 2);
blit(rt->source_surface[next_index], true, D3DPT_TRIANGLELIST, 0, 2);
color_effect->set_texture("Diffuse", rt->native_texture[next_index]);
color_effect->set_texture("Diffuse", rt->source_texture[next_index]);
return next_index;
}
@ -1293,7 +1281,7 @@ int shaders::color_convolution_pass(d3d_render_target *rt, int source_index, pol
// initial "Diffuse" texture is set in shaders::set_texture() or the result of shaders::ntsc_pass()
next_index = rt->next_index(next_index);
blit(rt->native_target[next_index], true, D3DPT_TRIANGLELIST, 0, 2);
blit(rt->source_surface[next_index], true, D3DPT_TRIANGLELIST, 0, 2);
return next_index;
}
@ -1304,10 +1292,10 @@ int shaders::prescale_pass(d3d_render_target *rt, int source_index, poly_info *p
curr_effect = prescale_effect;
curr_effect->update_uniforms();
curr_effect->set_texture("Diffuse", rt->native_texture[next_index]);
curr_effect->set_texture("Diffuse", rt->source_texture[next_index]);
next_index = rt->next_index(next_index);
blit(rt->prescale_target[next_index], true, D3DPT_TRIANGLELIST, 0, 2);
blit(rt->target_surface[next_index], true, D3DPT_TRIANGLELIST, 0, 2);
return next_index;
}
@ -1327,10 +1315,10 @@ int shaders::deconverge_pass(d3d_render_target *rt, int source_index, poly_info
curr_effect = deconverge_effect;
curr_effect->update_uniforms();
curr_effect->set_texture("Diffuse", rt->prescale_texture[next_index]);
curr_effect->set_texture("Diffuse", rt->target_texture[next_index]);
next_index = rt->next_index(next_index);
blit(rt->prescale_target[next_index], true, D3DPT_TRIANGLELIST, 0, 2);
blit(rt->target_surface[next_index], true, D3DPT_TRIANGLELIST, 0, 2);
return next_index;
}
@ -1347,10 +1335,10 @@ int shaders::defocus_pass(d3d_render_target *rt, int source_index, poly_info *po
curr_effect = focus_effect;
curr_effect->update_uniforms();
curr_effect->set_texture("Diffuse", rt->prescale_texture[next_index]);
curr_effect->set_texture("Diffuse", rt->target_texture[next_index]);
next_index = rt->next_index(next_index);
blit(rt->prescale_target[next_index], true, D3DPT_TRIANGLELIST, 0, 2);
blit(rt->target_surface[next_index], true, D3DPT_TRIANGLELIST, 0, 2);
return next_index;
}
@ -1367,17 +1355,17 @@ int shaders::phosphor_pass(d3d_render_target *rt, cache_target *ct, int source_i
curr_effect = phosphor_effect;
curr_effect->update_uniforms();
curr_effect->set_texture("Diffuse", rt->prescale_texture[next_index]);
curr_effect->set_texture("Diffuse", rt->target_texture[next_index]);
curr_effect->set_texture("LastPass", ct->last_texture);
curr_effect->set_bool("Passthrough", false);
next_index = rt->next_index(next_index);
blit(rt->prescale_target[next_index], true, D3DPT_TRIANGLELIST, 0, 2);
blit(rt->target_surface[next_index], true, D3DPT_TRIANGLELIST, 0, 2);
// Pass along our phosphor'd screen
curr_effect->update_uniforms();
curr_effect->set_texture("Diffuse", rt->prescale_texture[next_index]);
curr_effect->set_texture("LastPass", rt->prescale_texture[next_index]);
curr_effect->set_texture("Diffuse", rt->target_texture[next_index]);
curr_effect->set_texture("LastPass", rt->target_texture[next_index]);
curr_effect->set_bool("Passthrough", true);
// Avoid changing targets due to page flipping
@ -1390,9 +1378,6 @@ int shaders::post_pass(d3d_render_target *rt, int source_index, poly_info *poly,
{
int next_index = source_index;
bool prepare_vector =
machine->first_screen()->screen_type() == SCREEN_TYPE_VECTOR;
screen_device_iterator screen_iterator(machine->root_device());
screen_device *screen = screen_iterator.first();
for (int i = 0; i < curr_screen; i++)
@ -1409,15 +1394,20 @@ int shaders::post_pass(d3d_render_target *rt, int source_index, poly_info *poly,
float screen_scale[2] = { xscale, yscale };
float screen_offset[2] = { xoffset, yoffset };
rgb_t back_color_rgb = !machine->first_screen()->has_palette() ? rgb_t(0, 0, 0) : machine->first_screen()->palette().palette()->entry_color(0);
rgb_t back_color_rgb = !machine->first_screen()->has_palette()
? rgb_t(0, 0, 0)
: machine->first_screen()->palette().palette()->entry_color(0);
back_color_rgb = apply_color_convolution(back_color_rgb);
float back_color[3] = { static_cast<float>(back_color_rgb.r()) / 255.0f, static_cast<float>(back_color_rgb.g()) / 255.0f, static_cast<float>(back_color_rgb.b()) / 255.0f };
float back_color[3] = {
static_cast<float>(back_color_rgb.r()) / 255.0f,
static_cast<float>(back_color_rgb.g()) / 255.0f,
static_cast<float>(back_color_rgb.b()) / 255.0f };
curr_effect = post_effect;
curr_effect->update_uniforms();
curr_effect->set_texture("ShadowTexture", shadow_texture == nullptr ? nullptr : shadow_texture->get_finaltex());
curr_effect->set_int("ShadowTileMode", options->shadow_mask_tile_mode);
curr_effect->set_texture("DiffuseTexture", rt->prescale_texture[next_index]);
curr_effect->set_texture("DiffuseTexture", rt->target_texture[next_index]);
curr_effect->set_vector("BackColor", 3, back_color);
curr_effect->set_vector("ScreenScale", 2, screen_scale);
curr_effect->set_vector("ScreenOffset", 2, screen_offset);
@ -1425,10 +1415,9 @@ int shaders::post_pass(d3d_render_target *rt, int source_index, poly_info *poly,
curr_effect->set_float("TimeMilliseconds", (float)machine->time().as_double() * 1000.0f);
curr_effect->set_float("HumBarAlpha", options->hum_bar_alpha);
curr_effect->set_bool("PrepareBloom", prepare_bloom);
curr_effect->set_bool("PrepareVector", prepare_vector);
next_index = rt->next_index(next_index);
blit(prepare_bloom ? rt->native_target[next_index] : rt->prescale_target[next_index], true, poly->get_type(), vertnum, poly->get_count());
blit(prepare_bloom ? rt->source_surface[next_index] : rt->target_surface[next_index], true, D3DPT_TRIANGLELIST, 0, 2);
return next_index;
}
@ -1443,38 +1432,21 @@ int shaders::downsample_pass(d3d_render_target *rt, int source_index, poly_info
return next_index;
}
bool prepare_vector =
machine->first_screen()->screen_type() == SCREEN_TYPE_VECTOR;
curr_effect = downsample_effect;
curr_effect->update_uniforms();
curr_effect->set_bool("PrepareVector", prepare_vector);
int bloom_index = 0;
float bloom_width = prepare_vector ? rt->target_width : rt->target_width / hlsl_prescale_x;
float bloom_height = prepare_vector ? rt->target_height : rt->target_height / hlsl_prescale_y;
float bloom_size = (bloom_width < bloom_height) ? bloom_width : bloom_height;
for (; bloom_size >= 2.0f && bloom_index < 11; bloom_size *= 0.5f)
for (int bloom_index = 0; bloom_index < rt->bloom_count; bloom_index++)
{
bloom_dims[bloom_index][0] = (float)(int)bloom_width;
bloom_dims[bloom_index][1] = (float)(int)bloom_height;
curr_effect->set_vector("TargetDims", 2, bloom_dims[bloom_index]);
curr_effect->set_vector("TargetDims", 2, rt->bloom_dims[bloom_index]);
curr_effect->set_int("BloomLevel", bloom_index + 1);
curr_effect->set_texture("DiffuseTexture",
bloom_index == 0
? rt->native_texture[next_index]
? rt->source_texture[next_index]
: rt->bloom_texture[bloom_index - 1]);
blit(rt->bloom_target[bloom_index], true, poly->get_type(), vertnum, poly->get_count());
bloom_width *= 0.5f;
bloom_height *= 0.5f;
bloom_index++;
blit(rt->bloom_surface[bloom_index], true, D3DPT_TRIANGLELIST, 0, 2);
}
bloom_count = bloom_index;
return next_index;
}
@ -1519,33 +1491,33 @@ int shaders::bloom_pass(d3d_render_target *rt, int source_index, poly_info *poly
curr_effect->set_vector("Level78Weight", 2, weight78);
curr_effect->set_vector("Level9AWeight", 2, weight9A);
curr_effect->set_vector("Level0Size", 2, bloom_dims[0]);
curr_effect->set_vector("Level12Size", 4, bloom_dims[1]);
curr_effect->set_vector("Level34Size", 4, bloom_dims[3]);
curr_effect->set_vector("Level56Size", 4, bloom_dims[5]);
curr_effect->set_vector("Level78Size", 4, bloom_dims[7]);
curr_effect->set_vector("Level9ASize", 4, bloom_dims[9]);
curr_effect->set_vector("Level0Size", 2, rt->bloom_dims[0]);
curr_effect->set_vector("Level12Size", 4, rt->bloom_dims[1]);
curr_effect->set_vector("Level34Size", 4, rt->bloom_dims[3]);
curr_effect->set_vector("Level56Size", 4, rt->bloom_dims[5]);
curr_effect->set_vector("Level78Size", 4, rt->bloom_dims[7]);
curr_effect->set_vector("Level9ASize", 4, rt->bloom_dims[9]);
curr_effect->set_int("BloomBlendMode", options->bloom_blend_mode);
curr_effect->set_float("BloomScale", options->bloom_scale);
curr_effect->set_vector("BloomOverdrive", 3, options->bloom_overdrive);
curr_effect->set_texture("DiffuseA", rt->prescale_texture[next_index]);
curr_effect->set_texture("DiffuseA", rt->target_texture[next_index]);
char name[9] = "Diffuse*";
for (int index = 1; index < bloom_count; index++)
for (int index = 1; index < rt->bloom_count; index++)
{
name[7] = 'A' + index;
curr_effect->set_texture(name, rt->bloom_texture[index - 1]);
}
for (int index = bloom_count; index < 11; index++)
for (int index = rt->bloom_count; index < 11; index++)
{
name[7] = 'A' + index;
curr_effect->set_texture(name, black_texture);
}
next_index = rt->next_index(next_index);
blit(rt->prescale_target[next_index], true, poly->get_type(), vertnum, poly->get_count());
blit(rt->target_surface[next_index], true, D3DPT_TRIANGLELIST, 0, 2);
return next_index;
}
@ -1564,32 +1536,12 @@ int shaders::distortion_pass(d3d_render_target *rt, int source_index, poly_info
return next_index;
}
int screen_count = d3d->window().target()->current_view()->screens().count();
// only one screen is supported
if (screen_count > 1)
{
return next_index;
}
render_bounds bounds = d3d->window().target()->current_view()->bounds();
render_bounds screen_bounds = d3d->window().target()->current_view()->screen_bounds();
// artworks are not supported
if (bounds.x0 != screen_bounds.x0 ||
bounds.y0 != screen_bounds.y0 ||
bounds.x1 != screen_bounds.x1 ||
bounds.y1 != screen_bounds.y1)
{
return next_index;
}
curr_effect = distortion_effect;
curr_effect->update_uniforms();
curr_effect->set_texture("DiffuseTexture", rt->prescale_texture[next_index]);
curr_effect->set_texture("DiffuseTexture", rt->target_texture[next_index]);
next_index = rt->next_index(next_index);
blit(rt->prescale_target[next_index], true, poly->get_type(), vertnum, poly->get_count());
blit(rt->target_surface[next_index], true, D3DPT_TRIANGLELIST, 0, 2);
return next_index;
}
@ -1606,7 +1558,7 @@ int shaders::vector_pass(d3d_render_target *rt, int source_index, poly_info *pol
curr_effect->set_vector("TimeParams", 2, time_params);
curr_effect->set_vector("LengthParams", 3, length_params);
blit(rt->prescale_target[next_index], true, poly->get_type(), vertnum, poly->get_count());
blit(rt->target_surface[next_index], true, poly->get_type(), vertnum, poly->get_count());
return next_index;
}
@ -1617,13 +1569,12 @@ int shaders::vector_buffer_pass(d3d_render_target *rt, int source_index, poly_in
curr_effect = default_effect;
curr_effect->update_uniforms();
curr_effect->set_technique("VectorBufferTechnique");
curr_effect->set_texture("Diffuse", rt->prescale_texture[next_index]);
curr_effect->set_bool("PostPass", true);
curr_effect->set_float("Brighten", 1.0f);
curr_effect->set_texture("Diffuse", rt->target_texture[next_index]);
next_index = rt->next_index(next_index);
blit(rt->prescale_target[next_index], true, poly->get_type(), vertnum, poly->get_count());
blit(rt->target_surface[next_index], true, D3DPT_TRIANGLELIST, 0, 2);
return next_index;
}
@ -1632,17 +1583,13 @@ int shaders::screen_pass(d3d_render_target *rt, int source_index, poly_info *pol
{
int next_index = source_index;
bool prepare_vector =
machine->first_screen()->screen_type() == SCREEN_TYPE_VECTOR;
curr_effect = default_effect;
curr_effect->update_uniforms();
curr_effect->set_technique("ScreenTechnique");
curr_effect->set_texture("Diffuse", rt->prescale_texture[next_index]);
curr_effect->set_bool("PostPass", true);
curr_effect->set_float("Brighten", prepare_vector ? 1.0f : 0.0f);
curr_effect->set_texture("Diffuse", rt->target_texture[next_index]);
// we do not clear the backbuffe here because multiple screens might rendered into
// we do not clear the backbuffe here because multiple screens might be rendered into
blit(backbuffer, false, poly->get_type(), vertnum, poly->get_count());
if (avi_output_file != nullptr)
@ -1660,12 +1607,11 @@ int shaders::screen_pass(d3d_render_target *rt, int source_index, poly_info *pol
return next_index;
}
void shaders::menu_pass(poly_info *poly, int vertnum)
void shaders::ui_pass(poly_info *poly, int vertnum)
{
curr_effect = default_effect;
curr_effect->update_uniforms();
curr_effect->set_bool("PostPass", false);
curr_effect->set_float("Brighten", 0.0f);
curr_effect->set_technique("UiTechnique");
blit(nullptr, false, poly->get_type(), vertnum, poly->get_count());
}
@ -1694,10 +1640,11 @@ void shaders::render_quad(poly_info *poly, int vertnum)
d3d_render_target *rt = curr_render_target;
if (rt == nullptr)
{
osd_printf_verbose("Direct3D: No raster render target\n");
return;
}
cache_target *ct = find_cache_target(rt->screen_index, curr_texture->get_texinfo().width, curr_texture->get_texinfo().height);
cache_target *ct = find_cache_target(rt->screen_index, curr_texture->get_width(), curr_texture->get_height());
int next_index = 0;
@ -1729,22 +1676,21 @@ void shaders::render_quad(poly_info *poly, int vertnum)
curr_texture->increment_frame_count();
curr_texture->mask_frame_count(options->yiq_phase_count);
options->params_dirty = false;
curr_screen++;
}
else if (PRIMFLAG_GET_VECTOR(poly->get_flags()) && vector_enable)
{
lines_pending = true;
curr_render_target = find_render_target(d3d->get_width(), d3d->get_height(), 0, 0);
d3d_render_target *rt = curr_render_target;
if (rt == nullptr)
{
osd_printf_verbose("Direct3D: No vector render target\n");
return;
}
lines_pending = true;
int next_index = 0;
next_index = vector_pass(rt, next_index, poly, vertnum);
@ -1757,11 +1703,14 @@ void shaders::render_quad(poly_info *poly, int vertnum)
}
else if (PRIMFLAG_GET_VECTORBUF(poly->get_flags()) && vector_enable)
{
curr_screen = curr_screen < num_screens ? curr_screen : 0;
curr_render_target = find_render_target(d3d->get_width(), d3d->get_height(), 0, 0);
d3d_render_target *rt = curr_render_target;
if (rt == nullptr)
{
osd_printf_verbose("Direct3D: No vector buffer render target\n");
return;
}
@ -1788,7 +1737,9 @@ void shaders::render_quad(poly_info *poly, int vertnum)
next_index = distortion_pass(rt, next_index, poly, vertnum);
// render on screen
d3d->set_wrap(D3DTADDRESS_MIRROR);
next_index = screen_pass(rt, next_index, poly, vertnum);
d3d->set_wrap(PRIMFLAG_GET_TEXWRAP(curr_texture->get_flags()) ? D3DTADDRESS_WRAP : D3DTADDRESS_CLAMP);
HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, backbuffer);
if (result != D3D_OK)
@ -1797,12 +1748,16 @@ void shaders::render_quad(poly_info *poly, int vertnum)
}
lines_pending = false;
curr_screen++;
}
else
{
menu_pass(poly, vertnum);
ui_pass(poly, vertnum);
}
options->params_dirty = false;
curr_render_target = nullptr;
curr_texture = nullptr;
curr_poly = nullptr;
@ -1824,40 +1779,19 @@ void shaders::end_draw()
}
//============================================================
// shaders::register_prescaled_texture
//============================================================
bool shaders::register_prescaled_texture(texture_info *texture)
{
return register_texture(texture);
}
//============================================================
// shaders::add_cache_target - register a cache target
//============================================================
bool shaders::add_cache_target(renderer_d3d9* d3d, texture_info* info, int width, int height, int xprescale, int yprescale, int screen_index)
bool shaders::add_cache_target(renderer_d3d9* d3d, texture_info* texture, int source_width, int source_height, int target_width, int target_height, int screen_index)
{
cache_target* target = (cache_target*)global_alloc_clear<cache_target>();
if (!target->init(d3d, d3dintf, width, height, xprescale, yprescale))
if (!target->init(d3d, d3dintf, source_width, source_height, target_width, target_height))
{
global_free(target);
return false;
}
if (info != nullptr)
{
target->width = info->get_texinfo().width;
target->height = info->get_texinfo().height;
}
else
{
target->width = d3d->get_width();
target->height = d3d->get_height();
}
target->next = cachehead;
target->prev = nullptr;
@ -1872,19 +1806,65 @@ bool shaders::add_cache_target(renderer_d3d9* d3d, texture_info* info, int width
return true;
}
d3d_render_target* shaders::get_vector_target()
//============================================================
// shaders::get_texture_target(render_primitive::prim, texture_info::texture)
//============================================================
d3d_render_target* shaders::get_texture_target(render_primitive *prim, texture_info *texture)
{
if (!vector_enable)
{
return nullptr;
}
return find_render_target(d3d->get_width(), d3d->get_height(), 0, 0);
bool swap_xy = d3d->swap_xy();
int target_width = swap_xy
? static_cast<int>(prim->get_quad_height() + 0.5f)
: static_cast<int>(prim->get_quad_width() + 0.5f);
int target_height = swap_xy
? static_cast<int>(prim->get_quad_width() + 0.5f)
: static_cast<int>(prim->get_quad_height() + 0.5f);
// find render target and check if the size of the target quad has changed
d3d_render_target *target = find_render_target(texture);
if (target != nullptr && target->target_width == target_width && target->target_height == target_height)
{
return target;
}
osd_printf_verbose("get_texture_target() - invalid size\n");
return nullptr;
}
d3d_render_target* shaders::get_vector_target(render_primitive *prim)
{
if (!vector_enable)
{
return nullptr;
}
int target_width = static_cast<int>(prim->get_quad_width() + 0.5f);
int target_height = static_cast<int>(prim->get_quad_height() + 0.5f);
// find render target and check of the size of the target quad has changed
d3d_render_target *target = find_render_target(d3d->get_width(), d3d->get_height(), 0, 0);
if (target != nullptr && target->target_width == target_width && target->target_height == target_height)
{
return target;
}
osd_printf_verbose("get_vector_target() - invalid size\n");
return nullptr;
}
void shaders::create_vector_target(render_primitive *prim)
{
if (!add_render_target(d3d, nullptr, d3d->get_width(), d3d->get_height(), 1, 1))
int target_width = static_cast<int>(prim->get_quad_width() + 0.5f);
int target_height = static_cast<int>(prim->get_quad_height() + 0.5f);
osd_printf_verbose("create_vector_target() - %f, %f; %d, %d\n", prim->get_quad_width(), prim->get_quad_height(), (int)(prim->get_quad_width() + 0.5f), (int)(prim->get_quad_height() + 0.5f));
if (!add_render_target(d3d, nullptr, d3d->get_width(), d3d->get_height(), target_width, target_height))
{
vector_enable = false;
}
@ -1895,25 +1875,25 @@ void shaders::create_vector_target(render_primitive *prim)
// shaders::add_render_target - register a render target
//============================================================
bool shaders::add_render_target(renderer_d3d9* d3d, texture_info* info, int width, int height, int xprescale, int yprescale)
bool shaders::add_render_target(renderer_d3d9* d3d, texture_info* texture, int source_width, int source_height, int target_width, int target_height)
{
UINT32 screen_index = 0;
UINT32 page_index = 0;
if (info != nullptr)
if (texture != nullptr)
{
d3d_render_target *existing_target = find_render_target(info);
d3d_render_target *existing_target = find_render_target(texture);
if (existing_target != nullptr)
{
remove_render_target(existing_target);
}
UINT32 screen_index_data = (UINT32)info->get_texinfo().osddata;
UINT32 screen_index_data = (UINT32)texture->get_texinfo().osddata;
screen_index = screen_index_data >> 1;
page_index = screen_index_data & 1;
}
else
{
d3d_render_target *existing_target = find_render_target(d3d->get_width(), d3d->get_height(), 0, 0);
d3d_render_target *existing_target = find_render_target(source_width, source_height, 0, 0);
if (existing_target != nullptr)
{
remove_render_target(existing_target);
@ -1922,37 +1902,26 @@ bool shaders::add_render_target(renderer_d3d9* d3d, texture_info* info, int widt
d3d_render_target* target = (d3d_render_target*)global_alloc_clear<d3d_render_target>();
if (!target->init(d3d, d3dintf, width, height, xprescale, yprescale))
if (!target->init(d3d, d3dintf, source_width, source_height, target_width, target_height))
{
global_free(target);
return false;
}
if (info != nullptr)
{
target->width = info->get_texinfo().width;
target->height = info->get_texinfo().height;
}
else
{
target->width = d3d->get_width();
target->height = d3d->get_height();
}
target->screen_index = screen_index;
target->page_index = page_index;
HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, target->prescale_target[0]);
HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, target->target_surface[0]);
if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
result = (*d3dintf->device.clear)(d3d->get_device(), 0, nullptr, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, backbuffer);
if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
target->screen_index = screen_index;
target->page_index = page_index;
cache_target* cache = find_cache_target(target->screen_index, target->width, target->height);
cache_target* cache = find_cache_target(target->screen_index, source_width, source_height);
if (cache == nullptr)
{
if (!add_cache_target(d3d, info, width, height, xprescale, yprescale, target->screen_index))
if (!add_cache_target(d3d, texture, source_width, source_height, target_width, target_height, target->screen_index))
{
global_free(target);
return false;
@ -1986,51 +1955,27 @@ void shaders::enumerate_screens()
// shaders::register_texture(texture::info)
//============================================================
bool shaders::register_texture(texture_info *texture)
bool shaders::register_texture(render_primitive *prim, texture_info *texture)
{
int width = texture->get_width();
int height = texture->get_height();
int xscale = texture->get_xscale();
int yscale = texture->get_yscale();
if (!master_enable || !d3dintf->post_fx_available)
{
return false;
}
enumerate_screens();
bool swap_xy = d3d->swap_xy();
int target_width = swap_xy
? static_cast<int>(prim->get_quad_height() + 0.5f)
: static_cast<int>(prim->get_quad_width() + 0.5f);
int target_height = swap_xy
? static_cast<int>(prim->get_quad_width() + 0.5f)
: static_cast<int>(prim->get_quad_height() + 0.5f);
// Find the nearest prescale factor that is over our screen size
if (hlsl_prescale_x == 0)
{
hlsl_prescale_x = 1;
while (width * xscale * hlsl_prescale_x <= d3d->get_width())
{
hlsl_prescale_x++;
}
hlsl_prescale_x--;
}
if (hlsl_prescale_y == 0)
{
hlsl_prescale_y = 1;
while (height * yscale * hlsl_prescale_y <= d3d->get_height())
{
hlsl_prescale_y++;
}
hlsl_prescale_y--;
}
hlsl_prescale_x = ((hlsl_prescale_x == 0) ? 1 : hlsl_prescale_x);
hlsl_prescale_y = ((hlsl_prescale_y == 0) ? 1 : hlsl_prescale_y);
if (!add_render_target(d3d, texture, width, height, xscale * hlsl_prescale_x, yscale * hlsl_prescale_y))
osd_printf_verbose("register_texture() - %f, %f; %d, %d\n", prim->get_quad_width(), prim->get_quad_height(), (int)(prim->get_quad_width() + 0.5f), (int)(prim->get_quad_height() + 0.5f));
if (!add_render_target(d3d, texture, texture->get_width(), texture->get_height(), target_width, target_height))
{
return false;
}
options->params_dirty = true;
return true;
}
@ -2173,6 +2118,8 @@ void shaders::delete_resources(bool reset)
}
shadow_bitmap.reset();
g_slider_list = nullptr;
}
@ -2326,6 +2273,7 @@ enum slider_option
SLIDER_SCANLINE_ALPHA,
SLIDER_SCANLINE_SCALE,
SLIDER_SCANLINE_HEIGHT,
SLIDER_SCANLINE_VARIATION,
SLIDER_SCANLINE_BRIGHT_SCALE,
SLIDER_SCANLINE_BRIGHT_OFFSET,
SLIDER_SCANLINE_JITTER,
@ -2400,10 +2348,11 @@ slider_desc shaders::s_sliders[] =
{ "Screen Reflection", 0, 0, 100, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_ANY, SLIDER_REFLECTION, 0.01f, "%1.2f", {} },
{ "Image Vignetting", 0, 0, 100, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_ANY, SLIDER_VIGNETTING, 0.01f, "%1.2f", {} },
{ "Scanline Darkness", 0, 0, 100, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_SCANLINE_ALPHA, 0.01f, "%1.2f", {} },
{ "Scanline Screen Height", 1, 20, 80, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_SCANLINE_SCALE, 0.05f, "%1.2f", {} },
{ "Scanline Indiv. Height", 1, 20, 80, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_SCANLINE_HEIGHT, 0.05f, "%1.2f", {} },
{ "Scanline Brightness", 0, 20, 40, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_SCANLINE_BRIGHT_SCALE, 0.05f, "%1.2f", {} },
{ "Scanline Brightness Overdrive", 0, 0, 20, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_SCANLINE_BRIGHT_OFFSET, 0.05f, "%1.2f", {} },
{ "Scanline Screen Scale", 0, 100, 400, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_SCANLINE_SCALE, 0.01f, "%1.2f", {} },
{ "Scanline Height", 0, 100, 400, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_SCANLINE_HEIGHT, 0.01f, "%1.2f", {} },
{ "Scanline Height Variation", 0, 100, 400, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_SCANLINE_VARIATION, 0.01f, "%1.2f", {} },
{ "Scanline Brightness", 0, 100, 200, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_SCANLINE_BRIGHT_SCALE, 0.01f, "%1.2f", {} },
{ "Scanline Brightness Overdrive", 0, 0, 100, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_SCANLINE_BRIGHT_OFFSET, 0.01f, "%1.2f", {} },
{ "Scanline Jitter", 0, 0, 100, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_SCANLINE_JITTER, 0.01f, "%1.2f", {} },
{ "Hum Bar Darkness", 0, 0, 100, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_HUM_BAR_ALPHA, 0.01f, "%2.2f", {} },
{ "Defocus", 0, 0, 100, 1, SLIDER_VEC2, SLIDER_SCREEN_TYPE_ANY, SLIDER_DEFOCUS, 0.1f, "%2.1f", {} },
@ -2476,6 +2425,7 @@ void *shaders::get_slider_option(int id, int index)
case SLIDER_SCANLINE_ALPHA: return &(options->scanline_alpha);
case SLIDER_SCANLINE_SCALE: return &(options->scanline_scale);
case SLIDER_SCANLINE_HEIGHT: return &(options->scanline_height);
case SLIDER_SCANLINE_VARIATION: return &(options->scanline_variation);
case SLIDER_SCANLINE_BRIGHT_SCALE: return &(options->scanline_bright_scale);
case SLIDER_SCANLINE_BRIGHT_OFFSET: return &(options->scanline_bright_offset);
case SLIDER_SCANLINE_JITTER: return &(options->scanline_jitter);
@ -2524,20 +2474,19 @@ void *shaders::get_slider_option(int id, int index)
return nullptr;
}
slider_state *shaders::init_slider_list()
void shaders::init_slider_list()
{
if (!master_enable || !d3dintf->post_fx_available)
{
g_slider_list = nullptr;
return nullptr;
}
slider_state *listhead = nullptr;
slider_state **tailptr = &listhead;
for (int index = 0; s_sliders[index].name != nullptr; index++)
for (int i = 0; s_sliders[i].name != nullptr; i++)
{
slider_desc *desc = &s_sliders[index];
slider_desc *desc = &s_sliders[i];
int screen_type = machine->first_screen()->screen_type();
if ((screen_type == SCREEN_TYPE_VECTOR && (desc->screen_type & SLIDER_SCREEN_TYPE_VECTOR) == SLIDER_SCREEN_TYPE_VECTOR) ||
@ -2557,9 +2506,10 @@ slider_state *shaders::init_slider_list()
count = 1;
break;
}
for (int index = 0; index < count; index++)
for (int j = 0; j < count; j++)
{
slider* slider_arg = new slider(desc, get_slider_option(desc->id, index), &options->params_dirty);
slider* slider_arg = new slider(desc, get_slider_option(desc->id, j), &options->params_dirty);
sliders.push_back(slider_arg);
std::string name = desc->name;
switch (desc->slider_type)
@ -2567,13 +2517,13 @@ slider_state *shaders::init_slider_list()
case SLIDER_VEC2:
{
std::string names[2] = { " X", " Y" };
name = name + names[index];
name = name + names[j];
break;
}
case SLIDER_COLOR:
{
std::string names[3] = { " Red", " Green", " Blue" };
name = name + names[index];
name = name + names[j];
break;
}
default:
@ -2585,7 +2535,7 @@ slider_state *shaders::init_slider_list()
}
}
return listhead;
g_slider_list = listhead;
}
@ -2661,28 +2611,25 @@ void uniform::update()
vec2f sourcedims = shadersys->curr_texture->get_rawdims();
m_shader->set_vector("SourceDims", 2, &sourcedims.c.x);
}
else
{
vec2f sourcedims = d3d->get_dims();
m_shader->set_vector("SourceDims", 2, &sourcedims.c.x);
}
break;
}
case CU_SOURCE_RECT:
{
bool prepare_vector =
d3d->window().machine().first_screen()->screen_type() == SCREEN_TYPE_VECTOR;
if (prepare_vector)
{
float delta[2] = { 1.0f, 1.0f };
m_shader->set_vector("SourceRect", 2, delta);
break;
}
if (shadersys->curr_texture != nullptr)
{
vec2f delta = shadersys->curr_texture->get_uvstop() - shadersys->curr_texture->get_uvstart();
m_shader->set_vector("SourceRect", 2, &delta.c.x);
break;
}
else
{
float delta[2] = { 1.0f, 1.0f };
m_shader->set_vector("SourceRect", 2, delta);
}
break;
}
case CU_TARGET_DIMS:
@ -2701,8 +2648,9 @@ void uniform::update()
if (shadersys->curr_poly != nullptr)
{
float quaddims[2] = {
shadersys->curr_poly->get_prim_width(),
shadersys->curr_poly->get_prim_height() };
// round
static_cast<float>(static_cast<int>(shadersys->curr_poly->get_prim_width() + 0.5f)),
static_cast<float>(static_cast<int>(shadersys->curr_poly->get_prim_height() + 0.5f)) };
m_shader->set_vector("QuadDims", 2, quaddims);
}
break;
@ -2710,18 +2658,15 @@ void uniform::update()
case CU_SWAP_XY:
{
bool orientation_swap_xy =
(d3d->window().machine().system().flags & ORIENTATION_SWAP_XY) == ORIENTATION_SWAP_XY;
bool rotation_swap_xy =
(d3d->window().target()->orientation() & ROT90) == ROT90 ||
(d3d->window().target()->orientation() & ROT270) == ROT270;
m_shader->set_bool("SwapXY", orientation_swap_xy ^ rotation_swap_xy);
m_shader->set_bool("SwapXY", d3d->swap_xy());
break;
}
case CU_ORIENTATION_SWAP:
{
bool orientation_swap_xy =
(d3d->window().machine().system().flags & ORIENTATION_SWAP_XY) == ORIENTATION_SWAP_XY;
m_shader->set_bool("OrientationSwapXY", orientation_swap_xy);
break;
}
case CU_ROTATION_SWAP:
@ -2730,6 +2675,7 @@ void uniform::update()
(d3d->window().target()->orientation() & ROT90) == ROT90 ||
(d3d->window().target()->orientation() & ROT270) == ROT270;
m_shader->set_bool("RotationSwapXY", rotation_swap_xy);
break;
}
case CU_ROTATION_TYPE:
{
@ -2742,6 +2688,14 @@ void uniform::update()
? 3
: 0;
m_shader->set_int("RotationType", rotation_type);
break;
}
case CU_VECTOR_SCREEN:
{
bool vector_screen =
d3d->window().machine().first_screen()->screen_type() == SCREEN_TYPE_VECTOR;
m_shader->set_bool("VectorScreen", vector_screen);
break;
}
case CU_NTSC_CCFREQ:
@ -2880,6 +2834,9 @@ void uniform::update()
case CU_POST_SCANLINE_HEIGHT:
m_shader->set_float("ScanlineHeight", options->scanline_height);
break;
case CU_POST_SCANLINE_VARIATION:
m_shader->set_float("ScanlineVariation", options->scanline_variation);
break;
case CU_POST_SCANLINE_BRIGHT_SCALE:
m_shader->set_float("ScanlineBrightScale", options->scanline_bright_scale);
break;

View File

@ -53,6 +53,7 @@ public:
CU_ORIENTATION_SWAP,
CU_ROTATION_SWAP,
CU_ROTATION_TYPE,
CU_VECTOR_SCREEN,
CU_NTSC_CCFREQ,
CU_NTSC_A,
@ -96,6 +97,7 @@ public:
CU_POST_SCANLINE_ALPHA,
CU_POST_SCANLINE_SCALE,
CU_POST_SCANLINE_HEIGHT,
CU_POST_SCANLINE_VARIATION,
CU_POST_SCANLINE_BRIGHT_SCALE,
CU_POST_SCANLINE_BRIGHT_OFFSET,
CU_POST_POWER,
@ -207,6 +209,7 @@ struct hlsl_options
float scanline_alpha;
float scanline_scale;
float scanline_height;
float scanline_variation;
float scanline_bright_scale;
float scanline_bright_offset;
float scanline_jitter;
@ -306,7 +309,7 @@ public:
void toggle();
bool vector_enabled() { return master_enable && vector_enable; }
d3d_render_target* get_vector_target();
d3d_render_target* get_vector_target(render_primitive *prim);
void create_vector_target(render_primitive *prim);
void begin_frame();
@ -318,10 +321,10 @@ public:
void init_effect_info(poly_info *poly);
void render_quad(poly_info *poly, int vertnum);
bool register_texture(texture_info *texture);
bool register_prescaled_texture(texture_info *texture);
bool add_render_target(renderer_d3d9* d3d, texture_info* info, int width, int height, int xprescale, int yprescale);
bool add_cache_target(renderer_d3d9* d3d, texture_info* info, int width, int height, int xprescale, int yprescale, int screen_index);
bool register_texture(render_primitive *prim, texture_info *texture);
d3d_render_target* get_texture_target(render_primitive *prim, texture_info *texture);
bool add_render_target(renderer_d3d9* d3d, texture_info* texture, int source_width, int source_height, int target_width, int target_height);
bool add_cache_target(renderer_d3d9* d3d, texture_info* texture, int source_width, int source_height, int target_width, int target_height, int screen_index);
void window_save();
void window_record();
@ -332,17 +335,17 @@ public:
void record_texture();
void init_fsfx_quad(void *vertbuf);
void set_texture(texture_info *texture);
d3d_render_target * find_render_target(texture_info *info);
void set_texture(texture_info *info);
d3d_render_target * find_render_target(texture_info *texture);
void remove_render_target(texture_info *texture);
void remove_render_target(int width, int height, UINT32 screen_index, UINT32 page_index);
void remove_render_target(int source_width, int source_height, UINT32 screen_index, UINT32 page_index);
void remove_render_target(d3d_render_target *rt);
int create_resources(bool reset);
void delete_resources(bool reset);
// slider-related functions
slider_state *init_slider_list();
void init_slider_list();
void *get_slider_option(int id, int index = 0);
private:
@ -352,9 +355,7 @@ private:
void end_avi_recording();
void begin_avi_recording(const char *name);
bool register_texture(texture_info *texture, int width, int height, int xscale, int yscale);
d3d_render_target* find_render_target(int width, int height, UINT32 screen_index, UINT32 page_index);
d3d_render_target* find_render_target(int source_width, int source_height, UINT32 screen_index, UINT32 page_index);
cache_target * find_cache_target(UINT32 screen_index, int width, int height);
void remove_cache_target(cache_target *cache);
@ -374,7 +375,7 @@ private:
int vector_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum);
int vector_buffer_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum);
int screen_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum);
void menu_pass(poly_info *poly, int vertnum);
void ui_pass(poly_info *poly, int vertnum);
d3d_base * d3dintf; // D3D interface
@ -388,13 +389,6 @@ private:
int curr_screen; // current screen for render target operations
int curr_frame; // current frame (0/1) of a screen for render target operations
int lastidx; // index of the last-encountered target
bool write_ini; // enable external ini saving
bool read_ini; // enable external ini loading
int hlsl_prescale_x; // hlsl prescale x
int hlsl_prescale_y; // hlsl prescale y
float bloom_dims[11][2]; // bloom texture dimensions
int bloom_count; // count of used bloom textures
int preset; // preset, if relevant
bitmap_argb32 shadow_bitmap; // shadow mask bitmap for post-processing shader
texture_info * shadow_texture; // shadow mask texture for post-processing shader
hlsl_options * options; // current options

View File

@ -209,6 +209,7 @@ render_primitive_list *renderer_d3d9::get_primitives()
}
if (m_shaders != nullptr)
{
// do not transform primitives (scale, offset) if shaders are enabled, the shaders will handle the transformation
window().target()->set_transform_primitives(!m_shaders->enabled());
}
return &window().target()->get_primitives();
@ -636,8 +637,16 @@ void d3d_texture_manager::update_textures()
texture_info *texture = find_texinfo(&prim->texture, prim->flags);
if (texture == nullptr)
{
// if there isn't one, create a new texture
global_alloc(texture_info(this, &prim->texture, m_renderer->window().prescale(), prim->flags));
if (m_renderer->get_shaders()->enabled())
{
// if there isn't one, create a new texture without prescale
texture = global_alloc(texture_info(this, &prim->texture, 1, prim->flags));
}
else
{
// if there isn't one, create a new texture
texture = global_alloc(texture_info(this, &prim->texture, m_renderer->window().prescale(), prim->flags));
}
}
else
{
@ -648,10 +657,21 @@ void d3d_texture_manager::update_textures()
texture->get_texinfo().seqid = prim->texture.seqid;
}
}
if (m_renderer->get_shaders()->enabled())
{
if (!m_renderer->get_shaders()->get_texture_target(prim, texture))
{
if (!m_renderer->get_shaders()->register_texture(prim, texture))
{
d3dintf->post_fx_available = false;
}
}
}
}
else if(m_renderer->get_shaders()->vector_enabled() && PRIMFLAG_GET_VECTORBUF(prim->flags))
{
if (!m_renderer->get_shaders()->get_vector_target())
if (!m_renderer->get_shaders()->get_vector_target(prim))
{
m_renderer->get_shaders()->create_vector_target(prim);
}
@ -684,12 +704,15 @@ void renderer_d3d9::begin_frame()
m_shaders->init_fsfx_quad(m_hlsl_buf);
}
// loop over line primitives
m_line_count = 0;
// loop over primitives
for (render_primitive *prim = window().m_primlist->first(); prim != nullptr; prim = prim->next())
{
if (prim->type == render_primitive::LINE && PRIMFLAG_GET_VECTOR(prim->flags))
{
m_line_count++;
}
}
}
void renderer_d3d9::process_primitives()
@ -1374,6 +1397,9 @@ void renderer_d3d9::batch_vectors()
m_vectorbatch = mesh_alloc(m_line_count * vector_size);
m_batchindex = 0;
float width = 0.0f;
float height = 0.0f;
static int start_index = 0;
int line_index = 0;
float period = options.screen_vector_time_period();
@ -1398,6 +1424,14 @@ void renderer_d3d9::batch_vectors()
}
break;
case render_primitive::QUAD:
if (PRIMFLAG_GET_VECTORBUF(prim->flags))
{
width = prim->bounds.x1 - prim->bounds.x0;
height = prim->bounds.y1 - prim->bounds.y0;
}
break;
default:
// Skip
break;
@ -1406,7 +1440,7 @@ void renderer_d3d9::batch_vectors()
// now add a polygon entry
m_poly[m_numpolys].init(D3DPT_TRIANGLELIST, m_line_count * (options.antialias() ? 8 : 2), vector_size * m_line_count, cached_flags,
m_texture_manager->get_vector_texture(), D3DTOP_MODULATE, 0.0f, 1.0f, 0.0f, 0.0f);
m_texture_manager->get_vector_texture(), D3DTOP_MODULATE, 0.0f, 1.0f, width, height);
m_numpolys++;
start_index += (int)((float)line_index * period);
@ -1631,11 +1665,12 @@ void renderer_d3d9::draw_quad(const render_primitive *prim)
float height = prim->bounds.y1 - prim->bounds.y0;
// set the texture coordinates
if(texture != nullptr)
if (texture != nullptr)
{
vec2f& start = texture->get_uvstart();
vec2f& stop = texture->get_uvstop();
vec2f delta = stop - start;
vertex[0].u0 = start.c.x + delta.c.x * prim->texcoords.tl.u;
vertex[0].v0 = start.c.y + delta.c.y * prim->texcoords.tl.v;
vertex[1].u0 = start.c.x + delta.c.x * prim->texcoords.tr.u;
@ -1888,6 +1923,30 @@ texture_info::texture_info(d3d_texture_manager *manager, const render_texinfo* t
m_d3dsurface = nullptr;
m_d3dfinaltex = nullptr;
// determine texture type, required to compute texture size
if (!PRIMFLAG_GET_SCREENTEX(flags))
{
m_type = TEXTURE_TYPE_PLAIN;
}
else
{
if ((m_xprescale == 1 && m_yprescale == 1) || m_renderer->get_shaders()->enabled())
{
m_type = m_texture_manager->is_dynamic_supported() ? TEXTURE_TYPE_DYNAMIC : TEXTURE_TYPE_PLAIN;
}
else
{
if (m_texture_manager->is_stretch_supported() && PRIMFLAG_GET_TEXFORMAT(flags) != TEXFORMAT_YUY16)
{
m_type = TEXTURE_TYPE_SURFACE;
}
else
{
m_type = m_texture_manager->is_dynamic_supported() ? TEXTURE_TYPE_DYNAMIC : TEXTURE_TYPE_PLAIN;
}
}
}
// compute the size
compute_size(texsource->width, texsource->height);
@ -1899,7 +1958,6 @@ texture_info::texture_info(d3d_texture_manager *manager, const render_texinfo* t
if (result != D3D_OK)
goto error;
m_d3dfinaltex = m_d3dtex;
m_type = TEXTURE_TYPE_PLAIN;
}
// screen textures are allocated differently
@ -1964,16 +2022,9 @@ texture_info::texture_info(d3d_texture_manager *manager, const render_texinfo* t
if (result == D3D_OK)
{
m_d3dfinaltex = m_d3dtex;
m_type = m_texture_manager->is_dynamic_supported() ? TEXTURE_TYPE_DYNAMIC : TEXTURE_TYPE_PLAIN;
if (m_renderer->get_shaders()->enabled() && !m_renderer->get_shaders()->register_texture(this))
{
goto error;
}
break;
}
}
// screen textures with prescaling require two allocations
else
{
@ -1986,9 +2037,7 @@ texture_info::texture_info(d3d_texture_manager *manager, const render_texinfo* t
{
continue;
}
m_type = TEXTURE_TYPE_SURFACE;
}
// otherwise, we allocate a dynamic texture for the source
else
{
@ -1997,7 +2046,6 @@ texture_info::texture_info(d3d_texture_manager *manager, const render_texinfo* t
{
continue;
}
m_type = m_texture_manager->is_dynamic_supported() ? TEXTURE_TYPE_DYNAMIC : TEXTURE_TYPE_PLAIN;
}
// for the target surface, we allocate a render target texture
@ -2006,15 +2054,13 @@ texture_info::texture_info(d3d_texture_manager *manager, const render_texinfo* t
// target surfaces typically cannot be YCbCr, so we always pick RGB in that case
D3DFORMAT finalfmt = (format != m_texture_manager->get_yuv_format()) ? format : D3DFMT_A8R8G8B8;
result = (*d3dintf->device.create_texture)(m_renderer->get_device(), scwidth, scheight, 1, D3DUSAGE_RENDERTARGET, finalfmt, D3DPOOL_DEFAULT, &m_d3dfinaltex);
if (result == D3D_OK)
{
if (m_renderer->get_shaders()->enabled() && !m_renderer->get_shaders()->register_prescaled_texture(this))
{
goto error;
}
break;
}
(*d3dintf->texture.release)(m_d3dtex);
m_d3dtex = nullptr;
}
@ -2024,7 +2070,6 @@ texture_info::texture_info(d3d_texture_manager *manager, const render_texinfo* t
// copy the data to the texture
set_data(texsource, flags);
//texsource->osdhandle = (void*)this;
// add us to the texture list
if(m_texture_manager->get_texlist() != nullptr)
m_texture_manager->get_texlist()->m_prev = this;
@ -2112,30 +2157,42 @@ void texture_info::compute_size(int texwidth, int texheight)
m_xborderpix = 0;
m_yborderpix = 0;
// if we're not wrapping, add a 1-2 pixel border on all sides
if (ENABLE_BORDER_PIX && !(m_flags & PRIMFLAG_TEXWRAP_MASK))
bool shaders_enabled = m_renderer->get_shaders()->enabled();
bool wrap_texture = (m_flags & PRIMFLAG_TEXWRAP_MASK) == PRIMFLAG_TEXWRAP_MASK;
bool border_texture = ENABLE_BORDER_PIX && !wrap_texture;
bool surface_texture = m_type == TEXTURE_TYPE_SURFACE;
// skip border when shaders are enabled and we're not creating a surface (UI) texture
if (!shaders_enabled || surface_texture)
{
// note we need 2 pixels in X for YUY textures
m_xborderpix = (PRIMFLAG_GET_TEXFORMAT(m_flags) == TEXFORMAT_YUY16) ? 2 : 1;
m_yborderpix = 1;
// if we're not wrapping, add a 1-2 pixel border on all sides
if (border_texture)
{
// note we need 2 pixels in X for YUY textures
m_xborderpix = (PRIMFLAG_GET_TEXFORMAT(m_flags) == TEXFORMAT_YUY16) ? 2 : 1;
m_yborderpix = 1;
}
}
// compute final texture size
finalwidth += 2 * m_xborderpix;
finalheight += 2 * m_yborderpix;
compute_size_subroutine(finalwidth, finalheight, &finalwidth, &finalheight);
// if we added pixels for the border, and that just barely pushed us over, take it back
if (finalwidth > m_texture_manager->get_max_texture_width() || finalheight > m_texture_manager->get_max_texture_height())
// take texture size as given when shaders are enabled and we're not creating a surface (UI) texture, still update wrapped textures
if (!shaders_enabled || surface_texture || wrap_texture)
{
finalheight = texheight;
finalwidth = texwidth;
m_xborderpix = 0;
m_yborderpix = 0;
compute_size_subroutine(finalwidth, finalheight, &finalwidth, &finalheight);
// if we added pixels for the border, and that just barely pushed us over, take it back
if (finalwidth > m_texture_manager->get_max_texture_width() || finalheight > m_texture_manager->get_max_texture_height())
{
finalheight = texheight;
finalwidth = texwidth;
m_xborderpix = 0;
m_yborderpix = 0;
compute_size_subroutine(finalwidth, finalheight, &finalwidth, &finalheight);
}
}
// if we're above the max width/height, do what?
@ -2714,18 +2771,20 @@ cache_target::~cache_target()
// cache_target::init - initializes a target cache
//============================================================
bool cache_target::init(renderer_d3d9 *d3d, d3d_base *d3dintf, int width, int height, int prescale_x, int prescale_y)
bool cache_target::init(renderer_d3d9 *d3d, d3d_base *d3dintf, int source_width, int source_height, int target_width, int target_height)
{
HRESULT result = (*d3dintf->device.create_texture)(d3d->get_device(), width * prescale_x, height * prescale_y, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &last_texture);
this->width = source_width;
this->height = source_height;
this->target_width = target_width;
this->target_height = target_height;
HRESULT result = (*d3dintf->device.create_texture)(d3d->get_device(), target_width, target_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &last_texture);
if (result != D3D_OK)
{
return false;
}
(*d3dintf->texture.get_surface_level)(last_texture, 0, &last_target);
target_width = width * prescale_x;
target_height = height * prescale_y;
return true;
}
@ -2743,34 +2802,34 @@ d3d_render_target::~d3d_render_target()
(*d3dintf->texture.release)(bloom_texture[index]);
bloom_texture[index] = nullptr;
}
if (bloom_target[index] != nullptr)
if (bloom_surface[index] != nullptr)
{
(*d3dintf->surface.release)(bloom_target[index]);
bloom_target[index] = nullptr;
(*d3dintf->surface.release)(bloom_surface[index]);
bloom_surface[index] = nullptr;
}
}
for (int index = 0; index < 2; index++)
{
if (native_texture[index] != nullptr)
if (source_texture[index] != nullptr)
{
(*d3dintf->texture.release)(native_texture[index]);
native_texture[index] = nullptr;
(*d3dintf->texture.release)(source_texture[index]);
source_texture[index] = nullptr;
}
if (native_target[index] != nullptr)
if (source_surface[index] != nullptr)
{
(*d3dintf->surface.release)(native_target[index]);
native_target[index] = nullptr;
(*d3dintf->surface.release)(source_surface[index]);
source_surface[index] = nullptr;
}
if (prescale_texture[index] != nullptr)
if (target_texture[index] != nullptr)
{
(*d3dintf->texture.release)(prescale_texture[index]);
prescale_texture[index] = nullptr;
(*d3dintf->texture.release)(target_texture[index]);
target_texture[index] = nullptr;
}
if (prescale_target[index] != nullptr)
if (target_surface[index] != nullptr)
{
(*d3dintf->surface.release)(prescale_target[index]);
prescale_target[index] = nullptr;
(*d3dintf->surface.release)(target_surface[index]);
target_surface[index] = nullptr;
}
}
}
@ -2780,52 +2839,62 @@ d3d_render_target::~d3d_render_target()
// d3d_render_target::init - initializes a render target
//============================================================
bool d3d_render_target::init(renderer_d3d9 *d3d, d3d_base *d3dintf, int width, int height, int prescale_x, int prescale_y)
bool d3d_render_target::init(renderer_d3d9 *d3d, d3d_base *d3dintf, int source_width, int source_height, int target_width, int target_height)
{
HRESULT result;
this->width = source_width;
this->height = source_height;
this->target_width = target_width;
this->target_height = target_height;
for (int index = 0; index < 2; index++)
{
result = (*d3dintf->device.create_texture)(d3d->get_device(), width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &native_texture[index]);
result = (*d3dintf->device.create_texture)(d3d->get_device(), source_width, source_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &source_texture[index]);
if (result != D3D_OK)
{
return false;
}
(*d3dintf->texture.get_surface_level)(native_texture[index], 0, &native_target[index]);
(*d3dintf->texture.get_surface_level)(source_texture[index], 0, &source_surface[index]);
result = (*d3dintf->device.create_texture)(d3d->get_device(), width * prescale_x, height * prescale_y, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &prescale_texture[index]);
result = (*d3dintf->device.create_texture)(d3d->get_device(), target_width, target_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &target_texture[index]);
if (result != D3D_OK)
{
return false;
}
(*d3dintf->texture.get_surface_level)(prescale_texture[index], 0, &prescale_target[index]);
(*d3dintf->texture.get_surface_level)(target_texture[index], 0, &target_surface[index]);
}
int bloom_index = 0;
float bloom_size = (d3d->get_width() < d3d->get_height()) ? d3d->get_width() : d3d->get_height();
float bloom_width = d3d->get_width();
float bloom_height = d3d->get_height();
for (; bloom_size >= 2.0f && bloom_index < 11; bloom_size *= 0.5f)
bool vector_screen =
d3d->window().machine().first_screen()->screen_type() == SCREEN_TYPE_VECTOR;
// larger blur width for vector screens than raster screens
float scale_factor = vector_screen ? 0.5f : 0.75f;
float bloom_width = (float)source_width;
float bloom_height = (float)source_height;
float bloom_size = bloom_width < bloom_height ? bloom_width : bloom_height;
for (int bloom_index = 0; bloom_index < 11 && bloom_size >= 2.0f; bloom_size *= scale_factor)
{
bloom_width *= 0.5f;
bloom_height *= 0.5f;
this->bloom_dims[bloom_index][0] = (int)bloom_width;
this->bloom_dims[bloom_index][1] = (int)bloom_height;
result = (*d3dintf->device.create_texture)(d3d->get_device(), (int)bloom_width, (int)bloom_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &bloom_texture[bloom_index]);
if (result != D3D_OK)
{
return false;
}
(*d3dintf->texture.get_surface_level)(bloom_texture[bloom_index], 0, &bloom_target[bloom_index]);
(*d3dintf->texture.get_surface_level)(bloom_texture[bloom_index], 0, &bloom_surface[bloom_index]);
bloom_width *= scale_factor;
bloom_height *= scale_factor;
bloom_index++;
this->bloom_count = bloom_index;
}
this->width = width;
this->height = height;
target_width = width * prescale_x;
target_height = height * prescale_y;
return true;
}

View File

@ -54,6 +54,17 @@ public:
virtual void record() override;
virtual void toggle_fsfx() override;
bool swap_xy()
{
// todo: move to osd_window
bool orientation_swap_xy =
(window().machine().system().flags & ORIENTATION_SWAP_XY) == ORIENTATION_SWAP_XY;
bool rotation_swap_xy =
(window().target()->orientation() & ROT90) == ROT90 ||
(window().target()->orientation() & ROT270) == ROT270;
return orientation_swap_xy ^ rotation_swap_xy;
};
int initialize();
int device_create(HWND device_HWND);
@ -81,8 +92,6 @@ public:
vertex * mesh_alloc(int numverts);
void update_textures();
void process_primitives();
void primitive_flush_pending();

View File

@ -281,6 +281,7 @@ void windows_osd_interface::update_slider_list()
{
for (win_window_info *window = win_window_list; window != nullptr; window = window->m_next)
{
// check if any window has dirty sliders
if (window->m_renderer && window->m_renderer->sliders_dirty())
{
build_slider_list();
@ -291,26 +292,13 @@ void windows_osd_interface::update_slider_list()
void windows_osd_interface::build_slider_list()
{
m_sliders = nullptr;
slider_state *curr = m_sliders;
for (win_window_info *info = win_window_list; info != nullptr; info = info->m_next)
// FIXME: take all sliders from all windows without concatenate them by slider_state->next
for (win_window_info *window = win_window_list; window != nullptr; window = window->m_next)
{
slider_state *window_sliders = info->m_renderer->get_slider_list();
if (window_sliders != nullptr)
{
if (m_sliders == nullptr)
{
m_sliders = curr = window_sliders;
}
else
{
while (curr->next != nullptr)
{
curr = curr->next;
}
curr->next = window_sliders;
}
}
// take the sliders of the first window
m_sliders = window->m_renderer->get_slider_list();
return;
}
}

View File

@ -283,8 +283,6 @@ const options_entry windows_options::s_option_entries[] =
{ nullptr, nullptr, OPTION_HEADER, "DIRECT3D POST-PROCESSING OPTIONS" },
{ WINOPTION_HLSL_ENABLE";hlsl", "0", OPTION_BOOLEAN, "enables HLSL post-processing (PS3.0 required)" },
{ WINOPTION_HLSLPATH, "hlsl", OPTION_STRING, "path to hlsl files" },
{ WINOPTION_HLSL_PRESCALE_X, "0", OPTION_INTEGER, "HLSL pre-scale override factor for X (0 for auto)" },
{ WINOPTION_HLSL_PRESCALE_Y, "0", OPTION_INTEGER, "HLSL pre-scale override factor for Y (0 for auto)" },
{ WINOPTION_HLSL_WRITE, nullptr, OPTION_STRING, "enables HLSL AVI writing (huge disk bandwidth suggested)" },
{ WINOPTION_HLSL_SNAP_WIDTH, "2048", OPTION_STRING, "HLSL upscaled-snapshot width" },
{ WINOPTION_HLSL_SNAP_HEIGHT, "1536", OPTION_STRING, "HLSL upscaled-snapshot height" },
@ -306,25 +304,26 @@ const options_entry windows_options::s_option_entries[] =
{ WINOPTION_SCANLINE_AMOUNT";fs_scanam(0.0-4.0)", "0.0", OPTION_FLOAT, "overall alpha scaling value for scanlines" },
{ WINOPTION_SCANLINE_SCALE";fs_scansc(0.0-4.0)", "1.0", OPTION_FLOAT, "overall height scaling value for scanlines" },
{ WINOPTION_SCANLINE_HEIGHT";fs_scanh(0.0-4.0)", "1.0", OPTION_FLOAT, "individual height scaling value for scanlines" },
{ WINOPTION_SCANLINE_VARIATION";fs_scanv(0.0-4.0)", "1.0", OPTION_FLOAT, "individual height varying value for scanlines" },
{ WINOPTION_SCANLINE_BRIGHT_SCALE";fs_scanbs(0.0-2.0)", "1.0", OPTION_FLOAT, "overall brightness scaling value for scanlines (multiplicative)" },
{ WINOPTION_SCANLINE_BRIGHT_OFFSET";fs_scanbo(0.0-1.0)", "0.0", OPTION_FLOAT, "overall brightness offset value for scanlines (additive)" },
{ WINOPTION_SCANLINE_JITTER";fs_scanjt(0.0-4.0)", "0.0", OPTION_FLOAT, "overall interlace jitter scaling value for scanlines" },
{ WINOPTION_HUM_BAR_ALPHA";fs_humba(0.0-1.0)", "0.0", OPTION_FLOAT, "overall alpha scaling value for hum bar" },
{ WINOPTION_DEFOCUS";fs_focus", "1.0,0.0", OPTION_STRING, "overall defocus value in screen-relative coords" },
{ WINOPTION_CONVERGE_X";fs_convx", "0.25,0.00,-0.25", OPTION_STRING, "convergence in screen-relative X direction" },
{ WINOPTION_CONVERGE_Y";fs_convy", "0.0,0.25,-0.25", OPTION_STRING, "convergence in screen-relative Y direction" },
{ WINOPTION_DEFOCUS";fs_focus", "0.0,0.0", OPTION_STRING, "overall defocus value in screen-relative coords" },
{ WINOPTION_CONVERGE_X";fs_convx", "0.0,0.0,0.0", OPTION_STRING, "convergence in screen-relative X direction" },
{ WINOPTION_CONVERGE_Y";fs_convy", "0.0,0.0,0.0", OPTION_STRING, "convergence in screen-relative Y direction" },
{ WINOPTION_RADIAL_CONVERGE_X";fs_rconvx", "0.0,0.0,0.0", OPTION_STRING, "radial convergence in screen-relative X direction" },
{ WINOPTION_RADIAL_CONVERGE_Y";fs_rconvy", "0.0,0.0,0.0", OPTION_STRING, "radial convergence in screen-relative Y direction" },
/* RGB colorspace convolution below this line */
{ WINOPTION_RED_RATIO";fs_redratio", "1.0,0.0,0.0", OPTION_STRING, "red output signal generated by input signal" },
{ WINOPTION_GRN_RATIO";fs_grnratio", "0.0,1.0,0.0", OPTION_STRING, "green output signal generated by input signal" },
{ WINOPTION_BLU_RATIO";fs_bluratio", "0.0,0.0,1.0", OPTION_STRING, "blue output signal generated by input signal" },
{ WINOPTION_SATURATION";fs_sat(0.0-4.0)", "1.4", OPTION_FLOAT, "saturation scaling value" },
{ WINOPTION_SATURATION";fs_sat(0.0-4.0)", "1.0", OPTION_FLOAT, "saturation scaling value" },
{ WINOPTION_OFFSET";fs_offset", "0.0,0.0,0.0", OPTION_STRING, "signal offset value (additive)" },
{ WINOPTION_SCALE";fs_scale", "0.95,0.95,0.95", OPTION_STRING, "signal scaling value (multiplicative)" },
{ WINOPTION_POWER";fs_power", "0.8,0.8,0.8", OPTION_STRING, "signal power value (exponential)" },
{ WINOPTION_FLOOR";fs_floor", "0.05,0.05,0.05", OPTION_STRING, "signal floor level" },
{ WINOPTION_PHOSPHOR";fs_phosphor", "0.4,0.4,0.4", OPTION_STRING, "phosphorescence decay rate (0.0 is instant, 1.0 is forever)" },
{ WINOPTION_SCALE";fs_scale", "1.0,1.0,1.0", OPTION_STRING, "signal scaling value (multiplicative)" },
{ WINOPTION_POWER";fs_power", "1.0,1.0,1.0", OPTION_STRING, "signal power value (exponential)" },
{ WINOPTION_FLOOR";fs_floor", "0.0,0.0,0.0", OPTION_STRING, "signal floor level" },
{ WINOPTION_PHOSPHOR";fs_phosphor", "0.0,0.0,0.0", OPTION_STRING, "phosphorescence decay rate (0.0 is instant, 1.0 is forever)" },
/* NTSC simulation below this line */
{ nullptr, nullptr, OPTION_HEADER, "NTSC POST-PROCESSING OPTIONS" },
{ WINOPTION_YIQ_ENABLE";yiq", "0", OPTION_BOOLEAN, "enables YIQ-space HLSL post-processing" },
@ -346,20 +345,20 @@ const options_entry windows_options::s_option_entries[] =
{ WINOPTION_VECTOR_LENGTH_RATIO";vecsize", "500.0", OPTION_FLOAT, "Vector fade length (4.0 - vectors fade the most at and above 4 pixels, etc.)" },
/* Bloom below this line */
{ nullptr, nullptr, OPTION_HEADER, "BLOOM POST-PROCESSING OPTIONS" },
{ WINOPTION_BLOOM_BLEND_MODE, "0", OPTION_INTEGER, "bloom blend mode (0 for addition, 1 for darken)" },
{ WINOPTION_BLOOM_SCALE, "0.25", OPTION_FLOAT, "Intensity factor for bloom" },
{ WINOPTION_BLOOM_BLEND_MODE, "0", OPTION_INTEGER, "bloom blend mode (0 for brighten, 1 for darken)" },
{ WINOPTION_BLOOM_SCALE, "0.0", OPTION_FLOAT, "Intensity factor for bloom" },
{ WINOPTION_BLOOM_OVERDRIVE, "1.0,1.0,1.0", OPTION_STRING, "Overdrive factor for bloom" },
{ WINOPTION_BLOOM_LEVEL0_WEIGHT, "1.0", OPTION_FLOAT, "Bloom level 0 (full-size target) weight" },
{ WINOPTION_BLOOM_LEVEL1_WEIGHT, "0.64", OPTION_FLOAT, "Bloom level 1 (half-size target) weight" },
{ WINOPTION_BLOOM_LEVEL2_WEIGHT, "0.32", OPTION_FLOAT, "Bloom level 2 (quarter-size target) weight" },
{ WINOPTION_BLOOM_LEVEL3_WEIGHT, "0.16", OPTION_FLOAT, "Bloom level 3 (.) weight" },
{ WINOPTION_BLOOM_LEVEL4_WEIGHT, "0.08", OPTION_FLOAT, "Bloom level 4 (.) weight" },
{ WINOPTION_BLOOM_LEVEL5_WEIGHT, "0.04", OPTION_FLOAT, "Bloom level 5 (.) weight" },
{ WINOPTION_BLOOM_LEVEL6_WEIGHT, "0.04", OPTION_FLOAT, "Bloom level 6 (.) weight" },
{ WINOPTION_BLOOM_LEVEL7_WEIGHT, "0.02", OPTION_FLOAT, "Bloom level 7 (.) weight" },
{ WINOPTION_BLOOM_LEVEL8_WEIGHT, "0.02", OPTION_FLOAT, "Bloom level 8 (.) weight" },
{ WINOPTION_BLOOM_LEVEL9_WEIGHT, "0.01", OPTION_FLOAT, "Bloom level 9 (.) weight" },
{ WINOPTION_BLOOM_LEVEL10_WEIGHT, "0.01", OPTION_FLOAT, "Bloom level 10 (1x1 target) weight" },
{ WINOPTION_BLOOM_LEVEL1_WEIGHT, "0.64", OPTION_FLOAT, "Bloom level 1 (1/2-size target) weight" },
{ WINOPTION_BLOOM_LEVEL2_WEIGHT, "0.32", OPTION_FLOAT, "Bloom level 2 (1/4-size target) weight" },
{ WINOPTION_BLOOM_LEVEL3_WEIGHT, "0.16", OPTION_FLOAT, "Bloom level 3 (1/8-size target) weight" },
{ WINOPTION_BLOOM_LEVEL4_WEIGHT, "0.08", OPTION_FLOAT, "Bloom level 4 (1/16-size target) weight" },
{ WINOPTION_BLOOM_LEVEL5_WEIGHT, "0.04", OPTION_FLOAT, "Bloom level 5 (1/32-size target) weight" },
{ WINOPTION_BLOOM_LEVEL6_WEIGHT, "0.04", OPTION_FLOAT, "Bloom level 6 (1/64-size target) weight" },
{ WINOPTION_BLOOM_LEVEL7_WEIGHT, "0.02", OPTION_FLOAT, "Bloom level 7 (1/128-size target) weight" },
{ WINOPTION_BLOOM_LEVEL8_WEIGHT, "0.02", OPTION_FLOAT, "Bloom level 8 (1/256-size target) weight" },
{ WINOPTION_BLOOM_LEVEL9_WEIGHT, "0.01", OPTION_FLOAT, "Bloom level 9 (1/512-size target) weight" },
{ WINOPTION_BLOOM_LEVEL10_WEIGHT, "0.01", OPTION_FLOAT, "Bloom level 10 (1/1024-size target) weight" },
// full screen options
{ nullptr, nullptr, OPTION_HEADER, "FULL SCREEN OPTIONS" },

View File

@ -31,8 +31,6 @@
// core post-processing options
#define WINOPTION_HLSL_ENABLE "hlsl_enable"
#define WINOPTION_HLSLPATH "hlslpath"
#define WINOPTION_HLSL_PRESCALE_X "hlsl_prescale_x"
#define WINOPTION_HLSL_PRESCALE_Y "hlsl_prescale_y"
#define WINOPTION_HLSL_WRITE "hlsl_write"
#define WINOPTION_HLSL_SNAP_WIDTH "hlsl_snap_width"
#define WINOPTION_HLSL_SNAP_HEIGHT "hlsl_snap_height"
@ -53,6 +51,7 @@
#define WINOPTION_SCANLINE_AMOUNT "scanline_alpha"
#define WINOPTION_SCANLINE_SCALE "scanline_size"
#define WINOPTION_SCANLINE_HEIGHT "scanline_height"
#define WINOPTION_SCANLINE_VARIATION "scanline_variation"
#define WINOPTION_SCANLINE_BRIGHT_SCALE "scanline_bright_scale"
#define WINOPTION_SCANLINE_BRIGHT_OFFSET "scanline_bright_offset"
#define WINOPTION_SCANLINE_JITTER "scanline_jitter"
@ -136,8 +135,6 @@ public:
const char *screen_post_fx_dir() const { return value(WINOPTION_HLSLPATH); }
bool d3d_hlsl_enable() const { return bool_value(WINOPTION_HLSL_ENABLE); }
const char *d3d_hlsl_write() const { return value(WINOPTION_HLSL_WRITE); }
int d3d_hlsl_prescale_x() const { return int_value(WINOPTION_HLSL_PRESCALE_X); }
int d3d_hlsl_prescale_y() const { return int_value(WINOPTION_HLSL_PRESCALE_Y); }
int d3d_snap_width() const { return int_value(WINOPTION_HLSL_SNAP_WIDTH); }
int d3d_snap_height() const { return int_value(WINOPTION_HLSL_SNAP_HEIGHT); }
int screen_shadow_mask_tile_mode() const { return int_value(WINOPTION_SHADOW_MASK_TILE_MODE); }
@ -152,6 +149,7 @@ public:
float screen_scanline_amount() const { return float_value(WINOPTION_SCANLINE_AMOUNT); }
float screen_scanline_scale() const { return float_value(WINOPTION_SCANLINE_SCALE); }
float screen_scanline_height() const { return float_value(WINOPTION_SCANLINE_HEIGHT); }
float screen_scanline_variation() const { return float_value(WINOPTION_SCANLINE_VARIATION); }
float screen_scanline_bright_scale() const { return float_value(WINOPTION_SCANLINE_BRIGHT_SCALE); }
float screen_scanline_bright_offset() const { return float_value(WINOPTION_SCANLINE_BRIGHT_OFFSET); }
float screen_scanline_jitter() const { return float_value(WINOPTION_SCANLINE_JITTER); }