From 2820e314518e822aab30587a817f0266787ff4a4 Mon Sep 17 00:00:00 2001 From: Ryan Holtz Date: Wed, 18 May 2011 00:35:16 +0000 Subject: [PATCH] HLSL Updates [Ryan Holtz, Bat Country Entertainment] - Potential fix for some crashing reported by John IV - Split color convolution and deconvergence into separate shaders for potential GPU savings down the line - Added light and heavy variants of the color convolution shader, the former with YIQ colorspace removed - Re-worked defocus to occur prior to shadow mask application, as it would be on a real monitor. - Removed Edge Detection, as it was just for fun and can easily be added in by users if desired. - Split "pincushion" into "Pincushion" and "Screen Curvature", the former affecting the only the displayed image and the latter only affecting the shadow mask. --- .gitattributes | 4 + hlsl/color.fx | 219 ++++++++++++++++++++ hlsl/color_heavy.fx | 219 ++++++++++++++++++++ hlsl/color_light.fx | 154 ++++++++++++++ hlsl/deconverge.fx | 130 ++++++++++++ hlsl/focus.fx | 8 +- hlsl/post.fx | 232 +++++---------------- src/osd/windows/drawd3d.c | 423 +++++++++++++++++++++++++------------- src/osd/windows/winmain.c | 25 +-- src/osd/windows/winmain.h | 41 ++-- 10 files changed, 1089 insertions(+), 366 deletions(-) create mode 100644 hlsl/color.fx create mode 100644 hlsl/color_heavy.fx create mode 100644 hlsl/color_light.fx create mode 100644 hlsl/deconverge.fx diff --git a/.gitattributes b/.gitattributes index 6371c52fef4..8b913b1a032 100644 --- a/.gitattributes +++ b/.gitattributes @@ -8,6 +8,10 @@ docs/newvideo.txt svneol=native#text/plain docs/windows.txt svneol=native#text/plain hash/megatech.xml svneol=native#text/plain hash/softwarelist.dtd svneol=native#text/plain +hlsl/color.fx svneol=native#text/plain +hlsl/color_heavy.fx svneol=native#text/plain +hlsl/color_light.fx svneol=native#text/plain +hlsl/deconverge.fx svneol=native#text/plain hlsl/focus.fx svneol=native#text/plain hlsl/phosphor.fx svneol=native#text/plain hlsl/pincushion.fx svneol=native#text/plain diff --git a/hlsl/color.fx b/hlsl/color.fx new file mode 100644 index 00000000000..a94cb5a9eca --- /dev/null +++ b/hlsl/color.fx @@ -0,0 +1,219 @@ +//----------------------------------------------------------------------------- +// Color-Convolution Effect +//----------------------------------------------------------------------------- + +texture Diffuse; + +sampler DiffuseSampler = sampler_state +{ + Texture = ; + MipFilter = LINEAR; + MinFilter = LINEAR; + MagFilter = LINEAR; + AddressU = CLAMP; + AddressV = CLAMP; + AddressW = CLAMP; +}; + +//----------------------------------------------------------------------------- +// Vertex Definitions +//----------------------------------------------------------------------------- + +struct VS_OUTPUT +{ + float4 Position : POSITION; + float4 Color : COLOR0; + float2 TexCoord : TEXCOORD0; + float2 ExtraInfo : TEXCOORD1; +}; + +struct VS_INPUT +{ + float4 Position : POSITION; + float4 Color : COLOR0; + float2 TexCoord : TEXCOORD0; + float2 ExtraInfo : TEXCOORD1; +}; + +struct PS_INPUT +{ + float4 Color : COLOR0; + float2 TexCoord : TEXCOORD0; + float2 ExtraInfo : TEXCOORD1; +}; + +//----------------------------------------------------------------------------- +// Post-Processing Vertex Shader +//----------------------------------------------------------------------------- + +uniform float TargetWidth; +uniform float TargetHeight; + +uniform float RawWidth; +uniform float RawHeight; + +uniform float WidthRatio; +uniform float HeightRatio; + +VS_OUTPUT vs_main(VS_INPUT Input) +{ + VS_OUTPUT Output = (VS_OUTPUT)0; + + Output.Position = float4(Input.Position.xyz, 1.0f); + Output.Position.x /= TargetWidth; + Output.Position.y /= TargetHeight; + Output.Position.y = 1.0f - Output.Position.y; + Output.Position.x -= 0.5f; + Output.Position.y -= 0.5f; + Output.Position *= float4(2.0f, 2.0f, 1.0f, 1.0f); + Output.Color = Input.Color; + Output.TexCoord = Input.TexCoord;//(Input.TexCoord - float2(0.5f, 0.5f)) / 8.0f + float2(0.25f, 0.25f); + Output.ExtraInfo = Input.ExtraInfo; + + return Output; +} + +//----------------------------------------------------------------------------- +// Post-Processing Pixel Shader +//----------------------------------------------------------------------------- + +uniform float RedFromRed = 1.0f; +uniform float RedFromGrn = 0.0f; +uniform float RedFromBlu = 0.0f; +uniform float GrnFromRed = 0.0f; +uniform float GrnFromGrn = 1.0f; +uniform float GrnFromBlu = 0.0f; +uniform float BluFromRed = 0.0f; +uniform float BluFromGrn = 0.0f; +uniform float BluFromBlu = 1.0f; + +uniform float YfromY = 1.0f; +uniform float YfromI = 0.0f; +uniform float YfromQ = 0.0f; +uniform float IfromY = 0.0f; +uniform float IfromI = 1.0f; +uniform float IfromQ = 0.0f; +uniform float QfromY = 0.0f; +uniform float QfromI = 0.0f; +uniform float QfromQ = 1.0f; + +uniform float RedOffset = 0.0f; +uniform float GrnOffset = 0.0f; +uniform float BluOffset = 0.0f; + +uniform float RedScale = 1.0f; +uniform float GrnScale = 1.0f; +uniform float BluScale = 1.0f; + +uniform float RedFloor = 0.0f; +uniform float GrnFloor = 0.0f; +uniform float BluFloor = 0.0f; + +uniform float Saturation = 1.0f; + +uniform float YScale = 1.0f; +uniform float IScale = 1.0f; +uniform float QScale = 1.0f; +uniform float YOffset = 0.0f; +uniform float IOffset = 0.0f; +uniform float QOffset = 0.0f; + +uniform float RedPower = 2.2f; +uniform float GrnPower = 2.2f; +uniform float BluPower = 2.2f; + +uniform float YSubsampleLength = 3.0f; +uniform float ISubsampleLength = 3.0f; +uniform float QSubsampleLength = 3.0f; + +float4 ps_main(PS_INPUT Input) : COLOR +{ + // -- Bandwidth Subsampling -- + float YSubsampleWidth = (RawWidth * 2.0f) / YSubsampleLength; + float ISubsampleWidth = (RawWidth * 2.0f) / ISubsampleLength; + float QSubsampleWidth = (RawWidth * 2.0f) / QSubsampleLength; + float3 SubsampleWidth = float3(YSubsampleWidth, ISubsampleWidth, QSubsampleWidth); + float3 SubsampleFrac = frac(Input.TexCoord.x * SubsampleWidth); + float3 SubsampleCoord = (Input.TexCoord.x * SubsampleWidth - SubsampleFrac) / SubsampleWidth + SubsampleFrac / (SubsampleWidth * 2.0f); + + float4 BaseTexel = tex2D(DiffuseSampler, Input.TexCoord); + + float3 YTexel = tex2D(DiffuseSampler, float2(SubsampleCoord.x, Input.TexCoord.y)).rgb; + float3 ITexel = tex2D(DiffuseSampler, float2(SubsampleCoord.y, Input.TexCoord.y)).rgb; + float3 QTexel = tex2D(DiffuseSampler, float2(SubsampleCoord.z, Input.TexCoord.y)).rgb; + + float3 LastYTexel = tex2D(DiffuseSampler, float2(SubsampleCoord.x - SubsampleFrac.x / RawWidth, Input.TexCoord.y)).rgb; + float3 LastITexel = tex2D(DiffuseSampler, float2(SubsampleCoord.y - SubsampleFrac.y / RawWidth, Input.TexCoord.y)).rgb; + float3 LastQTexel = tex2D(DiffuseSampler, float2(SubsampleCoord.z - SubsampleFrac.z / RawWidth, Input.TexCoord.y)).rgb; + + YTexel = lerp(LastYTexel, YTexel, SubsampleFrac.x); + ITexel = lerp(LastITexel, ITexel, SubsampleFrac.y); + QTexel = lerp(LastQTexel, QTexel, SubsampleFrac.z); + + // -- RGB Tint & Shift -- + float ShiftedRedY = dot(YTexel, float3(RedFromRed, RedFromGrn, RedFromBlu)); + float ShiftedGrnY = dot(YTexel, float3(GrnFromRed, GrnFromGrn, GrnFromBlu)); + float ShiftedBluY = dot(YTexel, float3(BluFromRed, BluFromGrn, BluFromBlu)); + float ShiftedRedI = dot(ITexel, float3(RedFromRed, RedFromGrn, RedFromBlu)); + float ShiftedGrnI = dot(ITexel, float3(GrnFromRed, GrnFromGrn, GrnFromBlu)); + float ShiftedBluI = dot(ITexel, float3(BluFromRed, BluFromGrn, BluFromBlu)); + float ShiftedRedQ = dot(QTexel, float3(RedFromRed, RedFromGrn, RedFromBlu)); + float ShiftedGrnQ = dot(QTexel, float3(GrnFromRed, GrnFromGrn, GrnFromBlu)); + float ShiftedBluQ = dot(QTexel, float3(BluFromRed, BluFromGrn, BluFromBlu)); + + // -- RGB Offset & Scale -- + float3 RGBScale = float3(RedScale, GrnScale, BluScale); + float3 RGBShift = float3(RedOffset, GrnOffset, BluOffset); + float3 OutTexelY = float3(ShiftedRedY, ShiftedGrnY, ShiftedBluY) * RGBScale + RGBShift; + float3 OutTexelI = float3(ShiftedRedI, ShiftedGrnI, ShiftedBluI) * RGBScale + RGBShift; + float3 OutTexelQ = float3(ShiftedRedQ, ShiftedGrnQ, ShiftedBluQ) * RGBScale + RGBShift; + + // -- Saturation -- + float3 Gray = float3(0.3f, 0.59f, 0.11f); + float OutLumaY = dot(OutTexelY, Gray); + float OutLumaI = dot(OutTexelI, Gray); + float OutLumaQ = dot(OutTexelQ, Gray); + float3 OutChromaY = OutTexelY - OutLumaY; + float3 OutChromaI = OutTexelI - OutLumaI; + float3 OutChromaQ = OutTexelQ - OutLumaQ; + float3 SaturatedY = OutLumaY + OutChromaY * Saturation; + float3 SaturatedI = OutLumaI + OutChromaI * Saturation; + float3 SaturatedQ = OutLumaQ + OutChromaQ * Saturation; + + // -- YIQ Convolution -- + float Y = dot(SaturatedY, float3(0.299f, 0.587f, 0.114f)); + float I = dot(SaturatedI, float3(0.595716f, -0.274453f, -0.321263f)); + float Q = dot(SaturatedQ, float3(0.211456f, -0.522591f, 0.311135f)); + Y = dot(float3(Y, I, Q), float3(YfromY, YfromI, YfromQ)); + I = dot(float3(Y, I, Q), float3(IfromY, IfromI, IfromQ)); + Q = dot(float3(Y, I, Q), float3(QfromY, QfromI, QfromQ)); + float3 OutYIQ = float3(Y, I, Q) * float3(YScale, IScale, QScale) + float3(YOffset, IOffset, QOffset); + float3 OutRGB = float3(dot(OutYIQ, float3(1.0f, 0.9563f, 0.6210f)), dot(OutYIQ, float3(1.0f, -0.2721f, -0.6474f)), dot(OutYIQ, float3(1.0f, -1.1070f, 1.7046f))); + + OutRGB.r = pow(OutRGB.r, RedPower); + OutRGB.g = pow(OutRGB.g, GrnPower); + OutRGB.b = pow(OutRGB.b, BluPower); + + // -- Color Compression (increasing the floor of the signal without affecting the ceiling) -- + OutRGB = float3(RedFloor + (1.0f - RedFloor) * OutRGB.r, GrnFloor + (1.0f - GrnFloor) * OutRGB.g, BluFloor + (1.0f - BluFloor) * OutRGB.b); + + // -- Final Pixel -- + float4 Output = lerp(Input.Color, float4(OutRGB, BaseTexel.a) * Input.Color, Input.ExtraInfo.x); + + return BaseTexel; +} + +//----------------------------------------------------------------------------- +// Color-Convolution Technique +//----------------------------------------------------------------------------- + +technique ColorTechnique +{ + pass Pass0 + { + Lighting = FALSE; + + VertexShader = compile vs_3_0 vs_main(); + PixelShader = compile ps_3_0 ps_main(); + } +} diff --git a/hlsl/color_heavy.fx b/hlsl/color_heavy.fx new file mode 100644 index 00000000000..a94cb5a9eca --- /dev/null +++ b/hlsl/color_heavy.fx @@ -0,0 +1,219 @@ +//----------------------------------------------------------------------------- +// Color-Convolution Effect +//----------------------------------------------------------------------------- + +texture Diffuse; + +sampler DiffuseSampler = sampler_state +{ + Texture = ; + MipFilter = LINEAR; + MinFilter = LINEAR; + MagFilter = LINEAR; + AddressU = CLAMP; + AddressV = CLAMP; + AddressW = CLAMP; +}; + +//----------------------------------------------------------------------------- +// Vertex Definitions +//----------------------------------------------------------------------------- + +struct VS_OUTPUT +{ + float4 Position : POSITION; + float4 Color : COLOR0; + float2 TexCoord : TEXCOORD0; + float2 ExtraInfo : TEXCOORD1; +}; + +struct VS_INPUT +{ + float4 Position : POSITION; + float4 Color : COLOR0; + float2 TexCoord : TEXCOORD0; + float2 ExtraInfo : TEXCOORD1; +}; + +struct PS_INPUT +{ + float4 Color : COLOR0; + float2 TexCoord : TEXCOORD0; + float2 ExtraInfo : TEXCOORD1; +}; + +//----------------------------------------------------------------------------- +// Post-Processing Vertex Shader +//----------------------------------------------------------------------------- + +uniform float TargetWidth; +uniform float TargetHeight; + +uniform float RawWidth; +uniform float RawHeight; + +uniform float WidthRatio; +uniform float HeightRatio; + +VS_OUTPUT vs_main(VS_INPUT Input) +{ + VS_OUTPUT Output = (VS_OUTPUT)0; + + Output.Position = float4(Input.Position.xyz, 1.0f); + Output.Position.x /= TargetWidth; + Output.Position.y /= TargetHeight; + Output.Position.y = 1.0f - Output.Position.y; + Output.Position.x -= 0.5f; + Output.Position.y -= 0.5f; + Output.Position *= float4(2.0f, 2.0f, 1.0f, 1.0f); + Output.Color = Input.Color; + Output.TexCoord = Input.TexCoord;//(Input.TexCoord - float2(0.5f, 0.5f)) / 8.0f + float2(0.25f, 0.25f); + Output.ExtraInfo = Input.ExtraInfo; + + return Output; +} + +//----------------------------------------------------------------------------- +// Post-Processing Pixel Shader +//----------------------------------------------------------------------------- + +uniform float RedFromRed = 1.0f; +uniform float RedFromGrn = 0.0f; +uniform float RedFromBlu = 0.0f; +uniform float GrnFromRed = 0.0f; +uniform float GrnFromGrn = 1.0f; +uniform float GrnFromBlu = 0.0f; +uniform float BluFromRed = 0.0f; +uniform float BluFromGrn = 0.0f; +uniform float BluFromBlu = 1.0f; + +uniform float YfromY = 1.0f; +uniform float YfromI = 0.0f; +uniform float YfromQ = 0.0f; +uniform float IfromY = 0.0f; +uniform float IfromI = 1.0f; +uniform float IfromQ = 0.0f; +uniform float QfromY = 0.0f; +uniform float QfromI = 0.0f; +uniform float QfromQ = 1.0f; + +uniform float RedOffset = 0.0f; +uniform float GrnOffset = 0.0f; +uniform float BluOffset = 0.0f; + +uniform float RedScale = 1.0f; +uniform float GrnScale = 1.0f; +uniform float BluScale = 1.0f; + +uniform float RedFloor = 0.0f; +uniform float GrnFloor = 0.0f; +uniform float BluFloor = 0.0f; + +uniform float Saturation = 1.0f; + +uniform float YScale = 1.0f; +uniform float IScale = 1.0f; +uniform float QScale = 1.0f; +uniform float YOffset = 0.0f; +uniform float IOffset = 0.0f; +uniform float QOffset = 0.0f; + +uniform float RedPower = 2.2f; +uniform float GrnPower = 2.2f; +uniform float BluPower = 2.2f; + +uniform float YSubsampleLength = 3.0f; +uniform float ISubsampleLength = 3.0f; +uniform float QSubsampleLength = 3.0f; + +float4 ps_main(PS_INPUT Input) : COLOR +{ + // -- Bandwidth Subsampling -- + float YSubsampleWidth = (RawWidth * 2.0f) / YSubsampleLength; + float ISubsampleWidth = (RawWidth * 2.0f) / ISubsampleLength; + float QSubsampleWidth = (RawWidth * 2.0f) / QSubsampleLength; + float3 SubsampleWidth = float3(YSubsampleWidth, ISubsampleWidth, QSubsampleWidth); + float3 SubsampleFrac = frac(Input.TexCoord.x * SubsampleWidth); + float3 SubsampleCoord = (Input.TexCoord.x * SubsampleWidth - SubsampleFrac) / SubsampleWidth + SubsampleFrac / (SubsampleWidth * 2.0f); + + float4 BaseTexel = tex2D(DiffuseSampler, Input.TexCoord); + + float3 YTexel = tex2D(DiffuseSampler, float2(SubsampleCoord.x, Input.TexCoord.y)).rgb; + float3 ITexel = tex2D(DiffuseSampler, float2(SubsampleCoord.y, Input.TexCoord.y)).rgb; + float3 QTexel = tex2D(DiffuseSampler, float2(SubsampleCoord.z, Input.TexCoord.y)).rgb; + + float3 LastYTexel = tex2D(DiffuseSampler, float2(SubsampleCoord.x - SubsampleFrac.x / RawWidth, Input.TexCoord.y)).rgb; + float3 LastITexel = tex2D(DiffuseSampler, float2(SubsampleCoord.y - SubsampleFrac.y / RawWidth, Input.TexCoord.y)).rgb; + float3 LastQTexel = tex2D(DiffuseSampler, float2(SubsampleCoord.z - SubsampleFrac.z / RawWidth, Input.TexCoord.y)).rgb; + + YTexel = lerp(LastYTexel, YTexel, SubsampleFrac.x); + ITexel = lerp(LastITexel, ITexel, SubsampleFrac.y); + QTexel = lerp(LastQTexel, QTexel, SubsampleFrac.z); + + // -- RGB Tint & Shift -- + float ShiftedRedY = dot(YTexel, float3(RedFromRed, RedFromGrn, RedFromBlu)); + float ShiftedGrnY = dot(YTexel, float3(GrnFromRed, GrnFromGrn, GrnFromBlu)); + float ShiftedBluY = dot(YTexel, float3(BluFromRed, BluFromGrn, BluFromBlu)); + float ShiftedRedI = dot(ITexel, float3(RedFromRed, RedFromGrn, RedFromBlu)); + float ShiftedGrnI = dot(ITexel, float3(GrnFromRed, GrnFromGrn, GrnFromBlu)); + float ShiftedBluI = dot(ITexel, float3(BluFromRed, BluFromGrn, BluFromBlu)); + float ShiftedRedQ = dot(QTexel, float3(RedFromRed, RedFromGrn, RedFromBlu)); + float ShiftedGrnQ = dot(QTexel, float3(GrnFromRed, GrnFromGrn, GrnFromBlu)); + float ShiftedBluQ = dot(QTexel, float3(BluFromRed, BluFromGrn, BluFromBlu)); + + // -- RGB Offset & Scale -- + float3 RGBScale = float3(RedScale, GrnScale, BluScale); + float3 RGBShift = float3(RedOffset, GrnOffset, BluOffset); + float3 OutTexelY = float3(ShiftedRedY, ShiftedGrnY, ShiftedBluY) * RGBScale + RGBShift; + float3 OutTexelI = float3(ShiftedRedI, ShiftedGrnI, ShiftedBluI) * RGBScale + RGBShift; + float3 OutTexelQ = float3(ShiftedRedQ, ShiftedGrnQ, ShiftedBluQ) * RGBScale + RGBShift; + + // -- Saturation -- + float3 Gray = float3(0.3f, 0.59f, 0.11f); + float OutLumaY = dot(OutTexelY, Gray); + float OutLumaI = dot(OutTexelI, Gray); + float OutLumaQ = dot(OutTexelQ, Gray); + float3 OutChromaY = OutTexelY - OutLumaY; + float3 OutChromaI = OutTexelI - OutLumaI; + float3 OutChromaQ = OutTexelQ - OutLumaQ; + float3 SaturatedY = OutLumaY + OutChromaY * Saturation; + float3 SaturatedI = OutLumaI + OutChromaI * Saturation; + float3 SaturatedQ = OutLumaQ + OutChromaQ * Saturation; + + // -- YIQ Convolution -- + float Y = dot(SaturatedY, float3(0.299f, 0.587f, 0.114f)); + float I = dot(SaturatedI, float3(0.595716f, -0.274453f, -0.321263f)); + float Q = dot(SaturatedQ, float3(0.211456f, -0.522591f, 0.311135f)); + Y = dot(float3(Y, I, Q), float3(YfromY, YfromI, YfromQ)); + I = dot(float3(Y, I, Q), float3(IfromY, IfromI, IfromQ)); + Q = dot(float3(Y, I, Q), float3(QfromY, QfromI, QfromQ)); + float3 OutYIQ = float3(Y, I, Q) * float3(YScale, IScale, QScale) + float3(YOffset, IOffset, QOffset); + float3 OutRGB = float3(dot(OutYIQ, float3(1.0f, 0.9563f, 0.6210f)), dot(OutYIQ, float3(1.0f, -0.2721f, -0.6474f)), dot(OutYIQ, float3(1.0f, -1.1070f, 1.7046f))); + + OutRGB.r = pow(OutRGB.r, RedPower); + OutRGB.g = pow(OutRGB.g, GrnPower); + OutRGB.b = pow(OutRGB.b, BluPower); + + // -- Color Compression (increasing the floor of the signal without affecting the ceiling) -- + OutRGB = float3(RedFloor + (1.0f - RedFloor) * OutRGB.r, GrnFloor + (1.0f - GrnFloor) * OutRGB.g, BluFloor + (1.0f - BluFloor) * OutRGB.b); + + // -- Final Pixel -- + float4 Output = lerp(Input.Color, float4(OutRGB, BaseTexel.a) * Input.Color, Input.ExtraInfo.x); + + return BaseTexel; +} + +//----------------------------------------------------------------------------- +// Color-Convolution Technique +//----------------------------------------------------------------------------- + +technique ColorTechnique +{ + pass Pass0 + { + Lighting = FALSE; + + VertexShader = compile vs_3_0 vs_main(); + PixelShader = compile ps_3_0 ps_main(); + } +} diff --git a/hlsl/color_light.fx b/hlsl/color_light.fx new file mode 100644 index 00000000000..d83a4012473 --- /dev/null +++ b/hlsl/color_light.fx @@ -0,0 +1,154 @@ +//----------------------------------------------------------------------------- +// Color-Convolution Effect +//----------------------------------------------------------------------------- + +texture Diffuse; + +sampler DiffuseSampler = sampler_state +{ + Texture = ; + MipFilter = LINEAR; + MinFilter = LINEAR; + MagFilter = LINEAR; + AddressU = CLAMP; + AddressV = CLAMP; + AddressW = CLAMP; +}; + +//----------------------------------------------------------------------------- +// Vertex Definitions +//----------------------------------------------------------------------------- + +struct VS_OUTPUT +{ + float4 Position : POSITION; + float4 Color : COLOR0; + float2 TexCoord : TEXCOORD0; + float2 ExtraInfo : TEXCOORD1; +}; + +struct VS_INPUT +{ + float4 Position : POSITION; + float4 Color : COLOR0; + float2 TexCoord : TEXCOORD0; + float2 ExtraInfo : TEXCOORD1; +}; + +struct PS_INPUT +{ + float4 Color : COLOR0; + float2 TexCoord : TEXCOORD0; + float2 ExtraInfo : TEXCOORD1; +}; + +//----------------------------------------------------------------------------- +// Post-Processing Vertex Shader +//----------------------------------------------------------------------------- + +uniform float TargetWidth; +uniform float TargetHeight; + +uniform float RawWidth; +uniform float RawHeight; + +uniform float WidthRatio; +uniform float HeightRatio; + +VS_OUTPUT vs_main(VS_INPUT Input) +{ + VS_OUTPUT Output = (VS_OUTPUT)0; + + Output.Position = float4(Input.Position.xyz, 1.0f); + Output.Position.x /= TargetWidth; + Output.Position.y /= TargetHeight; + Output.Position.y = 1.0f - Output.Position.y; + Output.Position.x -= 0.5f; + Output.Position.y -= 0.5f; + Output.Position *= float4(2.0f, 2.0f, 1.0f, 1.0f); + Output.Color = Input.Color; + Output.TexCoord = Input.TexCoord;//(Input.TexCoord - float2(0.5f, 0.5f)) / 8.0f + float2(0.25f, 0.25f); + Output.ExtraInfo = Input.ExtraInfo; + + return Output; +} + +//----------------------------------------------------------------------------- +// Post-Processing Pixel Shader +//----------------------------------------------------------------------------- + +uniform float RedFromRed = 1.0f; +uniform float RedFromGrn = 0.0f; +uniform float RedFromBlu = 0.0f; +uniform float GrnFromRed = 0.0f; +uniform float GrnFromGrn = 1.0f; +uniform float GrnFromBlu = 0.0f; +uniform float BluFromRed = 0.0f; +uniform float BluFromGrn = 0.0f; +uniform float BluFromBlu = 1.0f; + +uniform float RedOffset = 0.0f; +uniform float GrnOffset = 0.0f; +uniform float BluOffset = 0.0f; + +uniform float RedScale = 1.0f; +uniform float GrnScale = 1.0f; +uniform float BluScale = 1.0f; + +uniform float RedFloor = 0.0f; +uniform float GrnFloor = 0.0f; +uniform float BluFloor = 0.0f; + +uniform float Saturation = 1.0f; + +uniform float RedPower = 2.2f; +uniform float GrnPower = 2.2f; +uniform float BluPower = 2.2f; + +float4 ps_main(PS_INPUT Input) : COLOR +{ + float4 BaseTexel = tex2D(DiffuseSampler, Input.TexCoord); + + // -- RGB Tint & Shift -- + float ShiftedRed = dot(BaseTexel, float3(RedFromRed, RedFromGrn, RedFromBlu)); + float ShiftedGrn = dot(BaseTexel, float3(GrnFromRed, GrnFromGrn, GrnFromBlu)); + float ShiftedBlu = dot(BaseTexel, float3(BluFromRed, BluFromGrn, BluFromBlu)); + + // -- RGB Offset & Scale -- + float3 RGBScale = float3(RedScale, GrnScale, BluScale); + float3 RGBShift = float3(RedOffset, GrnOffset, BluOffset); + float3 OutTexel = float3(ShiftedRed, ShiftedGrn, ShiftedBlu) * RGBScale + RGBShift; + + // -- Saturation -- + float3 Gray = float3(0.3f, 0.59f, 0.11f); + float OutLuma = dot(OutTexel, Gray); + float3 OutChroma = OutTexel - OutLuma; + float3 OutRGB = OutLuma + OutChroma * Saturation; + + OutRGB.r = pow(OutRGB.r, RedPower); + OutRGB.g = pow(OutRGB.g, GrnPower); + OutRGB.b = pow(OutRGB.b, BluPower); + + // -- Color Compression (increasing the floor of the signal without affecting the ceiling) -- + OutRGB = float3(RedFloor + (1.0f - RedFloor) * OutRGB.r, GrnFloor + (1.0f - GrnFloor) * OutRGB.g, BluFloor + (1.0f - BluFloor) * OutRGB.b); + + // -- Final Pixel -- + float4 Output = lerp(Input.Color, float4(OutRGB, BaseTexel.a) * Input.Color, Input.ExtraInfo.x); + + return BaseTexel; +} + +//----------------------------------------------------------------------------- +// Color-Convolution Technique +//----------------------------------------------------------------------------- + +technique ColorTechnique +{ + pass Pass0 + { + Lighting = FALSE; + + VertexShader = compile vs_3_0 vs_main(); + PixelShader = compile ps_3_0 ps_main(); + } +} diff --git a/hlsl/deconverge.fx b/hlsl/deconverge.fx new file mode 100644 index 00000000000..f79ffa49be9 --- /dev/null +++ b/hlsl/deconverge.fx @@ -0,0 +1,130 @@ +//----------------------------------------------------------------------------- +// Deconvergence Effect +//----------------------------------------------------------------------------- + +texture Diffuse; + +sampler DiffuseSampler = sampler_state +{ + Texture = ; + MipFilter = LINEAR; + MinFilter = LINEAR; + MagFilter = LINEAR; + AddressU = CLAMP; + AddressV = CLAMP; + AddressW = CLAMP; +}; + +//----------------------------------------------------------------------------- +// Vertex Definitions +//----------------------------------------------------------------------------- + +struct VS_OUTPUT +{ + float4 Position : POSITION; + float4 Color : COLOR0; + float2 RedCoord : TEXCOORD0; + float2 GrnCoord : TEXCOORD1; + float2 BluCoord : TEXCOORD2; +}; + +struct VS_INPUT +{ + float4 Position : POSITION; + float4 Color : COLOR0; + float2 TexCoord : TEXCOORD0; + float2 ExtraInfo : TEXCOORD1; +}; + +struct PS_INPUT +{ + float4 Color : COLOR0; + float2 RedCoord : TEXCOORD0; + float2 GrnCoord : TEXCOORD1; + float2 BluCoord : TEXCOORD2; +}; + +//----------------------------------------------------------------------------- +// Deconvergence Vertex Shader +//----------------------------------------------------------------------------- + +uniform float RedConvergeX; +uniform float RedConvergeY; +uniform float GrnConvergeX; +uniform float GrnConvergeY; +uniform float BluConvergeX; +uniform float BluConvergeY; + +uniform float TargetWidth; +uniform float TargetHeight; + +uniform float RawWidth; +uniform float RawHeight; + +uniform float WidthRatio; +uniform float HeightRatio; + +uniform float RedRadialConvergeX; +uniform float RedRadialConvergeY; +uniform float GrnRadialConvergeX; +uniform float GrnRadialConvergeY; +uniform float BluRadialConvergeX; +uniform float BluRadialConvergeY; + +VS_OUTPUT vs_main(VS_INPUT Input) +{ + VS_OUTPUT Output = (VS_OUTPUT)0; + + float2 TargetRawRatio = float2(TargetWidth / RawWidth, TargetWidth / RawWidth); + float2 invDims = float2(1.0f / RawWidth, 1.0f / RawHeight); + float2 Ratios = float2(1.0f / WidthRatio, 1.0f / HeightRatio); + Output.Position = float4(Input.Position.xyz, 1.0f); + Output.Position.x /= TargetWidth; + Output.Position.y /= TargetHeight; + Output.Position.y = 1.0f - Output.Position.y; + Output.Position.x -= 0.5f; + Output.Position.y -= 0.5f; + Output.Position *= float4(2.0f, 2.0f, 1.0f, 1.0f); + Output.Color = Input.Color; + float2 InvTexSize = float2(1.0f / TargetWidth, 1.0f / TargetHeight); + float2 TexCoord = (Input.Position.xy * InvTexSize); + TexCoord = TexCoord;// + float2(0.5f / TargetWidth, 0.5f / TargetHeight);// * float2(WidthRatio, HeightRatio);//(Input.TexCoord - float2(0.5f, 0.5f)) / 8.0f + float2(0.25f, 0.25f); + + Output.RedCoord.x = ((((TexCoord.x / Ratios.x) - 0.5f)) * (1.0f + RedRadialConvergeX / RawWidth) + 0.5f) * Ratios.x + RedConvergeX * invDims.x; + Output.GrnCoord.x = ((((TexCoord.x / Ratios.x) - 0.5f)) * (1.0f + GrnRadialConvergeX / RawWidth) + 0.5f) * Ratios.x + GrnConvergeX * invDims.x; + Output.BluCoord.x = ((((TexCoord.x / Ratios.x) - 0.5f)) * (1.0f + BluRadialConvergeX / RawWidth) + 0.5f) * Ratios.x + GrnConvergeX * invDims.x; + + Output.RedCoord.y = ((((TexCoord.y / Ratios.y) - 0.5f)) * (1.0f + RedRadialConvergeY / RawHeight) + 0.5f) * Ratios.y + RedConvergeY * invDims.y; + Output.GrnCoord.y = ((((TexCoord.y / Ratios.y) - 0.5f)) * (1.0f + GrnRadialConvergeY / RawHeight) + 0.5f) * Ratios.y + BluConvergeY * invDims.y; + Output.BluCoord.y = ((((TexCoord.y / Ratios.y) - 0.5f)) * (1.0f + BluRadialConvergeY / RawHeight) + 0.5f) * Ratios.y + BluConvergeY * invDims.y; + + return Output; +} + +//----------------------------------------------------------------------------- +// Deconvergence Pixel Shader +//----------------------------------------------------------------------------- + +float4 ps_main(PS_INPUT Input) : COLOR +{ + float RedTexel = tex2D(DiffuseSampler, Input.RedCoord).r; + float GrnTexel = tex2D(DiffuseSampler, Input.GrnCoord).g; + float BluTexel = tex2D(DiffuseSampler, Input.BluCoord).b; + + return float4(RedTexel, GrnTexel, BluTexel, 1.0f); +} + +//----------------------------------------------------------------------------- +// Deconvergence Effect +//----------------------------------------------------------------------------- + +technique DeconvergeTechnique +{ + pass Pass0 + { + Lighting = FALSE; + + VertexShader = compile vs_3_0 vs_main(); + PixelShader = compile ps_3_0 ps_main(); + } +} diff --git a/hlsl/focus.fx b/hlsl/focus.fx index 8856b06a6da..b31dcf06968 100644 --- a/hlsl/focus.fx +++ b/hlsl/focus.fx @@ -60,6 +60,10 @@ struct PS_INPUT uniform float TargetWidth; uniform float TargetHeight; + +uniform float WidthRatio; +uniform float HeightRatio; + uniform float DefocusX; uniform float DefocusY; uniform float FocusEnable; @@ -87,7 +91,7 @@ VS_OUTPUT vs_main(VS_INPUT Input) Output.Color = Input.Color; float2 InvTexSize = float2(1.0f / TargetWidth, 1.0f / TargetHeight); - float2 TexCoord = Input.Position.xy * InvTexSize; + float2 TexCoord = (Input.Position.xy * InvTexSize); float2 DefocusVal = float2(DefocusX, DefocusY); Output.TexCoord0 = TexCoord + Coord0Offset * InvTexSize * DefocusVal; Output.TexCoord1 = TexCoord + Coord1Offset * InvTexSize * DefocusVal; @@ -118,7 +122,7 @@ float4 ps_main(PS_INPUT Input) : COLOR float3 blurred = (d0 + d1 + d2 + d3 + d4 + d5 + d6 + d7) / 8.0f; - blurred = lerp(d0, blurred, FocusEnable); + blurred = lerp(d0, blurred, 1.0f); return float4(blurred, 1.0f); } diff --git a/hlsl/post.fx b/hlsl/post.fx index 50e779c31f2..fa2082e6591 100644 --- a/hlsl/post.fx +++ b/hlsl/post.fx @@ -1,5 +1,5 @@ //----------------------------------------------------------------------------- -// Post-Processing Effect +// Scanline & Shadowmask Effect //----------------------------------------------------------------------------- texture Diffuse; @@ -38,9 +38,6 @@ struct VS_OUTPUT float4 Color : COLOR0; float2 TexCoord : TEXCOORD0; float2 ExtraInfo : TEXCOORD1; - float3 CoordX : TEXCOORD2; - float3 CoordY : TEXCOORD3; - float2 ShadowCoord : TEXCOORD4; }; struct VS_INPUT @@ -56,22 +53,12 @@ struct PS_INPUT float4 Color : COLOR0; float2 TexCoord : TEXCOORD0; float2 ExtraInfo : TEXCOORD1; - float3 CoordX : TEXCOORD2; - float3 CoordY : TEXCOORD3; - float2 ShadowCoord : TEXCOORD4; }; //----------------------------------------------------------------------------- -// Post-Processing Vertex Shader +// Scanline & Shadowmask Vertex Shader //----------------------------------------------------------------------------- -uniform float RedConvergeX; -uniform float RedConvergeY; -uniform float GrnConvergeX; -uniform float GrnConvergeY; -uniform float BluConvergeX; -uniform float BluConvergeY; - uniform float TargetWidth; uniform float TargetHeight; @@ -81,19 +68,10 @@ uniform float RawHeight; uniform float WidthRatio; uniform float HeightRatio; -uniform float RedRadialConvergeX; -uniform float RedRadialConvergeY; -uniform float GrnRadialConvergeX; -uniform float GrnRadialConvergeY; -uniform float BluRadialConvergeX; -uniform float BluRadialConvergeY; - VS_OUTPUT vs_main(VS_INPUT Input) { VS_OUTPUT Output = (VS_OUTPUT)0; - float2 invDims = float2(1.0f / RawWidth, 1.0f / RawHeight); - float2 Ratios = float2(1.0f / WidthRatio, 1.0f / HeightRatio); Output.Position = float4(Input.Position.xyz, 1.0f); Output.Position.x /= TargetWidth; Output.Position.y /= TargetHeight; @@ -102,18 +80,11 @@ VS_OUTPUT vs_main(VS_INPUT Input) Output.Position.y -= 0.5f; Output.Position *= float4(2.0f, 2.0f, 1.0f, 1.0f); Output.Color = Input.Color; - Output.TexCoord = Input.TexCoord;//(Input.TexCoord - float2(0.5f, 0.5f)) / 8.0f + float2(0.25f, 0.25f); + float2 InvTexSize = float2(1.0f / TargetWidth, 1.0f / TargetHeight); + float2 TexCoord = (Input.Position.xy * InvTexSize) / float2(WidthRatio, HeightRatio); + Output.TexCoord = TexCoord;//(Input.TexCoord - float2(0.5f, 0.5f)) / 8.0f + float2(0.25f, 0.25f); Output.ExtraInfo = Input.ExtraInfo; - Output.CoordX.x = ((((Output.TexCoord.x / Ratios.x) - 0.5f)) * (1.0f + RedRadialConvergeX / RawWidth) + 0.5f) * Ratios.x + RedConvergeX * invDims.x; - Output.CoordX.y = ((((Output.TexCoord.x / Ratios.x) - 0.5f)) * (1.0f + GrnRadialConvergeX / RawWidth) + 0.5f) * Ratios.x + GrnConvergeX * invDims.x; - Output.CoordX.z = ((((Output.TexCoord.x / Ratios.x) - 0.5f)) * (1.0f + BluRadialConvergeX / RawWidth) + 0.5f) * Ratios.x + GrnConvergeX * invDims.x; - - Output.CoordY.x = ((((Output.TexCoord.y / Ratios.y) - 0.5f)) * (1.0f + RedRadialConvergeY / RawHeight) + 0.5f) * Ratios.y + RedConvergeY * invDims.y; - Output.CoordY.y = ((((Output.TexCoord.y / Ratios.y) - 0.5f)) * (1.0f + GrnRadialConvergeY / RawHeight) + 0.5f) * Ratios.y + BluConvergeY * invDims.y; - Output.CoordY.z = ((((Output.TexCoord.y / Ratios.y) - 0.5f)) * (1.0f + BluRadialConvergeY / RawHeight) + 0.5f) * Ratios.y + BluConvergeY * invDims.y; - - Output.ShadowCoord = Output.TexCoord * float2(RawWidth, RawHeight); return Output; } @@ -123,8 +94,8 @@ VS_OUTPUT vs_main(VS_INPUT Input) uniform float PI = 3.14159265f; -uniform float PincushionAmountX = 0.1f; -uniform float PincushionAmountY = 0.1f; +uniform float PincushionAmount = 0.00f; +uniform float CurvatureAmount = 0.08f; uniform float ScanlineAmount = 1.0f; uniform float ScanlineScale = 1.0f; @@ -132,65 +103,12 @@ uniform float ScanlineBrightScale = 1.0f; uniform float ScanlineBrightOffset = 1.0f; uniform float ScanlineOffset = 1.0f; -uniform float RedFromRed = 1.0f; -uniform float RedFromGrn = 0.0f; -uniform float RedFromBlu = 0.0f; -uniform float GrnFromRed = 0.0f; -uniform float GrnFromGrn = 1.0f; -uniform float GrnFromBlu = 0.0f; -uniform float BluFromRed = 0.0f; -uniform float BluFromGrn = 0.0f; -uniform float BluFromBlu = 1.0f; - -uniform float YfromY = 1.0f; -uniform float YfromI = 0.0f; -uniform float YfromQ = 0.0f; -uniform float IfromY = 0.0f; -uniform float IfromI = 1.0f; -uniform float IfromQ = 0.0f; -uniform float QfromY = 0.0f; -uniform float QfromI = 0.0f; -uniform float QfromQ = 1.0f; - -uniform float RedOffset = 0.0f; -uniform float GrnOffset = 0.0f; -uniform float BluOffset = 0.0f; - -uniform float RedScale = 1.0f; -uniform float GrnScale = 1.0f; -uniform float BluScale = 1.0f; - -uniform float RedFloor = 0.0f; -uniform float GrnFloor = 0.0f; -uniform float BluFloor = 0.0f; - -uniform float Saturation = 1.0f; - -uniform float YScale = 1.0f; -uniform float IScale = 1.0f; -uniform float QScale = 1.0f; -uniform float YOffset = 0.0f; -uniform float IOffset = 0.0f; -uniform float QOffset = 0.0f; - -uniform float RedPower = 2.2f; -uniform float GrnPower = 2.2f; -uniform float BluPower = 2.2f; - -uniform float EdgeDetectScale = 1.0f; -uniform float EdgeToBaseRatio = 0.0f; - -uniform float SubsampleLength = 3.0f; - -uniform float CurrFrame = 0.0f; -uniform float CrawlWidth = 3.0f; -uniform float CrawlHeight = 3.0f; -uniform float CrawlRate = 3.0f; - uniform float UseShadow = 0.0f; uniform float ShadowBrightness = 1.0f; uniform float ShadowPixelSizeX = 3.0f; uniform float ShadowPixelSizeY = 3.0f; +uniform float ShadowMaskSizeX = 3.0f; +uniform float ShadowMaskSizeY = 3.0f; uniform float ShadowU = 0.375f; uniform float ShadowV = 0.375f; uniform float ShadowWidth = 8.0f; @@ -201,105 +119,53 @@ float4 ps_main(PS_INPUT Input) : COLOR float2 Ratios = float2(WidthRatio, HeightRatio); // -- Screen Pincushion Calculation -- - float2 UnitCoord = Input.TexCoord * Ratios * 2.0f - 1.0f; + float2 PinViewpointOffset = float2(0.0f, 0.0f); + float2 PinUnitCoord = (Input.TexCoord + PinViewpointOffset) * Ratios * 2.0f - 1.0f; + float PincushionR2 = pow(length(PinUnitCoord), 2.0f) / pow(length(Ratios), 2.0f); + float2 PincushionCurve = PinUnitCoord * PincushionAmount * PincushionR2; + float2 BaseCoord = Input.TexCoord; + BaseCoord -= 0.5f / Ratios; + BaseCoord *= 1.0f - PincushionAmount * Ratios * 0.2f; // Warning: Magic constant + BaseCoord += 0.5f / Ratios; + BaseCoord += PincushionCurve; - float PincushionR2 = pow(length(UnitCoord),2.0f) / pow(length(Ratios), 2.0f); - float2 PincushionCurve = UnitCoord * PincushionAmountX * PincushionR2; - float2 BaseCoord = Input.TexCoord + PincushionCurve; + float2 CurveViewpointOffset = float2(0.2f, 0.0f); + float2 CurveUnitCoord = (Input.TexCoord + CurveViewpointOffset) * 2.0f - 1.0f; + float CurvatureR2 = pow(length(CurveUnitCoord),2.0f) / pow(length(Ratios), 2.0f); + float2 CurvatureCurve = CurveUnitCoord * CurvatureAmount * CurvatureR2; + float2 ScreenCurveCoord = Input.TexCoord + CurvatureCurve; + + float2 CurveClipUnitCoord = Input.TexCoord * Ratios * 2.0f - 1.0f; + float CurvatureClipR2 = pow(length(CurveClipUnitCoord),2.0f) / pow(length(Ratios), 2.0f); + float2 CurvatureClipCurve = CurveClipUnitCoord * CurvatureAmount * CurvatureClipR2; + float2 ScreenClipCoord = Input.TexCoord; + ScreenClipCoord -= 0.5f / Ratios; + ScreenClipCoord *= 1.0f - CurvatureAmount * Ratios * 0.2f; // Warning: Magic constant + ScreenClipCoord += 0.5f / Ratios; + ScreenClipCoord += CurvatureClipCurve; // RGB Pincushion Calculation - float3 PincushionCurveX = UnitCoord.x * PincushionAmountX * PincushionR2; - float3 PincushionCurveY = UnitCoord.y * PincushionAmountX * PincushionR2; + float3 PincushionCurveX = PinUnitCoord.x * PincushionAmount * PincushionR2; + float3 PincushionCurveY = PinUnitCoord.y * PincushionAmount * PincushionR2; - float4 BaseTexel = tex2D(DiffuseSampler, BaseCoord); + float4 BaseTexel = tex2D(DiffuseSampler, BaseCoord * Ratios); // -- Alpha Clipping (1px border in drawd3d does not work for some reason) -- - clip((BaseCoord.x < 2.0f / RawWidth) ? -1 : 1); - clip((BaseCoord.y < 1.0f / RawHeight) ? -1 : 1); - clip((BaseCoord.x > (2.0f / WidthRatio - 2.0f / RawWidth)) ? -1 : 1); - clip((BaseCoord.y > 1.0f / HeightRatio) ? -1 : 1); - - // -- Chroma Subsampling & RGB Deconvergence -- - float3 CoordX = Input.CoordX + PincushionCurveX; - float3 CoordY = Input.CoordY + PincushionCurveY; - float RedTexel = tex2D(DiffuseSampler, float2(CoordX.x, CoordY.x)).r; - float GrnTexel = tex2D(DiffuseSampler, float2(CoordX.y, CoordY.y)).g; - float BluTexel = tex2D(DiffuseSampler, float2(CoordX.z, CoordY.z)).b; - - float ChromaSubsampleWidth = RawWidth / SubsampleLength; - float LumaSubsampleWidth = RawWidth / SubsampleLength; // For now - float3 YFrac = frac((CoordY * RawHeight) / CrawlHeight); - float3 CrawlPercent = frac(CurrFrame / CrawlRate + (YFrac - frac(YFrac * CrawlWidth) / CrawlWidth)) * CrawlWidth; - float3 ChromaCoordX = Input.CoordX + CrawlPercent / RawWidth; - float3 ChannelFrac = frac((ChromaCoordX + PincushionCurveX) * ChromaSubsampleWidth); - ChromaCoordX = ((ChromaCoordX + PincushionCurveX) * ChromaSubsampleWidth - ChannelFrac) / ChromaSubsampleWidth + ChannelFrac / (ChromaSubsampleWidth * 2.0f); - float3 ChromaCoordY = Input.CoordY + PincushionCurveY; - - float3 BaseTexelRight = tex2D(DiffuseSampler, BaseCoord + float2(1.0f / TargetWidth, 0.0f)).rgb; - float3 BaseTexelUpper = tex2D(DiffuseSampler, BaseCoord + float2(0.0f, 1.0f / TargetHeight)).rgb; - - float3 UpperDifference = abs(BaseTexel.rgb - BaseTexelUpper); - float3 RightDifference = abs(BaseTexel.rgb - BaseTexelRight); - float3 EdgeDifference = (UpperDifference + RightDifference) * EdgeDetectScale; - - float RedChromaTexel = tex2D(DiffuseSampler, float2(ChromaCoordX.x, ChromaCoordY.x)).r; - float GrnChromaTexel = tex2D(DiffuseSampler, float2(ChromaCoordX.y, ChromaCoordY.y)).g; - float BluChromaTexel = tex2D(DiffuseSampler, float2(ChromaCoordX.z, ChromaCoordY.z)).b; - - float3 ChromaTexel = float3(RedChromaTexel, GrnChromaTexel, BluChromaTexel); - float3 LumaTexel = float3(RedTexel, GrnTexel, BluTexel); - - // -- RGB Tint & Shift -- - float ShiftedRed = dot(LumaTexel, float3(RedFromRed, RedFromGrn, RedFromBlu)); - float ShiftedGrn = dot(LumaTexel, float3(GrnFromRed, GrnFromGrn, GrnFromBlu)); - float ShiftedBlu = dot(LumaTexel, float3(BluFromRed, BluFromGrn, BluFromBlu)); - float ShiftedRedChroma = dot(ChromaTexel, float3(RedFromRed, RedFromGrn, RedFromBlu)); - float ShiftedGrnChroma = dot(ChromaTexel, float3(GrnFromRed, GrnFromGrn, GrnFromBlu)); - float ShiftedBluChroma = dot(ChromaTexel, float3(BluFromRed, BluFromGrn, BluFromBlu)); - float EdgeRed = dot(EdgeDifference, float3(RedFromRed, RedFromGrn, RedFromBlu)); - float EdgeGrn = dot(EdgeDifference, float3(GrnFromRed, GrnFromGrn, GrnFromBlu)); - float EdgeBlu = dot(EdgeDifference, float3(BluFromRed, BluFromGrn, BluFromBlu)); - - // -- RGB Offset & Scale -- - float3 OutTexelLuma = float3(ShiftedRed, ShiftedGrn, ShiftedBlu) * float3(RedScale, GrnScale, BluScale) + float3(RedOffset, GrnOffset, BluOffset); - float3 OutTexelChroma = float3(ShiftedRedChroma, ShiftedGrnChroma, ShiftedBluChroma) * float3(RedScale, GrnScale, BluScale) + float3(RedOffset, GrnOffset, BluOffset); - - // -- Saturation -- - float OutLumaLuma = dot(OutTexelLuma, float3(0.3f, 0.59f, 0.11f)); - float3 OutChromaLuma = OutTexelLuma - float3(OutLumaLuma, OutLumaLuma, OutLumaLuma); - float3 SaturatedLuma = OutLumaLuma + OutChromaLuma * Saturation; - - float OutLumaChroma = dot(OutTexelChroma, float3(0.3f, 0.59f, 0.11f)); - float3 OutChromaChroma = OutTexelChroma - float3(OutLumaChroma, OutLumaChroma, OutLumaChroma); - float3 SaturatedChroma = OutLumaChroma + OutChromaChroma * Saturation; - - // -- YIQ Convolution -- - float Y = dot(SaturatedLuma, float3(0.299f, 0.587f, 0.114f)); - float I = dot(SaturatedChroma, float3(0.595716f, -0.274453f, -0.321263f)); - float Q = dot(SaturatedChroma, float3(0.211456f, -0.522591f, 0.311135f)); - Y = dot(float3(Y, I, Q), float3(YfromY, YfromI, YfromQ)); - I = dot(float3(Y, I, Q), float3(IfromY, IfromI, IfromQ)); - Q = dot(float3(Y, I, Q), float3(QfromY, QfromI, QfromQ)); - float3 OutYIQ = float3(Y, I, Q) * float3(YScale, IScale, QScale) + float3(YOffset, IOffset, QOffset); - float3 OutRGB = float3(dot(OutYIQ, float3(1.0f, 0.9563f, 0.6210f)), dot(OutYIQ, float3(1.0f, -0.2721f, -0.6474f)), dot(OutYIQ, float3(1.0f, -1.1070f, 1.7046f))); - - OutRGB = lerp(OutRGB, float3(EdgeRed, EdgeGrn, EdgeBlu), EdgeToBaseRatio); - - float3 Power = float3(RedPower, GrnPower, BluPower); - OutRGB = pow(OutRGB, Power); - - // -- Color Compression (increasing the floor of the signal without affecting the ceiling) -- - float3 Floor = float3(RedFloor, GrnFloor, BluFloor); - OutRGB = Floor + (1.0f - Floor) * OutRGB; + clip((ScreenClipCoord.x < 1.0f / TargetWidth) ? -1 : 1); + clip((ScreenClipCoord.y < 3.0f / TargetHeight) ? -1 : 1); + clip((ScreenClipCoord.x > 1.0f / WidthRatio) ? -1 : 1); + clip((ScreenClipCoord.y > 1.0f / HeightRatio) ? -1 : 1); // -- Scanline Simulation -- - float3 ScanBrightness = lerp(1.0f, abs(sin(((CoordY * RawHeight * ScanlineScale) * PI + ScanlineOffset * RawHeight))) * ScanlineBrightScale + ScanlineBrightOffset, ScanlineAmount); - float3 Scanned = OutRGB * ScanBrightness; + float3 ScanBrightness = lerp(1.0f, abs(sin(((BaseCoord.y * Ratios.y * RawHeight * ScanlineScale) * PI + ScanlineOffset * RawHeight))) * ScanlineBrightScale + ScanlineBrightOffset, ScanlineAmount); + float3 Scanned = BaseTexel.rgb * ScanBrightness; - float2 ShadowCoord = BaseCoord * float2(RawWidth, RawHeight); - float ShadowCoordX = frac(ShadowCoord.x / ShadowPixelSizeX) * ShadowU + 1.0f / ShadowWidth; - float ShadowCoordY = frac(ShadowCoord.y / ShadowPixelSizeY) * ShadowV + 1.0f / ShadowHeight; - float3 ShadowTexel = lerp(1.0f, tex2D(ShadowSampler, float2(ShadowCoordX, ShadowCoordY)), UseShadow); + float2 ShadowDims = float2(ShadowWidth, ShadowHeight); + float2 ShadowUV = float2(ShadowU, ShadowV); + float2 ShadowMaskSize = float2(ShadowMaskSizeX, ShadowMaskSizeY); + float2 ShadowFrac = frac(ScreenCurveCoord * ShadowMaskSize * Ratios * 0.5f); + float2 ShadowCoord = ShadowFrac * ShadowUV + 2.5f / ShadowDims; + float3 ShadowTexel = lerp(1.0f, tex2D(ShadowSampler, ShadowCoord), UseShadow); // -- Final Pixel -- float4 Output = lerp(Input.Color, float4(Scanned * lerp(1.0f, ShadowTexel * 1.25f, ShadowBrightness), BaseTexel.a) * Input.Color, Input.ExtraInfo.x); @@ -308,10 +174,10 @@ float4 ps_main(PS_INPUT Input) : COLOR } //----------------------------------------------------------------------------- -// Post-Processing Effect +// Scanline & Shadowmask Effect //----------------------------------------------------------------------------- -technique TestTechnique +technique ScanMaskTechnique { pass Pass0 { diff --git a/src/osd/windows/drawd3d.c b/src/osd/windows/drawd3d.c index 1ac76980279..d336a2f3703 100644 --- a/src/osd/windows/drawd3d.c +++ b/src/osd/windows/drawd3d.c @@ -130,11 +130,15 @@ struct _texture_info d3d_texture * d3dtex; // Direct3D texture pointer d3d_surface * d3dsurface; // Direct3D offscreen plain surface pointer d3d_surface * d3dtarget0; // Direct3D render target surface pointer (pass 0, if necessary) - d3d_surface * d3dtarget1; // Direct3D render target surface pointer (pass 2, if necessary) - d3d_surface * d3dtarget2; // Direct3D render target surface pointer (pass 3, if necessary) + d3d_surface * d3dtarget1; // Direct3D render target surface pointer (pass 1, if necessary) + d3d_surface * d3dtarget2; // Direct3D render target surface pointer (pass 2, if necessary) + d3d_surface * d3dsmalltarget0; // Direct3D render target surface pointer (small pass 0, if necessary) + d3d_surface * d3dsmalltarget1; // Direct3D render target surface pointer (small pass 1, if necessary) d3d_texture * d3dtexture0; // Direct3D render target texture pointer (pass 0, if necessary) - d3d_texture * d3dtexture1; // Direct3D render target texture pointer (pass 2, if necessary) - d3d_texture * d3dtexture2; // Direct3D render target texture pointer (pass 3, if necessary) + d3d_texture * d3dtexture1; // Direct3D render target texture pointer (pass 1, if necessary) + d3d_texture * d3dtexture2; // Direct3D render target texture pointer (pass 2, if necessary) + d3d_texture * d3dsmalltexture0; // Direct3D render target texture pointer (small pass 0, if necessary) + d3d_texture * d3dsmalltexture1; // Direct3D render target texture pointer (small pass 1, if necessary) d3d_texture * d3dfinaltex; // Direct3D final (post-scaled) texture }; @@ -190,6 +194,8 @@ struct _d3d_info d3d_effect * pincushion_effect; // pointer to the current pincushion-effect object d3d_effect * focus_effect; // pointer to the current focus-effect object d3d_effect * phosphor_effect; // pointer to the current phosphor-effect object + d3d_effect * deconverge_effect; // pointer to the current deconvergence-effect object + d3d_effect * color_effect; // pointer to the current color-effect object poly_info poly[VERTEX_BUFFER_SIZE / 3];// array to hold polygons as they are created int numpolys; // number of accumulated polygons @@ -357,7 +363,7 @@ INLINE void set_texture(d3d_info *d3d, texture_info *texture) if(d3d->hlsl_enable && d3d->effect != NULL) { (*d3dintf->effect.set_texture)(d3d->effect, "Diffuse", (texture == NULL) ? NULL : texture->d3dfinaltex); - (*d3dintf->effect.set_texture)(d3d->post_effect, "Diffuse", (texture == NULL) ? NULL : texture->d3dfinaltex); + (*d3dintf->effect.set_texture)(d3d->color_effect, "Diffuse", (texture == NULL) ? NULL : texture->d3dfinaltex); (*d3dintf->effect.set_texture)(d3d->pincushion_effect, "Diffuse", (texture == NULL) ? NULL : texture->d3dfinaltex); } if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_texture call\n", (int)result); @@ -636,7 +642,7 @@ static void drawd3d_window_destroy(win_window_info *window) d3d->vector_bitmap = NULL; // experimental: free the shadow PNG - if(d3d->hlsl_enable) + if(d3d->hlsl_enable && d3d->shadow_bitmap != NULL) { global_free(d3d->shadow_bitmap); d3d->shadow_bitmap = NULL; @@ -850,7 +856,7 @@ try_again: // create the D3D device result = (*d3dintf->d3d.create_device)(d3dintf, d3d->adapter, D3DDEVTYPE_HAL, win_window_list->hwnd, - D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, &d3d->presentation, &d3d->device); + D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, &d3d->presentation, &d3d->device); if (result != D3D_OK) { // if we got a "DEVICELOST" error, it may be transitory; count it and only fail if @@ -900,7 +906,7 @@ try_again: } // experimental: initialize some more things if we're using HLSL - if(d3d->hlsl_enable) + if(d3d->hlsl_enable && d3dintf->post_fx_available) { const char *fx_dir = downcast(window->machine().options()).screen_post_fx_dir(); char primary_name_cstr[1024]; @@ -908,6 +914,8 @@ try_again: char pincushion_name_cstr[1024]; char phosphor_name_cstr[1024]; char focus_name_cstr[1024]; + char deconverge_name_cstr[1024]; + char color_name_cstr[1024]; sprintf(primary_name_cstr, "%s\\primary.fx", fx_dir); TCHAR *primary_name = tstring_from_utf8(primary_name_cstr); @@ -924,6 +932,12 @@ try_again: sprintf(focus_name_cstr, "%s\\focus.fx", fx_dir); TCHAR *focus_name = tstring_from_utf8(focus_name_cstr); + sprintf(deconverge_name_cstr, "%s\\deconverge.fx", fx_dir); + TCHAR *deconverge_name = tstring_from_utf8(deconverge_name_cstr); + + sprintf(color_name_cstr, "%s\\color.fx", fx_dir); + TCHAR *color_name = tstring_from_utf8(color_name_cstr); + // create the regular shader result = (*d3dintf->device.create_effect)(d3d->device, primary_name, &d3d->effect); @@ -939,6 +953,12 @@ try_again: // create the focus shader result = (*d3dintf->device.create_effect)(d3d->device, focus_name, &d3d->focus_effect); + // create the deconvergence shader + result = (*d3dintf->device.create_effect)(d3d->device, deconverge_name, &d3d->deconverge_effect); + + // create the color convolution shader + result = (*d3dintf->device.create_effect)(d3d->device, color_name, &d3d->color_effect); + if (primary_name) osd_free(primary_name); if (post_name) @@ -949,6 +969,10 @@ try_again: osd_free(phosphor_name); if (focus_name) osd_free(focus_name); + if (deconverge_name) + osd_free(deconverge_name); + if (color_name) + osd_free(color_name); } return device_create_resources(d3d); @@ -967,8 +991,8 @@ static int device_create_resources(d3d_info *d3d) // allocate a vertex buffer to use result = (*d3dintf->device.create_vertex_buffer)(d3d->device, sizeof(d3d_vertex) * VERTEX_BUFFER_SIZE, - D3DUSAGE_DYNAMIC | D3DUSAGE_SOFTWAREPROCESSING | D3DUSAGE_WRITEONLY, - VERTEX_BASE_FORMAT | (d3d->hlsl_enable ? D3DFVF_XYZW : D3DFVF_XYZRHW), D3DPOOL_DEFAULT, &d3d->vertexbuf); + D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, + VERTEX_BASE_FORMAT | ((d3d->hlsl_enable && d3dintf->post_fx_available) ? D3DFVF_XYZW : D3DFVF_XYZRHW), D3DPOOL_DEFAULT, &d3d->vertexbuf); if (result != D3D_OK) { mame_printf_error("Error creating vertex buffer (%08X)", (UINT32)result); @@ -976,7 +1000,7 @@ static int device_create_resources(d3d_info *d3d) } // set the vertex format - result = (*d3dintf->device.set_vertex_format)(d3d->device, (D3DFORMAT)(VERTEX_BASE_FORMAT | (d3d->hlsl_enable ? D3DFVF_XYZW : D3DFVF_XYZRHW))); + result = (*d3dintf->device.set_vertex_format)(d3d->device, (D3DFORMAT)(VERTEX_BASE_FORMAT | ((d3d->hlsl_enable && d3dintf->post_fx_available) ? D3DFVF_XYZW : D3DFVF_XYZRHW))); if (result != D3D_OK) { mame_printf_error("Error setting vertex format (%08X)", (UINT32)result); @@ -1033,7 +1057,7 @@ static int device_create_resources(d3d_info *d3d) } // experimental: initialize some more things if we're using HLSL - if(d3d->hlsl_enable) + if(d3d->hlsl_enable && d3dintf->post_fx_available) { // experimental: create a default bitmap for our shader if (d3d->default_bitmap != NULL) @@ -1120,12 +1144,20 @@ static void device_delete_resources(d3d_info *d3d) (*d3dintf->texture.release)(tex->d3dtexture1); if (tex->d3dtexture2 != NULL) (*d3dintf->texture.release)(tex->d3dtexture2); + if (tex->d3dsmalltexture0 != NULL) + (*d3dintf->texture.release)(tex->d3dsmalltexture0); + if (tex->d3dsmalltexture1 != NULL) + (*d3dintf->texture.release)(tex->d3dsmalltexture1); if (tex->d3dtarget0 != NULL) (*d3dintf->surface.release)(tex->d3dtarget0); if (tex->d3dtarget1 != NULL) (*d3dintf->surface.release)(tex->d3dtarget1); if (tex->d3dtarget2 != NULL) (*d3dintf->surface.release)(tex->d3dtarget2); + if (tex->d3dsmalltarget0 != NULL) + (*d3dintf->surface.release)(tex->d3dsmalltarget0); + if (tex->d3dsmalltarget1 != NULL) + (*d3dintf->surface.release)(tex->d3dsmalltarget1); global_free(tex); } @@ -1162,6 +1194,16 @@ static void device_delete_resources(d3d_info *d3d) (*d3dintf->effect.release)(d3d->focus_effect); d3d->focus_effect = NULL; } + if(d3d->deconverge_effect != NULL) + { + (*d3dintf->effect.release)(d3d->deconverge_effect); + d3d->deconverge_effect = NULL; + } + if(d3d->color_effect != NULL) + { + (*d3dintf->effect.release)(d3d->color_effect); + d3d->color_effect = NULL; + } for(int index = 0; index < 9; index++) { @@ -1943,20 +1985,25 @@ static void primitive_flush_pending(d3d_info *d3d) d3d_effect *curr_effect = d3d->effect; - if(d3d->hlsl_enable) + if(d3d->hlsl_enable && d3dintf->post_fx_available) { (*d3dintf->effect.set_technique)(d3d->effect, "TestTechnique"); - (*d3dintf->effect.set_technique)(d3d->post_effect, "TestTechnique"); + (*d3dintf->effect.set_technique)(d3d->post_effect, "ScanMaskTechnique"); (*d3dintf->effect.set_technique)(d3d->pincushion_effect, "TestTechnique"); (*d3dintf->effect.set_technique)(d3d->phosphor_effect, "TestTechnique"); (*d3dintf->effect.set_technique)(d3d->focus_effect, "TestTechnique"); + (*d3dintf->effect.set_technique)(d3d->deconverge_effect, "DeconvergeTechnique"); + (*d3dintf->effect.set_technique)(d3d->color_effect, "ColorTechnique"); } d3d_surface *backbuffer; // first remember the original render target in case we need to set a new one - result = (*d3dintf->device.get_render_target)(d3d->device, 0, &backbuffer); - if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device get_render_target call\n", (int)result); + if(d3d->hlsl_enable && d3dintf->post_fx_available) + { + result = (*d3dintf->device.get_render_target)(d3d->device, 0, &backbuffer); + if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device get_render_target call\n", (int)result); + } windows_options &options = downcast(d3d->window->machine().options()); @@ -1980,7 +2027,7 @@ static void primitive_flush_pending(d3d_info *d3d) set_wrap(d3d, PRIMFLAG_GET_TEXWRAP(poly->flags)); set_modmode(d3d, poly->modmode); - if(d3d->hlsl_enable) + if(d3d->hlsl_enable && d3dintf->post_fx_available) { if(PRIMFLAG_GET_TEXSHADE(d3d->last_texture_flags)) { @@ -1988,90 +2035,35 @@ static void primitive_flush_pending(d3d_info *d3d) } else if(PRIMFLAG_GET_SCREENTEX(d3d->last_texture_flags)) { + // Plug in all of the shader settings we're going to need + // This is extremely slow, but we're not rendering models here, + // just post-processing. curr_effect = d3d->post_effect; - (*d3dintf->effect.set_texture)(curr_effect, "Shadow", d3d->shadow_texture == NULL ? NULL : d3d->shadow_texture->d3dfinaltex); - (*d3dintf->effect.set_float)(curr_effect, "UseShadow", d3d->shadow_texture == NULL ? 0.0f : 1.0f); - (*d3dintf->effect.set_float)(curr_effect, "ShadowBrightness", (float)options.screen_shadow_mask_alpha()); - (*d3dintf->effect.set_float)(curr_effect, "ShadowPixelSizeX", (float)options.screen_shadow_mask_width()); - (*d3dintf->effect.set_float)(curr_effect, "ShadowPixelSizeY", (float)options.screen_shadow_mask_height()); - (*d3dintf->effect.set_float)(curr_effect, "ShadowU", (float)options.screen_shadow_mask_u_size()); - (*d3dintf->effect.set_float)(curr_effect, "ShadowV", (float)options.screen_shadow_mask_v_size()); - (*d3dintf->effect.set_float)(curr_effect, "ShadowWidth", d3d->shadow_texture == NULL ? 1.0f : (float)d3d->shadow_texture->rawwidth); - (*d3dintf->effect.set_float)(curr_effect, "ShadowHeight", d3d->shadow_texture == NULL ? 1.0f : (float)d3d->shadow_texture->rawheight); (*d3dintf->effect.set_float)(curr_effect, "RawWidth", poly->texture != NULL ? (float)poly->texture->rawwidth : 8.0f); (*d3dintf->effect.set_float)(curr_effect, "RawHeight", poly->texture != NULL ? (float)poly->texture->rawheight : 8.0f); (*d3dintf->effect.set_float)(curr_effect, "WidthRatio", poly->texture != NULL ? (1.0f / (poly->texture->ustop - poly->texture->ustart)) : 0.0f); (*d3dintf->effect.set_float)(curr_effect, "HeightRatio", poly->texture != NULL ? (1.0f / (poly->texture->vstop - poly->texture->vstart)) : 0.0f); (*d3dintf->effect.set_float)(curr_effect, "TargetWidth", (float)d3d->width); (*d3dintf->effect.set_float)(curr_effect, "TargetHeight", (float)d3d->height); - (*d3dintf->effect.set_float)(curr_effect, "PostPass", 0.0f); - (*d3dintf->effect.set_float)(curr_effect, "PincushionAmountX", (float)options.screen_pincushion_x()); - (*d3dintf->effect.set_float)(curr_effect, "PincushionAmountY", (float)options.screen_pincushion_y()); + (*d3dintf->effect.set_float)(curr_effect, "PincushionAmount", (float)options.screen_pincushion()); + (*d3dintf->effect.set_float)(curr_effect, "CurvatureAmount", (float)options.screen_curvature()); + (*d3dintf->effect.set_float)(curr_effect, "UseShadow", d3d->shadow_texture == NULL ? 0.0f : 1.0f); + (*d3dintf->effect.set_texture)(curr_effect, "Shadow", d3d->shadow_texture == NULL ? NULL : d3d->shadow_texture->d3dfinaltex); + (*d3dintf->effect.set_float)(curr_effect, "ShadowBrightness", (float)options.screen_shadow_mask_alpha()); + (*d3dintf->effect.set_float)(curr_effect, "ShadowPixelSizeX", (float)options.screen_shadow_mask_ratio_x()); + (*d3dintf->effect.set_float)(curr_effect, "ShadowPixelSizeY", (float)options.screen_shadow_mask_ratio_y()); + (*d3dintf->effect.set_float)(curr_effect, "ShadowMaskSizeX", (float)options.screen_shadow_mask_count_x()); + (*d3dintf->effect.set_float)(curr_effect, "ShadowMaskSizeY", (float)options.screen_shadow_mask_count_y()); + (*d3dintf->effect.set_float)(curr_effect, "ShadowU", (float)options.screen_shadow_mask_u_size()); + (*d3dintf->effect.set_float)(curr_effect, "ShadowV", (float)options.screen_shadow_mask_v_size()); + (*d3dintf->effect.set_float)(curr_effect, "ShadowWidth", d3d->shadow_texture == NULL ? 1.0f : (float)d3d->shadow_texture->rawwidth); + (*d3dintf->effect.set_float)(curr_effect, "ShadowHeight", d3d->shadow_texture == NULL ? 1.0f : (float)d3d->shadow_texture->rawheight); (*d3dintf->effect.set_float)(curr_effect, "ScanlineAmount", (float)options.screen_scanline_amount()); (*d3dintf->effect.set_float)(curr_effect, "ScanlineScale", (float)options.screen_scanline_scale()); (*d3dintf->effect.set_float)(curr_effect, "ScanlineBrightScale", (float)options.screen_scanline_bright_scale()); (*d3dintf->effect.set_float)(curr_effect, "ScanlineBrightOffset", (float)options.screen_scanline_bright_offset()); (*d3dintf->effect.set_float)(curr_effect, "ScanlineOffset", (poly->texture != NULL && poly->texture->cur_frame == 0) ? 0.0f : (float)options.screen_scanline_offset()); - (*d3dintf->effect.set_float)(curr_effect, "RedConvergeX", (float)options.screen_red_converge_x()); - (*d3dintf->effect.set_float)(curr_effect, "RedConvergeY", (float)options.screen_red_converge_y()); - (*d3dintf->effect.set_float)(curr_effect, "GrnConvergeX", (float)options.screen_green_converge_x()); - (*d3dintf->effect.set_float)(curr_effect, "GrnConvergeY", (float)options.screen_green_converge_y()); - (*d3dintf->effect.set_float)(curr_effect, "BluConvergeX", (float)options.screen_blue_converge_x()); - (*d3dintf->effect.set_float)(curr_effect, "BluConvergeY", (float)options.screen_blue_converge_y()); - (*d3dintf->effect.set_float)(curr_effect, "RedRadialConvergeX", (float)options.screen_red_radial_converge_x()); - (*d3dintf->effect.set_float)(curr_effect, "RedRadialConvergeY", (float)options.screen_red_radial_converge_y()); - (*d3dintf->effect.set_float)(curr_effect, "GrnRadialConvergeX", (float)options.screen_green_radial_converge_x()); - (*d3dintf->effect.set_float)(curr_effect, "GrnRadialConvergeY", (float)options.screen_green_radial_converge_y()); - (*d3dintf->effect.set_float)(curr_effect, "BluRadialConvergeX", (float)options.screen_blue_radial_converge_x()); - (*d3dintf->effect.set_float)(curr_effect, "BluRadialConvergeY", (float)options.screen_blue_radial_converge_y()); - (*d3dintf->effect.set_float)(curr_effect, "RedFromRed", (float)options.screen_red_from_red()); - (*d3dintf->effect.set_float)(curr_effect, "RedFromGrn", (float)options.screen_red_from_green()); - (*d3dintf->effect.set_float)(curr_effect, "RedFromBlu", (float)options.screen_red_from_blue()); - (*d3dintf->effect.set_float)(curr_effect, "GrnFromRed", (float)options.screen_green_from_red()); - (*d3dintf->effect.set_float)(curr_effect, "GrnFromGrn", (float)options.screen_green_from_green()); - (*d3dintf->effect.set_float)(curr_effect, "GrnFromBlu", (float)options.screen_green_from_blue()); - (*d3dintf->effect.set_float)(curr_effect, "BluFromRed", (float)options.screen_blue_from_red()); - (*d3dintf->effect.set_float)(curr_effect, "BluFromGrn", (float)options.screen_blue_from_green()); - (*d3dintf->effect.set_float)(curr_effect, "BluFromBlu", (float)options.screen_blue_from_blue()); - (*d3dintf->effect.set_float)(curr_effect, "YfromY", (float)options.screen_y_from_y()); - (*d3dintf->effect.set_float)(curr_effect, "YfromI", (float)options.screen_y_from_i()); - (*d3dintf->effect.set_float)(curr_effect, "YfromQ", (float)options.screen_y_from_q()); - (*d3dintf->effect.set_float)(curr_effect, "IfromY", (float)options.screen_i_from_y()); - (*d3dintf->effect.set_float)(curr_effect, "IfromI", (float)options.screen_i_from_i()); - (*d3dintf->effect.set_float)(curr_effect, "IfromQ", (float)options.screen_i_from_q()); - (*d3dintf->effect.set_float)(curr_effect, "QfromY", (float)options.screen_q_from_y()); - (*d3dintf->effect.set_float)(curr_effect, "QfromI", (float)options.screen_q_from_i()); - (*d3dintf->effect.set_float)(curr_effect, "QfromQ", (float)options.screen_q_from_q()); - (*d3dintf->effect.set_float)(curr_effect, "RedOffset", (float)options.screen_red_offset()); - (*d3dintf->effect.set_float)(curr_effect, "GrnOffset", (float)options.screen_green_offset()); - (*d3dintf->effect.set_float)(curr_effect, "BluOffset", (float)options.screen_blue_offset()); - (*d3dintf->effect.set_float)(curr_effect, "RedScale", (float)options.screen_red_scale()); - (*d3dintf->effect.set_float)(curr_effect, "GrnScale", (float)options.screen_green_scale()); - (*d3dintf->effect.set_float)(curr_effect, "BluScale", (float)options.screen_blue_scale()); - (*d3dintf->effect.set_float)(curr_effect, "RedPower", (float)options.screen_red_power()); - (*d3dintf->effect.set_float)(curr_effect, "GrnPower", (float)options.screen_green_power()); - (*d3dintf->effect.set_float)(curr_effect, "BluPower", (float)options.screen_blue_power()); - (*d3dintf->effect.set_float)(curr_effect, "RedFloor", (float)options.screen_red_floor()); - (*d3dintf->effect.set_float)(curr_effect, "GrnFloor", (float)options.screen_green_floor()); - (*d3dintf->effect.set_float)(curr_effect, "BluFloor", (float)options.screen_blue_floor()); - (*d3dintf->effect.set_float)(curr_effect, "Saturation", (float)options.screen_saturation()); - (*d3dintf->effect.set_float)(curr_effect, "YScale", (float)options.screen_y_scale()); - (*d3dintf->effect.set_float)(curr_effect, "IScale", (float)options.screen_i_scale()); - (*d3dintf->effect.set_float)(curr_effect, "QScale", (float)options.screen_q_scale()); - (*d3dintf->effect.set_float)(curr_effect, "YOffset", (float)options.screen_y_offset()); - (*d3dintf->effect.set_float)(curr_effect, "IOffset", (float)options.screen_i_offset()); - (*d3dintf->effect.set_float)(curr_effect, "QOffset", (float)options.screen_q_offset()); - (*d3dintf->effect.set_float)(curr_effect, "EdgeDetectScale", (float)options.screen_edge_amount()); - (*d3dintf->effect.set_float)(curr_effect, "EdgeToBaseRatio", (float)options.screen_edge_ratio()); - (*d3dintf->effect.set_float)(curr_effect, "SubsampleLength", (float)options.screen_chroma_subsample_length()); - int frame = (poly->texture != NULL && poly->texture->cur_frame) ? (float)poly->texture->cur_frame : 0; - frame = (frame == options.screen_dot_crawl_skip()) ? 0 : frame; - (*d3dintf->effect.set_float)(curr_effect, "CurrFrame", (float)frame); - (*d3dintf->effect.set_float)(curr_effect, "CrawlWidth", (float)options.screen_dot_crawl_width()); - (*d3dintf->effect.set_float)(curr_effect, "CrawlHeight", (float)options.screen_dot_crawl_height()); - (*d3dintf->effect.set_float)(curr_effect, "CrawlRate", (float)options.screen_dot_crawl_rate()); - (*d3dintf->effect.set_float)(curr_effect, "CrawlSkip", (float)options.screen_dot_crawl_skip()); } else { @@ -2085,7 +2077,7 @@ static void primitive_flush_pending(d3d_info *d3d) // set the blendmode if different set_blendmode(d3d, PRIMFLAG_GET_BLENDMODE(poly->flags)); - if(d3d->hlsl_enable) + if(d3d->hlsl_enable && d3dintf->post_fx_available) { assert(vertnum + poly->numverts <= d3d->numverts); @@ -2093,13 +2085,60 @@ static void primitive_flush_pending(d3d_info *d3d) if(PRIMFLAG_GET_SCREENTEX(d3d->last_texture_flags) && poly->texture != NULL) { - /* Render the initial screen pass */ - (*d3dintf->effect.set_float)(curr_effect, "FixedAlpha", 1.0f); + curr_effect = d3d->color_effect; - result = (*d3dintf->device.set_render_target)(d3d->device, 0, poly->texture->d3dtarget0); + /* Render the initial color-convolution pass */ + (*d3dintf->effect.set_float)(curr_effect, "RawWidth", poly->texture != NULL ? (float)poly->texture->rawwidth : 8.0f); + (*d3dintf->effect.set_float)(curr_effect, "RawHeight", poly->texture != NULL ? (float)poly->texture->rawheight : 8.0f); + (*d3dintf->effect.set_float)(curr_effect, "WidthRatio", poly->texture != NULL ? (1.0f / (poly->texture->ustop - poly->texture->ustart)) : 0.0f); + (*d3dintf->effect.set_float)(curr_effect, "HeightRatio", poly->texture != NULL ? (1.0f / (poly->texture->vstop - poly->texture->vstart)) : 0.0f); + (*d3dintf->effect.set_float)(curr_effect, "TargetWidth", (float)d3d->width); + (*d3dintf->effect.set_float)(curr_effect, "TargetHeight", (float)d3d->height); + (*d3dintf->effect.set_float)(curr_effect, "RedFromRed", (float)options.screen_red_from_red()); + (*d3dintf->effect.set_float)(curr_effect, "RedFromGrn", (float)options.screen_red_from_green()); + (*d3dintf->effect.set_float)(curr_effect, "RedFromBlu", (float)options.screen_red_from_blue()); + (*d3dintf->effect.set_float)(curr_effect, "GrnFromRed", (float)options.screen_green_from_red()); + (*d3dintf->effect.set_float)(curr_effect, "GrnFromGrn", (float)options.screen_green_from_green()); + (*d3dintf->effect.set_float)(curr_effect, "GrnFromBlu", (float)options.screen_green_from_blue()); + (*d3dintf->effect.set_float)(curr_effect, "BluFromRed", (float)options.screen_blue_from_red()); + (*d3dintf->effect.set_float)(curr_effect, "BluFromGrn", (float)options.screen_blue_from_green()); + (*d3dintf->effect.set_float)(curr_effect, "BluFromBlu", (float)options.screen_blue_from_blue()); + (*d3dintf->effect.set_float)(curr_effect, "YfromY", (float)options.screen_y_from_y()); + (*d3dintf->effect.set_float)(curr_effect, "YfromI", (float)options.screen_y_from_i()); + (*d3dintf->effect.set_float)(curr_effect, "YfromQ", (float)options.screen_y_from_q()); + (*d3dintf->effect.set_float)(curr_effect, "IfromY", (float)options.screen_i_from_y()); + (*d3dintf->effect.set_float)(curr_effect, "IfromI", (float)options.screen_i_from_i()); + (*d3dintf->effect.set_float)(curr_effect, "IfromQ", (float)options.screen_i_from_q()); + (*d3dintf->effect.set_float)(curr_effect, "QfromY", (float)options.screen_q_from_y()); + (*d3dintf->effect.set_float)(curr_effect, "QfromI", (float)options.screen_q_from_i()); + (*d3dintf->effect.set_float)(curr_effect, "QfromQ", (float)options.screen_q_from_q()); + (*d3dintf->effect.set_float)(curr_effect, "RedOffset", (float)options.screen_red_offset()); + (*d3dintf->effect.set_float)(curr_effect, "GrnOffset", (float)options.screen_green_offset()); + (*d3dintf->effect.set_float)(curr_effect, "BluOffset", (float)options.screen_blue_offset()); + (*d3dintf->effect.set_float)(curr_effect, "RedScale", (float)options.screen_red_scale()); + (*d3dintf->effect.set_float)(curr_effect, "GrnScale", (float)options.screen_green_scale()); + (*d3dintf->effect.set_float)(curr_effect, "BluScale", (float)options.screen_blue_scale()); + (*d3dintf->effect.set_float)(curr_effect, "RedPower", (float)options.screen_red_power()); + (*d3dintf->effect.set_float)(curr_effect, "GrnPower", (float)options.screen_green_power()); + (*d3dintf->effect.set_float)(curr_effect, "BluPower", (float)options.screen_blue_power()); + (*d3dintf->effect.set_float)(curr_effect, "RedFloor", (float)options.screen_red_floor()); + (*d3dintf->effect.set_float)(curr_effect, "GrnFloor", (float)options.screen_green_floor()); + (*d3dintf->effect.set_float)(curr_effect, "BluFloor", (float)options.screen_blue_floor()); + (*d3dintf->effect.set_float)(curr_effect, "Saturation", (float)options.screen_saturation()); + (*d3dintf->effect.set_float)(curr_effect, "YScale", (float)options.screen_y_scale()); + (*d3dintf->effect.set_float)(curr_effect, "IScale", (float)options.screen_i_scale()); + (*d3dintf->effect.set_float)(curr_effect, "QScale", (float)options.screen_q_scale()); + (*d3dintf->effect.set_float)(curr_effect, "YOffset", (float)options.screen_y_offset()); + (*d3dintf->effect.set_float)(curr_effect, "IOffset", (float)options.screen_i_offset()); + (*d3dintf->effect.set_float)(curr_effect, "QOffset", (float)options.screen_q_offset()); + (*d3dintf->effect.set_float)(curr_effect, "YSubsampleLength", (float)options.screen_y_subsample_length()); + (*d3dintf->effect.set_float)(curr_effect, "ISubsampleLength", (float)options.screen_i_subsample_length()); + (*d3dintf->effect.set_float)(curr_effect, "QSubsampleLength", (float)options.screen_q_subsample_length()); - if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call 3\n", (int)result); - result = (*d3dintf->device.clear)(d3d->device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0); + result = (*d3dintf->device.set_render_target)(d3d->device, 0, poly->texture->d3dsmalltarget0); + + if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result); + result = (*d3dintf->device.clear)(d3d->device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(255,0,0,0), 0, 0); if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result); (*d3dintf->effect.begin)(curr_effect, &num_passes, 0); @@ -2115,7 +2154,115 @@ static void primitive_flush_pending(d3d_info *d3d) (*d3dintf->effect.end)(curr_effect); - // max() the two previous frames + /* Deconverge pass */ + curr_effect = d3d->deconverge_effect; + (*d3dintf->effect.set_texture)(curr_effect, "Diffuse", poly->texture->d3dsmalltexture0); + + (*d3dintf->effect.set_float)(curr_effect, "TargetWidth", (float)d3d->width); + (*d3dintf->effect.set_float)(curr_effect, "TargetHeight", (float)d3d->height); + (*d3dintf->effect.set_float)(curr_effect, "RawWidth", (float)poly->texture->rawwidth); + (*d3dintf->effect.set_float)(curr_effect, "RawHeight", (float)poly->texture->rawheight); + (*d3dintf->effect.set_float)(curr_effect, "WidthRatio", poly->texture != NULL ? (1.0f / (poly->texture->ustop - poly->texture->ustart)) : 0.0f); + (*d3dintf->effect.set_float)(curr_effect, "HeightRatio", poly->texture != NULL ? (1.0f / (poly->texture->vstop - poly->texture->vstart)) : 0.0f); + (*d3dintf->effect.set_float)(curr_effect, "RedConvergeX", (float)options.screen_red_converge_x()); + (*d3dintf->effect.set_float)(curr_effect, "RedConvergeY", (float)options.screen_red_converge_y()); + (*d3dintf->effect.set_float)(curr_effect, "GrnConvergeX", (float)options.screen_green_converge_x()); + (*d3dintf->effect.set_float)(curr_effect, "GrnConvergeY", (float)options.screen_green_converge_y()); + (*d3dintf->effect.set_float)(curr_effect, "BluConvergeX", (float)options.screen_blue_converge_x()); + (*d3dintf->effect.set_float)(curr_effect, "BluConvergeY", (float)options.screen_blue_converge_y()); + (*d3dintf->effect.set_float)(curr_effect, "RedRadialConvergeX", (float)options.screen_red_radial_converge_x()); + (*d3dintf->effect.set_float)(curr_effect, "RedRadialConvergeY", (float)options.screen_red_radial_converge_y()); + (*d3dintf->effect.set_float)(curr_effect, "GrnRadialConvergeX", (float)options.screen_green_radial_converge_x()); + (*d3dintf->effect.set_float)(curr_effect, "GrnRadialConvergeY", (float)options.screen_green_radial_converge_y()); + (*d3dintf->effect.set_float)(curr_effect, "BluRadialConvergeX", (float)options.screen_blue_radial_converge_x()); + (*d3dintf->effect.set_float)(curr_effect, "BluRadialConvergeY", (float)options.screen_blue_radial_converge_y()); + + (*d3dintf->effect.begin)(curr_effect, &num_passes, 0); + + result = (*d3dintf->device.set_render_target)(d3d->device, 0, poly->texture->d3dtarget2); + if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call 6\n", (int)result); + result = (*d3dintf->device.clear)(d3d->device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0); + if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result); + + for (UINT pass = 0; pass < num_passes; pass++) + { + (*d3dintf->effect.begin_pass)(curr_effect, pass); + // add the primitives + result = (*d3dintf->device.draw_primitive)(d3d->device, poly->type, vertnum, poly->count); + if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result); + (*d3dintf->effect.end_pass)(curr_effect); + } + + (*d3dintf->effect.end)(curr_effect); + + /* Defocus pass 1 */ + curr_effect = d3d->focus_effect; + + (*d3dintf->effect.set_texture)(curr_effect, "Diffuse", poly->texture->d3dtexture2); + + float defocus_x = (float)options.screen_defocus_x(); + float defocus_y = (float)options.screen_defocus_y(); + (*d3dintf->effect.set_float)(curr_effect, "TargetWidth", (float)d3d->width); + (*d3dintf->effect.set_float)(curr_effect, "TargetHeight", (float)d3d->height); + (*d3dintf->effect.set_float)(curr_effect, "RawWidth", (float)poly->texture->rawwidth); + (*d3dintf->effect.set_float)(curr_effect, "RawHeight", (float)poly->texture->rawheight); + (*d3dintf->effect.set_float)(curr_effect, "WidthRatio", poly->texture != NULL ? (1.0f / (poly->texture->ustop - poly->texture->ustart)) : 0.0f); + (*d3dintf->effect.set_float)(curr_effect, "HeightRatio", poly->texture != NULL ? (1.0f / (poly->texture->vstop - poly->texture->vstart)) : 0.0f); + (*d3dintf->effect.set_float)(curr_effect, "DefocusX", defocus_x); + (*d3dintf->effect.set_float)(curr_effect, "DefocusY", defocus_y); + (*d3dintf->effect.set_float)(curr_effect, "FocusEnable", (defocus_x == 0.0f && defocus_y == 0.0f) ? 0.0f : 1.0f); + + (*d3dintf->effect.begin)(curr_effect, &num_passes, 0); + + result = (*d3dintf->device.set_render_target)(d3d->device, 0, poly->texture->d3dtarget0); + if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call 6\n", (int)result); + result = (*d3dintf->device.clear)(d3d->device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0); + if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result); + + for (UINT pass = 0; pass < num_passes; pass++) + { + (*d3dintf->effect.begin_pass)(curr_effect, pass); + // add the primitives + result = (*d3dintf->device.draw_primitive)(d3d->device, poly->type, vertnum, poly->count); + if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result); + (*d3dintf->effect.end_pass)(curr_effect); + } + + (*d3dintf->effect.end)(curr_effect); + + /* Defocus pass 2 */ + + (*d3dintf->effect.set_texture)(curr_effect, "Diffuse", poly->texture->d3dtexture0); + + (*d3dintf->effect.set_float)(curr_effect, "TargetWidth", (float)d3d->width); + (*d3dintf->effect.set_float)(curr_effect, "TargetHeight", (float)d3d->height); + (*d3dintf->effect.set_float)(curr_effect, "RawWidth", (float)poly->texture->rawwidth); + (*d3dintf->effect.set_float)(curr_effect, "RawHeight", (float)poly->texture->rawheight); + (*d3dintf->effect.set_float)(curr_effect, "WidthRatio", 1.0f); + (*d3dintf->effect.set_float)(curr_effect, "HeightRatio", 1.0f); + (*d3dintf->effect.set_float)(curr_effect, "DefocusX", defocus_x); + (*d3dintf->effect.set_float)(curr_effect, "DefocusY", defocus_y); + (*d3dintf->effect.set_float)(curr_effect, "FocusEnable", (defocus_x == 0.0f && defocus_y == 0.0f) ? 0.0f : 1.0f); + + (*d3dintf->effect.begin)(curr_effect, &num_passes, 0); + + result = (*d3dintf->device.set_render_target)(d3d->device, 0, poly->texture->d3dtarget1); + if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call 7\n", (int)result); + + for (UINT pass = 0; pass < num_passes; pass++) + { + (*d3dintf->effect.begin_pass)(curr_effect, pass); + // add the primitives + result = (*d3dintf->device.draw_primitive)(d3d->device, poly->type, vertnum, poly->count); + if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result); + (*d3dintf->effect.end_pass)(curr_effect); + } + + (*d3dintf->effect.end)(curr_effect); + + // Simulate phosphorescence. This should happen after the shadow/scanline pass, but since + // the phosphors are a direct result of the incoming texture, might as well just change the + // input texture. curr_effect = d3d->phosphor_effect; (*d3dintf->effect.set_float)(curr_effect, "TargetWidth", (float)d3d->width); @@ -2126,10 +2273,10 @@ static void primitive_flush_pending(d3d_info *d3d) (*d3dintf->effect.set_float)(curr_effect, "GreenPhosphor", (float)options.screen_green_phosphor()); (*d3dintf->effect.set_float)(curr_effect, "BluePhosphor", (float)options.screen_blue_phosphor()); - (*d3dintf->effect.set_texture)(curr_effect, "Diffuse", poly->texture->d3dtexture0); + (*d3dintf->effect.set_texture)(curr_effect, "Diffuse", poly->texture->d3dtexture1); (*d3dintf->effect.set_texture)(curr_effect, "LastPass", d3d->last_d3dtexture[cur_render_screen]); - result = (*d3dintf->device.set_render_target)(d3d->device, 0, poly->texture->d3dtarget1); + result = (*d3dintf->device.set_render_target)(d3d->device, 0, poly->texture->d3dtarget0); if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call 4\n", (int)result); result = (*d3dintf->device.clear)(d3d->device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0); if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result); @@ -2173,55 +2320,18 @@ static void primitive_flush_pending(d3d_info *d3d) (*d3dintf->effect.end)(curr_effect); - /* Next, defocus pass 1 */ - curr_effect = d3d->focus_effect; + /* Scanlines and shadow mask */ + curr_effect = d3d->post_effect; - (*d3dintf->effect.set_texture)(curr_effect, "Diffuse", poly->texture->d3dtexture1); + (*d3dintf->effect.set_texture)(curr_effect, "Diffuse", poly->texture->d3dtexture0); - float defocus_x = (float)options.screen_defocus_x(); - float defocus_y = (float)options.screen_defocus_y(); - (*d3dintf->effect.set_float)(curr_effect, "TargetWidth", (float)d3d->width); - (*d3dintf->effect.set_float)(curr_effect, "TargetHeight", (float)d3d->height); - (*d3dintf->effect.set_float)(curr_effect, "RawWidth", (float)poly->texture->rawwidth); - (*d3dintf->effect.set_float)(curr_effect, "RawHeight", (float)poly->texture->rawheight); - (*d3dintf->effect.set_float)(curr_effect, "DefocusX", defocus_x); - (*d3dintf->effect.set_float)(curr_effect, "DefocusY", defocus_y); - (*d3dintf->effect.set_float)(curr_effect, "FocusEnable", (defocus_x == 0.0f && defocus_y == 0.0f) ? 0.0f : 1.0f); - - (*d3dintf->effect.begin)(curr_effect, &num_passes, 0); - - result = (*d3dintf->device.set_render_target)(d3d->device, 0, poly->texture->d3dtarget2); - if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call 6\n", (int)result); + result = (*d3dintf->device.set_render_target)(d3d->device, 0, backbuffer); + if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call 5\n", (int)result); result = (*d3dintf->device.clear)(d3d->device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0); if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result); - for (UINT pass = 0; pass < num_passes; pass++) - { - (*d3dintf->effect.begin_pass)(curr_effect, pass); - // add the primitives - result = (*d3dintf->device.draw_primitive)(d3d->device, poly->type, vertnum, poly->count); - if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result); - (*d3dintf->effect.end_pass)(curr_effect); - } - - (*d3dintf->effect.end)(curr_effect); - - /* Lastly, defocus pass 1 */ - (*d3dintf->effect.set_texture)(curr_effect, "Diffuse", poly->texture->d3dtexture2); - - (*d3dintf->effect.set_float)(curr_effect, "TargetWidth", (float)d3d->width); - (*d3dintf->effect.set_float)(curr_effect, "TargetHeight", (float)d3d->height); - (*d3dintf->effect.set_float)(curr_effect, "RawWidth", (float)poly->texture->rawwidth); - (*d3dintf->effect.set_float)(curr_effect, "RawHeight", (float)poly->texture->rawheight); - (*d3dintf->effect.set_float)(curr_effect, "DefocusX", defocus_x); - (*d3dintf->effect.set_float)(curr_effect, "DefocusY", defocus_y); - (*d3dintf->effect.set_float)(curr_effect, "FocusEnable", (defocus_x == 0.0f && defocus_y == 0.0f) ? 0.0f : 1.0f); - (*d3dintf->effect.begin)(curr_effect, &num_passes, 0); - result = (*d3dintf->device.set_render_target)(d3d->device, 0, backbuffer); - if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call 7\n", (int)result); - for (UINT pass = 0; pass < num_passes; pass++) { (*d3dintf->effect.begin_pass)(curr_effect, pass); @@ -2234,7 +2344,7 @@ static void primitive_flush_pending(d3d_info *d3d) (*d3dintf->effect.end)(curr_effect); poly->texture->cur_frame++; - poly->texture->cur_frame %= options.screen_dot_crawl_rate(); + poly->texture->cur_frame %= 2; } else { @@ -2245,8 +2355,8 @@ static void primitive_flush_pending(d3d_info *d3d) (*d3dintf->effect.set_float)(curr_effect, "TargetWidth", (float)d3d->width); (*d3dintf->effect.set_float)(curr_effect, "TargetHeight", (float)d3d->height); (*d3dintf->effect.set_float)(curr_effect, "PostPass", 0.0f); - (*d3dintf->effect.set_float)(curr_effect, "PincushionAmountX", (float)options.screen_pincushion_x()); - (*d3dintf->effect.set_float)(curr_effect, "PincushionAmountY", (float)options.screen_pincushion_y()); + (*d3dintf->effect.set_float)(curr_effect, "PincushionAmountX", (float)options.screen_pincushion()); + (*d3dintf->effect.set_float)(curr_effect, "PincushionAmountY", (float)options.screen_pincushion()); (*d3dintf->effect.begin)(curr_effect, &num_passes, 0); @@ -2274,7 +2384,10 @@ static void primitive_flush_pending(d3d_info *d3d) vertnum += poly->numverts; } - (*d3dintf->surface.release)(backbuffer); + if(d3d->hlsl_enable && d3dintf->post_fx_available) + { + (*d3dintf->surface.release)(backbuffer); + } // reset the vertex count d3d->numverts = 0; @@ -2372,7 +2485,6 @@ static texture_info *texture_create(d3d_info *d3d, const render_texinfo *texsour if (result != D3D_OK) goto error; (*d3dintf->texture.get_surface_level)(d3d->last_d3dtexture[d3d->registered_targets], 0, &d3d->last_d3dtarget[d3d->registered_targets]); - d3d->registered_targets++; result = (*d3dintf->device.create_texture)(d3d->device, (int)(d3d->width * d3d->oversample_x), (int)(d3d->height * d3d->oversample_y), 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture->d3dtexture1); if (result != D3D_OK) @@ -2383,6 +2495,19 @@ static texture_info *texture_create(d3d_info *d3d, const render_texinfo *texsour if (result != D3D_OK) goto error; (*d3dintf->texture.get_surface_level)(texture->d3dtexture2, 0, &texture->d3dtarget2); + + result = (*d3dintf->device.create_texture)(d3d->device, texture->rawwidth, texture->rawheight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture->d3dsmalltexture0); + if (result != D3D_OK) + goto error; + (*d3dintf->texture.get_surface_level)(texture->d3dsmalltexture0, 0, &texture->d3dsmalltarget0); + + result = (*d3dintf->device.create_texture)(d3d->device, texture->rawwidth, texture->rawheight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture->d3dsmalltexture1); + if (result != D3D_OK) + goto error; + (*d3dintf->texture.get_surface_level)(texture->d3dsmalltexture1, 0, &texture->d3dsmalltarget1); + + d3d->registered_targets++; + break; } } @@ -2442,6 +2567,16 @@ static texture_info *texture_create(d3d_info *d3d, const render_texinfo *texsour goto error; (*d3dintf->texture.get_surface_level)(texture->d3dtexture2, 0, &texture->d3dtarget2); + result = (*d3dintf->device.create_texture)(d3d->device, scwidth, scheight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture->d3dsmalltexture0); + if (result != D3D_OK) + goto error; + (*d3dintf->texture.get_surface_level)(texture->d3dsmalltexture0, 0, &texture->d3dsmalltarget0); + + result = (*d3dintf->device.create_texture)(d3d->device, scwidth, scheight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture->d3dsmalltexture1); + if (result != D3D_OK) + goto error; + (*d3dintf->texture.get_surface_level)(texture->d3dsmalltexture0, 1, &texture->d3dsmalltarget1); + break; } (*d3dintf->texture.release)(texture->d3dtex); diff --git a/src/osd/windows/winmain.c b/src/osd/windows/winmain.c index ebee9160e60..b7d5b756a9e 100644 --- a/src/osd/windows/winmain.c +++ b/src/osd/windows/winmain.c @@ -332,15 +332,17 @@ const options_entry windows_options::s_option_entries[] = { WINOPTION_HLSLPATH, "hlsl", OPTION_STRING, "path to hlsl files" }, { WINOPTION_SHADOW_MASK_ALPHA";fs_shadwa(0.0-1.0)", "0.0", OPTION_FLOAT, "shadow mask alpha-blend value (1.0 is fully blended, 0.0 is no mask)" }, { WINOPTION_SHADOW_MASK_TEXTURE";fs_shadwt(0.0-1.0)", "aperture.png", OPTION_STRING, "shadow mask texture name" }, - { WINOPTION_SHADOW_MASK_WIDTH";fs_shadww", "3.0", OPTION_FLOAT, "shadow mask width, in shadow mask pixels per emulated pixel" }, - { WINOPTION_SHADOW_MASK_HEIGHT";fs_shadwh", "3.0", OPTION_FLOAT, "shadow mask height, in shadow mask pixels per emulated pixel" }, + { WINOPTION_SHADOW_MASK_RATIO_X";fs_shadwx", "3.0", OPTION_FLOAT, "shadow mask texels per dot mask pixel in screen-relative X direction" }, + { WINOPTION_SHADOW_MASK_RATIO_Y";fs_shadwy", "3.0", OPTION_FLOAT, "shadow mask texels per dot mask pixel in screen-relative Y direction" }, + { WINOPTION_SHADOW_MASK_COUNT_X";fs_shadww", "640", OPTION_INTEGER, "shadow mask width, in phosphor dots" }, + { WINOPTION_SHADOW_MASK_COUNT_Y";fs_shadwh", "480", OPTION_INTEGER, "shadow mask height, in phosphor dots" }, { WINOPTION_SHADOW_MASK_USIZE";fs_shadwu(0.0-1.0)", "0.1875", OPTION_FLOAT, "shadow mask texture size in U direction" }, { WINOPTION_SHADOW_MASK_VSIZE";fs_shadwv(0.0-1.0)", "0.1875", OPTION_FLOAT, "shadow mask texture size in V direction" }, - { WINOPTION_OVERSAMPLE_X";fs_overx(1.0-9.0)", "1.0", OPTION_FLOAT, "oversample amount in screen-relative X direction, multiple" }, - { WINOPTION_OVERSAMPLE_Y";fs_overy(1.0-9.0)", "1.0", OPTION_FLOAT, "oversample amount in screen-relative Y direction, multiple" }, + { WINOPTION_OVERSAMPLE_X";fs_overx(0.1-9.0)", "1.0", OPTION_FLOAT, "oversample amount in screen-relative X direction, multiple" }, + { WINOPTION_OVERSAMPLE_Y";fs_overy(0.1-9.0)", "1.0", OPTION_FLOAT, "oversample amount in screen-relative Y direction, multiple" }, + { WINOPTION_CURVATURE";fs_curv(0.0-4.0)", "0.0", OPTION_FLOAT, "screen curvature amount" }, /* Beam-related values below this line*/ - { WINOPTION_PINCUSHION_X";fs_pinx(0.0-4.0)", "0.0", OPTION_FLOAT, "pincushion amount in screen-relative X direction" }, - { WINOPTION_PINCUSHION_Y";fs_piny(0.0-4.0)", "0.0", OPTION_FLOAT, "pincushion amount in screen-relative Y direction" }, + { WINOPTION_PINCUSHION";fs_pin(0.0-4.0)", "0.0", OPTION_FLOAT, "pincushion amount" }, { 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_BRIGHT_SCALE";fs_scanbs(0.0-1.0)", "1.0", OPTION_FLOAT, "overall brightness scaling value for scanlines (multiplicative)" }, @@ -408,14 +410,9 @@ const options_entry windows_options::s_option_entries[] = { WINOPTION_Y_OFFSET";fs_yoffs(-1.0-1.0)", "0.0", OPTION_FLOAT, "Y signal offset value for NTSC colorspace convolution (additive)" }, { WINOPTION_I_OFFSET";fs_ioffs(-1.0-1.0)", "0.0", OPTION_FLOAT, "I signal offset value for NTSC colorspace convolution (additive)" }, { WINOPTION_Q_OFFSET";fs_qoffs(-1.0-1.0)", "0.0", OPTION_FLOAT, "Q signal offset value for NTSC colorspace convolution (additive)" }, - { WINOPTION_SUBSAMPLE_LENGTH";fs_chrsub(1.0+)", "1.0", OPTION_FLOAT, "chroma signal subsampling value, in pixels" }, - { WINOPTION_CRAWL_WIDTH";fs_crawlw(0.0-8.0)", "0.0", OPTION_FLOAT, "dot crawl width (in pixels, 1.0 upward)" }, - { WINOPTION_CRAWL_HEIGHT";fs_crawlh(0.0-8.0)", "2.0", OPTION_FLOAT, "dot crawl height (in pixels, 1.0 upward)" }, - { WINOPTION_CRAWL_RATE";fs_crawlr(1-8)", "2", OPTION_INTEGER, "dot crawl rate (in total frames, 1 upward)" }, - { WINOPTION_CRAWL_SKIP";fs_crawls(0-7)", "2", OPTION_INTEGER, "dot crawl frame to skip (frame index, 0 upward)" }, - /* "Just for fun" below this line */ - { WINOPTION_EDGE_AMOUNT";fs_edgeen(0.0-2.0)", "1.0", OPTION_FLOAT, "edge-detection alpha (just for fun)" }, - { WINOPTION_EDGE_RATIO";fs_edgert(0.0-1.0)", "0.0", OPTION_FLOAT, "edge-detection to baseline texel ratio (just for fun)" }, + { WINOPTION_Y_SUBSAMPLE_LENGTH";fs_ysub(0.5+)", "0.5", OPTION_FLOAT, "Y signal subsampling value, in pixels" }, + { WINOPTION_I_SUBSAMPLE_LENGTH";fs_isub(0.5+)", "0.5", OPTION_FLOAT, "I signal subsampling value, in pixels" }, + { WINOPTION_Q_SUBSAMPLE_LENGTH";fs_qsub(0.5+)", "0.5", OPTION_FLOAT, "Q signal subsampling value, in pixels" }, // per-window options { NULL, NULL, OPTION_HEADER, "PER-WINDOW VIDEO OPTIONS" }, diff --git a/src/osd/windows/winmain.h b/src/osd/windows/winmain.h index ee30b9bea35..96e71a468d5 100644 --- a/src/osd/windows/winmain.h +++ b/src/osd/windows/winmain.h @@ -83,12 +83,14 @@ #define WINOPTION_HLSLPATH "hlslpath" #define WINOPTION_SHADOW_MASK_ALPHA "shadow_mask_alpha" #define WINOPTION_SHADOW_MASK_TEXTURE "shadow_mask_texture" -#define WINOPTION_SHADOW_MASK_WIDTH "shadow_mask_pix_width" -#define WINOPTION_SHADOW_MASK_HEIGHT "shadow_mask_pix_height" +#define WINOPTION_SHADOW_MASK_RATIO_X "shadow_mask_pix_width" +#define WINOPTION_SHADOW_MASK_RATIO_Y "shadow_mask_pix_height" +#define WINOPTION_SHADOW_MASK_COUNT_X "shadow_mask_x_count" +#define WINOPTION_SHADOW_MASK_COUNT_Y "shadow_mask_y_count" #define WINOPTION_SHADOW_MASK_USIZE "shadow_mask_usize" #define WINOPTION_SHADOW_MASK_VSIZE "shadow_mask_vsize" -#define WINOPTION_PINCUSHION_X "pincushion_x" -#define WINOPTION_PINCUSHION_Y "pincushion_y" +#define WINOPTION_PINCUSHION "pincushion" +#define WINOPTION_CURVATURE "curvature" #define WINOPTION_OVERSAMPLE_X "oversample_x" #define WINOPTION_OVERSAMPLE_Y "oversample_y" #define WINOPTION_SCANLINE_AMOUNT "scanline_alpha" @@ -147,16 +149,12 @@ #define WINOPTION_Y_OFFSET "y_offset" #define WINOPTION_I_OFFSET "i_offset" #define WINOPTION_Q_OFFSET "q_offset" -#define WINOPTION_EDGE_AMOUNT "edge_amount" -#define WINOPTION_EDGE_RATIO "edge_ratio" -#define WINOPTION_SUBSAMPLE_LENGTH "subsample_length" +#define WINOPTION_Y_SUBSAMPLE_LENGTH "y_subsample_length" +#define WINOPTION_I_SUBSAMPLE_LENGTH "i_subsample_length" +#define WINOPTION_Q_SUBSAMPLE_LENGTH "q_subsample_length" #define WINOPTION_RED_PHOSPHOR "red_phosphor_life" #define WINOPTION_GREEN_PHOSPHOR "green_phosphor_life" #define WINOPTION_BLUE_PHOSPHOR "blue_phosphor_life" -#define WINOPTION_CRAWL_WIDTH "dot_crawl_width" -#define WINOPTION_CRAWL_HEIGHT "dot_crawl_height" -#define WINOPTION_CRAWL_RATE "dot_crawl_rate" -#define WINOPTION_CRAWL_SKIP "dot_crawl_skip" // per-window options #define WINOPTION_SCREEN "screen" @@ -223,15 +221,14 @@ public: // core post-processing options const char *screen_post_fx_dir() const { return value(WINOPTION_HLSLPATH); } bool d3d_hlsl_enable() const { return bool_value(WINOPTION_HLSL_ENABLE); } - float screen_pincushion_x() const { return float_value(WINOPTION_PINCUSHION_X); } - float screen_pincushion_y() const { return float_value(WINOPTION_PINCUSHION_Y); } float screen_shadow_mask_alpha() const { return float_value(WINOPTION_SHADOW_MASK_ALPHA); } const char *screen_shadow_mask_texture() const { return value(WINOPTION_SHADOW_MASK_TEXTURE); } - float screen_shadow_mask_width() const { return float_value(WINOPTION_SHADOW_MASK_WIDTH); } - float screen_shadow_mask_height() const { return float_value(WINOPTION_SHADOW_MASK_HEIGHT); } + float screen_shadow_mask_ratio_x() const { return float_value(WINOPTION_SHADOW_MASK_RATIO_X); } + float screen_shadow_mask_ratio_y() const { return float_value(WINOPTION_SHADOW_MASK_RATIO_Y); } + float screen_shadow_mask_count_x() const { return float_value(WINOPTION_SHADOW_MASK_COUNT_X); } + float screen_shadow_mask_count_y() const { return float_value(WINOPTION_SHADOW_MASK_COUNT_Y); } float screen_shadow_mask_u_size() const { return float_value(WINOPTION_SHADOW_MASK_USIZE); } float screen_shadow_mask_v_size() const { return float_value(WINOPTION_SHADOW_MASK_VSIZE); } - float screen_shadow_width_y() const { return float_value(WINOPTION_SHADOW_MASK_HEIGHT); } float screen_oversample_x() const { return float_value(WINOPTION_OVERSAMPLE_X); } float screen_oversample_y() const { return float_value(WINOPTION_OVERSAMPLE_Y); } float screen_scanline_amount() const { return float_value(WINOPTION_SCANLINE_AMOUNT); } @@ -239,6 +236,8 @@ public: 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_offset() const { return float_value(WINOPTION_SCANLINE_OFFSET); } + float screen_pincushion() const { return float_value(WINOPTION_PINCUSHION); } + float screen_curvature() const { return float_value(WINOPTION_CURVATURE); } float screen_defocus_x() const { return float_value(WINOPTION_DEFOCUS_X); } float screen_defocus_y() const { return float_value(WINOPTION_DEFOCUS_Y); } float screen_red_converge_x() const { return float_value(WINOPTION_RED_CONVERGE_X); } @@ -290,16 +289,12 @@ public: float screen_y_offset() const { return float_value(WINOPTION_Y_OFFSET); } float screen_i_offset() const { return float_value(WINOPTION_I_OFFSET); } float screen_q_offset() const { return float_value(WINOPTION_Q_OFFSET); } - float screen_edge_amount() const { return float_value(WINOPTION_EDGE_AMOUNT); } - float screen_edge_ratio() const { return float_value(WINOPTION_EDGE_RATIO); } - float screen_chroma_subsample_length() const { return float_value(WINOPTION_SUBSAMPLE_LENGTH); } + float screen_y_subsample_length() const { return float_value(WINOPTION_Y_SUBSAMPLE_LENGTH); } + float screen_i_subsample_length() const { return float_value(WINOPTION_I_SUBSAMPLE_LENGTH); } + float screen_q_subsample_length() const { return float_value(WINOPTION_Q_SUBSAMPLE_LENGTH); } float screen_red_phosphor() const { return float_value(WINOPTION_RED_PHOSPHOR); } float screen_green_phosphor() const { return float_value(WINOPTION_GREEN_PHOSPHOR); } float screen_blue_phosphor() const { return float_value(WINOPTION_BLUE_PHOSPHOR); } - float screen_dot_crawl_width() const { return float_value(WINOPTION_CRAWL_WIDTH); } - float screen_dot_crawl_height() const { return float_value(WINOPTION_CRAWL_HEIGHT); } - int screen_dot_crawl_rate() const { return int_value(WINOPTION_CRAWL_RATE); } - int screen_dot_crawl_skip() const { return int_value(WINOPTION_CRAWL_SKIP); } // per-window options const char *screen() const { return value(WINOPTION_SCREEN); }