Fixed several small issues in HLSL/BGFX

* fixed target texture dimension when -intoverscan is used (this fixes the appereance of scanline and shadow mask)
* added target_scale and screen_count uniforms
* rounded corners now remain aligned with screen bounds when -intoverscan is used (single screen only)
master
Jezze 2016-09-28 15:22:38 +02:00
parent 4727ff5e6a
commit ecf1e166fc
28 changed files with 265 additions and 125 deletions

View File

@ -28,7 +28,9 @@
{ "name": "s_tex", "type": "int", "values": [ 0.0 ] }, { "name": "s_tex", "type": "int", "values": [ 0.0 ] },
{ "name": "u_swap_xy", "type": "vec4", "values": [ 0.0, 0.0, 0.0, 0.0 ] }, { "name": "u_swap_xy", "type": "vec4", "values": [ 0.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_screen_dims", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] }, { "name": "u_screen_dims", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] },
{ "name": "u_screen_count", "type": "vec4", "values": [ 1.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_target_dims", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] }, { "name": "u_target_dims", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] },
{ "name": "u_target_scale", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] },
{ "name": "u_quad_dims", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] }, { "name": "u_quad_dims", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] },
{ "name": "u_distortion", "type": "vec4", "values": [ 0.20, 0.0, 0.0, 0.0 ] }, { "name": "u_distortion", "type": "vec4", "values": [ 0.20, 0.0, 0.0, 0.0 ] },
{ "name": "u_cubic_distortion", "type": "vec4", "values": [ 0.20, 0.0, 0.0, 0.0 ] }, { "name": "u_cubic_distortion", "type": "vec4", "values": [ 0.20, 0.0, 0.0, 0.0 ] },

View File

@ -29,6 +29,8 @@
{ "name": "s_shadow", "type": "int", "values": [ 1.0 ] }, { "name": "s_shadow", "type": "int", "values": [ 1.0 ] },
{ "name": "u_swap_xy", "type": "vec4", "values": [ 0.0, 0.0, 0.0, 0.0 ] }, { "name": "u_swap_xy", "type": "vec4", "values": [ 0.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_source_dims", "type": "vec4", "values": [ 256.0, 256.0, 0.0, 0.0 ] }, { "name": "u_source_dims", "type": "vec4", "values": [ 256.0, 256.0, 0.0, 0.0 ] },
{ "name": "u_target_dims", "type": "vec4", "values": [ 256.0, 256.0, 0.0, 0.0 ] },
{ "name": "u_target_scale", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] },
{ "name": "u_quad_dims", "type": "vec4", "values": [ 256.0, 256.0, 0.0, 0.0 ] }, { "name": "u_quad_dims", "type": "vec4", "values": [ 256.0, 256.0, 0.0, 0.0 ] },
{ "name": "u_humbar_hertz_rate", "type": "vec4", "values": [ 0.001, 0.0, 0.0, 0.0 ] }, { "name": "u_humbar_hertz_rate", "type": "vec4", "values": [ 0.001, 0.0, 0.0, 0.0 ] },
{ "name": "u_humbar_alpha", "type": "vec4", "values": [ 0.0, 0.0, 0.0, 0.0 ] }, { "name": "u_humbar_alpha", "type": "vec4", "values": [ 0.0, 0.0, 0.0, 0.0 ] },

View File

@ -86,7 +86,9 @@ float roundBox(float2 p, float2 b, float r)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
uniform float2 ScreenDims; // size of the window or fullscreen uniform float2 ScreenDims; // size of the window or fullscreen
uniform int ScreenCount;
uniform float2 TargetDims; // size of the target surface uniform float2 TargetDims; // size of the target surface
uniform float2 TargetScale;
uniform float2 QuadDims; // size of the screen quad uniform float2 QuadDims; // size of the screen quad
VS_OUTPUT vs_main(VS_INPUT Input) VS_OUTPUT vs_main(VS_INPUT Input)
@ -170,7 +172,7 @@ float GetSpotAddend(float2 coord, float amount)
return saturate(SigmoidSpot); return saturate(SigmoidSpot);
} }
float GetRoundCornerFactor(float2 coord, float2 bounds, float radiusAmount, float smoothAmount) float GetBoundsFactor(float2 coord, float2 bounds, float radiusAmount, float smoothAmount)
{ {
// reduce smooth amount down to radius amount // reduce smooth amount down to radius amount
smoothAmount = min(smoothAmount, radiusAmount); smoothAmount = min(smoothAmount, radiusAmount);
@ -216,7 +218,7 @@ float2 GetDistortedCoords(float2 centerCoord, float amount, float amountCube)
return centerCoord; return centerCoord;
} }
float2 GetCoords(float2 coord, float distortionAmount, float cubicDistortionAmount) float2 GetTextureCoords(float2 coord, float distortionAmount, float cubicDistortionAmount)
{ {
// center coordinates // center coordinates
coord -= 0.5f; coord -= 0.5f;
@ -230,35 +232,61 @@ float2 GetCoords(float2 coord, float distortionAmount, float cubicDistortionAmou
return coord; return coord;
} }
float2 GetQuadCoords(float2 coord, float distortionAmount, float cubicDistortionAmount)
{
// center coordinates
coord -= 0.5f;
// keep coords inside of the quad bounds of a single screen
if (ScreenCount == 1)
{
// base-target dimensions (without oversampling)
float2 BaseTargetDims = TargetDims / TargetScale;
// apply base-target/quad difference
coord *= BaseTargetDims / (SwapXY ? QuadDims.yx : QuadDims.xy);
}
// distort coordinates
coord = GetDistortedCoords(coord, distortionAmount, cubicDistortionAmount);
return coord;
}
float4 ps_main(PS_INPUT Input) : COLOR float4 ps_main(PS_INPUT Input) : COLOR
{ {
// image distortion
float distortionAmount = DistortionAmount; float distortionAmount = DistortionAmount;
float cubicDistortionAmount = CubicDistortionAmount > 0.0f float cubicDistortionAmount = CubicDistortionAmount > 0.0f
? CubicDistortionAmount * 1.1f // cubic distortion need to be a little higher to compensate the quartic distortion ? CubicDistortionAmount * 1.1f // cubic distortion need to be a little higher to compensate the quartic distortion
: CubicDistortionAmount * 1.2f; // negativ values even more : CubicDistortionAmount * 1.2f; // negativ values even more
// corner distortion at least by the amount of the image distorition
float distortCornerAmount = max(DistortCornerAmount, DistortionAmount + CubicDistortionAmount);
float roundCornerAmount = RoundCornerAmount * 0.5f;
float smoothBorderAmount = SmoothBorderAmount * 0.5f;
float2 TexelDims = 1.0f / TargetDims; float2 TexelDims = 1.0f / TargetDims;
// Screen Curvature // base-target dimensions (without oversampling)
float2 TexCoord = GetCoords(Input.TexCoord, distortionAmount, cubicDistortionAmount); float2 BaseTargetDims = TargetDims / TargetScale;
// Corner Curvature // Screen Texture Curvature
float2 CornerCoord = GetCoords(Input.TexCoord, DistortCornerAmount, 0.0f); float2 BaseCoord = GetTextureCoords(Input.TexCoord, distortionAmount, cubicDistortionAmount);
// Screen Quad Curvature
float2 QuadCoord = GetQuadCoords(Input.TexCoord, distortCornerAmount, 0.0f);
// clip border // clip border
clip(TexCoord < 0.0f - TexelDims || TexCoord > 1.0f + TexelDims ? -1 : 1); clip(BaseCoord < 0.0f - TexelDims || BaseCoord > 1.0f + TexelDims ? -1 : 1);
float2 TexCoordCentered = TexCoord;
TexCoordCentered -= 0.5f;
float2 CornerCoordCentered = CornerCoord;
CornerCoordCentered -= 0.5f;
// Color // Color
float4 BaseColor = tex2D(DiffuseSampler, TexCoord); float4 BaseColor = tex2D(DiffuseSampler, BaseCoord);
BaseColor.a = 1.0f; BaseColor.a = 1.0f;
// Vignetting Simulation // Vignetting Simulation
float2 VignetteCoord = CornerCoordCentered; float2 VignetteCoord = QuadCoord;
float VignetteFactor = GetVignetteFactor(VignetteCoord, VignettingAmount); float VignetteFactor = GetVignetteFactor(VignetteCoord, VignettingAmount);
BaseColor.rgb *= VignetteFactor; BaseColor.rgb *= VignetteFactor;
@ -266,20 +294,23 @@ float4 ps_main(PS_INPUT Input) : COLOR
// Light Reflection Simulation // Light Reflection Simulation
float3 LightColor = float3(1.0f, 0.90f, 0.80f); // color temperature 5.000 Kelvin float3 LightColor = float3(1.0f, 0.90f, 0.80f); // color temperature 5.000 Kelvin
float2 SpotCoord = CornerCoordCentered; float2 SpotCoord = QuadCoord;
float2 NoiseCoord = CornerCoordCentered; float2 NoiseCoord = QuadCoord;
float SpotAddend = GetSpotAddend(SpotCoord, ReflectionAmount); float SpotAddend = GetSpotAddend(SpotCoord, ReflectionAmount);
float NoiseFactor = GetNoiseFactor(SpotAddend, random(NoiseCoord)); float NoiseFactor = GetNoiseFactor(SpotAddend, random(NoiseCoord));
BaseColor.rgb += SpotAddend * NoiseFactor * LightColor; BaseColor.rgb += SpotAddend * NoiseFactor * LightColor;
// Round Corners Simulation // Round Corners Simulation
float2 RoundCornerCoord = CornerCoordCentered; float2 RoundCornerCoord = QuadCoord;
float2 RoundCornerBounds = SwapXY float2 RoundCornerBounds = ScreenCount == 1
? QuadDims.yx ? QuadDims // align corners to quad bounds of a single screen
: QuadDims.xy; : BaseTargetDims; // align corners to target bounds of multiple screens
RoundCornerBounds = SwapXY
? RoundCornerBounds.yx
: RoundCornerBounds.xy;
float roundCornerFactor = GetRoundCornerFactor(RoundCornerCoord, RoundCornerBounds, RoundCornerAmount * 0.5f, SmoothBorderAmount * 0.5f); float roundCornerFactor = GetBoundsFactor(RoundCornerCoord, RoundCornerBounds, roundCornerAmount, smoothBorderAmount);
BaseColor.rgb *= roundCornerFactor; BaseColor.rgb *= roundCornerFactor;
return BaseColor; return BaseColor;

View File

@ -76,6 +76,7 @@ static const float HalfPI = PI * 0.5f;
uniform float2 ScreenDims; uniform float2 ScreenDims;
uniform float2 SourceDims; uniform float2 SourceDims;
uniform float2 TargetDims; uniform float2 TargetDims;
uniform float2 TargetScale;
uniform float2 QuadDims; uniform float2 QuadDims;
uniform float2 ShadowDims = float2(32.0f, 32.0f); // size of the shadow texture (extended to power-of-two size) uniform float2 ShadowDims = float2(32.0f, 32.0f); // size of the shadow texture (extended to power-of-two size)
@ -158,17 +159,20 @@ float2 GetAdjustedCoords(float2 coord)
return coord; return coord;
} }
float2 GetShadowCoord(float2 QuadCoord, float2 SourceCoord) float2 GetShadowCoord(float2 TargetCoord, float2 SourceCoord)
{ {
float2 QuadTexel = 1.0f / QuadDims; // base-target dimensions (without oversampling)
float2 SourceTexel = 1.0f / SourceDims; float2 BaseTargetDims = TargetDims / TargetScale;
BaseTargetDims = SwapXY
? BaseTargetDims.yx
: BaseTargetDims.xy;
float2 canvasCoord = ShadowTileMode == 0 float2 canvasCoord = ShadowTileMode == 0
? QuadCoord + ShadowUVOffset / QuadDims ? TargetCoord + ShadowUVOffset / BaseTargetDims
: SourceCoord + ShadowUVOffset / SourceDims; : SourceCoord + ShadowUVOffset / SourceDims;
float2 canvasTexelDims = ShadowTileMode == 0 float2 canvasTexelDims = ShadowTileMode == 0
? QuadTexel ? 1.0f / BaseTargetDims
: SourceTexel; : 1.0f / SourceDims;
float2 shadowDims = ShadowDims; float2 shadowDims = ShadowDims;
float2 shadowUV = ShadowUV; float2 shadowUV = ShadowUV;
@ -204,15 +208,15 @@ float2 GetShadowCoord(float2 QuadCoord, float2 SourceCoord)
float4 ps_main(PS_INPUT Input) : COLOR float4 ps_main(PS_INPUT Input) : COLOR
{ {
float2 ScreenCoord = Input.ScreenCoord; float2 ScreenCoord = Input.ScreenCoord;
float2 TexCoord = GetAdjustedCoords(Input.TexCoord); float2 BaseCoord = GetAdjustedCoords(Input.TexCoord);
float2 SourceCoord = GetAdjustedCoords(Input.SourceCoord); float2 SourceCoord = GetAdjustedCoords(Input.SourceCoord);
// Color // Color
float4 BaseColor = tex2D(DiffuseSampler, TexCoord); float4 BaseColor = tex2D(DiffuseSampler, BaseCoord);
BaseColor.a = 1.0f; BaseColor.a = 1.0f;
// clip border // clip border
clip(TexCoord < 0.0f || TexCoord > 1.0f ? -1 : 1); clip(BaseCoord < 0.0f || BaseCoord > 1.0f ? -1 : 1);
// Mask Simulation (may not affect bloom) // Mask Simulation (may not affect bloom)
if (!PrepareBloom && ShadowAlpha > 0.0f) if (!PrepareBloom && ShadowAlpha > 0.0f)

View File

@ -40,7 +40,6 @@ struct VS_INPUT
float4 Position : POSITION; float4 Position : POSITION;
float4 Color : COLOR0; float4 Color : COLOR0;
float2 TexCoord : TEXCOORD0; float2 TexCoord : TEXCOORD0;
float2 Unused : TEXCOORD1;
}; };
struct PS_INPUT struct PS_INPUT

View File

@ -53,7 +53,6 @@ static const float Epsilon = 1.0e-7f;
uniform float2 ScreenDims; uniform float2 ScreenDims;
uniform float2 TargetDims; uniform float2 TargetDims;
uniform float2 QuadDims;
VS_OUTPUT vs_screen_main(VS_INPUT Input) VS_OUTPUT vs_screen_main(VS_INPUT Input)
{ {

View File

@ -46,7 +46,7 @@ float roundBox(float2 p, float2 b, float r)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
uniform float2 ScreenDims; uniform float2 ScreenDims;
uniform float2 QuadDims; uniform float2 TargetDims;
VS_OUTPUT vs_main(VS_INPUT Input) VS_OUTPUT vs_main(VS_INPUT Input)
{ {
@ -76,7 +76,7 @@ uniform float LengthRatio; // Size at which fade is maximum
uniform float LengthScale; // How much length affects the vector's fade uniform float LengthScale; // How much length affects the vector's fade
uniform float BeamSmooth; uniform float BeamSmooth;
float GetRoundCornerFactor(float2 coord, float2 bounds, float radiusAmount, float smoothAmount) float GetBoundsFactor(float2 coord, float2 bounds, float radiusAmount, float smoothAmount)
{ {
// reduce smooth amount down to radius amount // reduce smooth amount down to radius amount
smoothAmount = min(smoothAmount, radiusAmount); smoothAmount = min(smoothAmount, radiusAmount);
@ -100,7 +100,7 @@ float GetRoundCornerFactor(float2 coord, float2 bounds, float radiusAmount, floa
float4 ps_main(PS_INPUT Input) : COLOR float4 ps_main(PS_INPUT Input) : COLOR
{ {
float2 lineSize = Input.SizeInfo / max(QuadDims.x, QuadDims.y); // normalize float2 lineSize = Input.SizeInfo / max(TargetDims.x, TargetDims.y); // normalize
float lineLength = lineSize.x; float lineLength = lineSize.x;
float lineLengthRatio = LengthRatio; float lineLengthRatio = LengthRatio;
@ -113,7 +113,7 @@ float4 ps_main(PS_INPUT Input) : COLOR
float4 outColor = float4(timeLengthModulate, timeLengthModulate, timeLengthModulate, 1.0f); float4 outColor = float4(timeLengthModulate, timeLengthModulate, timeLengthModulate, 1.0f);
outColor *= Input.Color; outColor *= Input.Color;
float RoundCornerFactor = GetRoundCornerFactor(Input.TexCoord - 0.5f, Input.SizeInfo, 1.0f, BeamSmooth); float RoundCornerFactor = GetBoundsFactor(Input.TexCoord - 0.5f, Input.SizeInfo, 1.0f, BeamSmooth);
outColor.rgb *= RoundCornerFactor; outColor.rgb *= RoundCornerFactor;
return outColor; return outColor;

View File

@ -1402,6 +1402,7 @@ render_primitive_list &render_target::get_primitives()
{ {
render_primitive *prim = list.alloc(render_primitive::QUAD); render_primitive *prim = list.alloc(render_primitive::QUAD);
set_render_bounds_xy(&prim->bounds, 0.0f, 0.0f, (float)m_width, (float)m_height); set_render_bounds_xy(&prim->bounds, 0.0f, 0.0f, (float)m_width, (float)m_height);
prim->full_bounds = prim->bounds;
set_render_color(&prim->color, 1.0f, 1.0f, 1.0f, 1.0f); set_render_color(&prim->color, 1.0f, 1.0f, 1.0f, 1.0f);
prim->texture.base = nullptr; prim->texture.base = nullptr;
prim->flags = PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA); prim->flags = PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA);
@ -1411,6 +1412,7 @@ render_primitive_list &render_target::get_primitives()
{ {
prim = list.alloc(render_primitive::QUAD); prim = list.alloc(render_primitive::QUAD);
set_render_bounds_xy(&prim->bounds, 1.0f, 1.0f, (float)(m_width - 1), (float)(m_height - 1)); set_render_bounds_xy(&prim->bounds, 1.0f, 1.0f, (float)(m_width - 1), (float)(m_height - 1));
prim->full_bounds = prim->bounds;
set_render_color(&prim->color, 1.0f, 0.0f, 0.0f, 0.0f); set_render_color(&prim->color, 1.0f, 0.0f, 0.0f, 0.0f);
prim->texture.base = nullptr; prim->texture.base = nullptr;
prim->flags = PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA); prim->flags = PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA);
@ -1855,6 +1857,9 @@ void render_target::add_container_primitives(render_primitive_list &list, const
prim->color.b = container_xform.color.b * curitem.color().b; prim->color.b = container_xform.color.b * curitem.color().b;
prim->color.a = container_xform.color.a * curitem.color().a; prim->color.a = container_xform.color.a * curitem.color().a;
// copy unclipped bounds
prim->full_bounds = prim->bounds;
// now switch off the type // now switch off the type
bool clipped = true; bool clipped = true;
switch (curitem.type()) switch (curitem.type())
@ -1917,7 +1922,7 @@ void render_target::add_container_primitives(render_primitive_list &list, const
clipped = render_clip_quad(&prim->bounds, &cliprect, &prim->texcoords); clipped = render_clip_quad(&prim->bounds, &cliprect, &prim->texcoords);
// apply the final orientation from the quad flags and then build up the final flags // apply the final orientation from the quad flags and then build up the final flags
prim->flags = (curitem.flags() & ~(PRIMFLAG_TEXORIENT_MASK | PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK)) prim->flags |= (curitem.flags() & ~(PRIMFLAG_TEXORIENT_MASK | PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK))
| PRIMFLAG_TEXORIENT(finalorient) | PRIMFLAG_TEXORIENT(finalorient)
| PRIMFLAG_TEXFORMAT(curitem.texture()->format()); | PRIMFLAG_TEXFORMAT(curitem.texture()->format());
prim->flags |= blendmode != -1 prim->flags |= blendmode != -1
@ -1977,7 +1982,7 @@ void render_target::add_container_primitives(render_primitive_list &list, const
clipped = render_clip_quad(&prim->bounds, &cliprect, &prim->texcoords); clipped = render_clip_quad(&prim->bounds, &cliprect, &prim->texcoords);
// apply the final orientation from the quad flags and then build up the final flags // apply the final orientation from the quad flags and then build up the final flags
prim->flags = (curitem.flags() & ~(PRIMFLAG_TEXORIENT_MASK | PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK)) prim->flags |= (curitem.flags() & ~(PRIMFLAG_TEXORIENT_MASK | PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK))
| PRIMFLAG_TEXORIENT(finalorient); | PRIMFLAG_TEXORIENT(finalorient);
prim->flags |= blendmode != -1 prim->flags |= blendmode != -1
? PRIMFLAG_BLENDMODE(blendmode) ? PRIMFLAG_BLENDMODE(blendmode)
@ -1986,7 +1991,7 @@ void render_target::add_container_primitives(render_primitive_list &list, const
else else
{ {
// set the basic flags // set the basic flags
prim->flags = (curitem.flags() & ~PRIMFLAG_BLENDMODE_MASK) prim->flags |= (curitem.flags() & ~PRIMFLAG_BLENDMODE_MASK)
| PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA); | PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA);
// apply clipping // apply clipping
@ -2008,22 +2013,23 @@ void render_target::add_container_primitives(render_primitive_list &list, const
// allocate a primitive // allocate a primitive
render_primitive *prim = list.alloc(render_primitive::QUAD); render_primitive *prim = list.alloc(render_primitive::QUAD);
set_render_bounds_wh(&prim->bounds, xform.xoffs, xform.yoffs, xform.xscale, xform.yscale); set_render_bounds_wh(&prim->bounds, xform.xoffs, xform.yoffs, xform.xscale, xform.yscale);
prim->full_bounds = prim->bounds;
prim->color = container_xform.color; prim->color = container_xform.color;
width = render_round_nearest(prim->bounds.x1) - render_round_nearest(prim->bounds.x0); width = render_round_nearest(prim->bounds.x1) - render_round_nearest(prim->bounds.x0);
height = render_round_nearest(prim->bounds.y1) - render_round_nearest(prim->bounds.y0); height = render_round_nearest(prim->bounds.y1) - render_round_nearest(prim->bounds.y0);
container.overlay()->get_scaled( container.overlay()->get_scaled(
(container_xform.orientation & ORIENTATION_SWAP_XY) ? height : width, (container_xform.orientation & ORIENTATION_SWAP_XY) ? height : width,
(container_xform.orientation & ORIENTATION_SWAP_XY) ? width : height, prim->texture, list); (container_xform.orientation & ORIENTATION_SWAP_XY) ? width : height, prim->texture, list);
// determine UV coordinates // determine UV coordinates
prim->texcoords = oriented_texcoords[container_xform.orientation]; prim->texcoords = oriented_texcoords[container_xform.orientation];
// set the flags and add it to the list // set the flags and add it to the list
prim->flags = PRIMFLAG_TEXORIENT(container_xform.orientation) | prim->flags = PRIMFLAG_TEXORIENT(container_xform.orientation)
PRIMFLAG_BLENDMODE(BLENDMODE_RGB_MULTIPLY) | | PRIMFLAG_BLENDMODE(BLENDMODE_RGB_MULTIPLY)
PRIMFLAG_TEXFORMAT(container.overlay()->format()) | | PRIMFLAG_TEXFORMAT(container.overlay()->format())
PRIMFLAG_TEXSHADE(1); | PRIMFLAG_TEXSHADE(1);
list.append_or_return(*prim, false); list.append_or_return(*prim, false);
} }
@ -2057,6 +2063,7 @@ void render_target::add_element_primitives(render_primitive_list &list, const ob
INT32 width = render_round_nearest(xform.xscale); INT32 width = render_round_nearest(xform.xscale);
INT32 height = render_round_nearest(xform.yscale); INT32 height = render_round_nearest(xform.yscale);
set_render_bounds_wh(&prim->bounds, render_round_nearest(xform.xoffs), render_round_nearest(xform.yoffs), (float) width, (float) height); set_render_bounds_wh(&prim->bounds, render_round_nearest(xform.xoffs), render_round_nearest(xform.yoffs), (float) width, (float) height);
prim->full_bounds = prim->bounds;
if (xform.orientation & ORIENTATION_SWAP_XY) if (xform.orientation & ORIENTATION_SWAP_XY)
std::swap(width, height); std::swap(width, height);
width = std::min(width, m_maxtexwidth); width = std::min(width, m_maxtexwidth);
@ -2511,6 +2518,7 @@ void render_target::add_clear_extents(render_primitive_list &list)
{ {
render_primitive *prim = list.alloc(render_primitive::QUAD); render_primitive *prim = list.alloc(render_primitive::QUAD);
set_render_bounds_xy(&prim->bounds, (float)x0, (float)y0, (float)x1, (float)y1); set_render_bounds_xy(&prim->bounds, (float)x0, (float)y0, (float)x1, (float)y1);
prim->full_bounds = prim->bounds;
set_render_color(&prim->color, 1.0f, 0.0f, 0.0f, 0.0f); set_render_color(&prim->color, 1.0f, 0.0f, 0.0f, 0.0f);
prim->texture.base = nullptr; prim->texture.base = nullptr;
prim->flags = PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA); prim->flags = PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA);

View File

@ -203,7 +203,7 @@ struct render_color
// render_texuv - floating point set of UV texture coordinates // render_texuv - floating point set of UV texture coordinates
struct render_texuv struct render_texuv
{ {
float u; // U coodinate (0.0-1.0) float u; // U coordinate (0.0-1.0)
float v; // V coordinate (0.0-1.0) float v; // V coordinate (0.0-1.0)
}; };
@ -345,8 +345,10 @@ public:
// getters // getters
render_primitive *next() const { return m_next; } render_primitive *next() const { return m_next; }
bool packable(const INT32 pack_size) const { return (flags & PRIMFLAG_PACKABLE) && texture.base != nullptr && texture.width <= pack_size && texture.height <= pack_size; } bool packable(const INT32 pack_size) const { return (flags & PRIMFLAG_PACKABLE) && texture.base != nullptr && texture.width <= pack_size && texture.height <= pack_size; }
float get_quad_width() const { return bounds.x1 - bounds.x0; } float get_quad_width() const { return abs(bounds.x1 - bounds.x0); }
float get_quad_height() const { return bounds.y1 - bounds.y0; } float get_quad_height() const { return abs(bounds.y1 - bounds.y0); }
float get_full_quad_width() const { return abs(full_bounds.x1 - full_bounds.x0); }
float get_full_quad_height() const { return abs(full_bounds.y1 - full_bounds.y0); }
// reset to prepare for re-use // reset to prepare for re-use
void reset(); void reset();
@ -354,6 +356,7 @@ public:
// public state // public state
primitive_type type; // type of primitive primitive_type type; // type of primitive
render_bounds bounds; // bounds or positions render_bounds bounds; // bounds or positions
render_bounds full_bounds; // bounds or positions (unclipped)
render_color color; // RGBA values render_color color; // RGBA values
UINT32 flags; // flags UINT32 flags; // flags
float width; // width (for line primitives) float width; // width (for line primitives)
@ -602,8 +605,8 @@ private:
user_settings m_user; // user settings user_settings m_user; // user settings
bitmap_argb32 * m_overlaybitmap; // overlay bitmap bitmap_argb32 * m_overlaybitmap; // overlay bitmap
render_texture * m_overlaytexture; // overlay texture render_texture * m_overlaytexture; // overlay texture
std::unique_ptr<palette_client> m_palclient; // client to the screen palette std::unique_ptr<palette_client> m_palclient; // client to the screen palette
std::vector<rgb_t> m_bcglookup; // copy of screen palette with bcg adjustment std::vector<rgb_t> m_bcglookup; // copy of screen palette with bcg adjustment
rgb_t m_bcglookup256[0x400]; // lookup table for brightness/contrast/gamma rgb_t m_bcglookup256[0x400]; // lookup table for brightness/contrast/gamma
}; };

View File

@ -77,9 +77,9 @@ void bgfx_chain::process(render_primitive* prim, int view, int screen, texture_m
screen_device_iterator screen_iterator(window.machine().root_device()); screen_device_iterator screen_iterator(window.machine().root_device());
screen_device* screen_device = screen_iterator.byindex(screen); screen_device* screen_device = screen_iterator.byindex(screen);
int current_view = view; uint16_t screen_count(window.target()->current_view()->screens().count());
uint16_t screen_width(floor((prim->bounds.x1 - prim->bounds.x0) + 0.5f)); uint16_t screen_width(floor(prim->get_quad_width() + 0.5f));
uint16_t screen_height(floor((prim->bounds.y1 - prim->bounds.y0) + 0.5f)); uint16_t screen_height(floor(prim->get_quad_height() + 0.5f));
uint32_t rotation_type = uint32_t rotation_type =
(window.target()->orientation() & ROT90) == ROT90 ? 1 : (window.target()->orientation() & ROT90) == ROT90 ? 1 :
(window.target()->orientation() & ROT180) == ROT180 ? 2 : (window.target()->orientation() & ROT180) == ROT180 ? 2 :
@ -101,11 +101,12 @@ void bgfx_chain::process(render_primitive* prim, int view, int screen, texture_m
screen_offset_y = -screen_container.yoffset(); screen_offset_y = -screen_container.yoffset();
} }
int current_view = view;
for (bgfx_chain_entry* entry : m_entries) for (bgfx_chain_entry* entry : m_entries)
{ {
if (!entry->skip()) if (!entry->skip())
{ {
entry->submit(current_view, prim, textures, screen_width, screen_height, screen_scale_x, screen_scale_y, screen_offset_x, screen_offset_y, rotation_type, swap_xy, blend, screen); entry->submit(current_view, prim, textures, screen_count, screen_width, screen_height, screen_scale_x, screen_scale_y, screen_offset_x, screen_offset_y, rotation_type, swap_xy, blend, screen);
current_view++; current_view++;
} }
} }

View File

@ -55,7 +55,7 @@ bgfx_chain_entry::~bgfx_chain_entry()
delete m_clear; delete m_clear;
} }
void bgfx_chain_entry::submit(int view, render_primitive* prim, texture_manager& textures, uint16_t screen_width, uint16_t screen_height, float screen_scale_x, float screen_scale_y, float screen_offset_x, float screen_offset_y, uint32_t rotation_type, bool swap_xy, uint64_t blend, int32_t screen) void bgfx_chain_entry::submit(int view, render_primitive* prim, texture_manager& textures, uint16_t screen_count, uint16_t screen_width, uint16_t screen_height, float screen_scale_x, float screen_scale_y, float screen_offset_x, float screen_offset_y, uint32_t rotation_type, bool swap_xy, uint64_t blend, int32_t screen)
{ {
bgfx::setViewSeq(view, true); bgfx::setViewSeq(view, true);
@ -73,7 +73,7 @@ void bgfx_chain_entry::submit(int view, render_primitive* prim, texture_manager&
put_screen_buffer(prim, &buffer); put_screen_buffer(prim, &buffer);
bgfx::setVertexBuffer(&buffer); bgfx::setVertexBuffer(&buffer);
setup_auto_uniforms(prim, textures, screen_width, screen_height, screen_scale_x, screen_scale_y, screen_offset_x, screen_offset_y, rotation_type, swap_xy, screen); setup_auto_uniforms(prim, textures, screen_count, screen_width, screen_height, screen_scale_x, screen_scale_y, screen_offset_x, screen_offset_y, rotation_type, swap_xy, screen);
for (bgfx_entry_uniform* uniform : m_uniforms) for (bgfx_entry_uniform* uniform : m_uniforms)
{ {
@ -137,6 +137,16 @@ void bgfx_chain_entry::setup_screenoffset_uniforms(float screen_offset_x, float
} }
} }
void bgfx_chain_entry::setup_screencount_uniforms(uint16_t screen_count)
{
bgfx_uniform* u_screen_count = m_effect->uniform("u_screen_count");
if (u_screen_count != nullptr)
{
float values[1] = { float(screen_count) };
u_screen_count->set(values, sizeof(float));
}
}
void bgfx_chain_entry::setup_sourcesize_uniform(render_primitive* prim) const void bgfx_chain_entry::setup_sourcesize_uniform(render_primitive* prim) const
{ {
bgfx_uniform* source_dims = m_effect->uniform("u_source_dims"); bgfx_uniform* source_dims = m_effect->uniform("u_source_dims");
@ -161,6 +171,20 @@ void bgfx_chain_entry::setup_targetsize_uniform(int32_t screen) const
} }
} }
void bgfx_chain_entry::setup_targetscale_uniform(int32_t screen) const
{
bgfx_uniform* target_scale = m_effect->uniform("u_target_scale");
if (target_scale != nullptr)
{
bgfx_target* output = m_targets.target(screen, m_output);
if (output != nullptr)
{
float values[2] = { float(output->scale()), float(output->scale()) };
target_scale->set(values, sizeof(float) * 2);
}
}
}
void bgfx_chain_entry::setup_rotationtype_uniform(uint32_t rotation_type) const void bgfx_chain_entry::setup_rotationtype_uniform(uint32_t rotation_type) const
{ {
bgfx_uniform* rotation_type_uniform = m_effect->uniform("u_rotation_type"); bgfx_uniform* rotation_type_uniform = m_effect->uniform("u_rotation_type");
@ -201,13 +225,15 @@ void bgfx_chain_entry::setup_screenindex_uniform(int32_t screen) const
} }
} }
void bgfx_chain_entry::setup_auto_uniforms(render_primitive* prim, texture_manager& textures, uint16_t screen_width, uint16_t screen_height, float screen_scale_x, float screen_scale_y, float screen_offset_x, float screen_offset_y, uint32_t rotation_type, bool swap_xy, int32_t screen) void bgfx_chain_entry::setup_auto_uniforms(render_primitive* prim, texture_manager& textures, uint16_t screen_count, uint16_t screen_width, uint16_t screen_height, float screen_scale_x, float screen_scale_y, float screen_offset_x, float screen_offset_y, uint32_t rotation_type, bool swap_xy, int32_t screen)
{ {
setup_screensize_uniforms(textures, screen_width, screen_height, screen); setup_screensize_uniforms(textures, screen_width, screen_height, screen);
setup_screenscale_uniforms(screen_scale_x, screen_scale_y); setup_screenscale_uniforms(screen_scale_x, screen_scale_y);
setup_screenoffset_uniforms(screen_offset_x, screen_offset_y); setup_screenoffset_uniforms(screen_offset_x, screen_offset_y);
setup_screencount_uniforms(screen_count);
setup_sourcesize_uniform(prim); setup_sourcesize_uniform(prim);
setup_targetsize_uniform(screen); setup_targetsize_uniform(screen);
setup_targetscale_uniform(screen);
setup_rotationtype_uniform(rotation_type); setup_rotationtype_uniform(rotation_type);
setup_swapxy_uniform(swap_xy); setup_swapxy_uniform(swap_xy);
setup_quaddims_uniform(prim); setup_quaddims_uniform(prim);

View File

@ -37,7 +37,7 @@ public:
bgfx_chain_entry(std::string name, bgfx_effect* effect, clear_state* clear, std::vector<bgfx_suppressor*> suppressors, std::vector<bgfx_input_pair*> inputs, std::vector<bgfx_entry_uniform*> uniforms, target_manager& targets, std::string output); bgfx_chain_entry(std::string name, bgfx_effect* effect, clear_state* clear, std::vector<bgfx_suppressor*> suppressors, std::vector<bgfx_input_pair*> inputs, std::vector<bgfx_entry_uniform*> uniforms, target_manager& targets, std::string output);
~bgfx_chain_entry(); ~bgfx_chain_entry();
void submit(int view, render_primitive* prim, texture_manager& textures, uint16_t screen_width, uint16_t screen_height, float screen_scale_x, float screen_scale_y, float screen_offset_x, float screen_offset_y, uint32_t rotation_type, bool swap_xy, uint64_t blend, int32_t screen); void submit(int view, render_primitive* prim, texture_manager& textures, uint16_t screen_count, uint16_t screen_width, uint16_t screen_height, float screen_scale_x, float screen_scale_y, float screen_offset_x, float screen_offset_y, uint32_t rotation_type, bool swap_xy, uint64_t blend, int32_t screen);
// Getters // Getters
std::string name() const { return m_name; } std::string name() const { return m_name; }
@ -45,12 +45,14 @@ public:
bool skip(); bool skip();
private: private:
void setup_auto_uniforms(render_primitive* prim, texture_manager& textures, uint16_t screen_width, uint16_t screen_height, float screen_scale_x, float screen_scale_y, float screen_offset_x, float screen_offset_y, uint32_t rotation_type, bool swap_xy, int32_t screen); void setup_auto_uniforms(render_primitive* prim, texture_manager& textures, uint16_t screen_count, uint16_t screen_width, uint16_t screen_height, float screen_scale_x, float screen_scale_y, float screen_offset_x, float screen_offset_y, uint32_t rotation_type, bool swap_xy, int32_t screen);
void setup_screensize_uniforms(texture_manager& textures, uint16_t screen_width, uint16_t screen_height, int32_t screen); void setup_screensize_uniforms(texture_manager& textures, uint16_t screen_width, uint16_t screen_height, int32_t screen);
void setup_screenscale_uniforms(float screen_scale_x, float screen_scale_y); void setup_screenscale_uniforms(float screen_scale_x, float screen_scale_y);
void setup_screenoffset_uniforms(float screen_offset_x, float screen_offset_y); void setup_screenoffset_uniforms(float screen_offset_x, float screen_offset_y);
void setup_screencount_uniforms(uint16_t screen_count);
void setup_sourcesize_uniform(render_primitive* prim) const; void setup_sourcesize_uniform(render_primitive* prim) const;
void setup_targetsize_uniform(int32_t screen) const; void setup_targetsize_uniform(int32_t screen) const;
void setup_targetscale_uniform(int32_t screen) const;
void setup_rotationtype_uniform(uint32_t rotation_type) const; void setup_rotationtype_uniform(uint32_t rotation_type) const;
void setup_swapxy_uniform(bool swap_xy) const; void setup_swapxy_uniform(bool swap_xy) const;
void setup_quaddims_uniform(render_primitive* prim) const; void setup_quaddims_uniform(render_primitive* prim) const;

View File

@ -435,8 +435,8 @@ uint32_t chain_manager::handle_screen_chains(uint32_t view, render_primitive *st
continue; continue;
} }
uint16_t screen_width(floor((prim->bounds.x1 - prim->bounds.x0) + 0.5f)); uint16_t screen_width(floor(prim->get_full_quad_width() + 0.5f));
uint16_t screen_height(floor((prim->bounds.y1 - prim->bounds.y0) + 0.5f)); uint16_t screen_height(floor(prim->get_full_quad_height() + 0.5f));
if (window.swap_xy()) if (window.swap_xy())
{ {
std::swap(screen_width, screen_height); std::swap(screen_width, screen_height);

View File

@ -11,7 +11,9 @@ $input v_color0, v_texcoord0
// Autos // Autos
uniform vec4 u_swap_xy; uniform vec4 u_swap_xy;
uniform vec4 u_screen_dims; uniform vec4 u_screen_dims;
uniform vec4 u_screen_count;
uniform vec4 u_target_dims; uniform vec4 u_target_dims;
uniform vec4 u_target_scale;
uniform vec4 u_quad_dims; uniform vec4 u_quad_dims;
// User-supplied // User-supplied
@ -97,7 +99,7 @@ float GetSpotAddend(vec2 coord, float amount)
return saturate(SigmoidSpot); return saturate(SigmoidSpot);
} }
float GetRoundCornerFactor(vec2 coord, vec2 bounds, float radiusAmount, float smoothAmount) float GetBoundsFactor(vec2 coord, vec2 bounds, float radiusAmount, float smoothAmount)
{ {
// reduce smooth amount down to radius amount // reduce smooth amount down to radius amount
smoothAmount = min(smoothAmount, radiusAmount); smoothAmount = min(smoothAmount, radiusAmount);
@ -141,7 +143,7 @@ vec2 GetDistortedCoords(vec2 centerCoord, float amount, float amountCube)
return centerCoord; return centerCoord;
} }
vec2 GetCoords(vec2 coord, float distortionAmount, float cubicDistortionAmount) vec2 GetTextureCoords(vec2 coord, float distortionAmount, float cubicDistortionAmount)
{ {
// center coordinates // center coordinates
coord -= 0.5; coord -= 0.5;
@ -155,6 +157,27 @@ vec2 GetCoords(vec2 coord, float distortionAmount, float cubicDistortionAmount)
return coord; return coord;
} }
vec2 GetQuadCoords(vec2 coord, float distortionAmount, float cubicDistortionAmount)
{
// center coordinates
coord -= 0.5;
// keep coords inside of the quad bounds of a single screen
if (u_screen_count.x > 0.0 && u_screen_count.x < 2.0)
{
// base-target dimensions (without oversampling)
vec2 BaseTargetDims = u_target_dims.xy / u_target_scale.xy;
// apply base-target/quad difference
coord *= BaseTargetDims / ((u_swap_xy.x > 0.0) ? u_quad_dims.yx : u_quad_dims.xy);
}
// distort coordinates
coord = GetDistortedCoords(coord, distortionAmount, cubicDistortionAmount);
return coord;
}
// Shader // Shader
void main() void main()
@ -164,18 +187,22 @@ void main()
? u_cubic_distortion.x * 1.1 // cubic distortion need to be a little higher to compensate the quartic distortion ? u_cubic_distortion.x * 1.1 // cubic distortion need to be a little higher to compensate the quartic distortion
: u_cubic_distortion.x * 1.2; // negativ values even more : u_cubic_distortion.x * 1.2; // negativ values even more
// corner distortion at least by the amount of the image distorition
float distortCornerAmount = max(u_distort_corner.x, u_distortion.x + u_cubic_distortion.x);
float roundCornerAmount = u_round_corner.x * 0.5;
float smoothBorderAmount = u_smooth_border.x * 0.5;
vec2 TexelDims = vec2(1.0 / u_target_dims.x, 1.0 / u_target_dims.y); vec2 TexelDims = vec2(1.0 / u_target_dims.x, 1.0 / u_target_dims.y);
// Screen Curvature // base-target dimensions (without oversampling)
vec2 BaseCoord = GetCoords(v_texcoord0, distortionAmount, cubicDistortionAmount); vec2 BaseTargetDims = u_target_dims.xy / u_target_scale.xy;
// Corner Curvature // Screen Texture Curvature
vec2 CornerCoord = GetCoords(v_texcoord0, u_distort_corner.x, 0.0); vec2 BaseCoord = GetTextureCoords(v_texcoord0, distortionAmount, cubicDistortionAmount);
vec2 BaseCoordCentered = BaseCoord; // Screen Quad Curvature
BaseCoordCentered -= 0.5; vec2 QuadCoord = GetQuadCoords(v_texcoord0, distortCornerAmount, 0.0);
vec2 CornerCoordCentered = CornerCoord;
CornerCoordCentered -= 0.5;
// Color // Color
vec4 BaseColor = texture2D(s_tex, BaseCoord); vec4 BaseColor = texture2D(s_tex, BaseCoord);
@ -188,7 +215,7 @@ void main()
else else
{ {
// Vignetting Simulation // Vignetting Simulation
vec2 VignetteCoord = CornerCoordCentered; vec2 VignetteCoord = QuadCoord;
float VignetteFactor = GetVignetteFactor(VignetteCoord, u_vignetting.x); float VignetteFactor = GetVignetteFactor(VignetteCoord, u_vignetting.x);
BaseColor.rgb *= VignetteFactor; BaseColor.rgb *= VignetteFactor;
@ -196,20 +223,23 @@ void main()
// Light Reflection Simulation // Light Reflection Simulation
vec4 LightColor = vec4(1.0, 0.90, 0.80, 1.0); // color temperature 5.000 Kelvin vec4 LightColor = vec4(1.0, 0.90, 0.80, 1.0); // color temperature 5.000 Kelvin
vec2 SpotCoord = CornerCoordCentered; vec2 SpotCoord = QuadCoord;
vec2 NoiseCoord = CornerCoordCentered; vec2 NoiseCoord = QuadCoord;
float SpotAddend = GetSpotAddend(SpotCoord, u_reflection.x); float SpotAddend = GetSpotAddend(SpotCoord, u_reflection.x);
float NoiseFactor = GetNoiseFactor(SpotAddend, rand(NoiseCoord)); float NoiseFactor = GetNoiseFactor(SpotAddend, rand(NoiseCoord));
BaseColor += SpotAddend * NoiseFactor * LightColor; BaseColor += SpotAddend * NoiseFactor * LightColor;
// Round Corners Simulation // Round Corners Simulation
vec2 RoundCornerCoord = CornerCoordCentered; vec2 RoundCornerCoord = QuadCoord;
vec2 RoundCornerBounds = (u_swap_xy.x > 0.0) vec2 RoundCornerBounds = (u_screen_count.x > 0.0 && u_screen_count.x < 2.0)
? u_quad_dims.yx ? u_quad_dims.xy // align corners to screen quad bounds
: u_quad_dims.xy; : BaseTargetDims; // align corners to target texture bounds
RoundCornerBounds = (u_swap_xy.x > 0.0)
? RoundCornerBounds.yx
: RoundCornerBounds.xy;
float roundCornerFactor = GetRoundCornerFactor(RoundCornerCoord, RoundCornerBounds, u_round_corner.x * 0.5f, u_smooth_border.x * 0.5f); float roundCornerFactor = GetBoundsFactor(RoundCornerCoord, RoundCornerBounds, roundCornerAmount, smoothBorderAmount);
BaseColor.rgb *= roundCornerFactor; BaseColor.rgb *= roundCornerFactor;
gl_FragColor = BaseColor; gl_FragColor = BaseColor;

View File

@ -11,6 +11,8 @@ $input v_color0, v_texcoord0
// Autos // Autos
uniform vec4 u_swap_xy; uniform vec4 u_swap_xy;
uniform vec4 u_source_dims; // size of the guest machine uniform vec4 u_source_dims; // size of the guest machine
uniform vec4 u_target_dims;
uniform vec4 u_target_scale;
uniform vec4 u_quad_dims; uniform vec4 u_quad_dims;
uniform vec4 u_screen_scale; uniform vec4 u_screen_scale;
uniform vec4 u_screen_offset; uniform vec4 u_screen_offset;
@ -63,13 +65,19 @@ vec2 GetAdjustedCoords(vec2 coord)
return coord; return coord;
} }
vec2 GetShadowCoord(vec2 QuadCoord, vec2 SourceCoord) vec2 GetShadowCoord(vec2 TargetCoord, vec2 SourceCoord)
{ {
// base-target dimensions (remove oversampling)
vec2 BaseTargetDims = u_target_dims.xy / u_target_scale.xy;
BaseTargetDims = u_swap_xy.x > 0.0
? BaseTargetDims.yx
: BaseTargetDims.xy;
vec2 canvasCoord = u_shadow_tile_mode.x == 0.0 vec2 canvasCoord = u_shadow_tile_mode.x == 0.0
? QuadCoord + u_shadow_uv_offset.xy / u_quad_dims.xy ? TargetCoord + u_shadow_uv_offset.xy / BaseTargetDims
: SourceCoord + u_shadow_uv_offset.xy / u_source_dims.xy; : SourceCoord + u_shadow_uv_offset.xy / u_source_dims.xy;
vec2 canvasTexelDims = u_shadow_tile_mode.x == 0.0 vec2 canvasTexelDims = u_shadow_tile_mode.x == 0.0
? vec2(1.0, 1.0) / u_quad_dims.xy ? vec2(1.0, 1.0) / BaseTargetDims
: vec2(1.0, 1.0) / u_source_dims.xy; : vec2(1.0, 1.0) / u_source_dims.xy;
vec2 shadowUV = u_shadow_uv.xy; vec2 shadowUV = u_shadow_uv.xy;

View File

@ -787,7 +787,9 @@ int shaders::create_resources()
{ {
effects[i]->add_uniform("SourceDims", uniform::UT_VEC2, uniform::CU_SOURCE_DIMS); effects[i]->add_uniform("SourceDims", uniform::UT_VEC2, uniform::CU_SOURCE_DIMS);
effects[i]->add_uniform("TargetDims", uniform::UT_VEC2, uniform::CU_TARGET_DIMS); effects[i]->add_uniform("TargetDims", uniform::UT_VEC2, uniform::CU_TARGET_DIMS);
effects[i]->add_uniform("TargetScale", uniform::UT_FLOAT, uniform::CU_TARGET_SCALE);
effects[i]->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS); effects[i]->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS);
effects[i]->add_uniform("ScreenCount", uniform::UT_INT, uniform::CU_SCREEN_COUNT);
effects[i]->add_uniform("QuadDims", uniform::UT_VEC2, uniform::CU_QUAD_DIMS); effects[i]->add_uniform("QuadDims", uniform::UT_VEC2, uniform::CU_QUAD_DIMS);
effects[i]->add_uniform("SwapXY", uniform::UT_BOOL, uniform::CU_SWAP_XY); effects[i]->add_uniform("SwapXY", uniform::UT_BOOL, uniform::CU_SWAP_XY);
effects[i]->add_uniform("VectorScreen", uniform::UT_BOOL, uniform::CU_VECTOR_SCREEN); effects[i]->add_uniform("VectorScreen", uniform::UT_BOOL, uniform::CU_VECTOR_SCREEN);
@ -1018,9 +1020,9 @@ rgb_t shaders::apply_color_convolution(rgb_t color)
{ {
// this function uses the same algorithm as the color convolution shader pass // this function uses the same algorithm as the color convolution shader pass
float r = static_cast<float>(color.r()) / 255.0f; float r = float(color.r()) / 255.0f;
float g = static_cast<float>(color.g()) / 255.0f; float g = float(color.g()) / 255.0f;
float b = static_cast<float>(color.b()) / 255.0f; float b = float(color.b()) / 255.0f;
float *rRatio = options->red_ratio; float *rRatio = options->red_ratio;
float *gRatio = options->grn_ratio; float *gRatio = options->grn_ratio;
@ -1049,9 +1051,9 @@ rgb_t shaders::apply_color_convolution(rgb_t color)
b = chroma[2] * saturation + luma; b = chroma[2] * saturation + luma;
return rgb_t( return rgb_t(
std::max(0, std::min(255, static_cast<int>(r * 255.0f))), std::max(0, std::min(255, int(r * 255.0f))),
std::max(0, std::min(255, static_cast<int>(g * 255.0f))), std::max(0, std::min(255, int(g * 255.0f))),
std::max(0, std::min(255, static_cast<int>(b * 255.0f)))); std::max(0, std::min(255, int(b * 255.0f))));
} }
int shaders::color_convolution_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum) int shaders::color_convolution_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum)
@ -1161,6 +1163,8 @@ int shaders::post_pass(d3d_render_target *rt, int source_index, poly_info *poly,
{ {
int next_index = source_index; int next_index = source_index;
auto win = d3d->assert_window();
screen_device_iterator screen_iterator(machine->root_device()); screen_device_iterator screen_iterator(machine->root_device());
screen_device *screen = screen_iterator.byindex(curr_screen); screen_device *screen = screen_iterator.byindex(curr_screen);
render_container &screen_container = screen->container(); render_container &screen_container = screen->container();
@ -1177,9 +1181,9 @@ int shaders::post_pass(d3d_render_target *rt, int source_index, poly_info *poly,
: rgb_t(0, 0, 0); : rgb_t(0, 0, 0);
back_color_rgb = apply_color_convolution(back_color_rgb); back_color_rgb = apply_color_convolution(back_color_rgb);
float back_color[3] = { float back_color[3] = {
static_cast<float>(back_color_rgb.r()) / 255.0f, float(back_color_rgb.r()) / 255.0f,
static_cast<float>(back_color_rgb.g()) / 255.0f, float(back_color_rgb.g()) / 255.0f,
static_cast<float>(back_color_rgb.b()) / 255.0f }; float(back_color_rgb.b()) / 255.0f };
curr_effect = post_effect; curr_effect = post_effect;
curr_effect->update_uniforms(); curr_effect->update_uniforms();
@ -1582,8 +1586,8 @@ d3d_render_target* shaders::get_texture_target(render_primitive *prim, texture_i
auto win = d3d->assert_window(); auto win = d3d->assert_window();
int target_width = int(prim->get_quad_width() + 0.5f); int target_width = int(prim->get_full_quad_width() + 0.5f);
int target_height = int(prim->get_quad_height() + 0.5f); int target_height = int(prim->get_full_quad_height() + 0.5f);
target_width *= oversampling_enable ? 2 : 1; target_width *= oversampling_enable ? 2 : 1;
target_height *= oversampling_enable ? 2 : 1; target_height *= oversampling_enable ? 2 : 1;
if (win->swap_xy()) if (win->swap_xy())
@ -1618,11 +1622,10 @@ d3d_render_target* shaders::get_vector_target(render_primitive *prim)
auto win = d3d->assert_window(); auto win = d3d->assert_window();
// source and target size are the same for vector targets
int source_width = int(prim->get_quad_width() + 0.5f); int source_width = int(prim->get_quad_width() + 0.5f);
int source_height = int(prim->get_quad_height() + 0.5f); int source_height = int(prim->get_quad_height() + 0.5f);
int target_width = source_width; int target_width = int(prim->get_full_quad_width() + 0.5f);
int target_height = source_height; int target_height = int(prim->get_full_quad_height() + 0.5f);
target_width *= oversampling_enable ? 2 : 1; target_width *= oversampling_enable ? 2 : 1;
target_height *= oversampling_enable ? 2 : 1; target_height *= oversampling_enable ? 2 : 1;
if (win->swap_xy()) if (win->swap_xy())
@ -1658,11 +1661,10 @@ bool shaders::create_vector_target(render_primitive *prim)
auto win = d3d->assert_window(); auto win = d3d->assert_window();
// source and target size are the same for vector targets
int source_width = int(prim->get_quad_width() + 0.5f); int source_width = int(prim->get_quad_width() + 0.5f);
int source_height = int(prim->get_quad_height() + 0.5f); int source_height = int(prim->get_quad_height() + 0.5f);
int target_width = source_width; int target_width = int(prim->get_full_quad_width() + 0.5f);
int target_height = source_height; int target_height = int(prim->get_full_quad_height() + 0.5f);
target_width *= oversampling_enable ? 2 : 1; target_width *= oversampling_enable ? 2 : 1;
target_height *= oversampling_enable ? 2 : 1; target_height *= oversampling_enable ? 2 : 1;
if (win->swap_xy()) if (win->swap_xy())
@ -1748,8 +1750,8 @@ bool shaders::register_texture(render_primitive *prim, texture_info *texture)
int source_width = texture->get_width(); int source_width = texture->get_width();
int source_height = texture->get_height(); int source_height = texture->get_height();
int target_width = int(prim->get_quad_width() + 0.5f); int target_width = int(prim->get_full_quad_width() + 0.5f);
int target_height = int(prim->get_quad_height() + 0.5f); int target_height = int(prim->get_full_quad_height() + 0.5f);
target_width *= oversampling_enable ? 2 : 1; target_width *= oversampling_enable ? 2 : 1;
target_height *= oversampling_enable ? 2 : 1; target_height *= oversampling_enable ? 2 : 1;
if (win->swap_xy()) if (win->swap_xy())
@ -2339,6 +2341,12 @@ void uniform::update()
m_shader->set_vector("ScreenDims", 2, &screendims.c.x); m_shader->set_vector("ScreenDims", 2, &screendims.c.x);
break; break;
} }
case CU_SCREEN_COUNT:
{
int screen_count = win->target()->current_view()->screens().count();
m_shader->set_int("ScreenCount", screen_count);
break;
}
case CU_SOURCE_DIMS: case CU_SOURCE_DIMS:
{ {
if (vector_screen) if (vector_screen)
@ -2347,8 +2355,8 @@ void uniform::update()
{ {
// vector screen has no source texture, so take the source dimensions of the render target // vector screen has no source texture, so take the source dimensions of the render target
float sourcedims[2] = { float sourcedims[2] = {
static_cast<float>(shadersys->curr_render_target->width), float(shadersys->curr_render_target->width),
static_cast<float>(shadersys->curr_render_target->height) }; float(shadersys->curr_render_target->height) };
m_shader->set_vector("SourceDims", 2, sourcedims); m_shader->set_vector("SourceDims", 2, sourcedims);
} }
} }
@ -2367,20 +2375,30 @@ void uniform::update()
if (shadersys->curr_render_target) if (shadersys->curr_render_target)
{ {
float targetdims[2] = { float targetdims[2] = {
static_cast<float>(shadersys->curr_render_target->target_width), float(shadersys->curr_render_target->target_width),
static_cast<float>(shadersys->curr_render_target->target_height) }; float(shadersys->curr_render_target->target_height) };
m_shader->set_vector("TargetDims", 2, targetdims); m_shader->set_vector("TargetDims", 2, targetdims);
} }
break; break;
} }
case CU_TARGET_SCALE:
{
if (shadersys->curr_render_target)
{
float targetscale[2] = {
shadersys->oversampling_enable ? 2.0f : 1.0f,
shadersys->oversampling_enable ? 2.0f : 1.0f };
m_shader->set_vector("TargetScale", 2, targetscale);
}
break;
}
case CU_QUAD_DIMS: case CU_QUAD_DIMS:
{ {
if (shadersys->curr_poly) if (shadersys->curr_poly)
{ {
float quaddims[2] = { float quaddims[2] = {
// round floor(shadersys->curr_poly->prim_width() + 0.5f),
static_cast<float>(static_cast<int>(shadersys->curr_poly->prim_width() + 0.5f)), floor(shadersys->curr_poly->prim_height() + 0.5f) };
static_cast<float>(static_cast<int>(shadersys->curr_poly->prim_height() + 0.5f)) };
m_shader->set_vector("QuadDims", 2, quaddims); m_shader->set_vector("QuadDims", 2, quaddims);
} }
break; break;
@ -2497,7 +2515,7 @@ void uniform::update()
break; break;
case CU_POST_SHADOW_COUNT: case CU_POST_SHADOW_COUNT:
{ {
float shadowcount[2] = { static_cast<float>(options->shadow_mask_count_x), static_cast<float>(options->shadow_mask_count_y) }; float shadowcount[2] = { float(options->shadow_mask_count_x), float(options->shadow_mask_count_y) };
m_shader->set_vector("ShadowCount", 2, shadowcount); m_shader->set_vector("ShadowCount", 2, shadowcount);
break; break;
} }

View File

@ -42,8 +42,10 @@ public:
enum enum
{ {
CU_SCREEN_DIMS = 0, CU_SCREEN_DIMS = 0,
CU_SCREEN_COUNT,
CU_SOURCE_DIMS, CU_SOURCE_DIMS,
CU_TARGET_DIMS, CU_TARGET_DIMS,
CU_TARGET_SCALE,
CU_QUAD_DIMS, CU_QUAD_DIMS,
CU_SWAP_XY, CU_SWAP_XY,

View File

@ -1423,6 +1423,8 @@ void renderer_d3d9::batch_vectors(int vector_count)
float quad_width = 0.0f; float quad_width = 0.0f;
float quad_height = 0.0f; float quad_height = 0.0f;
float target_width = 0.0f;
float target_height = 0.0f;
int vertex_count = vector_count * 6; int vertex_count = vector_count * 6;
int triangle_count = vector_count * 2; int triangle_count = vector_count * 2;
@ -1445,8 +1447,10 @@ void renderer_d3d9::batch_vectors(int vector_count)
case render_primitive::QUAD: case render_primitive::QUAD:
if (PRIMFLAG_GET_VECTORBUF(prim.flags)) if (PRIMFLAG_GET_VECTORBUF(prim.flags))
{ {
quad_width = prim.bounds.x1 - prim.bounds.x0; quad_width = prim.get_quad_width();
quad_height = prim.bounds.y1 - prim.bounds.y0; quad_height = prim.get_quad_height();
target_width = prim.get_full_quad_width();
target_height = prim.get_full_quad_height();
} }
break; break;
@ -1476,18 +1480,18 @@ void renderer_d3d9::batch_vectors(int vector_count)
((rotation_0 || rotation_90) && orientation_swap_xy) || ((rotation_0 || rotation_90) && orientation_swap_xy) ||
((rotation_180 || rotation_90) && !orientation_swap_xy); ((rotation_180 || rotation_90) && !orientation_swap_xy);
float screen_width = static_cast<float>(this->get_width()); float screen_width = float(this->get_width());
float screen_height = static_cast<float>(this->get_height()); float screen_height = float(this->get_height());
float half_screen_width = screen_width * 0.5f; float half_screen_width = screen_width * 0.5f;
float half_screen_height = screen_height * 0.5f; float half_screen_height = screen_height * 0.5f;
float screen_swap_x_factor = 1.0f / screen_width * screen_height; float screen_swap_x_factor = 1.0f / screen_width * screen_height;
float screen_swap_y_factor = 1.0f / screen_height * screen_width; float screen_swap_y_factor = 1.0f / screen_height * screen_width;
float screen_quad_ratio_x = screen_width / quad_width; float screen_target_ratio_x = screen_width / target_width;
float screen_quad_ratio_y = screen_height / quad_height; float screen_target_ratio_y = screen_height / target_height;
if (swap_xy) if (swap_xy)
{ {
std::swap(screen_quad_ratio_x, screen_quad_ratio_y); std::swap(screen_target_ratio_x, screen_target_ratio_y);
} }
for (int batchindex = 0; batchindex < m_batchindex; batchindex++) for (int batchindex = 0; batchindex < m_batchindex; batchindex++)
@ -1513,9 +1517,9 @@ void renderer_d3d9::batch_vectors(int vector_count)
m_vectorbatch[batchindex].x -= half_screen_width; m_vectorbatch[batchindex].x -= half_screen_width;
m_vectorbatch[batchindex].y -= half_screen_height; m_vectorbatch[batchindex].y -= half_screen_height;
// correct screen/quad ratio (vectors are created in screen coordinates and have to be adjusted for texture corrdinates of the quad) // correct screen/target ratio (vectors are created in screen coordinates and have to be adjusted for texture corrdinates of the target)
m_vectorbatch[batchindex].x *= screen_quad_ratio_x; m_vectorbatch[batchindex].x *= screen_target_ratio_x;
m_vectorbatch[batchindex].y *= screen_quad_ratio_y; m_vectorbatch[batchindex].y *= screen_target_ratio_y;
// un-center // un-center
m_vectorbatch[batchindex].x += half_screen_width; m_vectorbatch[batchindex].x += half_screen_width;
@ -1668,10 +1672,10 @@ void renderer_d3d9::draw_line(const render_primitive &prim)
vertex[0].u0 = start.c.x; vertex[0].u0 = start.c.x;
vertex[0].v0 = start.c.y; vertex[0].v0 = start.c.y;
vertex[2].u0 = stop.c.x;
vertex[2].v0 = start.c.y;
vertex[1].u0 = start.c.x; vertex[1].u0 = start.c.x;
vertex[1].v0 = stop.c.y; vertex[1].v0 = stop.c.y;
vertex[2].u0 = stop.c.x;
vertex[2].v0 = start.c.y;
vertex[3].u0 = stop.c.x; vertex[3].u0 = stop.c.x;
vertex[3].v0 = stop.c.y; vertex[3].v0 = stop.c.y;
@ -1703,7 +1707,6 @@ void renderer_d3d9::draw_line(const render_primitive &prim)
void renderer_d3d9::draw_quad(const render_primitive &prim) void renderer_d3d9::draw_quad(const render_primitive &prim)
{ {
texture_info *texture = m_texture_manager->find_texinfo(&prim.texture, prim.flags); texture_info *texture = m_texture_manager->find_texinfo(&prim.texture, prim.flags);
if (texture == nullptr) if (texture == nullptr)
{ {
texture = get_default_texture(); texture = get_default_texture();
@ -1712,7 +1715,9 @@ void renderer_d3d9::draw_quad(const render_primitive &prim)
// get a pointer to the vertex buffer // get a pointer to the vertex buffer
vertex *vertex = mesh_alloc(4); vertex *vertex = mesh_alloc(4);
if (vertex == nullptr) if (vertex == nullptr)
{
return; return;
}
// fill in the vertexes clockwise // fill in the vertexes clockwise
vertex[0].x = prim.bounds.x0; vertex[0].x = prim.bounds.x0;
@ -1723,8 +1728,8 @@ void renderer_d3d9::draw_quad(const render_primitive &prim)
vertex[2].y = prim.bounds.y1; vertex[2].y = prim.bounds.y1;
vertex[3].x = prim.bounds.x1; vertex[3].x = prim.bounds.x1;
vertex[3].y = prim.bounds.y1; vertex[3].y = prim.bounds.y1;
float width = prim.bounds.x1 - prim.bounds.x0; float quad_width = prim.get_quad_width();
float height = prim.bounds.y1 - prim.bounds.y0; float quad_height = prim.get_quad_height();
// set the texture coordinates // set the texture coordinates
if (texture != nullptr) if (texture != nullptr)
@ -1761,7 +1766,7 @@ void renderer_d3d9::draw_quad(const render_primitive &prim)
} }
// now add a polygon entry // now add a polygon entry
m_poly[m_numpolys].init(D3DPT_TRIANGLESTRIP, 2, 4, prim.flags, texture, D3DTOP_MODULATE, width, height); m_poly[m_numpolys].init(D3DPT_TRIANGLESTRIP, 2, 4, prim.flags, texture, D3DTOP_MODULATE, quad_width, quad_height);
m_numpolys++; m_numpolys++;
} }