Add screen-specific shader chain support, nw

This commit is contained in:
therealmogminer@gmail.com 2016-03-23 15:11:12 +01:00
parent 5fa870ccee
commit 9f48ad4fbb
64 changed files with 218 additions and 114 deletions

View File

@ -18,7 +18,7 @@
"fragment": "fs_defocus", "fragment": "fs_defocus",
"uniforms": [ "uniforms": [
{ "name": "s_tex", "type": "int", "values": [ 1.0 ] }, { "name": "s_tex", "type": "int", "values": [ 1.0 ] },
{ "name": "u_screen_dims", "type": "vec4", "values": [ 1.0, 0.0, 0.0, 0.0 ] }, { "name": "u_tex_size0", "type": "vec4", "values": [ 1.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_defocus", "type": "vec4", "values": [ 0.5, 0.5, 0.0, 0.0 ] } { "name": "u_defocus", "type": "vec4", "values": [ 0.5, 0.5, 0.0, 0.0 ] }
] ]
} }

View File

@ -17,13 +17,16 @@
"vertex": "vs_distortion", "vertex": "vs_distortion",
"fragment": "fs_distortion", "fragment": "fs_distortion",
"uniforms": [ "uniforms": [
{ "name": "s_tex", "type": "int", "values": [ 0.0 ] }, { "name": "s_tex", "type": "int", "values": [ 0.0 ] },
{ "name": "u_screen_dims", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] }, { "name": "u_swap_xy", "type": "vec4", "values": [ 0.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_curvature", "type": "vec4", "values": [ 0.25, 0.0, 0.0, 0.0 ] }, { "name": "u_screen_dims", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] },
{ "name": "u_round_corner", "type": "vec4", "values": [ 0.2, 0.0, 0.0, 0.0 ] }, { "name": "u_quad_dims", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] },
{ "name": "u_smooth_border", "type": "vec4", "values": [ 0.05, 0.0, 0.0, 0.0 ] }, { "name": "u_rotation_type", "type": "vec4", "values": [ 0.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_vignetting", "type": "vec4", "values": [ 0.20, 0.0, 0.0, 0.0 ] }, { "name": "u_prepare_vector", "type": "vec4", "values": [ 0.0, 0.0, 0.0, 0.0 ] },
{ "name": "u_reflection", "type": "vec4", "values": [ 0.30, 0.0, 0.0, 0.0 ] }, { "name": "u_curvature", "type": "vec4", "values": [ 0.25, 0.0, 0.0, 0.0 ] },
{ "name": "u_rotation_type", "type": "vec4", "values": [ 0.0, 0.0, 0.0, 0.0 ] } { "name": "u_round_corner", "type": "vec4", "values": [ 0.2, 0.0, 0.0, 0.0 ] },
{ "name": "u_smooth_border", "type": "vec4", "values": [ 0.05, 0.0, 0.0, 0.0 ] },
{ "name": "u_vignetting", "type": "vec4", "values": [ 0.20, 0.0, 0.0, 0.0 ] },
{ "name": "u_reflection", "type": "vec4", "values": [ 0.30, 0.0, 0.0, 0.0 ] }
] ]
} }

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -144,7 +144,7 @@ const options_entry osd_options::s_option_entries[] =
{ OSDOPTION_BGFX_PATH, "bgfx", OPTION_STRING, "path to BGFX-related files" }, { OSDOPTION_BGFX_PATH, "bgfx", OPTION_STRING, "path to BGFX-related files" },
{ OSDOPTION_BGFX_BACKEND, "auto", OPTION_STRING, "BGFX backend to use (d3d9, d3d11, metal, opengl, gles)" }, { OSDOPTION_BGFX_BACKEND, "auto", OPTION_STRING, "BGFX backend to use (d3d9, d3d11, metal, opengl, gles)" },
{ OSDOPTION_BGFX_DEBUG, "0", OPTION_BOOLEAN, "enable BGFX debugging statistics" }, { OSDOPTION_BGFX_DEBUG, "0", OPTION_BOOLEAN, "enable BGFX debugging statistics" },
{ OSDOPTION_BGFX_SCREEN_CHAIN, "default", OPTION_STRING, "screen chain JSON file to use" }, { OSDOPTION_BGFX_SCREEN_CHAINS, "default", OPTION_STRING, "comma-delimited list of JSON files to use per-screen" },
{ OSDOPTION_BGFX_SHADOW_MASK, "shadow-mask.png", OPTION_STRING, "shadow mask texture name" }, { OSDOPTION_BGFX_SHADOW_MASK, "shadow-mask.png", OPTION_STRING, "shadow mask texture name" },
{ OSDOPTION_BGFX_PRESCALE_X, "2", OPTION_INTEGER, "x prescale" }, { OSDOPTION_BGFX_PRESCALE_X, "2", OPTION_INTEGER, "x prescale" },
{ OSDOPTION_BGFX_PRESCALE_Y, "2", OPTION_INTEGER, "y prescale" }, { OSDOPTION_BGFX_PRESCALE_Y, "2", OPTION_INTEGER, "y prescale" },

View File

@ -80,7 +80,7 @@
#define OSDOPTION_BGFX_PATH "bgfx_path" #define OSDOPTION_BGFX_PATH "bgfx_path"
#define OSDOPTION_BGFX_BACKEND "bgfx_backend" #define OSDOPTION_BGFX_BACKEND "bgfx_backend"
#define OSDOPTION_BGFX_DEBUG "bgfx_debug" #define OSDOPTION_BGFX_DEBUG "bgfx_debug"
#define OSDOPTION_BGFX_SCREEN_CHAIN "bgfx_screen_chain" #define OSDOPTION_BGFX_SCREEN_CHAINS "bgfx_screen_chains"
#define OSDOPTION_BGFX_SHADOW_MASK "bgfx_shadow_mask" #define OSDOPTION_BGFX_SHADOW_MASK "bgfx_shadow_mask"
#define OSDOPTION_BGFX_PRESCALE_X "bgfx_prescale_x" #define OSDOPTION_BGFX_PRESCALE_X "bgfx_prescale_x"
#define OSDOPTION_BGFX_PRESCALE_Y "bgfx_prescale_y" #define OSDOPTION_BGFX_PRESCALE_Y "bgfx_prescale_y"
@ -157,7 +157,7 @@ public:
const char *bgfx_path() const { return value(OSDOPTION_BGFX_PATH); } const char *bgfx_path() const { return value(OSDOPTION_BGFX_PATH); }
const char *bgfx_backend() const { return value(OSDOPTION_BGFX_BACKEND); } const char *bgfx_backend() const { return value(OSDOPTION_BGFX_BACKEND); }
const bool bgfx_debug() const { return bool_value(OSDOPTION_BGFX_DEBUG); } const bool bgfx_debug() const { return bool_value(OSDOPTION_BGFX_DEBUG); }
const char *bgfx_screen_chain() const { return value(OSDOPTION_BGFX_SCREEN_CHAIN); } const char *bgfx_screen_chains() const { return value(OSDOPTION_BGFX_SCREEN_CHAINS); }
const char *bgfx_shadow_mask() const { return value(OSDOPTION_BGFX_SHADOW_MASK); } const char *bgfx_shadow_mask() const { return value(OSDOPTION_BGFX_SHADOW_MASK); }
const uint32_t bgfx_prescale_x() const { return int_value(OSDOPTION_BGFX_PRESCALE_X); } const uint32_t bgfx_prescale_x() const { return int_value(OSDOPTION_BGFX_PRESCALE_X); }
const uint32_t bgfx_prescale_y() const { return int_value(OSDOPTION_BGFX_PRESCALE_Y); } const uint32_t bgfx_prescale_y() const { return int_value(OSDOPTION_BGFX_PRESCALE_Y); }

View File

@ -111,7 +111,7 @@ void bgfx_chain_entry::setup_screensize_uniforms(texture_manager& textures, uint
} }
} }
void bgfx_chain_entry::setup_sourcesize_uniform(render_primitive* prim) 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");
if (source_dims != nullptr) if (source_dims != nullptr)
@ -121,7 +121,7 @@ void bgfx_chain_entry::setup_sourcesize_uniform(render_primitive* prim)
} }
} }
void bgfx_chain_entry::setup_rotationtype_uniform(uint32_t rotation_type) 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");
if (rotation_type_uniform != nullptr) if (rotation_type_uniform != nullptr)
@ -131,14 +131,24 @@ void bgfx_chain_entry::setup_rotationtype_uniform(uint32_t rotation_type)
} }
} }
void bgfx_chain_entry::setup_swapxy_uniform(bool swap_xy) void bgfx_chain_entry::setup_swapxy_uniform(bool swap_xy) const
{ {
bgfx_uniform* swap_xy_uniform = m_effect->uniform("u_swap_xy"); bgfx_uniform* swap_xy_uniform = m_effect->uniform("u_swap_xy");
if (swap_xy_uniform != nullptr) if (swap_xy_uniform != nullptr)
{ {
float values[1] = { swap_xy ? 1.0f : 0.0f }; float values[1] = { swap_xy ? 1.0f : 0.0f };
swap_xy_uniform->set(values, sizeof(float)); swap_xy_uniform->set(values, sizeof(float));
} }
}
void bgfx_chain_entry::setup_quaddims_uniform(render_primitive* prim) const
{
bgfx_uniform* quad_dims_uniform = m_effect->uniform("u_quad_dims");
if (quad_dims_uniform != nullptr)
{
float values[2] = { (prim->bounds.x1 - prim->bounds.x0) + 0.5f, (prim->bounds.y1 - prim->bounds.y0) + 0.5f};
quad_dims_uniform->set(values, sizeof(float) * 2);
}
} }
void bgfx_chain_entry::setup_auto_uniforms(render_primitive* prim, texture_manager& textures, uint16_t screen_width, uint16_t screen_height, 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_width, uint16_t screen_height, uint32_t rotation_type, bool swap_xy, int32_t screen)
@ -147,9 +157,10 @@ void bgfx_chain_entry::setup_auto_uniforms(render_primitive* prim, texture_manag
setup_sourcesize_uniform(prim); setup_sourcesize_uniform(prim);
setup_rotationtype_uniform(rotation_type); setup_rotationtype_uniform(rotation_type);
setup_swapxy_uniform(swap_xy); setup_swapxy_uniform(swap_xy);
setup_quaddims_uniform(prim);
} }
bool bgfx_chain_entry::setup_view(int view, uint16_t screen_width, uint16_t screen_height, int32_t screen) bool bgfx_chain_entry::setup_view(int view, uint16_t screen_width, uint16_t screen_height, int32_t screen) const
{ {
bgfx::FrameBufferHandle handle = BGFX_INVALID_HANDLE; bgfx::FrameBufferHandle handle = BGFX_INVALID_HANDLE;
uint16_t width = screen_width; uint16_t width = screen_width;
@ -174,11 +185,11 @@ bool bgfx_chain_entry::setup_view(int view, uint16_t screen_width, uint16_t scre
bx::mtxOrtho(projMat, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 100.0f); bx::mtxOrtho(projMat, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 100.0f);
bgfx::setViewTransform(view, nullptr, projMat); bgfx::setViewTransform(view, nullptr, projMat);
bgfx::setViewClear(view, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x000000ff, 1.0f, 0); bgfx::setViewClear(view, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x00ff00ff, 1.0f, 0);
return true; return true;
} }
void bgfx_chain_entry::put_screen_buffer(render_primitive* prim, bgfx::TransientVertexBuffer* buffer) void bgfx_chain_entry::put_screen_buffer(render_primitive* prim, bgfx::TransientVertexBuffer* buffer) const
{ {
if (bgfx::checkAvailTransientVertexBuffer(6, ScreenVertex::ms_decl)) if (bgfx::checkAvailTransientVertexBuffer(6, ScreenVertex::ms_decl))
{ {

View File

@ -45,12 +45,13 @@ public:
private: private:
void setup_auto_uniforms(render_primitive* prim, texture_manager& textures, uint16_t screen_width, uint16_t screen_height, uint32_t rotation_type, bool swap_xy, int32_t screen); void setup_auto_uniforms(render_primitive* prim, texture_manager& textures, uint16_t screen_width, uint16_t screen_height, 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_sourcesize_uniform(render_primitive* prim); void setup_sourcesize_uniform(render_primitive* prim) const;
void setup_rotationtype_uniform(uint32_t rotation_type); void setup_rotationtype_uniform(uint32_t rotation_type) const;
void setup_swapxy_uniform(bool swap_xy); void setup_swapxy_uniform(bool swap_xy) const;
void setup_quaddims_uniform(render_primitive* prim) const;
bool setup_view(int view, uint16_t screen_width, uint16_t screen_height, int32_t screen); bool setup_view(int view, uint16_t screen_width, uint16_t screen_height, int32_t screen) const;
void put_screen_buffer(render_primitive* prim, bgfx::TransientVertexBuffer* buffer); void put_screen_buffer(render_primitive* prim, bgfx::TransientVertexBuffer* buffer) const;
std::string m_name; std::string m_name;
bgfx_effect* m_effect; bgfx_effect* m_effect;

View File

@ -36,6 +36,11 @@ bgfx_chain_entry* chain_entry_reader::read_from_value(const Value& value, std::s
} }
bgfx_effect* effect = effects.effect(value["effect"].GetString()); bgfx_effect* effect = effects.effect(value["effect"].GetString());
if (effect == nullptr)
{
return nullptr;
}
std::string name = value["name"].GetString(); std::string name = value["name"].GetString();
std::vector<bgfx_input_pair> inputs; std::vector<bgfx_input_pair> inputs;

View File

@ -12,6 +12,7 @@
#include "emu.h" #include "emu.h"
#include <rapidjson/document.h> #include <rapidjson/document.h>
#include <rapidjson/error/en.h>
#include <bgfx/bgfxplatform.h> #include <bgfx/bgfxplatform.h>
#include <bgfx/bgfx.h> #include <bgfx/bgfx.h>
@ -52,7 +53,11 @@ bgfx_effect* effect_manager::load_effect(std::string name)
std::string path = std::string(m_options.bgfx_path()) + "/effects/" + name; std::string path = std::string(m_options.bgfx_path()) + "/effects/" + name;
bx::CrtFileReader reader; bx::CrtFileReader reader;
bx::open(&reader, path.c_str()); if (!bx::open(&reader, path.c_str()))
{
printf("Unable to open effect file %s\n", path.c_str());
return nullptr;
}
int32_t size (bx::getSize(&reader)); int32_t size (bx::getSize(&reader));
@ -63,9 +68,22 @@ bgfx_effect* effect_manager::load_effect(std::string name)
Document document; Document document;
document.Parse<0>(data); document.Parse<0>(data);
bgfx_effect* effect = effect_reader::read_from_value(document, "Effect '" + name + "': ", m_shaders);
m_effects[name] = effect; if (document.HasParseError()) {
std::string error(GetParseError_En(document.GetParseError()));
printf("Unable to parse effect %s. Errors returned:\n", path.c_str());
printf("%s\n", error.c_str());
return nullptr;
}
bgfx_effect* effect = effect_reader::read_from_value(document, "Effect '" + name + "': ", m_shaders);
if (effect == nullptr) {
printf("Unable to load effect %s\n", path.c_str());
return nullptr;
}
m_effects[name] = effect;
return effect; return effect;
} }

View File

@ -42,7 +42,12 @@ bgfx_effect* effect_reader::read_from_value(const Value& value, std::string pref
const Value& uniform_array = value["uniforms"]; const Value& uniform_array = value["uniforms"];
for (UINT32 i = 0; i < uniform_array.Size(); i++) for (UINT32 i = 0; i < uniform_array.Size(); i++)
{ {
uniforms.push_back(uniform_reader::read_from_value(uniform_array[i], prefix + "uniforms[" + std::to_string(i) + "]: ")); bgfx_uniform* uniform = uniform_reader::read_from_value(uniform_array[i], prefix + "uniforms[" + std::to_string(i) + "]: ");
if (uniform == nullptr)
{
return nullptr;
}
uniforms.push_back(uniform);
} }
std::string vertex_name(value["vertex"].GetString()); std::string vertex_name(value["vertex"].GetString());

View File

@ -9,7 +9,7 @@ $input v_color0, v_texcoord0
#include "../../../../../3rdparty/bgfx/examples/common/common.sh" #include "../../../../../3rdparty/bgfx/examples/common/common.sh"
// Autos // Autos
uniform vec4 u_screen_dims; uniform vec4 u_tex_size0;
// User-supplied // User-supplied
uniform vec4 u_defocus; uniform vec4 u_defocus;
@ -32,7 +32,7 @@ void main()
const vec2 Coord7Offset = vec2( 0.50, -0.75); const vec2 Coord7Offset = vec2( 0.50, -0.75);
const vec2 Coord8Offset = vec2( 1.00, -0.25); const vec2 Coord8Offset = vec2( 1.00, -0.25);
vec2 DefocusTexelDims = u_defocus.xy / u_screen_dims.xy; vec2 DefocusTexelDims = u_defocus.xy / u_tex_size0.xy;
vec4 d0 = texture2D(s_tex, v_texcoord0); vec4 d0 = texture2D(s_tex, v_texcoord0);
vec4 d1 = texture2D(s_tex, v_texcoord0 + Coord1Offset * DefocusTexelDims); vec4 d1 = texture2D(s_tex, v_texcoord0 + Coord1Offset * DefocusTexelDims);
@ -46,5 +46,5 @@ void main()
vec4 blurred = (d0 + d1 + d2 + d3 + d4 + d5 + d6 + d7 + d8) / 9.0; vec4 blurred = (d0 + d1 + d2 + d3 + d4 + d5 + d6 + d7 + d8) / 9.0;
gl_FragColor = vec4(blurred.xyz, 1.0) * v_color0; gl_FragColor = vec4(blurred.rgb, 1.0) * v_color0;
} }

View File

@ -9,10 +9,13 @@ $input v_color0, v_texcoord0
#include "../../../../../3rdparty/bgfx/examples/common/common.sh" #include "../../../../../3rdparty/bgfx/examples/common/common.sh"
// Autos // Autos
uniform vec4 u_swap_xy;
uniform vec4 u_screen_dims; uniform vec4 u_screen_dims;
uniform vec4 u_quad_dims;
uniform vec4 u_rotation_type; uniform vec4 u_rotation_type;
// User-supplied // User-supplied
uniform vec4 u_prepare_vector;
uniform vec4 u_curvature; uniform vec4 u_curvature;
uniform vec4 u_round_corner; uniform vec4 u_round_corner;
uniform vec4 u_smooth_border; uniform vec4 u_smooth_border;
@ -46,15 +49,6 @@ float roundBox(vec2 p, vec2 b, float r)
return length(max(abs(p) - b + r, 0.0)) - r; return length(max(abs(p) - b + r, 0.0)) - r;
} }
vec2 GetRatioCorrection()
{
float ScreenQuadRatio = 1.0;
return ScreenQuadRatio > 1.0f
? vec2(1.0, 1.0f / ScreenQuadRatio)
: vec2(ScreenQuadRatio, 1.0);
}
float GetNoiseFactor(float n, float random) float GetNoiseFactor(float n, float random)
{ {
// smaller n become more noisy // smaller n become more noisy
@ -77,22 +71,37 @@ float GetVignetteFactor(vec2 coord, float amount)
float GetSpotAddend(vec2 coord, float amount) float GetSpotAddend(vec2 coord, float amount)
{ {
vec2 RatioCorrection = GetRatioCorrection(); vec2 SpotCoord = coord;
// hack for vector screen
if (u_prepare_vector.x > 0.0)
{
// upper right quadrant
vec2 spotOffset = vec2(-0.25, 0.25); // 0 degrees
if (u_rotation_type.x == 1.0)
spotOffset = vec2(-0.25, -0.25); // 90 degrees
if (u_rotation_type.x == 2.0)
spotOffset = vec2(0.25, -0.25); // 180 degrees
if (u_rotation_type.x == 3.0)
spotOffset = vec2(0.25, 0.25); // 270 degrees
// normalized screen canvas ratio
vec2 CanvasRatio = ((u_swap_xy.x > 0.0) ? vec2(u_quad_dims.x / u_quad_dims.y, 1.0) : vec2(1.0, u_quad_dims.y / u_quad_dims.x));
SpotCoord += spotOffset;
SpotCoord *= CanvasRatio;
}
else
{
// upper right quadrant
vec2 spotOffset = vec2(-0.25, 0.25);
// normalized screen quad ratio // normalized screen canvas ratio
vec2 QuadRatio = vec2(1.0, u_screen_dims.y / u_screen_dims.x); vec2 CanvasRatio = ((u_swap_xy.x > 0.0) ? vec2(1.0, u_quad_dims.x / u_quad_dims.y) : vec2(1.0, u_quad_dims.y / u_quad_dims.x));
// normalized screen quad ratio SpotCoord += spotOffset;
// upper right quadrant SpotCoord *= CanvasRatio;
vec2 spotOffset = vec2(-0.25, 0.25); // 0 degrees }
if (u_rotation_type.x == 1.0)
spotOffset = vec2(-0.25, -0.25); // 90 degrees
if (u_rotation_type.x == 2.0)
spotOffset = vec2(0.25, -0.25); // 180 degrees
if (u_rotation_type.x == 3.0)
spotOffset = vec2(0.25, 0.25); // 270 degrees
vec2 SpotCoord = (coord + spotOffset * RatioCorrection) / RatioCorrection;
float SpotBlur = amount; float SpotBlur = amount;
@ -110,17 +119,17 @@ float GetSpotAddend(vec2 coord, float amount)
float GetRoundCornerFactor(vec2 coord, float radiusAmount, float smoothAmount) float GetRoundCornerFactor(vec2 coord, float radiusAmount, float smoothAmount)
{ {
vec2 RatioCorrection = GetRatioCorrection();
// reduce smooth amount down to radius amount // reduce smooth amount down to radius amount
smoothAmount = min(smoothAmount, radiusAmount); smoothAmount = min(smoothAmount, radiusAmount);
float range = min(u_screen_dims.x, u_screen_dims.y) * 0.5; vec2 quadDims = (u_prepare_vector.x > 0.0 && 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 radius = range * max(radiusAmount, 0.0025);
float smooth_val = 1.0 / (range * max(smoothAmount, 0.0025)); float smooth_val = 1.0 / (range * max(smoothAmount, 0.0025));
// compute box // compute box
float box = roundBox(u_screen_dims.xy * (coord * 2.0f), u_screen_dims.xy * RatioCorrection, radius); float box = roundBox(quadDims * (coord * 2.0f), quadDims, radius);
// apply smooth // apply smooth
box *= smooth_val; box *= smooth_val;
@ -155,20 +164,12 @@ vec2 GetDistortedCoords(vec2 centerCoord, float amount)
vec2 GetCoords(vec2 coord, float distortionAmount) vec2 GetCoords(vec2 coord, float distortionAmount)
{ {
vec2 RatioCorrection = GetRatioCorrection();
// center coordinates // center coordinates
coord -= 0.5; coord -= 0.5;
// apply ratio difference between screen and quad
coord /= RatioCorrection;
// distort coordinates // distort coordinates
coord = GetDistortedCoords(coord, distortionAmount); coord = GetDistortedCoords(coord, distortionAmount);
// revert ratio difference between screen and quad
coord *= RatioCorrection;
// un-center coordinates // un-center coordinates
coord += 0.5; coord += 0.5;

View File

@ -29,10 +29,19 @@ bgfx_input_pair::bgfx_input_pair(int index, std::string sampler, std::string tex
void bgfx_input_pair::bind(bgfx_effect *effect, target_manager& targets, texture_manager& textures, const int32_t screen) const void bgfx_input_pair::bind(bgfx_effect *effect, target_manager& targets, texture_manager& textures, const int32_t screen) const
{ {
assert(effect->uniform(m_sampler) != nullptr); assert(effect->uniform(m_sampler) != nullptr);
std::string texture = m_texture; std::string name = m_texture;
if (targets.target(m_texture + std::to_string(screen)) != nullptr) if (targets.target(m_texture + std::to_string(screen)) != nullptr)
{ {
texture = m_texture + std::to_string(screen); name = m_texture + std::to_string(screen);
} }
bgfx::setTexture(m_index, effect->uniform(m_sampler)->handle(), textures.handle(texture));
bgfx_texture_handle_provider* provider = textures.provider(name);
bgfx_uniform *tex_size = effect->uniform("u_tex_size" + std::to_string(m_index));
if (tex_size != nullptr)
{
float values[2] = { float(provider->width()), float(provider->height()) };
tex_size->set(values, sizeof(float) * 2);
}
bgfx::setTexture(m_index, effect->uniform(m_sampler)->handle(), textures.handle(name));
} }

View File

@ -66,10 +66,11 @@ const char* renderer_bgfx::WINDOW_PREFIX = "Window 0, ";
#define GIBBERISH (0) #define GIBBERISH (0)
//============================================================ //============================================================
// TYPES // STATICS
//============================================================ //============================================================
bool renderer_bgfx::s_window_set = false; bool renderer_bgfx::s_window_set = false;
uint32_t renderer_bgfx::s_current_view = 0;
//============================================================ //============================================================
// renderer_bgfx::create // renderer_bgfx::create
@ -190,7 +191,7 @@ int renderer_bgfx::create()
m_screen_effect[3] = m_effects->effect("screen_add"); m_screen_effect[3] = m_effects->effect("screen_add");
m_chains = new chain_manager(options, *m_textures, *m_targets, *m_effects, m_width[window().m_index], m_height[window().m_index]); m_chains = new chain_manager(options, *m_textures, *m_targets, *m_effects, m_width[window().m_index], m_height[window().m_index]);
m_screen_chain = m_chains->chain(options.bgfx_screen_chain(), window().machine(), window().m_index); parse_screen_chains(options.bgfx_screen_chains());
m_sliders_dirty = true; m_sliders_dirty = true;
uint32_t flags = BGFX_TEXTURE_U_CLAMP | BGFX_TEXTURE_V_CLAMP | BGFX_TEXTURE_MIN_POINT | BGFX_TEXTURE_MAG_POINT | BGFX_TEXTURE_MIP_POINT; uint32_t flags = BGFX_TEXTURE_U_CLAMP | BGFX_TEXTURE_V_CLAMP | BGFX_TEXTURE_MIN_POINT | BGFX_TEXTURE_MAG_POINT | BGFX_TEXTURE_MIP_POINT;
@ -205,6 +206,36 @@ int renderer_bgfx::create()
return 0; return 0;
} }
//============================================================
// parse_screen_chains
//============================================================
void renderer_bgfx::parse_screen_chains(std::string chain_str)
{
std::vector<std::string> chains;
uint32_t length = chain_str.length();
uint32_t last_start = 0;
for (uint32_t i = 0; i < length + 1; i++)
{
if (i == length || chain_str[i] == ',')
{
chains.push_back(chain_str.substr(last_start, i - last_start));
last_start = i + 1;
}
}
for (uint32_t index = 0; index < chains.size(); index++)
{
bgfx_chain* chain = m_chains->chain(chains[index], window().machine(), index);
if (chain == nullptr)
{
chains.clear();
return;
}
m_screen_chains.push_back(chain);
}
}
//============================================================ //============================================================
// destructor // destructor
//============================================================ //============================================================
@ -350,7 +381,8 @@ void renderer_bgfx::process_screen_quad(int screen, render_primitive* prim)
m_targets->update_guest_targets(screen, tex_width, tex_height); m_targets->update_guest_targets(screen, tex_width, tex_height);
m_screen_chain->process(prim, screen * m_screen_chain->applicable_passes(), screen, *m_textures, window(), get_blend_state(PRIMFLAG_GET_BLENDMODE(prim->flags))); screen_chain(screen)->process(prim, s_current_view, screen, *m_textures, window(), get_blend_state(PRIMFLAG_GET_BLENDMODE(prim->flags)));
s_current_view += screen_chain(screen)->applicable_passes();
m_textures->add_provider("screen", nullptr); m_textures->add_provider("screen", nullptr);
delete texture; delete texture;
@ -727,23 +759,29 @@ const bgfx::Memory* renderer_bgfx::mame_texture_data_to_bgfx_texture_data(UINT32
int renderer_bgfx::handle_screen_chains() int renderer_bgfx::handle_screen_chains()
{ {
if (!m_screen_chain) if (m_screen_chains.size() == 0)
{ {
return 0; return 0;
} }
window().m_primlist->acquire_lock(); window().m_primlist->acquire_lock();
// process
render_primitive *prim = window().m_primlist->first(); render_primitive *prim = window().m_primlist->first();
// Determine how many post-processing passes are needed
int screens = 0; int screens = 0;
screen_device_iterator iter(window().machine().root_device()); while (prim != nullptr)
for (const screen_device *screen = iter.first(); screen != nullptr; screen = iter.next()) { {
screens++; if (PRIMFLAG_GET_SCREENTEX(prim->flags))
{
screens++;
}
prim = prim->next();
} }
m_targets->update_screen_count(screens); m_targets->update_screen_count(screens);
// Process each screen as necessary
prim = window().m_primlist->first();
int seen_screen_quads = 0; int seen_screen_quads = 0;
while (prim != nullptr) while (prim != nullptr)
{ {
@ -757,25 +795,34 @@ int renderer_bgfx::handle_screen_chains()
window().m_primlist->release_lock(); window().m_primlist->release_lock();
uint32_t total_passes = seen_screen_quads * m_screen_chain->applicable_passes(); bgfx::setViewFrameBuffer(s_current_view, BGFX_INVALID_HANDLE);
bgfx::setViewFrameBuffer(total_passes, BGFX_INVALID_HANDLE);
return total_passes; return s_current_view;
}
bgfx_chain* renderer_bgfx::screen_chain(int32_t screen)
{
if (screen >= m_screen_chains.size())
{
return m_screen_chains[m_screen_chains.size() - 1];
}
else
{
return m_screen_chains[screen];
}
} }
int renderer_bgfx::draw(int update) int renderer_bgfx::draw(int update)
{ {
m_screens.clear();
int window_index = window().m_index; int window_index = window().m_index;
int post_view_index = handle_screen_chains(); if (window_index == 0)
int view_index = window_index;
int first_view_index = 0;
if (m_screen_chain && post_view_index > 0)
{ {
view_index += post_view_index; s_current_view = 0;
first_view_index = post_view_index;
} }
handle_screen_chains();
int view_index = s_current_view;
// Set view 0 default viewport. // Set view 0 default viewport.
osd_dim wdim = window().get_size(); osd_dim wdim = window().get_size();
m_width[window_index] = wdim.width(); m_width[window_index] = wdim.width();
@ -803,7 +850,7 @@ int renderer_bgfx::draw(int update)
m_dimensions = osd_dim(m_width[window_index], m_height[window_index]); m_dimensions = osd_dim(m_width[window_index], m_height[window_index]);
bgfx::setViewClear(view_index bgfx::setViewClear(view_index
, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH , BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH
, 0x000000ff , 0x00ff00ff
, 1.0f , 1.0f
, 0 , 0
); );
@ -811,12 +858,10 @@ int renderer_bgfx::draw(int update)
bgfx::frame(); bgfx::frame();
return 0; return 0;
} }
}
if (view_index != first_view_index) bgfx::setViewFrameBuffer(view_index, m_framebuffer->target());
{ }
bgfx::setViewFrameBuffer(view_index, m_framebuffer->target());
}
bgfx::setViewSeq(view_index, true); bgfx::setViewSeq(view_index, true);
bgfx::setViewRect(view_index, 0, 0, m_width[window_index], m_height[window_index]); bgfx::setViewRect(view_index, 0, 0, m_width[window_index], m_height[window_index]);
@ -885,11 +930,13 @@ int renderer_bgfx::draw(int update)
// Advance to next frame. Rendering thread will be kicked to // Advance to next frame. Rendering thread will be kicked to
// process submitted rendering primitives. // process submitted rendering primitives.
if (view_index == first_view_index) if (window_index == 0)
{ {
bgfx::frame(); bgfx::frame();
} }
s_current_view++;
return 0; return 0;
} }
@ -928,7 +975,7 @@ renderer_bgfx::buffer_status renderer_bgfx::buffer_primitives(int view, bool atl
return BUFFER_PRE_FLUSH; return BUFFER_PRE_FLUSH;
} }
if (PRIMFLAG_GET_SCREENTEX((*prim)->flags) && m_screen_chain != nullptr) if (PRIMFLAG_GET_SCREENTEX((*prim)->flags) && m_screen_chains.size() > 0)
{ {
render_post_screen_quad(view, *prim, buffer, screen); render_post_screen_quad(view, *prim, buffer, screen);
return BUFFER_SCREEN; return BUFFER_SCREEN;
@ -1148,24 +1195,27 @@ void renderer_bgfx::allocate_buffer(render_primitive *prim, UINT32 blend, bgfx::
slider_state* renderer_bgfx::get_slider_list() slider_state* renderer_bgfx::get_slider_list()
{ {
if (!m_screen_chain) if (m_screen_chains.size() == 0)
{ {
return nullptr; return nullptr;
} }
slider_state *listhead = nullptr; slider_state *listhead = nullptr;
slider_state **tailptr = &listhead; slider_state **tailptr = &listhead;
std::vector<bgfx_slider*> sliders = m_screen_chain->sliders(); for (bgfx_chain* chain : m_screen_chains)
for (bgfx_slider* slider : sliders)
{ {
if (*tailptr == nullptr) std::vector<bgfx_slider*> sliders = chain->sliders();
for (bgfx_slider* slider : sliders)
{ {
*tailptr = slider->core_slider(); if (*tailptr == nullptr)
} {
else *tailptr = slider->core_slider();
{ }
(*tailptr)->next = slider->core_slider(); else
tailptr = &(*tailptr)->next; {
(*tailptr)->next = slider->core_slider();
tailptr = &(*tailptr)->next;
}
} }
} }
if (*tailptr != nullptr) if (*tailptr != nullptr)

View File

@ -61,6 +61,8 @@ public:
private: private:
int handle_screen_chains(); int handle_screen_chains();
void parse_screen_chains(std::string chain_str);
bgfx_chain* screen_chain(int32_t screen);
void allocate_buffer(render_primitive *prim, UINT32 blend, bgfx::TransientVertexBuffer *buffer); void allocate_buffer(render_primitive *prim, UINT32 blend, bgfx::TransientVertexBuffer *buffer);
enum buffer_status enum buffer_status
@ -92,8 +94,6 @@ private:
const bgfx::Memory* mame_texture_data_to_bgfx_texture_data(UINT32 format, int width, int height, int rowpixels, const rgb_t *palette, void *base); const bgfx::Memory* mame_texture_data_to_bgfx_texture_data(UINT32 format, int width, int height, int rowpixels, const rgb_t *palette, void *base);
UINT32 get_texture_hash(render_primitive *prim); UINT32 get_texture_hash(render_primitive *prim);
std::vector<screen_device*> m_screens;
bgfx_target* m_framebuffer; bgfx_target* m_framebuffer;
bgfx_texture* m_texture_cache; bgfx_texture* m_texture_cache;
@ -108,7 +108,7 @@ private:
bgfx_effect* m_gui_effect[4]; bgfx_effect* m_gui_effect[4];
bgfx_effect* m_screen_effect[4]; bgfx_effect* m_screen_effect[4];
bgfx_chain* m_screen_chain; std::vector<bgfx_chain*> m_screen_chains;
std::map<UINT32, rectangle_packer::packed_rectangle> m_hash_to_entry; std::map<UINT32, rectangle_packer::packed_rectangle> m_hash_to_entry;
std::vector<rectangle_packer::packable_rectangle> m_texinfo; std::vector<rectangle_packer::packable_rectangle> m_texinfo;
@ -123,6 +123,7 @@ private:
static const uint32_t WHITE_HASH; static const uint32_t WHITE_HASH;
static bool s_window_set; static bool s_window_set;
static uint32_t s_current_view;
}; };
#endif #endif