mirror of
https://github.com/mamedev/mame.git
synced 2024-11-16 07:48:32 +01: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
24 changed files with 217 additions and 163 deletions
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 a new issue