diff options
author | 2015-09-26 18:22:51 +0200 | |
---|---|---|
committer | 2015-09-26 18:22:51 +0200 | |
commit | 062e6e0383050546656dfed7261273a2d7d142a4 (patch) | |
tree | b28fdb238ce5501908086d41f0e443cf11e6c313 | |
parent | 37f6ff0b653f840010a9b2dd18b5df9e6337aa2c (diff) |
Refactoring, Fixes and Cleanup
- added distortion pass, which is applied after the bloom pass
- moved vignetting, curvature, round corners and reflection effect to
distortion pass
- disabled distortion pass for multi screens and activated artworks due
to not yet fixed misalignments
- disabled scanlines for vector rendering in post pass shader
- removed prescale knowledge from downsample, bloom and post pass shader
- fixed half pixel offset in most shaders
- fixed position of reflection effect when screen is rotated or flipped
- fixed roundness of round corners in any aspect ratio
- fixed shadow mask bleeding (nearly completly)
- added bounds() and screen_bounds() getter to layout_view
- added current_view() getter to render_target
- some cleanup and refactoring
-rw-r--r-- | hlsl/bloom.fx | 72 | ||||
-rw-r--r-- | hlsl/distortion.fx | 330 | ||||
-rw-r--r-- | hlsl/downsample.fx | 19 | ||||
-rw-r--r-- | hlsl/focus.fx | 7 | ||||
-rw-r--r-- | hlsl/phosphor.fx | 14 | ||||
-rw-r--r-- | hlsl/post.fx | 247 | ||||
-rw-r--r-- | hlsl/primary.fx | 17 | ||||
-rw-r--r-- | src/emu/render.h | 1 | ||||
-rw-r--r-- | src/emu/rendlay.h | 2 | ||||
-rw-r--r-- | src/osd/modules/render/d3d/d3dhlsl.c | 449 | ||||
-rw-r--r-- | src/osd/modules/render/d3d/d3dhlsl.h | 7 | ||||
-rw-r--r-- | src/osd/modules/render/drawd3d.c | 24 |
12 files changed, 742 insertions, 447 deletions
diff --git a/hlsl/bloom.fx b/hlsl/bloom.fx index e41a663b204..0b3a230bf5b 100644 --- a/hlsl/bloom.fx +++ b/hlsl/bloom.fx @@ -172,12 +172,32 @@ struct PS_INPUT }; //----------------------------------------------------------------------------- +// Constants +//----------------------------------------------------------------------------- + +static const float E = 2.7182817f; +static const float Gelfond = 23.140692f; // e^pi (Gelfond constant) +static const float GelfondSchneider = 2.6651442f; // 2^sqrt(2) (Gelfond-Schneider constant) + +//----------------------------------------------------------------------------- +// Funcions +//----------------------------------------------------------------------------- + +// www.stackoverflow.com/questions/5149544/can-i-generate-a-random-number-inside-a-pixel-shader/ +float random(float2 seed) +{ + // irrationals for pseudo randomness + float2 i = float2(Gelfond, GelfondSchneider); + + return frac(cos(dot(seed, i)) * 123456.0f); +} + +//----------------------------------------------------------------------------- // Bloom Vertex Shader //----------------------------------------------------------------------------- uniform float2 ScreenDims; - -uniform float2 Prescale = float2(1.0f, 1.0f); +uniform float2 TargetDims; uniform float4 Level01Size; uniform float4 Level23Size; @@ -199,15 +219,16 @@ VS_OUTPUT vs_main(VS_INPUT Input) Output.Color = Input.Color; float2 TexCoord = Input.Position.xy / ScreenDims; + TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9) Output.TexCoord01.xy = TexCoord.xy; - Output.TexCoord01.zw = TexCoord.xy + Prescale.xy / Level01Size.zw; - Output.TexCoord23 = TexCoord.xyxy + Prescale.xyxy / Level23Size; - Output.TexCoord45 = TexCoord.xyxy + Prescale.xyxy / Level45Size; - Output.TexCoord67 = TexCoord.xyxy + Prescale.xyxy / Level67Size; - Output.TexCoord89 = TexCoord.xyxy + Prescale.xyxy / Level89Size; - Output.TexCoordA = TexCoord.xy + Prescale.xy / LevelASize; - + Output.TexCoord01.zw = TexCoord.xy + 0.5f / Level01Size.zw; + Output.TexCoord23 = TexCoord.xyxy + 0.5f / Level23Size; + Output.TexCoord45 = TexCoord.xyxy + 0.5f / Level45Size; + Output.TexCoord67 = TexCoord.xyxy + 0.5f / Level67Size; + Output.TexCoord89 = TexCoord.xyxy + 0.5f / Level89Size; + Output.TexCoordA = TexCoord.xy + 0.5f / LevelASize; + return Output; } @@ -219,6 +240,12 @@ uniform float4 Level0123Weight; uniform float4 Level4567Weight; uniform float3 Level89AWeight; +float3 GetNoiseFactor(float3 n, float random) +{ + // smaller n become more noisy + return 1.0f + random * max(0.0f, 0.25f * pow(E, -8 * n)); +} + float4 ps_main(PS_INPUT Input) : COLOR { float3 texel0 = tex2D(DiffuseSampler0, Input.TexCoord01.xy).rgb; @@ -245,19 +272,22 @@ float4 ps_main(PS_INPUT Input) : COLOR texel9 = texel9 * Level89AWeight.y; texelA = texelA * Level89AWeight.z; - float4 sum = float4( - texel0 + - texel1 + - texel2 + - texel3 + + float3 bloom = float3( + texel1 + + texel2 + + texel3 + texel4 + - texel5 + - texel6 + - texel7 + - texel8 + - texel9 + - texelA, 1.0f); - return sum; + texel5 + + texel6 + + texel7 + + texel8 + + texel9 + + texelA); + + float2 NoiseCoord = Input.TexCoord01.xy; + float3 NoiseFactor = GetNoiseFactor(bloom, random(NoiseCoord)); + + return float4(texel0 + bloom * NoiseFactor, 1.0f); } //----------------------------------------------------------------------------- diff --git a/hlsl/distortion.fx b/hlsl/distortion.fx new file mode 100644 index 00000000000..9db6edd4fb5 --- /dev/null +++ b/hlsl/distortion.fx @@ -0,0 +1,330 @@ +// license:BSD-3-Clause +// copyright-holders:ImJezze +//----------------------------------------------------------------------------- +// Distortion Effect +//----------------------------------------------------------------------------- + +texture DiffuseTexture; + +sampler DiffuseSampler = sampler_state +{ + Texture = <DiffuseTexture>; + MipFilter = LINEAR; + MinFilter = LINEAR; + MagFilter = LINEAR; + AddressU = CLAMP; + AddressV = CLAMP; + AddressW = CLAMP; +}; + +//----------------------------------------------------------------------------- +// Vertex Definitions +//----------------------------------------------------------------------------- + +struct VS_INPUT +{ + float4 Position : POSITION; + float4 Color : COLOR0; + float2 TexCoord : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float4 Position : POSITION; + float4 Color : COLOR0; + float2 TexCoord : TEXCOORD0; +}; + +struct PS_INPUT +{ + float4 Color : COLOR0; + float2 TexCoord : TEXCOORD0; +}; + +//----------------------------------------------------------------------------- +// Constants +//----------------------------------------------------------------------------- + +static const float Epsilon = 1.0e-7f; +static const float PI = 3.1415927f; +static const float E = 2.7182817f; +static const float Gelfond = 23.140692f; // e^pi (Gelfond constant) +static const float GelfondSchneider = 2.6651442f; // 2^sqrt(2) (Gelfond-Schneider constant) + +//----------------------------------------------------------------------------- +// Functions +//----------------------------------------------------------------------------- + +bool xor(bool a, bool b) +{ + return (a || b) && !(a && b); +} + +// www.stackoverflow.com/questions/5149544/can-i-generate-a-random-number-inside-a-pixel-shader/ +float random(float2 seed) +{ + // irrationals for pseudo randomness + float2 i = float2(Gelfond, GelfondSchneider); + + return frac(cos(dot(seed, i)) * 123456.0f); +} + +// www.dinodini.wordpress.com/2010/04/05/normalized-tunable-sigmoid-functions/ +float normalizedSigmoid(float n, float k) +{ + // valid for n and k in range of -1.0 and 1.0 + return (n - n * k) / (k - abs(n) * 2.0f * k + 1); +} + +// www.iquilezles.org/www/articles/distfunctions/distfunctions.htm +float roundBox(float2 p, float2 b, float r) +{ + return length(max(abs(p) - b + r, 0.0f)) - r; +} + +//----------------------------------------------------------------------------- +// Distortion Vertex Shader +//----------------------------------------------------------------------------- + +uniform float2 ScreenDims; // size of the window or fullscreen +uniform float2 TargetDims; +uniform float2 QuadDims; // size of the screen quad + +VS_OUTPUT vs_main(VS_INPUT Input) +{ + VS_OUTPUT Output = (VS_OUTPUT)0; + + Output.Position = float4(Input.Position.xyz, 1.0f); + Output.Position.xy /= ScreenDims; + Output.Position.y = 1.0f - Output.Position.y; // flip y + Output.Position.xy -= 0.5f; // center + Output.Position.xy *= 2.0f; // zoom + + Output.Color = Input.Color; + + Output.TexCoord = Input.Position.xy / ScreenDims; + Output.TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9) + + return Output; +} + +//----------------------------------------------------------------------------- +// Post-Processing Pixel Shader +//----------------------------------------------------------------------------- + +uniform float2 DefaultScreenRatio = float2(1.0f, 3.0f / 4.0f); // normalized screen ratio (defalt ratio of 4:3) + +uniform float CurvatureAmount = 0.0f; +uniform float RoundCornerAmount = 0.0f; +uniform float SmoothBorderAmount = 0.5f; +uniform float VignettingAmount = 0.0f; +uniform float ReflectionAmount = 0.0f; + +uniform bool OrientationSwapXY = false; // false landscape, true portrait for default screen orientation +uniform bool RotationSwapXY = false; // swapped default screen orientation due to screen rotation +uniform int RotationType = 0; // 0 = 0°, 1 = 90°, 2 = 180°, 3 = 270° + +float2 GetRatioCorrecton() +{ + float ScreenRatio = ScreenDims.x / ScreenDims.y; + float QuadRatio = QuadDims.x / QuadDims.y; + float ScreenQuadRatio = QuadRatio / ScreenRatio; + + return ScreenQuadRatio > 1.0f + ? float2(1.0, 1.0f / ScreenQuadRatio) + : float2(ScreenQuadRatio, 1.0); +} + +float GetNoiseFactor(float3 n, float random) +{ + // smaller n become more noisy + return 1.0f + random * max(0.0f, 0.25f * pow(E, -8 * n)); +} + +float GetVignetteFactor(float2 coord, float amount) +{ + float2 VignetteCoord = coord; + + float VignetteLength = length(VignetteCoord); + float VignetteBlur = (amount * 0.75f) + 0.25; + + // 0.5 full screen fitting circle + float VignetteRadius = 1.0f - (amount * 0.25f); + float Vignette = smoothstep(VignetteRadius, VignetteRadius - VignetteBlur, VignetteLength); + + return saturate(Vignette); +} + +float GetSpotAddend(float2 coord, float amount) +{ + float2 RatioCorrection = GetRatioCorrecton(); + + float2 defaultScreenRatio = xor(OrientationSwapXY, RotationSwapXY) + ? DefaultScreenRatio.yx + : DefaultScreenRatio.xy; + + // upper right quadrant + float2 spotOffset = + RotationType == 1 // 90° + ? float2(-0.25f, -0.25f) + : RotationType == 2 // 180° + ? float2(0.25f, -0.25f) + : RotationType == 3 // 270° + ? float2(0.25f, 0.25f) + : float2(-0.25f, 0.25f); + + float2 SpotCoord = coord; + SpotCoord += spotOffset * defaultScreenRatio * RatioCorrection; + + float SpotBlur = amount; + + // 0.5 full screen fitting circle + float SpotRadius = amount * 0.75f; + float Spot = smoothstep(SpotRadius, SpotRadius - SpotBlur, length(SpotCoord)); + + float SigmoidSpot = normalizedSigmoid(Spot, 0.75) * amount; + + // increase strength by 100% + SigmoidSpot = SigmoidSpot * 2.0f; + + return saturate(SigmoidSpot); +} + +float GetRoundCornerFactor(float2 coord, float radiusAmount, float smoothAmount) +{ + float2 RatioCorrection = GetRatioCorrecton(); + + smoothAmount = min(smoothAmount, radiusAmount); + + float2 RoundCornerCoord = coord * 2; + + float MinScreenDims = min(ScreenDims.x, ScreenDims.y); + + float radius = MinScreenDims * 0.5 * max(radiusAmount, 0.01f); + float smooth = 1.0 / (MinScreenDims * 0.25 * max(smoothAmount, 0.01f)); + + // compute box + float box = roundBox(ScreenDims * RoundCornerCoord, ScreenDims * RatioCorrection, radius); + + // apply smooth + // box *= smooth; + // box += 1.0f - pow(smooth * 0.5f, 0.5f); + + float border = smoothstep(1.0f, 0.0f, box); + + return saturate(border); +} + +// www.francois-tarlier.com/blog/cubic-lens-distortion-shader/ +float2 GetDistortedCoords(float2 coord, float amount) +{ + amount *= 0.25f; // reduced amount + + float2 RatioCorrection = GetRatioCorrecton(); + + // center coordinates + coord -= 0.5f; + + coord /= RatioCorrection; + + // lens distortion coefficient + float k = amount; + + // cubic distortion value + float kcube = amount * 2.0f; + + // compute cubic distortion factor + float r2 = coord.x * coord.x + coord.y * coord.y; + float f = kcube == 0.0f + ? 1 + r2 * k + : 1 + r2 * (k + kcube * sqrt(r2)); + + // correct zoom + f /= 1.0f + amount * 0.5f; + + // apply cubic distortion factor + coord *= f; + + coord *= RatioCorrection; + + // uncenter coordinates + coord += 0.5f; + + return coord; +} + +float4 ps_main(PS_INPUT Input) : COLOR +{ + float2 TexCoord = Input.TexCoord; + float2 BaseCoord = TexCoord; + + // // test code + // // BaseCoord.x += (TexCoord.x > 0.5f ? -0.5f : 0.0f); + // BaseCoord.y += (TexCoord.y > 0.5f ? -0.5f : 0.0f); + // BaseCoord.y *= 2.0f; + + // Screen Curvature + BaseCoord = GetDistortedCoords(BaseCoord, CurvatureAmount); + + float2 BaseCoordCentered = BaseCoord; + BaseCoordCentered -= 0.5f; + + // // test code + // BaseCoord.y /= 2.0f; + // // BaseCoord.x += (TexCoord.x > 0.5f ? +0.5f : 0.0f); + // BaseCoord.y += (TexCoord.y > 0.5 ? +0.5f : 0.0f); + + float2 defaultScreenRatio = xor(OrientationSwapXY, RotationSwapXY) + ? DefaultScreenRatio.yx + : DefaultScreenRatio.xy; + + float2 BaseRatioCoordCentered = BaseCoordCentered; + BaseRatioCoordCentered *= defaultScreenRatio; + + // Color + float4 BaseColor = tex2D(DiffuseSampler, BaseCoord); + BaseColor.a = 1.0f; + + // Vignetting Simulation + float2 VignetteCoord = BaseCoordCentered; + + float VignetteFactor = GetVignetteFactor(VignetteCoord, VignettingAmount); + BaseColor.rgb *= VignetteFactor; + + // Light Reflection Simulation + float3 LightColor = float3(1.0f, 0.90f, 0.80f); + + float2 SpotCoord = BaseRatioCoordCentered; + float2 NoiseCoord = BaseRatioCoordCentered; + + float SpotAddend = GetSpotAddend(SpotCoord, ReflectionAmount); + float NoiseFactor = GetNoiseFactor(SpotAddend, random(NoiseCoord)); + BaseColor.rgb += SpotAddend * NoiseFactor * LightColor; + + // Round Corners Simulation + float2 RoundCornerCoord = BaseCoordCentered; + + float roundCornerFactor = GetRoundCornerFactor(RoundCornerCoord, RoundCornerAmount, 0); + BaseColor.rgb *= roundCornerFactor; + + // // test code + // BaseColor.rgb = BaseCoord.x * BaseCoord.y; + // BaseColor.rgb = TexCoord.y > 0.5f ? 1.0f : 0.5f; + + return BaseColor; +} + +//----------------------------------------------------------------------------- +// Distortion Effect +//----------------------------------------------------------------------------- + +technique DistortionTechnique +{ + pass Pass0 + { + Lighting = FALSE; + + VertexShader = compile vs_3_0 vs_main(); + PixelShader = compile ps_3_0 ps_main(); + } +}
\ No newline at end of file diff --git a/hlsl/downsample.fx b/hlsl/downsample.fx index 376e4b8802d..4a4a8fe3743 100644 --- a/hlsl/downsample.fx +++ b/hlsl/downsample.fx @@ -48,15 +48,15 @@ struct PS_INPUT //----------------------------------------------------------------------------- uniform float2 ScreenDims; -uniform float2 TargetSize; +uniform float2 TargetDims; -uniform float2 Prescale = float2(1.0f, 1.0f); +uniform bool PrepareVector; VS_OUTPUT vs_main(VS_INPUT Input) { VS_OUTPUT Output = (VS_OUTPUT)0; - float2 TargetTexelSize = 1.0f / TargetSize; + float2 TargetTexelDims = 1.0f / TargetDims; Output.Position = float4(Input.Position.xyz, 1.0f); Output.Position.xy /= ScreenDims; @@ -67,11 +67,14 @@ VS_OUTPUT vs_main(VS_INPUT Input) Output.Color = Input.Color; float2 TexCoord = Input.Position.xy / ScreenDims; - - Output.TexCoord01.xy = TexCoord + float2(-0.5f, -0.5f) * TargetTexelSize * Prescale; - Output.TexCoord01.zw = TexCoord + float2( 0.5f, -0.5f) * TargetTexelSize * Prescale; - Output.TexCoord23.xy = TexCoord + float2(-0.5f, 0.5f) * TargetTexelSize * Prescale; - Output.TexCoord23.zw = TexCoord + float2( 0.5f, 0.5f) * TargetTexelSize * Prescale; + TexCoord += PrepareVector + ? 0.5f / TargetDims // half texel offset correction (DX9) + : 0.0f; + + Output.TexCoord01.xy = TexCoord + float2(-0.5f, -0.5f) * TargetTexelDims; + Output.TexCoord01.zw = TexCoord + float2( 0.5f, -0.5f) * TargetTexelDims; + Output.TexCoord23.xy = TexCoord + float2(-0.5f, 0.5f) * TargetTexelDims; + Output.TexCoord23.zw = TexCoord + float2( 0.5f, 0.5f) * TargetTexelDims; return Output; } diff --git a/hlsl/focus.fx b/hlsl/focus.fx index b71bc0dcdc6..39e642b58c4 100644 --- a/hlsl/focus.fx +++ b/hlsl/focus.fx @@ -83,8 +83,9 @@ VS_OUTPUT vs_main(VS_INPUT Input) Output.Position.y = 1.0f - Output.Position.y; // flip y Output.Position.xy -= 0.5f; // center Output.Position.xy *= 2.0f; // zoom - - float2 TexCoord = Input.TexCoord + 0.5f / TargetDims; + + float2 TexCoord = Input.TexCoord; + TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9) Output.TexCoord0 = TexCoord; Output.TexCoord1 = TexCoord + Coord1Offset * TargetTexelDims * Defocus; @@ -117,7 +118,7 @@ float4 ps_main(PS_INPUT Input) : COLOR float3 blurred = (d0.rgb + d1 + d2 + d3 + d4 + d5 + d6 + d7) / 8.0f; blurred = lerp(d0.rgb, blurred, 1.0f); - + return float4(blurred, d0.a); } diff --git a/hlsl/phosphor.fx b/hlsl/phosphor.fx index 44b00ac0ee7..13c7700e2e8 100644 --- a/hlsl/phosphor.fx +++ b/hlsl/phosphor.fx @@ -68,18 +68,20 @@ uniform bool Passthrough; VS_OUTPUT vs_main(VS_INPUT Input) { VS_OUTPUT Output = (VS_OUTPUT)0; - + Output.Position = float4(Input.Position.xyz, 1.0f); Output.Position.xy /= ScreenDims; Output.Position.y = 1.0f - Output.Position.y; // flip y Output.Position.xy -= 0.5f; // center Output.Position.xy *= 2.0f; // zoom - - Output.TexCoord = Input.TexCoord + 0.5f / TargetDims; + + Output.TexCoord = Input.TexCoord; + Output.TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9) + Output.PrevCoord = Output.TexCoord; Output.Color = Input.Color; - + return Output; } @@ -93,13 +95,13 @@ float4 ps_main(PS_INPUT Input) : COLOR { float4 CurrPix = tex2D(DiffuseSampler, Input.TexCoord); float3 PrevPix = tex2D(PreviousSampler, Input.PrevCoord).rgb * float3(Phosphor.r, Phosphor.g, Phosphor.b); - + float RedMax = max(CurrPix.r, PrevPix.r); float GreenMax = max(CurrPix.g, PrevPix.g); float BlueMax = max(CurrPix.b, PrevPix.b); return Passthrough - ? CurrPix + ? CurrPix : float4(RedMax, GreenMax, BlueMax, CurrPix.a); } diff --git a/hlsl/post.fx b/hlsl/post.fx index 57cf821071f..1a49ab55d4d 100644 --- a/hlsl/post.fx +++ b/hlsl/post.fx @@ -66,22 +66,16 @@ bool xor(bool a, bool b) //----------------------------------------------------------------------------- uniform float2 ScreenDims; // size of the window or fullscreen -uniform float2 ScreenRatio = float2(1.0f, 3.0f / 4.0f); // normalized screen ratio (defalt ratio of 4:3) - uniform float2 SourceDims; // size of the texture in power-of-two size -uniform float2 SourceRect; // size of the uv rectangle - -uniform float2 TargetDims; // size of target +uniform float2 TargetDims; // size of the target surface uniform float2 ShadowDims = float2(32.0f, 32.0f); // size of the shadow texture (extended to power-of-two size) uniform float2 ShadowUVOffset = float2(0.0f, 0.0f); -uniform float2 Prescale = float2(8.0f, 8.0f); - uniform bool OrientationSwapXY = false; // false landscape, true portrait for default screen orientation uniform bool RotationSwapXY = false; // swapped default screen orientation due to screen rotation -uniform bool PrepareBloom = false; // disables some effects for rendering bloom textures +uniform bool PrepareBloom = false; // disables some effects for rendering bloom textures uniform bool PrepareVector = false; VS_OUTPUT vs_main(VS_INPUT Input) @@ -93,12 +87,11 @@ VS_OUTPUT vs_main(VS_INPUT Input) ? shadowUVOffset.yx : shadowUVOffset.xy; - // todo: calculate offset - float2 ScreenCoordPrescaleOffset = 0.0f; - ScreenCoordPrescaleOffset += shadowUVOffset; + float2 ScreenCoordOffset = 0.0f; + ScreenCoordOffset += shadowUVOffset; Output.ScreenCoord = Input.Position.xy; - Output.ScreenCoord += ScreenCoordPrescaleOffset; + Output.ScreenCoord += ScreenCoordOffset; Output.Position = float4(Input.Position.xyz, 1.0f); Output.Position.xy /= ScreenDims; @@ -108,7 +101,8 @@ VS_OUTPUT vs_main(VS_INPUT Input) Output.TexCoord = PrepareVector ? Input.Position.xy / ScreenDims - : Input.TexCoord; // + 0.5f / TargetDims; + : Input.TexCoord; + Output.TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9) Output.Color = Input.Color; @@ -126,11 +120,6 @@ uniform float ScanlineBrightOffset = 1.0f; uniform float ScanlineOffset = 1.0f; uniform float ScanlineHeight = 1.0f; -uniform float CurvatureAmount = 0.0f; -uniform float RoundCornerAmount = 0.0f; -uniform float VignettingAmount = 0.0f; -uniform float ReflectionAmount = 0.0f; - uniform float ShadowAlpha = 0.0f; uniform float2 ShadowCount = float2(6.0f, 6.0f); uniform float2 ShadowUV = float2(0.25f, 0.25f); @@ -138,198 +127,18 @@ uniform float2 ShadowUV = float2(0.25f, 0.25f); uniform float3 Power = float3(1.0f, 1.0f, 1.0f); uniform float3 Floor = float3(0.0f, 0.0f, 0.0f); -static const float Epsilon = 1.0e-7f; static const float PI = 3.1415927f; -static const float E = 2.7182817f; -static const float Gelfond = 23.140692f; // e^pi (Gelfond constant) -static const float GelfondSchneider = 2.6651442f; // 2^sqrt(2) (Gelfond-Schneider constant) - -float nextPowerOfTwo(float n) -{ - return pow(2, floor(log2(n) / log2(2)) + 1); -} - -// www.stackoverflow.com/questions/5149544/can-i-generate-a-random-number-inside-a-pixel-shader/ -float random(float2 seed) -{ - // irrationals for pseudo randomness - float2 i = float2(Gelfond, GelfondSchneider); - - return frac(cos(dot(seed, i)) * 123456.0f); -} - -// www.dinodini.wordpress.com/2010/04/05/normalized-tunable-sigmoid-functions/ -float normalizedSigmoid(float n, float k) -{ - // valid for n and k in range of -1.0 and 1.0 - return (n - n * k) / (k - abs(n) * 2.0f * k + 1); -} - -float GetNoiseFactor(float n, float random) -{ - // smaller n become more noisy - return 1.0f + random * max(0.0f, 0.25f * pow(E, -4 * n)); -} - -float GetVignetteFactor(float2 coord, float amount) -{ - float2 VignetteCoord = coord; - - float VignetteLength = length(VignetteCoord); - float VignetteBlur = (amount * 0.75f) + 0.25; - - // 0.5 full screen fitting circle - float VignetteRadius = 1.0f - (amount * 0.25f); - float Vignette = smoothstep(VignetteRadius, VignetteRadius - VignetteBlur, VignetteLength); - - return saturate(Vignette); -} - -float GetSpotAddend(float2 coord, float amount) -{ - float2 SpotCoord = coord; - SpotCoord += OrientationSwapXY - ? float2(-0.25f, -0.25f) * ScreenRatio // upper right quadrant - : float2(-0.25f, 0.25f) * ScreenRatio; // upper right quadrant - - float SpotBlur = amount; - - // 0.5 full screen fitting circle - float SpotRadius = amount * 0.75f; - float Spot = smoothstep(SpotRadius, SpotRadius - SpotBlur, length(SpotCoord)); - - float SigmoidSpot = normalizedSigmoid(Spot, 0.75) * amount; - - // increase strength by 100% - SigmoidSpot = SigmoidSpot * 2.0f; - - return saturate(SigmoidSpot); -} - -// www.iquilezles.org/www/articles/distfunctions/distfunctions.htm -float RoundBox(float2 p, float2 b, float r) -{ - return length(max(abs(p) - b + r, 0.0f)) - r; -} - -float GetRoundCornerFactor(float2 coord, float amount) -{ - // hint: vector target area is always quadratic - float2 UsedSourceRect = PrepareVector - ? float2(1.0f, 1.0f) - : SourceRect; - float2 SourceArea = 1.0f / UsedSourceRect; - float2 SourceDimsArea = SourceDims * UsedSourceRect; - float2 SourceRatio = float2(1.0f, SourceDimsArea.y / SourceDimsArea.x); - float2 SourceTexelDims = 1.0f / SourceDims; - - // base on the default ratio of 4:3 - float2 RoundCoordScale = (SourceDims / SourceArea / SourceRatio) * ScreenRatio; - - float2 RoundCoord = coord; - // hint: alignment correction - RoundCoord -= SourceTexelDims * SourceArea; - RoundCoord *= SourceTexelDims * SourceArea + 1.0f; - // hint: roundness correction - RoundCoord *= RoundCoordScale; - - float radius = amount * 50.0f; - - // compute box (base on the default ratio of 4:3) - float box = RoundBox(RoundCoord.xy, (RoundCoordScale * 0.5f), radius); - - // // apply blur - // float blurAmount = 1.0f / max(1.0f, amount * 25.0f); - // float blueOffset = 1.0f - pow(blurAmount * 0.5f, 0.5f); - // box *= blurAmount; - // box += blueOffset; - - float border = smoothstep(1.0f, 0.5f, box); - - return saturate(border); -} float4 ps_main(PS_INPUT Input) : COLOR { float2 ScreenTexelDims = 1.0f / ScreenDims; - float2 SourceTexelDims = 1.0f / SourceDims; - - // hint: vector target area is always quadratic - float2 UsedSourceRect = PrepareVector - ? float2(1.0f, 1.0f) - : SourceRect; - float UsedCurvatureAmount = CurvatureAmount * 0.25f; // reduced curvature - - float2 SourceArea = 1.0f / UsedSourceRect; - float2 DoubleSourceArea = SourceArea * 2.0f; - float SquareSourceAreaLength = pow(length(SourceArea), 2.0f); - float2 HalfSourceRect = UsedSourceRect * 0.5f; - - // Screen Curvature - float2 CurvatureUnitCoord = (Input.TexCoord * DoubleSourceArea) - 1.0f; - float2 CurvatureFactor = (1.0 / SquareSourceAreaLength) * UsedCurvatureAmount; - float2 CurvatureCurve = CurvatureUnitCoord * pow(length(CurvatureUnitCoord), 2.0f) * CurvatureFactor; - float2 CurvatureZoom = 1.0f - (DoubleSourceArea * CurvatureFactor); - - // todo: vector cuverture requires a correction on y-axis if screen and target size differ and y > x float2 ScreenCoord = Input.ScreenCoord / ScreenDims; - ScreenCoord -= HalfSourceRect; - ScreenCoord *= CurvatureZoom; // zoom - ScreenCoord += HalfSourceRect; - ScreenCoord += CurvatureCurve; // distortion - float2 BaseCoord = Input.TexCoord; - BaseCoord -= HalfSourceRect; - BaseCoord *= CurvatureZoom; // zoom - BaseCoord += HalfSourceRect; - BaseCoord += CurvatureCurve; // distortion - - float2 CurvatureCorrection = 1.0f; - - // vector cuverture correction - if (PrepareVector) - { - float ScreenRatio = ScreenDims.x / ScreenDims.y; - float TargetRatio = TargetDims.x / TargetDims.y; - - // hint: vector cuverture requires a correction on the x-axis by the amount that screen and target size differ - CurvatureCorrection.x += - (ScreenRatio / TargetRatio - 1.0f) - * (1.0f + SquareSourceAreaLength * UsedCurvatureAmount); - } - - // the floowing coordinates are used for effects - float2 BaseCoordCentered = Input.TexCoord; - BaseCoordCentered -= HalfSourceRect; - BaseCoordCentered *= CurvatureZoom * CurvatureCorrection; // zoom - BaseCoordCentered += CurvatureCurve * CurvatureCorrection; // distortion - - float2 BaseAreaCoord = BaseCoord; - BaseAreaCoord *= SourceArea; - - float2 BaseAreaCoordCentered = BaseCoordCentered; - BaseAreaCoordCentered *= SourceArea; - - float2 BaseAreaRatioCoord = BaseAreaCoord; - BaseAreaRatioCoord *= ScreenRatio; - - float2 BaseAreaRatioCoordCentered = BaseAreaCoordCentered; - BaseAreaRatioCoordCentered *= ScreenRatio; - - // // Alpha Clipping (round corners applies smoother clipping when screen is curved) - // clip((BaseCoord < SourceTexelDims) ? -1 : 1); - // clip((BaseCoord > SourceRect + SourceTexelDims) ? -1 : 1); + // Color float4 BaseColor = tex2D(DiffuseSampler, BaseCoord); BaseColor.a = 1.0f; - // BaseColor.rgb = 1.0f; - - // Vignetting Simulation (may affect bloom) - float2 VignetteCoord = BaseAreaCoordCentered; - - float VignetteFactor = GetVignetteFactor(VignetteCoord, VignettingAmount); - BaseColor.rgb *= VignetteFactor; // Mask Simulation (may not affect bloom) if (!PrepareBloom) @@ -387,15 +196,16 @@ float4 ps_main(PS_INPUT Input) : COLOR // Scanline Simulation (may not affect bloom) if (!PrepareBloom) { - // todo: there is an offset which can be noticed at lower prescale in high-resolution - float2 ScanlinePrescaleOffset = 0.0f; - - float InnerSine = BaseCoord.y * ScanlineScale * SourceDims.y; - float ScanJitter = ScanlineOffset * SourceDims.y; - float ScanBrightMod = sin(InnerSine * PI + ScanJitter + ScanlinePrescaleOffset); - float3 ScanColor = lerp(1.0f, (pow(ScanBrightMod * ScanBrightMod, ScanlineHeight) * ScanlineBrightScale + 1.0f + ScanlineBrightOffset) * 0.5f, ScanlineAlpha); - - BaseColor.rgb *= ScanColor; + // Scanline Simulation (disabled for vector) + if (!PrepareVector) + { + float InnerSine = BaseCoord.y * ScanlineScale * SourceDims.y; + float ScanJitter = ScanlineOffset * SourceDims.y; + float ScanBrightMod = sin(InnerSine * PI + ScanJitter); + float3 ScanColor = lerp(1.0f, (pow(ScanBrightMod * ScanBrightMod, ScanlineHeight) * ScanlineBrightScale + 1.0f + ScanlineBrightOffset) * 0.5f, ScanlineAlpha); + + BaseColor.rgb *= ScanColor; + } } // Output @@ -404,25 +214,6 @@ float4 ps_main(PS_INPUT Input) : COLOR : BaseColor * Input.Color; Output.a = 1.0f; - // Light Reflection Simulation (may not affect bloom) - if (!PrepareBloom) - { - float3 LightColor = float3(1.0f, 0.90f, 0.80f); - - float2 SpotCoord = BaseAreaRatioCoordCentered; - float2 NoiseCoord = BaseAreaRatioCoordCentered; - - float SpotAddend = GetSpotAddend(SpotCoord, ReflectionAmount); - float NoiseFactor = GetNoiseFactor(SpotAddend, random(NoiseCoord)); - Output.rgb += SpotAddend * NoiseFactor * LightColor; - } - - // Round Corners Simulation (may affect bloom) - float2 RoundCornerCoord = BaseAreaCoordCentered; - - float roundCornerFactor = GetRoundCornerFactor(RoundCornerCoord, RoundCornerAmount); - Output.rgb *= roundCornerFactor; - return Output; } @@ -436,7 +227,7 @@ technique ScanMaskTechnique { Lighting = FALSE; - //Sampler[0] = <DiffuseSampler>; + Sampler[0] = <DiffuseSampler>; VertexShader = compile vs_3_0 vs_main(); PixelShader = compile ps_3_0 ps_main(); diff --git a/hlsl/primary.fx b/hlsl/primary.fx index da9abf028be..130c1cd4706 100644 --- a/hlsl/primary.fx +++ b/hlsl/primary.fx @@ -45,24 +45,33 @@ struct PS_INPUT // Simple Vertex Shader //----------------------------------------------------------------------------- +static const float Epsilon = 1.0e-7f; + uniform float2 ScreenDims; +uniform float2 TargetDims; uniform bool PostPass; + uniform float Brighten; VS_OUTPUT vs_main(VS_INPUT Input) { VS_OUTPUT Output = (VS_OUTPUT)0; - + Output.Position = float4(Input.Position.xyz, 1.0f); Output.Position.xy /= ScreenDims; Output.Position.y = 1.0f - Output.Position.y; // flip y Output.Position.xy -= 0.5f; // center Output.Position.xy *= 2.0f; // zoom - Output.TexCoord = PostPass + float2 targetDims = TargetDims + Epsilon; // bug: with exact target dimensions the font disappears + + Output.TexCoord = PostPass ? Input.Position.xy / ScreenDims : Input.TexCoord; + Output.TexCoord += PostPass + ? 0.5f / targetDims // half texel offset correction (DX9) + : 0.0f; Output.Color = Input.Color; @@ -76,7 +85,9 @@ VS_OUTPUT vs_main(VS_INPUT Input) float4 ps_main(PS_INPUT Input) : COLOR { float4 BaseTexel = tex2D(DiffuseSampler, Input.TexCoord); - return BaseTexel * (Input.Color + float4(Brighten, Brighten, Brighten, 0.0f)); + BaseTexel *= Input.Color + float4(Brighten, Brighten, Brighten, 0.0f); + + return BaseTexel; } //----------------------------------------------------------------------------- diff --git a/src/emu/render.h b/src/emu/render.h index 8598a565be2..3c3a100a987 100644 --- a/src/emu/render.h +++ b/src/emu/render.h @@ -605,6 +605,7 @@ public: float max_update_rate() const { return m_max_refresh; } int orientation() const { return m_orientation; } render_layer_config layer_config() const { return m_layerconfig; } + layout_view *current_view() const { return m_curview; } int view() const { return view_index(*m_curview); } bool hidden() const { return ((m_flags & RENDER_CREATE_HIDDEN) != 0); } bool is_ui_target() const; diff --git a/src/emu/rendlay.h b/src/emu/rendlay.h index 068fc5cfec0..966e3d2b901 100644 --- a/src/emu/rendlay.h +++ b/src/emu/rendlay.h @@ -235,6 +235,8 @@ public: layout_view *next() const { return m_next; } item *first_item(item_layer layer) const; const char *name() const { return m_name.c_str(); } + const render_bounds &bounds() const { return m_bounds; } + const render_bounds &screen_bounds() const { return m_scrbounds; } const render_screen_list &screens() const { return m_screens; } bool layer_enabled(item_layer layer) const { return m_layenabled[layer]; } diff --git a/src/osd/modules/render/d3d/d3dhlsl.c b/src/osd/modules/render/d3d/d3dhlsl.c index 4fd6403fb15..f32f618e9ee 100644 --- a/src/osd/modules/render/d3d/d3dhlsl.c +++ b/src/osd/modules/render/d3d/d3dhlsl.c @@ -989,6 +989,7 @@ int shaders::create_resources(bool reset) default_effect = new effect(this, d3d->get_device(), "primary.fx", fx_dir); post_effect = new effect(this, d3d->get_device(), "post.fx", fx_dir); + distortion_effect = new effect(this, d3d->get_device(), "distortion.fx", fx_dir); prescale_effect = new effect(this, d3d->get_device(), "prescale.fx", fx_dir); phosphor_effect = new effect(this, d3d->get_device(), "phosphor.fx", fx_dir); focus_effect = new effect(this, d3d->get_device(), "focus.fx", fx_dir); @@ -1002,6 +1003,7 @@ int shaders::create_resources(bool reset) if (!default_effect->is_valid() || !post_effect->is_valid() || + !distortion_effect->is_valid() || !prescale_effect->is_valid() || !phosphor_effect->is_valid() || !focus_effect->is_valid() || @@ -1076,15 +1078,11 @@ int shaders::create_resources(bool reset) downsample_effect->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS); bloom_effect->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS); + bloom_effect->add_uniform("TargetDims", uniform::UT_VEC2, uniform::CU_TARGET_DIMS); post_effect->add_uniform("SourceDims", uniform::UT_VEC2, uniform::CU_SOURCE_DIMS); - post_effect->add_uniform("SourceRect", uniform::UT_VEC2, uniform::CU_SOURCE_RECT); post_effect->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS); - - post_effect->add_uniform("VignettingAmount", uniform::UT_FLOAT, uniform::CU_POST_VIGNETTING); - post_effect->add_uniform("CurvatureAmount", uniform::UT_FLOAT, uniform::CU_POST_CURVATURE); - post_effect->add_uniform("RoundCornerAmount", uniform::UT_FLOAT, uniform::CU_POST_ROUND_CORNER); - post_effect->add_uniform("ReflectionAmount", uniform::UT_FLOAT, uniform::CU_POST_REFLECTION); + post_effect->add_uniform("TargetDims", uniform::UT_VEC2, uniform::CU_TARGET_DIMS); post_effect->add_uniform("ShadowAlpha", uniform::UT_FLOAT, uniform::CU_POST_SHADOW_ALPHA); post_effect->add_uniform("ShadowCount", uniform::UT_VEC2, uniform::CU_POST_SHADOW_COUNT); @@ -1100,9 +1098,19 @@ int shaders::create_resources(bool reset) post_effect->add_uniform("Power", uniform::UT_VEC3, uniform::CU_POST_POWER); post_effect->add_uniform("Floor", uniform::UT_VEC3, uniform::CU_POST_FLOOR); + distortion_effect->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS); + distortion_effect->add_uniform("TargetDims", uniform::UT_VEC2, uniform::CU_TARGET_DIMS); + distortion_effect->add_uniform("QuadDims", uniform::UT_VEC2, uniform::CU_QUAD_DIMS); + + distortion_effect->add_uniform("VignettingAmount", uniform::UT_FLOAT, uniform::CU_POST_VIGNETTING); + distortion_effect->add_uniform("CurvatureAmount", uniform::UT_FLOAT, uniform::CU_POST_CURVATURE); + distortion_effect->add_uniform("RoundCornerAmount", uniform::UT_FLOAT, uniform::CU_POST_ROUND_CORNER); + distortion_effect->add_uniform("ReflectionAmount", uniform::UT_FLOAT, uniform::CU_POST_REFLECTION); + vector_effect->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS); default_effect->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS); + default_effect->add_uniform("TargetDims", uniform::UT_VEC2, uniform::CU_TARGET_DIMS); initialized = true; @@ -1125,6 +1133,7 @@ void shaders::begin_draw() default_effect->set_technique("TestTechnique"); post_effect->set_technique("ScanMaskTechnique"); + distortion_effect->set_technique("DistortionTechnique"); phosphor_effect->set_technique("TestTechnique"); focus_effect->set_technique("TestTechnique"); deconverge_effect->set_technique("DeconvergeTechnique"); @@ -1187,14 +1196,14 @@ void shaders::blit( for (UINT pass = 0; pass < num_passes; pass++) { curr_effect->begin_pass(pass); - + // add the primitives result = (*d3dintf->device.draw_primitive)(d3d->get_device(), prim_type, prim_index, prim_count); - if (result != D3D_OK) + if (result != D3D_OK) { osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result); } - + curr_effect->end_pass(); } @@ -1311,7 +1320,7 @@ int shaders::ntsc_pass(render_target *rt, int source_index, poly_info *poly, int // Convert our signal into YIQ curr_effect = yiq_encode_effect; curr_effect->update_uniforms(); - + // initial "Diffuse" texture is set in shaders::set_texture() next_index = rt->next_index(next_index); @@ -1325,7 +1334,7 @@ int shaders::ntsc_pass(render_target *rt, int source_index, poly_info *poly, int next_index = rt->next_index(next_index); blit(rt->native_target[next_index], true, D3DPT_TRIANGLELIST, 0, 2); - + color_effect->set_texture("Diffuse", rt->native_texture[next_index]); return next_index; @@ -1337,7 +1346,7 @@ int shaders::color_convolution_pass(render_target *rt, int source_index, poly_in curr_effect = color_effect; curr_effect->update_uniforms(); - + // initial "Diffuse" texture is set in shaders::set_texture() or the result of shaders::ntsc_pass() next_index = rt->next_index(next_index); @@ -1380,9 +1389,9 @@ int shaders::defocus_pass(render_target *rt, int source_index, poly_info *poly, float defocus_x = options->defocus[0]; float defocus_y = options->defocus[1]; - bool focus_enable = defocus_x != 0.0f || defocus_y != 0.0f; - if (!focus_enable) + // skip defocus if no influencing settings + if (defocus_x == 0.0f && defocus_y == 0.0f) { return next_index; } @@ -1409,7 +1418,7 @@ int shaders::phosphor_pass(render_target *rt, cache_target *ct, int source_index next_index = rt->next_index(next_index); blit(rt->prescale_target[next_index], true, D3DPT_TRIANGLELIST, 0, 2); - + // Pass along our phosphor'd screen curr_effect->update_uniforms(); curr_effect->set_texture("Diffuse", rt->prescale_texture[next_index]); @@ -1428,53 +1437,26 @@ int shaders::post_pass(render_target *rt, int source_index, poly_info *poly, int texture_info *texture = poly->get_texture(); - bool prepare_vector = + bool prepare_vector = PRIMFLAG_GET_VECTORBUF(poly->get_flags()) && vector_enable; - float prescale[2] = { - prepare_vector ? 1.0f : (float)hlsl_prescale_x, - prepare_vector ? 1.0f : (float)hlsl_prescale_y }; - float target_dims[2] = { - poly->get_prim_width(), - poly->get_prim_height() }; bool orientation_swap_xy = (d3d->window().machine().system().flags & ORIENTATION_SWAP_XY) == ORIENTATION_SWAP_XY; bool rotation_swap_xy = (d3d->window().target()->orientation() & ROT90) == ROT90 || (d3d->window().target()->orientation() & ROT270) == ROT270; - + curr_effect = post_effect; curr_effect->update_uniforms(); curr_effect->set_texture("ShadowTexture", shadow_texture == NULL ? NULL : shadow_texture->get_finaltex()); curr_effect->set_texture("DiffuseTexture", rt->prescale_texture[next_index]); curr_effect->set_float("ScanlineOffset", texture->get_cur_frame() == 0 ? 0.0f : options->scanline_offset); - curr_effect->set_vector("Prescale", 2, prescale); - curr_effect->set_vector("TargetDims", 2, target_dims); curr_effect->set_bool("OrientationSwapXY", orientation_swap_xy); curr_effect->set_bool("RotationSwapXY", rotation_swap_xy); curr_effect->set_bool("PrepareBloom", prepare_bloom); curr_effect->set_bool("PrepareVector", prepare_vector); - if (prepare_vector) - { - int texture_width = 0; - int texture_height = 0; - - texture_info::compute_size_subroutine(d3d->get_texture_manager(), (int)target_dims[0], (int)target_dims[1], &texture_width, &texture_height); - - float source_dims[2] = { (float)texture_width, (float)texture_height }; - float source_rect[2] = { target_dims[0] / texture_width , target_dims[1] / texture_height }; - - // override uniforms - curr_effect->set_vector("SourceDims", 2, source_dims); - curr_effect->set_vector("SourceRect", 2, source_rect); - } - - d3d->set_wrap(D3DTADDRESS_MIRROR); - next_index = rt->next_index(next_index); blit(prepare_bloom ? rt->native_target[next_index] : rt->prescale_target[next_index], true, poly->get_type(), vertnum, poly->get_count()); - - d3d->set_wrap(PRIMFLAG_GET_TEXWRAP(poly->get_texture()->get_flags()) ? D3DTADDRESS_WRAP : D3DTADDRESS_CLAMP); return next_index; } @@ -1483,35 +1465,45 @@ int shaders::downsample_pass(render_target *rt, int source_index, poly_info *pol { int next_index = source_index; - bool prepare_vector = + bool prepare_vector = PRIMFLAG_GET_VECTORBUF(poly->get_flags()) && vector_enable; - float prescale[2] = { - prepare_vector ? 1.0f : (float)hlsl_prescale_x, // no prescale for vector - prepare_vector ? 1.0f : (float)hlsl_prescale_y }; // full prescale for raster + float bloom_rescale = prepare_vector + ? options->vector_bloom_scale + : options->raster_bloom_scale; + + // skip downsample if no influencing settings + if (bloom_rescale == 0.0f) + { + return next_index; + } curr_effect = downsample_effect; curr_effect->update_uniforms(); - curr_effect->set_vector("Prescale", 2, prescale); + curr_effect->set_bool("PrepareVector", prepare_vector); - float bloom_size = (d3d->get_width() < d3d->get_height()) ? d3d->get_width() : d3d->get_height(); int bloom_index = 0; - float bloom_width = rt->target_width; - float bloom_height = rt->target_height; + float bloom_size = (d3d->get_width() < d3d->get_height()) ? d3d->get_width() : d3d->get_height(); + float bloom_width = prepare_vector ? rt->target_width : rt->target_width / hlsl_prescale_x; + float bloom_height = prepare_vector ? rt->target_height : rt->target_height / hlsl_prescale_y; for (; bloom_size >= 2.0f && bloom_index < 11; bloom_size *= 0.5f) { - bloom_dims[bloom_index][0] = bloom_width; - bloom_dims[bloom_index][1] = bloom_height; + bloom_dims[bloom_index][0] = (float)(int)bloom_width; + bloom_dims[bloom_index][1] = (float)(int)bloom_height; - curr_effect->set_vector("TargetSize", 2, bloom_dims[bloom_index]); - curr_effect->set_texture("DiffuseTexture", (bloom_index == 0) ? rt->native_texture[next_index] : rt->bloom_texture[bloom_index - 1]); + curr_effect->set_vector("TargetDims", 2, bloom_dims[bloom_index]); + curr_effect->set_texture("DiffuseTexture", + bloom_index == 0 + ? rt->native_texture[next_index] + : rt->bloom_texture[bloom_index - 1]); blit(rt->bloom_target[bloom_index], true, poly->get_type(), vertnum, poly->get_count()); - bloom_index++; bloom_width *= 0.5f; bloom_height *= 0.5f; + + bloom_index++; } - + bloom_count = bloom_index; return next_index; @@ -1521,17 +1513,20 @@ int shaders::bloom_pass(render_target *rt, int source_index, poly_info *poly, in { int next_index = source_index; - bool prepare_vector = PRIMFLAG_GET_VECTORBUF(poly->get_flags()) && vector_enable; - float prescale[2] = { - prepare_vector ? 1.0f : (float)hlsl_prescale_x / 2.0f, // no prescale for vector - prepare_vector ? 1.0f : (float)hlsl_prescale_y / 2.0f }; // half prescale for raster + bool prepare_vector = + PRIMFLAG_GET_VECTORBUF(poly->get_flags()) && vector_enable; float bloom_rescale = prepare_vector - ? options->vector_bloom_scale + ? options->vector_bloom_scale : options->raster_bloom_scale; + // skip bloom if no influencing settings + if (bloom_rescale == 0.0f) + { + return next_index; + } + curr_effect = bloom_effect; curr_effect->update_uniforms(); - curr_effect->set_vector("Prescale", 2, prescale); float weight0123[4] = { options->bloom_level0_weight, @@ -1545,7 +1540,7 @@ int shaders::bloom_pass(render_target *rt, int source_index, poly_info *poly, in options->bloom_level6_weight * bloom_rescale, options->bloom_level7_weight * bloom_rescale }; - float weight89A[3] = { + float weight89A[3] = { options->bloom_level8_weight * bloom_rescale, options->bloom_level9_weight * bloom_rescale, options->bloom_level10_weight * bloom_rescale @@ -1580,8 +1575,102 @@ int shaders::bloom_pass(render_target *rt, int source_index, poly_info *poly, in return next_index; } +int shaders::distortion_pass(render_target *rt, int source_index, poly_info *poly, int vertnum) +{ + int next_index = source_index; + + int screen_count = d3d->window().target()->current_view()->screens().count(); + + // todo: currently only one screen is supported + if (screen_count > 1) + { + return next_index; + } + + render_bounds bounds = d3d->window().target()->current_view()->bounds(); + render_bounds screen_bounds = d3d->window().target()->current_view()->screen_bounds(); + + // todo: cuccently artworks are not supported + if (bounds.x0 != screen_bounds.x0 || + bounds.y0 != screen_bounds.y0 || + bounds.x1 != screen_bounds.x1 || + bounds.y1 != screen_bounds.y1) + { + return next_index; + } + + // skip distortion if no influencing settings + if (options->reflection == 0 && + options->vignetting == 0 && + options->curvature == 0 && + options->round_corner == 0) + { + return next_index; + } + + bool orientation_swap_xy = + (d3d->window().machine().system().flags & ORIENTATION_SWAP_XY) == ORIENTATION_SWAP_XY; + bool rotation_swap_xy = + (d3d->window().target()->orientation() & ROT90) == ROT90 || + (d3d->window().target()->orientation() & ROT270) == ROT270; + int rotation_type = + (d3d->window().target()->orientation() & ROT90) == ROT90 + ? 1 + : (d3d->window().target()->orientation() & ROT180) == ROT180 + ? 2 + : (d3d->window().target()->orientation() & ROT270) == ROT270 + ? 3 + : 0; + + curr_effect = distortion_effect; + curr_effect->update_uniforms(); + curr_effect->set_texture("DiffuseTexture", rt->prescale_texture[next_index]); + curr_effect->set_bool("OrientationSwapXY", orientation_swap_xy); + curr_effect->set_bool("RotationSwapXY", rotation_swap_xy); + curr_effect->set_int("RotationType", rotation_type); + + next_index = rt->next_index(next_index); + blit(rt->prescale_target[next_index], true, poly->get_type(), vertnum, poly->get_count()); + + return next_index; +} + +int shaders::vector_pass(render_target *rt, int source_index, poly_info *poly, int vertnum) +{ + int next_index = source_index; + + float time_params[2] = { 0.0f, 0.0f }; + float length_params[3] = { poly->get_line_length(), options->vector_length_scale, options->vector_length_ratio }; + + curr_effect = vector_effect; + curr_effect->update_uniforms(); + curr_effect->set_vector("TimeParams", 2, time_params); + curr_effect->set_vector("LengthParams", 3, length_params); + + blit(rt->prescale_target[next_index], true, poly->get_type(), vertnum, poly->get_count()); + + return next_index; +} + +int shaders::vector_buffer_pass(render_target *rt, int source_index, poly_info *poly, int vertnum) +{ + int next_index = source_index; + + curr_effect = default_effect; + curr_effect->update_uniforms(); + + curr_effect->set_texture("Diffuse", rt->prescale_texture[next_index]); + curr_effect->set_bool("PostPass", true); + curr_effect->set_float("Brighten", 1.0f); + + next_index = rt->next_index(next_index); + blit(rt->prescale_target[next_index], true, poly->get_type(), vertnum, poly->get_count()); + + return next_index; +} + int shaders::screen_pass(render_target *rt, int source_index, poly_info *poly, int vertnum) -{ +{ int next_index = source_index; bool prepare_vector = PRIMFLAG_GET_VECTORBUF(poly->get_flags()) && vector_enable; @@ -1611,6 +1700,16 @@ int shaders::screen_pass(render_target *rt, int source_index, poly_info *poly, i return next_index; } +void shaders::menu_pass(poly_info *poly, int vertnum) +{ + curr_effect = default_effect; + curr_effect->update_uniforms(); + curr_effect->set_bool("PostPass", false); + curr_effect->set_float("Brighten", 0.0f); + + blit(NULL, false, poly->get_type(), vertnum, poly->get_count()); +} + //============================================================ // shaders::render_quad @@ -1624,6 +1723,7 @@ void shaders::render_quad(poly_info *poly, int vertnum) } curr_texture = poly->get_texture(); + curr_poly = poly; if (PRIMFLAG_GET_SCREENTEX(d3d->get_last_texture_flags()) && curr_texture != NULL) { @@ -1657,8 +1757,12 @@ void shaders::render_quad(poly_info *poly, int vertnum) next_index = post_pass(rt, next_index, poly, vertnum, false); next_index = bloom_pass(rt, next_index, poly, vertnum); + next_index = distortion_pass(rt, next_index, poly, vertnum); + // render on screen + d3d->set_wrap(D3DTADDRESS_MIRROR); next_index = screen_pass(rt, next_index, poly, vertnum); + d3d->set_wrap(PRIMFLAG_GET_TEXWRAP(poly->get_texture()->get_flags()) ? D3DTADDRESS_WRAP : D3DTADDRESS_CLAMP); curr_texture->increment_frame_count(); curr_texture->mask_frame_count(options->yiq_phase_count); @@ -1679,15 +1783,7 @@ void shaders::render_quad(poly_info *poly, int vertnum) int next_index = 0; - float time_params[2] = { 0.0f, 0.0f }; - float length_params[3] = { poly->get_line_length(), options->vector_length_scale, options->vector_length_ratio }; - - curr_effect = vector_effect; - curr_effect->update_uniforms(); - curr_effect->set_vector("TimeParams", 2, time_params); - curr_effect->set_vector("LengthParams", 3, length_params); - - blit(rt->prescale_target[next_index], true, poly->get_type(), vertnum, poly->get_count()); + next_index = vector_pass(rt, next_index, poly, vertnum); HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, backbuffer); if (result != D3D_OK) @@ -1704,21 +1800,13 @@ void shaders::render_quad(poly_info *poly, int vertnum) { return; } - + cache_target *ct = find_cache_target(rt->screen_index, rt->width, rt->height); int next_index = 0; - curr_effect = default_effect; - curr_effect->update_uniforms(); - - curr_effect->set_texture("Diffuse", rt->prescale_texture[next_index]); - curr_effect->set_bool("PostPass", true); - curr_effect->set_float("Brighten", 1.0f); - - next_index = rt->next_index(next_index); - blit(rt->prescale_target[next_index], true, poly->get_type(), vertnum, poly->get_count()); - + next_index = vector_buffer_pass(rt, next_index, poly, vertnum); + next_index = defocus_pass(rt, next_index, poly, vertnum); next_index = phosphor_pass(rt, ct, next_index, poly, vertnum); // create bloom textures @@ -1731,6 +1819,8 @@ void shaders::render_quad(poly_info *poly, int vertnum) next_index = post_pass(rt, next_index, poly, vertnum, false); next_index = bloom_pass(rt, next_index, poly, vertnum); + next_index = distortion_pass(rt, next_index, poly, vertnum); + // render on screen next_index = screen_pass(rt, next_index, poly, vertnum); @@ -1744,16 +1834,12 @@ void shaders::render_quad(poly_info *poly, int vertnum) } else { - curr_effect = default_effect; - curr_effect->update_uniforms(); - curr_effect->set_bool("PostPass", false); - curr_effect->set_float("Brighten", 0.0f); - - blit(NULL, false, poly->get_type(), vertnum, poly->get_count()); + menu_pass(poly, vertnum); } curr_render_target = NULL; curr_texture = NULL; + curr_poly = NULL; } @@ -2040,6 +2126,11 @@ void shaders::delete_resources(bool reset) delete post_effect; post_effect = NULL; } + if (distortion_effect != NULL) + { + delete distortion_effect; + distortion_effect = NULL; + } if (prescale_effect != NULL) { delete prescale_effect; @@ -2151,9 +2242,9 @@ static void get_vector(const char *data, int count, float *out, int report_error /*------------------------------------------------- - slider_alloc - allocate a new slider entry - currently duplicated from ui.c, this could - be done in a more ideal way. + slider_alloc - allocate a new slider entry + currently duplicated from ui.c, this could + be done in a more ideal way. -------------------------------------------------*/ static slider_state *slider_alloc(running_machine &machine, const char *title, INT32 minval, INT32 defval, INT32 maxval, INT32 incval, slider_update update, void *arg) @@ -2187,7 +2278,7 @@ static INT32 slider_set(float *option, float scale, const char *fmt, std::string { strprintf(*str, fmt, *option); } - + return floor(*option / scale + 0.5f); } @@ -2202,13 +2293,13 @@ static INT32 slider_shadow_mask_x_count(running_machine &machine, void *arg, std if (newval != SLIDER_NOCHANGE) { options->shadow_mask_count_x = newval; - } + } if (str != NULL) { strprintf(*str, "%d", options->shadow_mask_count_x); } options->params_dirty = true; - + return options->shadow_mask_count_x; } @@ -2224,7 +2315,7 @@ static INT32 slider_shadow_mask_y_count(running_machine &machine, void *arg, std strprintf(*str, "%d", options->shadow_mask_count_y); } options->params_dirty = true; - + return options->shadow_mask_count_y; } @@ -2643,77 +2734,77 @@ static INT32 slider_bloom_lvl10_scale(running_machine &machine, void *arg, std:: shaders::slider_desc shaders::s_sliders[] = { - { "Shadow Mask Darkness", 0, 0, 100, 1, slider_shadow_mask_alpha }, - { "Shadow Mask X Count", 1, 6, 1024, 1, slider_shadow_mask_x_count }, - { "Shadow Mask Y Count", 1, 6, 1024, 1, slider_shadow_mask_y_count }, - { "Shadow Mask Pixel Count X", 1, 6, 64, 1, slider_shadow_mask_usize }, - { "Shadow Mask Pixel Count Y", 1, 6, 64, 1, slider_shadow_mask_vsize }, - { "Shadow Mask Offset X", -100, 0, 100, 1, slider_shadow_mask_uoffset }, - { "Shadow Mask Offset Y", -100, 0, 100, 1, slider_shadow_mask_voffset }, - { "Screen Curvature", 0, 3, 100, 1, slider_curvature }, - { "Screen Round Corner", 0, 3, 100, 1, slider_round_corner }, - { "Screen Reflection", 0, 3, 100, 1, slider_reflection }, - { "Image Vignetting", 0, 3, 100, 1, slider_vignetting }, - { "Scanline Darkness", 0, 100, 100, 1, slider_scanline_alpha }, - { "Scanline Screen Height", 1, 20, 80, 1, slider_scanline_scale }, - { "Scanline Indiv. Height", 1, 20, 80, 1, slider_scanline_height }, - { "Scanline Brightness", 0, 20, 40, 1, slider_scanline_bright_scale }, - { "Scanline Brightness Overdrive", 0, 0, 20, 1, slider_scanline_bright_offset }, - { "Scanline Jitter", 0, 0, 40, 1, slider_scanline_offset }, - { "Defocus X", 0, 0, 64, 1, slider_defocus_x }, - { "Defocus Y", 0, 0, 64, 1, slider_defocus_y }, - { "Red Position Offset X", -1500, 3, 1500, 1, slider_red_converge_x }, - { "Red Position Offset Y", -1500, 0, 1500, 1, slider_red_converge_y }, - { "Green Position Offset X", -1500, 0, 1500, 1, slider_green_converge_x }, - { "Green Position Offset Y", -1500, 3, 1500, 1, slider_green_converge_y }, - { "Blue Position Offset X", -1500, 3, 1500, 1, slider_blue_converge_x }, - { "Blue Position Offset Y", -1500, 3, 1500, 1, slider_blue_converge_y }, - { "Red Convergence X", -1500, 0, 1500, 1, slider_red_radial_converge_x }, - { "Red Convergence Y", -1500, 0, 1500, 1, slider_red_radial_converge_y }, - { "Green Convergence X", -1500, 0, 1500, 1, slider_green_radial_converge_x }, - { "Green Convergence Y", -1500, 0, 1500, 1, slider_green_radial_converge_y }, - { "Blue Convergence X", -1500, 0, 1500, 1, slider_blue_radial_converge_x }, - { "Blue Convergence Y", -1500, 0, 1500, 1, slider_blue_radial_converge_y }, - { "Red Output from Red Input", -400, 0, 400, 5, slider_red_from_r }, - { "Red Output from Green Input", -400, 0, 400, 5, slider_red_from_g }, - { "Red Output from Blue Input", -400, 0, 400, 5, slider_red_from_b }, - { "Green Output from Red Input", -400, 0, 400, 5, slider_green_from_r }, - { "Green Output from Green Input", -400, 0, 400, 5, slider_green_from_g }, - { "Green Output from Blue Input", -400, 0, 400, 5, slider_green_from_b }, - { "Blue Output from Red Input", -400, 0, 400, 5, slider_blue_from_r }, - { "Blue Output from Green Input", -400, 0, 400, 5, slider_blue_from_g }, - { "Blue Output from Blue Input", -400, 0, 400, 5, slider_blue_from_b }, - { "Saturation", 0, 140, 400, 1, slider_saturation }, - { "Red DC Offset", -100, 0, 100, 1, slider_red_offset }, - { "Green DC Offset", -100, 0, 100, 1, slider_green_offset }, - { "Blue DC Offset", -100, 0, 100, 1, slider_blue_offset }, - { "Red Scale", -200, 95, 200, 1, slider_red_scale }, - { "Green Scale", -200, 95, 200, 1, slider_green_scale }, - { "Blue Scale", -200, 95, 200, 1, slider_blue_scale }, - { "Red Gamma", -80, 16, 80, 1, slider_red_power }, - { "Green Gamma", -80, 16, 80, 1, slider_green_power }, - { "Blue Gamma", -80, 16, 80, 1, slider_blue_power }, - { "Red Floor", 0, 5, 100, 1, slider_red_floor }, - { "Green Floor", 0, 5, 100, 1, slider_green_floor }, - { "Blue Floor", 0, 5, 100, 1, slider_blue_floor }, - { "Red Phosphor Life", 0, 40, 100, 1, slider_red_phosphor_life }, - { "Green Phosphor Life", 0, 40, 100, 1, slider_green_phosphor_life }, - { "Blue Phosphor Life", 0, 40, 100, 1, slider_blue_phosphor_life }, - { "Vector Length Attenuation", 0, 80, 100, 1, slider_vector_attenuation }, - { "Vector Attenuation Length Limit", 1, 500, 1000, 1, slider_vector_length_max }, - { "Vector Bloom Scale", 0, 300, 1000, 5, slider_vector_bloom_scale }, - { "Raster Bloom Scale", 0, 225, 1000, 5, slider_raster_bloom_scale }, - { "Bloom Level 0 Scale", 0, 100, 100, 1, slider_bloom_lvl0_scale }, - { "Bloom Level 1 Scale", 0, 21, 100, 1, slider_bloom_lvl1_scale }, - { "Bloom Level 2 Scale", 0, 19, 100, 1, slider_bloom_lvl2_scale }, - { "Bloom Level 3 Scale", 0, 17, 100, 1, slider_bloom_lvl3_scale }, - { "Bloom Level 4 Scale", 0, 15, 100, 1, slider_bloom_lvl4_scale }, - { "Bloom Level 5 Scale", 0, 14, 100, 1, slider_bloom_lvl5_scale }, - { "Bloom Level 6 Scale", 0, 13, 100, 1, slider_bloom_lvl6_scale }, - { "Bloom Level 7 Scale", 0, 12, 100, 1, slider_bloom_lvl7_scale }, - { "Bloom Level 8 Scale", 0, 11, 100, 1, slider_bloom_lvl8_scale }, - { "Bloom Level 9 Scale", 0, 10, 100, 1, slider_bloom_lvl9_scale }, - { "Bloom Level 10 Scale", 0, 9, 100, 1, slider_bloom_lvl10_scale }, + { "Shadow Mask Darkness", 0, 0, 100, 1, slider_shadow_mask_alpha }, + { "Shadow Mask X Count", 1, 6, 1024, 1, slider_shadow_mask_x_count }, + { "Shadow Mask Y Count", 1, 6, 1024, 1, slider_shadow_mask_y_count }, + { "Shadow Mask Pixel Count X", 1, 6, 64, 1, slider_shadow_mask_usize }, + { "Shadow Mask Pixel Count Y", 1, 6, 64, 1, slider_shadow_mask_vsize }, + { "Shadow Mask Offset X", -100, 0, 100, 1, slider_shadow_mask_uoffset }, + { "Shadow Mask Offset Y", -100, 0, 100, 1, slider_shadow_mask_voffset }, + { "Screen Curvature", 0, 3, 100, 1, slider_curvature }, + { "Screen Round Corner", 0, 3, 100, 1, slider_round_corner }, + { "Screen Reflection", 0, 3, 100, 1, slider_reflection }, + { "Image Vignetting", 0, 3, 100, 1, slider_vignetting }, + { "Scanline Darkness", 0, 100, 100, 1, slider_scanline_alpha }, + { "Scanline Screen Height", 1, 20, 80, 1, slider_scanline_scale }, + { "Scanline Indiv. Height", 1, 20, 80, 1, slider_scanline_height }, + { "Scanline Brightness", 0, 20, 40, 1, slider_scanline_bright_scale }, + { "Scanline Brightness Overdrive", 0, 0, 20, 1, slider_scanline_bright_offset }, + { "Scanline Jitter", 0, 0, 40, 1, slider_scanline_offset }, + { "Defocus X", 0, 0, 64, 1, slider_defocus_x }, + { "Defocus Y", 0, 0, 64, 1, slider_defocus_y }, + { "Red Position Offset X", -1500, 3, 1500, 1, slider_red_converge_x }, + { "Red Position Offset Y", -1500, 0, 1500, 1, slider_red_converge_y }, + { "Green Position Offset X", -1500, 0, 1500, 1, slider_green_converge_x }, + { "Green Position Offset Y", -1500, 3, 1500, 1, slider_green_converge_y }, + { "Blue Position Offset X", -1500, 3, 1500, 1, slider_blue_converge_x }, + { "Blue Position Offset Y", -1500, 3, 1500, 1, slider_blue_converge_y }, + { "Red Convergence X", -1500, 0, 1500, 1, slider_red_radial_converge_x }, + { "Red Convergence Y", -1500, 0, 1500, 1, slider_red_radial_converge_y }, + { "Green Convergence X", -1500, 0, 1500, 1, slider_green_radial_converge_x }, + { "Green Convergence Y", -1500, 0, 1500, 1, slider_green_radial_converge_y }, + { "Blue Convergence X", -1500, 0, 1500, 1, slider_blue_radial_converge_x }, + { "Blue Convergence Y", -1500, 0, 1500, 1, slider_blue_radial_converge_y }, + { "Red Output from Red Input", -400, 0, 400, 5, slider_red_from_r }, + { "Red Output from Green Input", -400, 0, 400, 5, slider_red_from_g }, + { "Red Output from Blue Input", -400, 0, 400, 5, slider_red_from_b }, + { "Green Output from Red Input", -400, 0, 400, 5, slider_green_from_r }, + { "Green Output from Green Input", -400, 0, 400, 5, slider_green_from_g }, + { "Green Output from Blue Input", -400, 0, 400, 5, slider_green_from_b }, + { "Blue Output from Red Input", -400, 0, 400, 5, slider_blue_from_r }, + { "Blue Output from Green Input", -400, 0, 400, 5, slider_blue_from_g }, + { "Blue Output from Blue Input", -400, 0, 400, 5, slider_blue_from_b }, + { "Saturation", 0, 140, 400, 1, slider_saturation }, + { "Red DC Offset", -100, 0, 100, 1, slider_red_offset }, + { "Green DC Offset", -100, 0, 100, 1, slider_green_offset }, + { "Blue DC Offset", -100, 0, 100, 1, slider_blue_offset }, + { "Red Scale", -200, 95, 200, 1, slider_red_scale }, + { "Green Scale", -200, 95, 200, 1, slider_green_scale }, + { "Blue Scale", -200, 95, 200, 1, slider_blue_scale }, + { "Red Gamma", -80, 16, 80, 1, slider_red_power }, + { "Green Gamma", -80, 16, 80, 1, slider_green_power }, + { "Blue Gamma", -80, 16, 80, 1, slider_blue_power }, + { "Red Floor", 0, 5, 100, 1, slider_red_floor }, + { "Green Floor", 0, 5, 100, 1, slider_green_floor }, + { "Blue Floor", 0, 5, 100, 1, slider_blue_floor }, + { "Red Phosphor Life", 0, 40, 100, 1, slider_red_phosphor_life }, + { "Green Phosphor Life", 0, 40, 100, 1, slider_green_phosphor_life }, + { "Blue Phosphor Life", 0, 40, 100, 1, slider_blue_phosphor_life }, + { "Vector Length Attenuation", 0, 80, 100, 1, slider_vector_attenuation }, + { "Vector Attenuation Length Limit", 1, 500, 1000, 1, slider_vector_length_max }, + { "Vector Bloom Scale", 0, 300, 1000, 5, slider_vector_bloom_scale }, + { "Raster Bloom Scale", 0, 225, 1000, 5, slider_raster_bloom_scale }, + { "Bloom Level 0 Scale", 0, 100, 100, 1, slider_bloom_lvl0_scale }, + { "Bloom Level 1 Scale", 0, 21, 100, 1, slider_bloom_lvl1_scale }, + { "Bloom Level 2 Scale", 0, 19, 100, 1, slider_bloom_lvl2_scale }, + { "Bloom Level 3 Scale", 0, 17, 100, 1, slider_bloom_lvl3_scale }, + { "Bloom Level 4 Scale", 0, 15, 100, 1, slider_bloom_lvl4_scale }, + { "Bloom Level 5 Scale", 0, 14, 100, 1, slider_bloom_lvl5_scale }, + { "Bloom Level 6 Scale", 0, 13, 100, 1, slider_bloom_lvl6_scale }, + { "Bloom Level 7 Scale", 0, 12, 100, 1, slider_bloom_lvl7_scale }, + { "Bloom Level 8 Scale", 0, 11, 100, 1, slider_bloom_lvl8_scale }, + { "Bloom Level 9 Scale", 0, 10, 100, 1, slider_bloom_lvl9_scale }, + { "Bloom Level 10 Scale", 0, 9, 100, 1, slider_bloom_lvl10_scale }, { NULL, 0, 0, 0, 0, NULL }, }; @@ -2816,8 +2907,22 @@ void uniform::update() } case CU_TARGET_DIMS: { - float rtsize[2] = { shadersys->curr_render_target->target_width, shadersys->curr_render_target->target_height }; - m_shader->set_vector("TargetDims", 2, rtsize); + if (shadersys->curr_render_target == NULL) + { + float targetdims[2] = { 0.0f, 0.0f }; + m_shader->set_vector("TargetDims", 2, targetdims); + } + else + { + float targetdims[2] = { shadersys->curr_render_target->target_width, shadersys->curr_render_target->target_height }; + m_shader->set_vector("TargetDims", 2, targetdims); + } + break; + } + case CU_QUAD_DIMS: + { + float quaddims[2] = { shadersys->curr_poly->get_prim_width(), shadersys->curr_poly->get_prim_height() }; + m_shader->set_vector("QuadDims", 2, quaddims); break; } diff --git a/src/osd/modules/render/d3d/d3dhlsl.h b/src/osd/modules/render/d3d/d3dhlsl.h index 01346371310..9c6fbaec5eb 100644 --- a/src/osd/modules/render/d3d/d3dhlsl.h +++ b/src/osd/modules/render/d3d/d3dhlsl.h @@ -45,6 +45,7 @@ public: CU_SOURCE_DIMS, CU_SOURCE_RECT, CU_TARGET_DIMS, + CU_QUAD_DIMS, CU_NTSC_CCFREQ, CU_NTSC_A, @@ -337,7 +338,11 @@ private: int post_pass(render_target *rt, int source_index, poly_info *poly, int vertnum, bool prepare_bloom); int downsample_pass(render_target *rt, int source_index, poly_info *poly, int vertnum); int bloom_pass(render_target *rt, int source_index, poly_info *poly, int vertnum); + int distortion_pass(render_target *rt, int source_index, poly_info *poly, int vertnum); + int vector_pass(render_target *rt, int source_index, poly_info *poly, int vertnum); + int vector_buffer_pass(render_target *rt, int source_index, poly_info *poly, int vertnum); int screen_pass(render_target *rt, int source_index, poly_info *poly, int vertnum); + void menu_pass(poly_info *poly, int vertnum); base * d3dintf; // D3D interface @@ -400,6 +405,7 @@ private: effect * default_effect; // pointer to the primary-effect object effect * prescale_effect; // pointer to the prescale-effect object effect * post_effect; // pointer to the post-effect object + effect * distortion_effect; // pointer to the distortion-effect object effect * focus_effect; // pointer to the focus-effect object effect * phosphor_effect; // pointer to the phosphor-effect object effect * deconverge_effect; // pointer to the deconvergence-effect object @@ -413,6 +419,7 @@ private: texture_info * curr_texture; render_target * curr_render_target; + poly_info * curr_poly; public: render_target * targethead; diff --git a/src/osd/modules/render/drawd3d.c b/src/osd/modules/render/drawd3d.c index caeee46ada9..2beeb16b663 100644 --- a/src/osd/modules/render/drawd3d.c +++ b/src/osd/modules/render/drawd3d.c @@ -2757,26 +2757,30 @@ cache_target::~cache_target() bool cache_target::init(renderer *d3d, base *d3dintf, int width, int height, int prescale_x, int prescale_y) { - int bloom_size = (width < height) ? width : height; int bloom_index = 0; + int bloom_size = (width < height) ? width : height; int bloom_width = width; int bloom_height = height; for (; bloom_size >= 2 && bloom_index < 11; bloom_size >>= 1) { bloom_width >>= 1; bloom_height >>= 1; + HRESULT result = (*d3dintf->device.create_texture)(d3d->get_device(), bloom_width, bloom_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &bloom_texture[bloom_index]); if (result != D3D_OK) { return false; } (*d3dintf->texture.get_surface_level)(bloom_texture[bloom_index], 0, &bloom_target[bloom_index]); + bloom_index++; } HRESULT result = (*d3dintf->device.create_texture)(d3d->get_device(), width * prescale_x, height * prescale_y, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &last_texture); if (result != D3D_OK) + { return false; + } (*d3dintf->texture.get_surface_level)(last_texture, 0, &last_target); target_width = width * prescale_x; @@ -2804,8 +2808,8 @@ render_target::~render_target() (*d3dintf->surface.release)(bloom_target[index]); bloom_target[index] = NULL; } - } - + } + for (int index = 0; index < 2; index++) { if (native_texture[index] != NULL) @@ -2837,34 +2841,42 @@ render_target::~render_target() //============================================================ bool render_target::init(renderer *d3d, base *d3dintf, int width, int height, int prescale_x, int prescale_y) -{ +{ HRESULT result; - + for (int index = 0; index < 2; index++) { result = (*d3dintf->device.create_texture)(d3d->get_device(), width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &native_texture[index]); if (result != D3D_OK) + { return false; + } (*d3dintf->texture.get_surface_level)(native_texture[index], 0, &native_target[index]); result = (*d3dintf->device.create_texture)(d3d->get_device(), width * prescale_x, height * prescale_y, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &prescale_texture[index]); if (result != D3D_OK) + { return false; + } (*d3dintf->texture.get_surface_level)(prescale_texture[index], 0, &prescale_target[index]); } - float bloom_size = (d3d->get_width() < d3d->get_height()) ? d3d->get_width() : d3d->get_height(); int bloom_index = 0; + float bloom_size = (d3d->get_width() < d3d->get_height()) ? d3d->get_width() : d3d->get_height(); float bloom_width = d3d->get_width(); float bloom_height = d3d->get_height(); for (; bloom_size >= 2.0f && bloom_index < 11; bloom_size *= 0.5f) { bloom_width *= 0.5f; bloom_height *= 0.5f; + result = (*d3dintf->device.create_texture)(d3d->get_device(), (int)bloom_width, (int)bloom_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &bloom_texture[bloom_index]); if (result != D3D_OK) + { return false; + } (*d3dintf->texture.get_surface_level)(bloom_texture[bloom_index], 0, &bloom_target[bloom_index]); + bloom_index++; } |