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:
ImJezze 2016-06-05 23:50:44 +02:00
parent 396c2a0946
commit 6ea15072a7
24 changed files with 217 additions and 163 deletions

View file

@ -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

View file

@ -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)

View file

@ -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;

View file

@ -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;
}

View file

@ -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

View file

@ -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

View file

@ -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());

View file

@ -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 " },

View file

@ -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); }

View file

@ -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;
}

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -245,6 +245,7 @@ struct hlsl_options
int yiq_phase_count;
// Vectors
float vector_beam_smooth;
float vector_length_scale;
float vector_length_ratio;

View file

@ -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];

View file

@ -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

View file

@ -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);

View file

@ -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 */

View file

@ -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); }