mirror of
https://github.com/holub/mame
synced 2025-04-15 13:07:23 +03:00
Procedural texture for vectors in HLSL
* added simple procedural texture for vectors with rounded line ends and beam smoothness * added optional -vector_beam_smooth option * removed -antialias option, antialiasing is now always applied, except for plain D3D
This commit is contained in:
parent
396c2a0946
commit
6ea15072a7
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -876,18 +876,21 @@ Core screen options
|
||||
Core vector options
|
||||
-------------------
|
||||
|
||||
-[no]antialias / -[no]aa
|
||||
-beam_width_min <value>
|
||||
-beam_width_max <value>
|
||||
|
||||
Enables antialiased line rendering for vector games. The default is ON
|
||||
(-antialias).
|
||||
|
||||
-beam <width>
|
||||
|
||||
Sets the width of the vectors. This is a scaling factor against the
|
||||
standard vector width. A value of 1.0 will keep the default vector
|
||||
line width. Smaller values will reduce the width, and larger values
|
||||
Sets the minimum and maximum width of the vectors. This is a scaling factor
|
||||
against the standard vector width, which is interpolated between minimum and
|
||||
maximum according to the beam's intensity. A value of 1.0 will keep the default
|
||||
vector line width. Smaller values will reduce the width, and larger values
|
||||
will increase the width. The default is 1.0.
|
||||
|
||||
-beam_intensity_weight <value>
|
||||
|
||||
Applies an exponential weight to the minimum and maximum beam width. For positive
|
||||
values the interpolated scaling factor will affect lines with higher intensity
|
||||
more than lines with lower intensity. The default is 0.0.
|
||||
|
||||
-flicker <value>
|
||||
|
||||
Simulates a vector "flicker" effect, similar to a vector monitor that
|
||||
|
@ -97,6 +97,7 @@ yiq_phase_count 2 Phase Count value for NTSC signal proces
|
||||
Vector Post-Processing Options
|
||||
------------------------------
|
||||
Name Default Values Description
|
||||
vector_beam_smooth 0.0 The vector beam smoothness. (0.00 to 1.00)
|
||||
vector_length_scale 0.5 The maximum vector attenuation. (0.00 to 1.00)
|
||||
vector_length_ratio 0.5 The minimum vector length (vector length to screen size ratio)
|
||||
that is affected by the attenuation (0.000 to 1.000)
|
||||
@ -115,7 +116,7 @@ bloom_lvl3_weight 0.16 Bloom level 3 weight. (1/4 smaller that
|
||||
bloom_lvl4_weight 0.08 Bloom level 4 weight. (1/4 smaller that level 3 target) (0.00 to 1.00)
|
||||
bloom_lvl5_weight 0.06 Bloom level 5 weight. (1/4 smaller that level 4 target) (0.00 to 1.00)
|
||||
bloom_lvl6_weight 0.04 Bloom level 6 weight. (1/4 smaller that level 5 target) (0.00 to 1.00)
|
||||
bloom_lvl7_weight 0.02 Bloom level 7 weight. (1/4 smaller that level 6 target)
|
||||
bloom_lvl7_weight 0.02 Bloom level 7 weight. (1/4 smaller that level 6 target) (0.00 to 1.00)
|
||||
bloom_lvl8_weight 0.01 Bloom level 8 weight. (1/4 smaller that level 7 target) (0.00 to 1.00)
|
||||
|
||||
|
||||
|
@ -170,22 +170,18 @@ float GetSpotAddend(float2 coord, float amount)
|
||||
return saturate(SigmoidSpot);
|
||||
}
|
||||
|
||||
float GetRoundCornerFactor(float2 coord, float radiusAmount, float smoothAmount)
|
||||
float GetRoundCornerFactor(float2 coord, float2 bounds, float radiusAmount, float smoothAmount)
|
||||
{
|
||||
// reduce smooth amount down to radius amount
|
||||
smoothAmount = min(smoothAmount, radiusAmount);
|
||||
|
||||
float2 quadDims = QuadDims;
|
||||
quadDims = SwapXY
|
||||
? quadDims.yx
|
||||
: quadDims.xy;
|
||||
|
||||
float range = min(quadDims.x, quadDims.y) * 0.5;
|
||||
float radius = range * max(radiusAmount, 0.0025f);
|
||||
float smooth = 1.0 / (range * max(smoothAmount, 0.0025f));
|
||||
float range = min(bounds.x, bounds.y);
|
||||
float amountMinimum = range > 0.0f ? 1.0f / range : 0.0f;
|
||||
float radius = range * max(radiusAmount, amountMinimum);
|
||||
float smooth = 1.0f / (range * max(smoothAmount, amountMinimum * 3.0f));
|
||||
|
||||
// compute box
|
||||
float box = roundBox(quadDims * (coord * 2.0f), quadDims, radius);
|
||||
float box = roundBox(bounds * (coord * 2.0f), bounds, radius);
|
||||
|
||||
// apply smooth
|
||||
box *= smooth;
|
||||
@ -279,8 +275,11 @@ float4 ps_main(PS_INPUT Input) : COLOR
|
||||
|
||||
// Round Corners Simulation
|
||||
float2 RoundCornerCoord = CornerCoordCentered;
|
||||
float2 RoundCornerBounds = SwapXY
|
||||
? QuadDims.yx
|
||||
: QuadDims.xy;
|
||||
|
||||
float roundCornerFactor = GetRoundCornerFactor(RoundCornerCoord, RoundCornerAmount, SmoothBorderAmount);
|
||||
float roundCornerFactor = GetRoundCornerFactor(RoundCornerCoord, RoundCornerBounds, RoundCornerAmount * 0.5f, SmoothBorderAmount * 0.5f);
|
||||
BaseColor.rgb *= roundCornerFactor;
|
||||
|
||||
return BaseColor;
|
||||
|
@ -1,5 +1,5 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz
|
||||
// copyright-holders:Ryan Holtz,ImJezze
|
||||
//-----------------------------------------------------------------------------
|
||||
// Vector Effect
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -13,7 +13,7 @@ struct VS_OUTPUT
|
||||
float4 Position : POSITION;
|
||||
float4 Color : COLOR0;
|
||||
float2 TexCoord : TEXCOORD0;
|
||||
float2 LineInfo : TEXCOORD1;
|
||||
float2 SizeInfo : TEXCOORD1;
|
||||
};
|
||||
|
||||
struct VS_INPUT
|
||||
@ -21,16 +21,26 @@ struct VS_INPUT
|
||||
float3 Position : POSITION;
|
||||
float4 Color : COLOR0;
|
||||
float2 TexCoord : TEXCOORD0;
|
||||
float2 LineInfo : TEXCOORD1;
|
||||
float2 SizeInfo : TEXCOORD1;
|
||||
};
|
||||
|
||||
struct PS_INPUT
|
||||
{
|
||||
float4 Color : COLOR0;
|
||||
float2 TexCoord : TEXCOORD0;
|
||||
float2 LineInfo : TEXCOORD1; // x is the line length, y is unused
|
||||
float2 SizeInfo : TEXCOORD1;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Functions
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Vector Vertex Shader
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -49,7 +59,7 @@ VS_OUTPUT vs_main(VS_INPUT Input)
|
||||
Output.Position.xy *= 2.0f; // zoom
|
||||
|
||||
Output.TexCoord = Input.TexCoord;
|
||||
Output.LineInfo = Input.LineInfo;
|
||||
Output.SizeInfo = Input.SizeInfo;
|
||||
|
||||
Output.Color = Input.Color;
|
||||
|
||||
@ -64,10 +74,35 @@ uniform float TimeRatio; // Frame time of the vector (not set)
|
||||
uniform float TimeScale; // How much frame time affects the vector's fade (not set)
|
||||
uniform float LengthRatio; // Size at which fade is maximum
|
||||
uniform float LengthScale; // How much length affects the vector's fade
|
||||
uniform float BeamSmooth;
|
||||
|
||||
float GetRoundCornerFactor(float2 coord, float2 bounds, float radiusAmount, float smoothAmount)
|
||||
{
|
||||
// reduce smooth amount down to radius amount
|
||||
smoothAmount = min(smoothAmount, radiusAmount);
|
||||
|
||||
float range = min(bounds.x, bounds.y);
|
||||
float amountMinimum = range > 0.0f ? 1.0f / range : 0.0f;
|
||||
float radius = range * max(radiusAmount, amountMinimum);
|
||||
float smooth = 1.0f / (range * max(smoothAmount, amountMinimum * 3.0f));
|
||||
|
||||
// compute box
|
||||
float box = roundBox(bounds * (coord * 2.0f), bounds, 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);
|
||||
}
|
||||
|
||||
float4 ps_main(PS_INPUT Input) : COLOR
|
||||
{
|
||||
float lineLength = Input.LineInfo.x / max(QuadDims.x, QuadDims.y); // normalize
|
||||
float2 lineSize = Input.SizeInfo / max(QuadDims.x, QuadDims.y); // normalize
|
||||
|
||||
float lineLength = lineSize.x;
|
||||
float lineLengthRatio = LengthRatio;
|
||||
float lineLengthScale = LengthScale;
|
||||
|
||||
@ -78,6 +113,9 @@ float4 ps_main(PS_INPUT Input) : COLOR
|
||||
float4 outColor = float4(timeLengthModulate, timeLengthModulate, timeLengthModulate, 1.0f);
|
||||
outColor *= Input.Color;
|
||||
|
||||
float RoundCornerFactor = GetRoundCornerFactor(Input.TexCoord - 0.5f, Input.SizeInfo, 1.0f, BeamSmooth);
|
||||
outColor.rgb *= RoundCornerFactor;
|
||||
|
||||
return outColor;
|
||||
}
|
||||
|
||||
|
@ -6,8 +6,7 @@ gamma 0.50
|
||||
#
|
||||
# CORE VECTOR OPTIONS
|
||||
#
|
||||
antialias 1
|
||||
beam_width_min 0.75
|
||||
beam_width_min 1.00
|
||||
beam_width_max 4.00
|
||||
beam_intensity_weight 0.75
|
||||
flicker 0.15
|
||||
@ -48,6 +47,7 @@ yiq_enable 0
|
||||
#
|
||||
# VECTOR POST-PROCESSING OPTIONS
|
||||
#
|
||||
vector_beam_smooth 0.0
|
||||
vector_length_scale 0.5
|
||||
vector_length_ratio 0.5
|
||||
|
||||
|
@ -1,8 +1,7 @@
|
||||
#
|
||||
# CORE VECTOR OPTIONS
|
||||
#
|
||||
antialias 1
|
||||
beam_width_min 0.75
|
||||
beam_width_min 1.00
|
||||
beam_width_max 4.00
|
||||
beam_intensity_weight 0.75
|
||||
flicker 0.15
|
||||
@ -51,6 +50,7 @@ yiq_enable 0
|
||||
#
|
||||
# VECTOR POST-PROCESSING OPTIONS
|
||||
#
|
||||
vector_beam_smooth 0.0
|
||||
vector_length_scale 0.5
|
||||
vector_length_ratio 0.5
|
||||
|
||||
|
@ -145,7 +145,7 @@ void vector_device::clear_list(void)
|
||||
|
||||
UINT32 vector_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
UINT32 flags = PRIMFLAG_ANTIALIAS(machine().options().antialias() ? 1 : 0) | PRIMFLAG_BLENDMODE(BLENDMODE_ADD) | PRIMFLAG_VECTOR(1);
|
||||
UINT32 flags = PRIMFLAG_ANTIALIAS(1) | PRIMFLAG_BLENDMODE(BLENDMODE_ADD) | PRIMFLAG_VECTOR(1);
|
||||
const rectangle &visarea = screen.visible_area();
|
||||
float xscale = 1.0f / (65536 * visarea.width());
|
||||
float yscale = 1.0f / (65536 * visarea.height());
|
||||
|
@ -120,7 +120,6 @@ const options_entry emu_options::s_option_entries[] =
|
||||
|
||||
// vector options
|
||||
{ nullptr, nullptr, OPTION_HEADER, "CORE VECTOR OPTIONS" },
|
||||
{ OPTION_ANTIALIAS ";aa", "1", OPTION_BOOLEAN, "use antialiasing when drawing vectors" },
|
||||
{ OPTION_BEAM_WIDTH_MIN, "1.0", OPTION_FLOAT, "set vector beam width minimum" },
|
||||
{ OPTION_BEAM_WIDTH_MAX, "1.0", OPTION_FLOAT, "set vector beam width maximum" },
|
||||
{ OPTION_BEAM_INTENSITY_WEIGHT, "0", OPTION_FLOAT, "set vector beam intensity weight " },
|
||||
|
@ -108,7 +108,6 @@
|
||||
#define OPTION_EFFECT "effect"
|
||||
|
||||
// core vector options
|
||||
#define OPTION_ANTIALIAS "antialias"
|
||||
#define OPTION_BEAM_WIDTH_MIN "beam_width_min"
|
||||
#define OPTION_BEAM_WIDTH_MAX "beam_width_max"
|
||||
#define OPTION_BEAM_INTENSITY_WEIGHT "beam_intensity_weight"
|
||||
@ -295,7 +294,6 @@ public:
|
||||
const char *effect() const { return value(OPTION_EFFECT); }
|
||||
|
||||
// core vector options
|
||||
bool antialias() const { return bool_value(OPTION_ANTIALIAS); }
|
||||
float beam_width_min() const { return float_value(OPTION_BEAM_WIDTH_MIN); }
|
||||
float beam_width_max() const { return float_value(OPTION_BEAM_WIDTH_MAX); }
|
||||
float beam_intensity_weight() const { return float_value(OPTION_BEAM_INTENSITY_WEIGHT); }
|
||||
|
@ -535,7 +535,7 @@ void render_line_to_quad(const render_bounds *bounds, float width, float length_
|
||||
bounds1->x0 = modbounds.x1 - unity;
|
||||
bounds1->y0 = modbounds.y1 + unitx;
|
||||
|
||||
/* rotate the unit vector by -09 degrees and add to point 1 */
|
||||
/* rotate the unit vector by -90 degrees and add to point 1 */
|
||||
bounds1->x1 = modbounds.x1 + unity;
|
||||
bounds1->y1 = modbounds.y1 - unitx;
|
||||
}
|
||||
|
@ -2015,8 +2015,8 @@ std::vector<ui::menu_item> mame_ui_manager::slider_init(running_machine &machine
|
||||
{
|
||||
// add vector control
|
||||
sliders.push_back(slider_alloc(machine, SLIDER_ID_FLICKER + slider_index, _("Vector Flicker"), 0, 0, 1000, 10, nullptr));
|
||||
sliders.push_back(slider_alloc(machine, SLIDER_ID_BEAM_WIDTH_MIN + slider_index, _("Beam Width Minimum"), 1, 100, 1000, 1, nullptr));
|
||||
sliders.push_back(slider_alloc(machine, SLIDER_ID_BEAM_WIDTH_MAX + slider_index, _("Beam Width Maximum"), 1, 100, 1000, 1, nullptr));
|
||||
sliders.push_back(slider_alloc(machine, SLIDER_ID_BEAM_WIDTH_MIN + slider_index, _("Beam Width Minimum"), 100, 100, 1000, 1, nullptr));
|
||||
sliders.push_back(slider_alloc(machine, SLIDER_ID_BEAM_WIDTH_MAX + slider_index, _("Beam Width Maximum"), 100, 100, 1000, 1, nullptr));
|
||||
sliders.push_back(slider_alloc(machine, SLIDER_ID_BEAM_INTENSITY + slider_index, _("Beam Intensity Weight"), -1000, 0, 1000, 10, nullptr));
|
||||
slider_index++;
|
||||
break;
|
||||
|
@ -97,19 +97,18 @@ float GetSpotAddend(vec2 coord, float amount)
|
||||
return saturate(SigmoidSpot);
|
||||
}
|
||||
|
||||
float GetRoundCornerFactor(vec2 coord, float radiusAmount, float smoothAmount)
|
||||
float GetRoundCornerFactor(vec2 coord, vec2 bounds, float radiusAmount, float smoothAmount)
|
||||
{
|
||||
// reduce smooth amount down to radius amount
|
||||
smoothAmount = min(smoothAmount, radiusAmount);
|
||||
|
||||
vec2 quadDims = (u_swap_xy.x > 0.0) ? u_quad_dims.yx : u_quad_dims.xy;
|
||||
|
||||
float range = min(quadDims.x, quadDims.y) * 0.5;
|
||||
float radius = range * max(radiusAmount, 0.0025);
|
||||
float smooth_val = 1.0 / (range * max(smoothAmount, 0.0025));
|
||||
float range = min(bounds.x, bounds.y);
|
||||
float amountMinimum = range > 0.0f ? 1.0f / range : 0.0f;
|
||||
float radius = range * max(radiusAmount, amountMinimum);
|
||||
float smooth_val = 1.0f / (range * max(smoothAmount, amountMinimum * 3.0f));
|
||||
|
||||
// compute box
|
||||
float box = roundBox(quadDims * (coord * 2.0f), quadDims, radius);
|
||||
float box = roundBox(bounds * (coord * 2.0f), bounds, radius);
|
||||
|
||||
// apply smooth
|
||||
box *= smooth_val;
|
||||
@ -206,8 +205,11 @@ void main()
|
||||
|
||||
// Round Corners Simulation
|
||||
vec2 RoundCornerCoord = CornerCoordCentered;
|
||||
vec2 RoundCornerBounds = (u_swap_xy.x > 0.0)
|
||||
? u_quad_dims.yx
|
||||
: u_quad_dims.xy;
|
||||
|
||||
float roundCornerFactor = GetRoundCornerFactor(RoundCornerCoord, u_round_corner.x, u_smooth_border.x);
|
||||
float roundCornerFactor = GetRoundCornerFactor(RoundCornerCoord, RoundCornerBounds, u_round_corner.x * 0.5f, u_smooth_border.x * 0.5f);
|
||||
BaseColor.rgb *= roundCornerFactor;
|
||||
|
||||
gl_FragColor = BaseColor;
|
||||
|
@ -722,6 +722,7 @@ void shaders::init(d3d_base *d3dintf, running_machine *machine, renderer_d3d9 *r
|
||||
options->yiq_q = winoptions.screen_yiq_q();
|
||||
options->yiq_scan_time = winoptions.screen_yiq_scan_time();
|
||||
options->yiq_phase_count = winoptions.screen_yiq_phase_count();
|
||||
options->vector_beam_smooth = winoptions.screen_vector_beam_smooth();
|
||||
options->vector_length_scale = winoptions.screen_vector_length_scale();
|
||||
options->vector_length_ratio = winoptions.screen_vector_length_ratio();
|
||||
options->bloom_blend_mode = winoptions.screen_bloom_blend_mode();
|
||||
@ -1524,6 +1525,7 @@ int shaders::vector_pass(d3d_render_target *rt, int source_index, poly_info *pol
|
||||
// curr_effect->set_float("TimeScale", options->vector_time_scale);
|
||||
curr_effect->set_float("LengthRatio", options->vector_length_ratio);
|
||||
curr_effect->set_float("LengthScale", options->vector_length_scale);
|
||||
curr_effect->set_float("BeamSmooth", options->vector_beam_smooth);
|
||||
|
||||
blit(rt->target_surface[next_index], true, poly->get_type(), vertnum, poly->get_count());
|
||||
|
||||
@ -2285,7 +2287,8 @@ hlsl_options shaders::last_options = { false };
|
||||
|
||||
enum slider_option
|
||||
{
|
||||
SLIDER_VECTOR_ATT_MAX = 0,
|
||||
SLIDER_VECTOR_BEAM_SMOOTH = 0,
|
||||
SLIDER_VECTOR_ATT_MAX,
|
||||
SLIDER_VECTOR_ATT_LEN_MIN,
|
||||
SLIDER_SHADOW_MASK_TILE_MODE,
|
||||
SLIDER_SHADOW_MASK_ALPHA,
|
||||
@ -2362,6 +2365,7 @@ enum slider_screen_type
|
||||
|
||||
slider_desc shaders::s_sliders[] =
|
||||
{
|
||||
{ "Vector Beam Smooth Amount", 0, 0, 100, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_VECTOR, SLIDER_VECTOR_BEAM_SMOOTH, 0.01f, "%1.2f", {} },
|
||||
{ "Vector Attenuation Maximum", 0, 50, 100, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_VECTOR, SLIDER_VECTOR_ATT_MAX, 0.01f, "%1.2f", {} },
|
||||
{ "Vector Attenuation Length Minimum", 1, 500, 1000, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_VECTOR, SLIDER_VECTOR_ATT_LEN_MIN, 0.001f, "%1.3f", {} },
|
||||
{ "Shadow Mask Tile Mode", 0, 0, 1, 1, SLIDER_INT_ENUM, SLIDER_SCREEN_TYPE_ANY, SLIDER_SHADOW_MASK_TILE_MODE, 0, "%s", { "Screen", "Source" } },
|
||||
@ -2433,6 +2437,7 @@ void *shaders::get_slider_option(int id, int index)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case SLIDER_VECTOR_BEAM_SMOOTH: return &(options->vector_beam_smooth);
|
||||
case SLIDER_VECTOR_ATT_MAX: return &(options->vector_length_scale);
|
||||
case SLIDER_VECTOR_ATT_LEN_MIN: return &(options->vector_length_ratio);
|
||||
case SLIDER_SHADOW_MASK_TILE_MODE: return &(options->shadow_mask_tile_mode);
|
||||
|
@ -245,6 +245,7 @@ struct hlsl_options
|
||||
int yiq_phase_count;
|
||||
|
||||
// Vectors
|
||||
float vector_beam_smooth;
|
||||
float vector_length_scale;
|
||||
float vector_length_ratio;
|
||||
|
||||
|
@ -624,6 +624,13 @@ void renderer_bgfx::put_line(float x0, float y0, float x1, float y1, float r, UI
|
||||
dy *= d;
|
||||
}
|
||||
|
||||
// create diamond shape for points
|
||||
else
|
||||
{
|
||||
// set distance to unit vector length (1,1)
|
||||
dx = dy = 0.70710678f;
|
||||
}
|
||||
|
||||
float nx = dy;
|
||||
float ny = -dx;
|
||||
float verts[4 * 3];
|
||||
|
@ -41,33 +41,6 @@ enum
|
||||
};
|
||||
|
||||
|
||||
//============================================================
|
||||
// MACROS
|
||||
//============================================================
|
||||
|
||||
#define FSWAP(var1, var2) do { float temp = var1; var1 = var2; var2 = temp; } while (0)
|
||||
|
||||
|
||||
//============================================================
|
||||
// GLOBALS
|
||||
//============================================================
|
||||
|
||||
static const line_aa_step line_aa_1step[] =
|
||||
{
|
||||
{ 0.00f, 0.00f, 1.00f },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const line_aa_step line_aa_4step[] =
|
||||
{
|
||||
{ -0.25f, 0.00f, 0.25f },
|
||||
{ 0.25f, 0.00f, 0.25f },
|
||||
{ 0.00f, -0.25f, 0.25f },
|
||||
{ 0.00f, 0.25f, 0.25f },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
||||
//============================================================
|
||||
// INLINES
|
||||
//============================================================
|
||||
@ -1388,13 +1361,11 @@ void renderer_d3d9::batch_vectors(int vector_count)
|
||||
{
|
||||
auto win = assert_window();
|
||||
|
||||
windows_options &options = downcast<windows_options &>(win->machine().options());
|
||||
|
||||
float quad_width = 0.0f;
|
||||
float quad_height = 0.0f;
|
||||
|
||||
int vertex_count = vector_count * (options.antialias() ? 24 : 6);
|
||||
int triangle_count = vector_count * (options.antialias() ? 8 : 2);
|
||||
int vertex_count = vector_count * 6;
|
||||
int triangle_count = vector_count * 2;
|
||||
m_vectorbatch = mesh_alloc(vertex_count);
|
||||
m_batchindex = 0;
|
||||
|
||||
@ -1499,71 +1470,103 @@ void renderer_d3d9::batch_vectors(int vector_count)
|
||||
|
||||
void renderer_d3d9::batch_vector(const render_primitive &prim)
|
||||
{
|
||||
// get a pointer to the vertex buffer
|
||||
if (m_vectorbatch == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// compute the effective width based on the direction of the line
|
||||
float effwidth = prim.width;
|
||||
if (effwidth < 0.5f)
|
||||
if (effwidth < 2.0f)
|
||||
{
|
||||
effwidth = 0.5f;
|
||||
effwidth = 2.0f;
|
||||
}
|
||||
|
||||
// determine the bounds of a quad to draw this line
|
||||
render_bounds b0, b1;
|
||||
render_line_to_quad(&prim.bounds, effwidth, effwidth, &b0, &b1);
|
||||
|
||||
float dx = b1.x1 - b0.x1;
|
||||
float dy = b1.y1 - b0.y1;
|
||||
float line_length = sqrtf(dx * dx + dy * dy);
|
||||
float lx = b1.x1 - b0.x1;
|
||||
float ly = b1.y1 - b0.y1;
|
||||
float wx = b1.x1 - b1.x0;
|
||||
float wy = b1.y1 - b1.y0;
|
||||
float line_length = sqrtf(lx * lx + ly * ly);
|
||||
float line_width = sqrtf(wx * wx + wy * wy);
|
||||
|
||||
// iterate over AA steps
|
||||
for (const line_aa_step *step = PRIMFLAG_GET_ANTIALIAS(prim.flags) ? line_aa_4step : line_aa_1step;
|
||||
step->weight != 0; step++)
|
||||
m_vectorbatch[m_batchindex + 0].x = b0.x0;
|
||||
m_vectorbatch[m_batchindex + 0].y = b0.y0;
|
||||
m_vectorbatch[m_batchindex + 1].x = b0.x1;
|
||||
m_vectorbatch[m_batchindex + 1].y = b0.y1;
|
||||
m_vectorbatch[m_batchindex + 2].x = b1.x0;
|
||||
m_vectorbatch[m_batchindex + 2].y = b1.y0;
|
||||
|
||||
m_vectorbatch[m_batchindex + 3].x = b0.x1;
|
||||
m_vectorbatch[m_batchindex + 3].y = b0.y1;
|
||||
m_vectorbatch[m_batchindex + 4].x = b1.x0;
|
||||
m_vectorbatch[m_batchindex + 4].y = b1.y0;
|
||||
m_vectorbatch[m_batchindex + 5].x = b1.x1;
|
||||
m_vectorbatch[m_batchindex + 5].y = b1.y1;
|
||||
|
||||
if (m_shaders->enabled())
|
||||
{
|
||||
// get a pointer to the vertex buffer
|
||||
if (m_vectorbatch == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// procedural generated texture
|
||||
m_vectorbatch[m_batchindex + 0].u0 = 0.0f;
|
||||
m_vectorbatch[m_batchindex + 0].v0 = 0.0f;
|
||||
m_vectorbatch[m_batchindex + 1].u0 = 0.0f;
|
||||
m_vectorbatch[m_batchindex + 1].v0 = 1.0f;
|
||||
m_vectorbatch[m_batchindex + 2].u0 = 1.0f;
|
||||
m_vectorbatch[m_batchindex + 2].v0 = 0.0f;
|
||||
|
||||
m_vectorbatch[m_batchindex + 0].x = b0.x0 + step->xoffs;
|
||||
m_vectorbatch[m_batchindex + 0].y = b0.y0 + step->yoffs;
|
||||
m_vectorbatch[m_batchindex + 1].x = b0.x1 + step->xoffs;
|
||||
m_vectorbatch[m_batchindex + 1].y = b0.y1 + step->yoffs;
|
||||
m_vectorbatch[m_batchindex + 2].x = b1.x0 + step->xoffs;
|
||||
m_vectorbatch[m_batchindex + 2].y = b1.y0 + step->yoffs;
|
||||
|
||||
m_vectorbatch[m_batchindex + 3].x = b0.x1 + step->xoffs;
|
||||
m_vectorbatch[m_batchindex + 3].y = b0.y1 + step->yoffs;
|
||||
m_vectorbatch[m_batchindex + 4].x = b1.x0 + step->xoffs;
|
||||
m_vectorbatch[m_batchindex + 4].y = b1.y0 + step->yoffs;
|
||||
m_vectorbatch[m_batchindex + 5].x = b1.x1 + step->xoffs;
|
||||
m_vectorbatch[m_batchindex + 5].y = b1.y1 + step->yoffs;
|
||||
|
||||
// determine the color of the line
|
||||
INT32 r = (INT32)(prim.color.r * step->weight * 255.0f);
|
||||
INT32 g = (INT32)(prim.color.g * step->weight * 255.0f);
|
||||
INT32 b = (INT32)(prim.color.b * step->weight * 255.0f);
|
||||
INT32 a = (INT32)(prim.color.a * 255.0f);
|
||||
DWORD color = D3DCOLOR_ARGB(a, r, g, b);
|
||||
|
||||
// set the color, Z parameters to standard values
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
m_vectorbatch[m_batchindex + i].x -= 0.5f;
|
||||
m_vectorbatch[m_batchindex + i].y -= 0.5f;
|
||||
m_vectorbatch[m_batchindex + i].z = 0.0f;
|
||||
m_vectorbatch[m_batchindex + i].rhw = 1.0f;
|
||||
m_vectorbatch[m_batchindex + i].color = color;
|
||||
|
||||
// no texture mapping
|
||||
m_vectorbatch[m_batchindex + i].u0 = 0.0f;
|
||||
m_vectorbatch[m_batchindex + i].v0 = 0.0f;
|
||||
|
||||
// line length
|
||||
m_vectorbatch[m_batchindex + i].u1 = line_length;
|
||||
}
|
||||
|
||||
m_batchindex += 6;
|
||||
m_vectorbatch[m_batchindex + 3].u0 = 0.0f;
|
||||
m_vectorbatch[m_batchindex + 3].v0 = 1.0f;
|
||||
m_vectorbatch[m_batchindex + 4].u0 = 1.0f;
|
||||
m_vectorbatch[m_batchindex + 4].v0 = 0.0f;
|
||||
m_vectorbatch[m_batchindex + 5].u0 = 1.0f;
|
||||
m_vectorbatch[m_batchindex + 5].v0 = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
vec2f& start = get_default_texture()->get_uvstart();
|
||||
vec2f& stop = get_default_texture()->get_uvstop();
|
||||
|
||||
m_vectorbatch[m_batchindex + 0].u0 = start.c.x;
|
||||
m_vectorbatch[m_batchindex + 0].v0 = start.c.y;
|
||||
m_vectorbatch[m_batchindex + 1].u0 = start.c.x;
|
||||
m_vectorbatch[m_batchindex + 1].v0 = stop.c.y;
|
||||
m_vectorbatch[m_batchindex + 2].u0 = stop.c.x;
|
||||
m_vectorbatch[m_batchindex + 2].v0 = start.c.y;
|
||||
|
||||
m_vectorbatch[m_batchindex + 3].u0 = start.c.x;
|
||||
m_vectorbatch[m_batchindex + 3].v0 = stop.c.y;
|
||||
m_vectorbatch[m_batchindex + 4].u0 = stop.c.x;
|
||||
m_vectorbatch[m_batchindex + 4].v0 = start.c.y;
|
||||
m_vectorbatch[m_batchindex + 5].u0 = stop.c.x;
|
||||
m_vectorbatch[m_batchindex + 5].v0 = stop.c.y;
|
||||
}
|
||||
|
||||
// determine the color of the line
|
||||
INT32 r = (INT32)(prim.color.r * 255.0f);
|
||||
INT32 g = (INT32)(prim.color.g * 255.0f);
|
||||
INT32 b = (INT32)(prim.color.b * 255.0f);
|
||||
INT32 a = (INT32)(prim.color.a * 255.0f);
|
||||
DWORD color = D3DCOLOR_ARGB(a, r, g, b);
|
||||
|
||||
// set the color, Z parameters to standard values
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
m_vectorbatch[m_batchindex + i].x -= 0.5f;
|
||||
m_vectorbatch[m_batchindex + i].y -= 0.5f;
|
||||
m_vectorbatch[m_batchindex + i].z = 0.0f;
|
||||
m_vectorbatch[m_batchindex + i].rhw = 1.0f;
|
||||
m_vectorbatch[m_batchindex + i].color = color;
|
||||
|
||||
// vector length/width
|
||||
m_vectorbatch[m_batchindex + i].u1 = line_length;
|
||||
m_vectorbatch[m_batchindex + i].v1 = line_width;
|
||||
}
|
||||
|
||||
m_batchindex += 6;
|
||||
}
|
||||
|
||||
|
||||
@ -1573,38 +1576,45 @@ void renderer_d3d9::batch_vector(const render_primitive &prim)
|
||||
|
||||
void renderer_d3d9::draw_line(const render_primitive &prim)
|
||||
{
|
||||
// get a pointer to the vertex buffer
|
||||
vertex *vertex = mesh_alloc(4);
|
||||
if (vertex == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// compute the effective width based on the direction of the line
|
||||
float effwidth = prim.width;
|
||||
if (effwidth < 0.5f)
|
||||
if (effwidth < 1.0f)
|
||||
{
|
||||
effwidth = 0.5f;
|
||||
effwidth = 1.0f;
|
||||
}
|
||||
|
||||
// determine the bounds of a quad to draw this line
|
||||
render_bounds b0, b1;
|
||||
render_line_to_quad(&prim.bounds, effwidth, 0.0f, &b0, &b1);
|
||||
|
||||
// get a pointer to the vertex buffer
|
||||
vertex *vertex = mesh_alloc(4);
|
||||
if (vertex == nullptr)
|
||||
return;
|
||||
|
||||
// rotate the unit vector by 135 degrees and add to point 0
|
||||
vertex[0].x = b0.x0;
|
||||
vertex[0].y = b0.y0;
|
||||
|
||||
// rotate the unit vector by -135 degrees and add to point 0
|
||||
vertex[1].x = b0.x1;
|
||||
vertex[1].y = b0.y1;
|
||||
|
||||
// rotate the unit vector by 45 degrees and add to point 1
|
||||
vertex[2].x = b1.x0;
|
||||
vertex[2].y = b1.y0;
|
||||
|
||||
// rotate the unit vector by -45 degrees and add to point 1
|
||||
vertex[3].x = b1.x1;
|
||||
vertex[3].y = b1.y1;
|
||||
|
||||
vec2f& start = get_default_texture()->get_uvstart();
|
||||
vec2f& stop = get_default_texture()->get_uvstop();
|
||||
|
||||
vertex[0].u0 = start.c.x;
|
||||
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].v0 = stop.c.y;
|
||||
vertex[3].u0 = stop.c.x;
|
||||
vertex[3].v0 = stop.c.y;
|
||||
|
||||
// determine the color of the line
|
||||
INT32 r = (INT32)(prim.color.r * 255.0f);
|
||||
INT32 g = (INT32)(prim.color.g * 255.0f);
|
||||
@ -1618,10 +1628,6 @@ void renderer_d3d9::draw_line(const render_primitive &prim)
|
||||
vertex[i].z = 0.0f;
|
||||
vertex[i].rhw = 1.0f;
|
||||
vertex[i].color = color;
|
||||
|
||||
// no texture mapping
|
||||
vertex[i].u0 = 0.0f;
|
||||
vertex[i].v0 = 0.0f;
|
||||
}
|
||||
|
||||
// now add a polygon entry
|
||||
|
@ -1085,22 +1085,14 @@ int renderer_ogl::draw(const int update)
|
||||
// we're doing nothing 3d, so the Z-buffer is currently not interesting
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
if (win->machine().options().antialias())
|
||||
{
|
||||
// enable antialiasing for lines
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
// enable antialiasing for points
|
||||
glEnable(GL_POINT_SMOOTH);
|
||||
// enable antialiasing for lines
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
// enable antialiasing for points
|
||||
glEnable(GL_POINT_SMOOTH);
|
||||
|
||||
// prefer quality to speed
|
||||
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
|
||||
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_LINE_SMOOTH);
|
||||
glDisable(GL_POINT_SMOOTH);
|
||||
}
|
||||
// prefer quality to speed
|
||||
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
|
||||
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
|
||||
|
||||
// enable blending
|
||||
glEnable(GL_BLEND);
|
||||
|
@ -217,6 +217,7 @@ const options_entry windows_options::s_option_entries[] =
|
||||
{ WINOPTION_YIQ_PHASE_COUNT";yiqp", "2", OPTION_INTEGER, "Phase Count value for NTSC signal processing" },
|
||||
/* Vector simulation below this line */
|
||||
{ nullptr, nullptr, OPTION_HEADER, "VECTOR POST-PROCESSING OPTIONS" },
|
||||
{ WINOPTION_VECTOR_BEAM_SMOOTH";vecsmooth", "0.0", OPTION_FLOAT, "The vector beam smoothness" },
|
||||
{ WINOPTION_VECTOR_LENGTH_SCALE";vecscale", "0.5", OPTION_FLOAT, "The maximum vector attenuation" },
|
||||
{ WINOPTION_VECTOR_LENGTH_RATIO";vecratio", "0.5", OPTION_FLOAT, "The minimum vector length (vector length to screen size ratio) that is affected by the attenuation" },
|
||||
/* Bloom below this line */
|
||||
|
@ -83,6 +83,7 @@
|
||||
#define WINOPTION_YIQ_QVALUE "yiq_q"
|
||||
#define WINOPTION_YIQ_SCAN_TIME "yiq_scan_time"
|
||||
#define WINOPTION_YIQ_PHASE_COUNT "yiq_phase_count"
|
||||
#define WINOPTION_VECTOR_BEAM_SMOOTH "vector_beam_smooth"
|
||||
#define WINOPTION_VECTOR_LENGTH_SCALE "vector_length_scale"
|
||||
#define WINOPTION_VECTOR_LENGTH_RATIO "vector_length_ratio"
|
||||
#define WINOPTION_BLOOM_BLEND_MODE "bloom_blend_mode"
|
||||
@ -177,6 +178,7 @@ public:
|
||||
float screen_yiq_q() const { return float_value(WINOPTION_YIQ_QVALUE); }
|
||||
float screen_yiq_scan_time() const { return float_value(WINOPTION_YIQ_SCAN_TIME); }
|
||||
int screen_yiq_phase_count() const { return int_value(WINOPTION_YIQ_PHASE_COUNT); }
|
||||
float screen_vector_beam_smooth() const { return float_value(WINOPTION_VECTOR_BEAM_SMOOTH); }
|
||||
float screen_vector_length_scale() const { return float_value(WINOPTION_VECTOR_LENGTH_SCALE); }
|
||||
float screen_vector_length_ratio() const { return float_value(WINOPTION_VECTOR_LENGTH_RATIO); }
|
||||
int screen_bloom_blend_mode() const { return int_value(WINOPTION_BLOOM_BLEND_MODE); }
|
||||
|
Loading…
Reference in New Issue
Block a user