Add anaglyph settings
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
@@ -1027,3 +1028,6 @@ using color1u = color1_base<unsigned int>;
|
|||||||
using color1i = color1_base<int>;
|
using color1i = color1_base<int>;
|
||||||
using color1f = color1_base<float>;
|
using color1f = color1_base<float>;
|
||||||
using color1d = color1_base<double>;
|
using color1d = color1_base<double>;
|
||||||
|
|
||||||
|
using mat3f = color3_base<float>[3];
|
||||||
|
static_assert(sizeof(mat3f) == sizeof(float) * 3 * 3);
|
||||||
|
|||||||
@@ -0,0 +1,160 @@
|
|||||||
|
#include "stdafx.h"
|
||||||
|
#include "stereo_config.h"
|
||||||
|
#include "Emu/system_config.h"
|
||||||
|
|
||||||
|
stereo_config::stereo_matrices::stereo_matrices(const std::array<color3_base<f32>, 3>& l, const std::array<color3_base<f32>, 3>& r)
|
||||||
|
{
|
||||||
|
for (usz i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
left[i] = l[i];
|
||||||
|
right[i] = r[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
atomic_t<bool> stereo_config::s_live_preview_enabled = false;
|
||||||
|
stereo_config::stereo_matrices stereo_config::m_live_matrices = {};
|
||||||
|
|
||||||
|
const std::unordered_map<stereo_render_mode_options, stereo_config::stereo_matrices> stereo_config::m_matrices =
|
||||||
|
{
|
||||||
|
{stereo_render_mode_options::anaglyph_red_cyan, stereo_matrices(
|
||||||
|
{
|
||||||
|
color3_base<f32>(1, 0, 0),
|
||||||
|
color3_base<f32>(0, 0, 0),
|
||||||
|
color3_base<f32>(0, 0, 0)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color3_base<f32>(0, 0, 0),
|
||||||
|
color3_base<f32>(0, 1, 0),
|
||||||
|
color3_base<f32>(0, 0, 1)
|
||||||
|
}
|
||||||
|
)},
|
||||||
|
{stereo_render_mode_options::anaglyph_red_green, stereo_matrices(
|
||||||
|
{
|
||||||
|
color3_base<f32>(1, 0, 0),
|
||||||
|
color3_base<f32>(0, 0, 0),
|
||||||
|
color3_base<f32>(0, 0, 0)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color3_base<f32>(0, 0, 0),
|
||||||
|
color3_base<f32>(0, 1, 0),
|
||||||
|
color3_base<f32>(0, 0, 0)
|
||||||
|
}
|
||||||
|
)},
|
||||||
|
{stereo_render_mode_options::anaglyph_red_blue, stereo_matrices(
|
||||||
|
{
|
||||||
|
color3_base<f32>(1, 0, 0),
|
||||||
|
color3_base<f32>(0, 0, 0),
|
||||||
|
color3_base<f32>(0, 0, 0)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color3_base<f32>(0, 0, 0),
|
||||||
|
color3_base<f32>(0, 0, 0),
|
||||||
|
color3_base<f32>(0, 0, 1)
|
||||||
|
}
|
||||||
|
)},
|
||||||
|
{stereo_render_mode_options::anaglyph_magenta_cyan, stereo_matrices(
|
||||||
|
{
|
||||||
|
color3_base<f32>(1, 0, 0),
|
||||||
|
color3_base<f32>(0, 0, 0),
|
||||||
|
color3_base<f32>(0, 0, 0.5f)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color3_base<f32>(0, 0, 0),
|
||||||
|
color3_base<f32>(0, 1, 0),
|
||||||
|
color3_base<f32>(0, 0, 0.5f)
|
||||||
|
}
|
||||||
|
)},
|
||||||
|
{stereo_render_mode_options::anaglyph_trioscopic, stereo_matrices(
|
||||||
|
{
|
||||||
|
color3_base<f32>(0, 0, 0),
|
||||||
|
color3_base<f32>(0, 1, 0),
|
||||||
|
color3_base<f32>(0, 0, 0)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color3_base<f32>(1, 0, 0),
|
||||||
|
color3_base<f32>(0, 0, 0),
|
||||||
|
color3_base<f32>(0, 0, 1)
|
||||||
|
}
|
||||||
|
)},
|
||||||
|
{stereo_render_mode_options::anaglyph_amber_blue, stereo_matrices(
|
||||||
|
{
|
||||||
|
color3_base<f32>(1, 0, 0),
|
||||||
|
color3_base<f32>(0, 1, 0),
|
||||||
|
color3_base<f32>(0, 0, 0)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color3_base<f32>(0, 0, 1.0f / 3.0f),
|
||||||
|
color3_base<f32>(0, 0, 1.0f / 3.0f),
|
||||||
|
color3_base<f32>(0, 0, 1.0f / 3.0f)
|
||||||
|
}
|
||||||
|
)},
|
||||||
|
};
|
||||||
|
|
||||||
|
void stereo_config::update_from_config(bool stereo_enabled)
|
||||||
|
{
|
||||||
|
m_stereo_mode = stereo_enabled ? g_cfg.video.stereo_render_mode.get() : stereo_render_mode_options::disabled;
|
||||||
|
|
||||||
|
if (m_stereo_mode == stereo_render_mode_options::anaglyph_custom)
|
||||||
|
{
|
||||||
|
stereo_config::stereo_matrices custom_matrices {};
|
||||||
|
stereo_config::convert_matrix(m_custom_matrices.left, g_cfg.video.custom_anaglyph_matrices.left.get_map());
|
||||||
|
stereo_config::convert_matrix(m_custom_matrices.right, g_cfg.video.custom_anaglyph_matrices.right.get_map());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const stereo_config::stereo_matrices& stereo_config::matrices() const
|
||||||
|
{
|
||||||
|
if (m_in_emulation && s_live_preview_enabled)
|
||||||
|
{
|
||||||
|
return m_live_matrices;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (m_stereo_mode)
|
||||||
|
{
|
||||||
|
case stereo_render_mode_options::disabled:
|
||||||
|
case stereo_render_mode_options::side_by_side:
|
||||||
|
case stereo_render_mode_options::over_under:
|
||||||
|
case stereo_render_mode_options::interlaced:
|
||||||
|
break;
|
||||||
|
case stereo_render_mode_options::anaglyph_red_green:
|
||||||
|
case stereo_render_mode_options::anaglyph_red_blue:
|
||||||
|
case stereo_render_mode_options::anaglyph_red_cyan:
|
||||||
|
case stereo_render_mode_options::anaglyph_magenta_cyan:
|
||||||
|
case stereo_render_mode_options::anaglyph_trioscopic:
|
||||||
|
case stereo_render_mode_options::anaglyph_amber_blue:
|
||||||
|
return ::at32(m_matrices, m_stereo_mode);
|
||||||
|
case stereo_render_mode_options::anaglyph_custom:
|
||||||
|
return m_custom_matrices;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const stereo_matrices s_left_only_matrices = stereo_matrices(
|
||||||
|
{
|
||||||
|
color3_base<float>(1, 0, 0),
|
||||||
|
color3_base<float>(0, 1, 0),
|
||||||
|
color3_base<float>(0, 0, 1)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color3_base<float>(0, 0, 0),
|
||||||
|
color3_base<float>(0, 0, 0),
|
||||||
|
color3_base<float>(0, 0, 0)
|
||||||
|
});
|
||||||
|
return s_left_only_matrices;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<std::string, std::string> stereo_config::get_custom_matrix(bool is_left) const
|
||||||
|
{
|
||||||
|
return convert_matrix(is_left ? m_custom_matrices.left : m_custom_matrices.right);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<std::string, std::string> stereo_config::convert_matrix(const mat3f& mat)
|
||||||
|
{
|
||||||
|
std::map<std::string, std::string> values {};
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < 3; j++)
|
||||||
|
{
|
||||||
|
values[fmt::format("%d%d", i, j)] = fmt::format("%f", mat[i].rgb[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return values;
|
||||||
|
}
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "geometry.h"
|
||||||
|
#include "Emu/system_config_types.h"
|
||||||
|
#include "Utilities/StrUtil.h"
|
||||||
|
#include <map>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
struct stereo_config
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct stereo_matrices
|
||||||
|
{
|
||||||
|
stereo_matrices() = default;
|
||||||
|
stereo_matrices(const std::array<color3_base<f32>, 3>& l, const std::array<color3_base<f32>, 3>& r);
|
||||||
|
|
||||||
|
mat3f left {};
|
||||||
|
mat3f right {};
|
||||||
|
};
|
||||||
|
|
||||||
|
stereo_config(bool in_emulation) : m_in_emulation(in_emulation) {}
|
||||||
|
|
||||||
|
void set_stereo_mode(stereo_render_mode_options mode) { m_stereo_mode = mode; }
|
||||||
|
stereo_render_mode_options stereo_mode() const { return m_stereo_mode; }
|
||||||
|
|
||||||
|
const stereo_matrices& matrices() const;
|
||||||
|
|
||||||
|
void update_from_config(bool stereo_enabled);
|
||||||
|
|
||||||
|
void set_custom_matrices(const stereo_matrices& matrices) { m_custom_matrices = matrices; }
|
||||||
|
static void set_live_matrices(const stereo_matrices& matrices) { m_live_matrices = matrices; }
|
||||||
|
|
||||||
|
std::map<std::string, std::string> get_custom_matrix(bool is_left) const;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static void convert_matrix(mat3f& mat, const T& values)
|
||||||
|
{
|
||||||
|
mat[0] = {};
|
||||||
|
mat[1] = {};
|
||||||
|
mat[2] = {};
|
||||||
|
|
||||||
|
if (values.empty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < 3; j++)
|
||||||
|
{
|
||||||
|
const std::string key = fmt::format("%d%d", i, j);
|
||||||
|
const auto it = values.find(key);
|
||||||
|
if (it == values.cend()) continue;
|
||||||
|
|
||||||
|
const std::string& val_s = it->second;
|
||||||
|
if (val_s.empty()) continue;
|
||||||
|
|
||||||
|
if (f64 val = 0.0f; try_to_float(&val, val_s, -10.0f, 10.0f))
|
||||||
|
{
|
||||||
|
mat[i].rgb[j] = static_cast<f32>(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::map<std::string, std::string> convert_matrix(const mat3f& mat);
|
||||||
|
|
||||||
|
static atomic_t<bool> s_live_preview_enabled;
|
||||||
|
|
||||||
|
private:
|
||||||
|
stereo_matrices m_custom_matrices {};
|
||||||
|
stereo_render_mode_options m_stereo_mode = stereo_render_mode_options::disabled;
|
||||||
|
bool m_in_emulation = false;
|
||||||
|
|
||||||
|
static stereo_matrices m_live_matrices;
|
||||||
|
static const std::unordered_map<stereo_render_mode_options, stereo_matrices> m_matrices;
|
||||||
|
};
|
||||||
@@ -126,7 +126,7 @@ struct PKGEntry
|
|||||||
struct PKGMetaData
|
struct PKGMetaData
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
static std::string to_hex_string(u8 buf[], usz size)
|
static std::string to_hex_string(const u8* buf, usz size)
|
||||||
{
|
{
|
||||||
std::stringstream sstream;
|
std::stringstream sstream;
|
||||||
for (usz i = 0; i < size; i++)
|
for (usz i = 0; i < size; i++)
|
||||||
@@ -135,7 +135,7 @@ private:
|
|||||||
}
|
}
|
||||||
return sstream.str();
|
return sstream.str();
|
||||||
}
|
}
|
||||||
static std::string to_hex_string(u8 buf[], usz size, usz dotpos)
|
static std::string to_hex_string(const u8* buf, usz size, usz dotpos)
|
||||||
{
|
{
|
||||||
std::string result = to_hex_string(buf, size);
|
std::string result = to_hex_string(buf, size);
|
||||||
if (result.size() > dotpos)
|
if (result.size() > dotpos)
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ target_sources(rpcs3_emu PRIVATE
|
|||||||
../../Utilities/sema.cpp
|
../../Utilities/sema.cpp
|
||||||
../../Utilities/simple_ringbuf.cpp
|
../../Utilities/simple_ringbuf.cpp
|
||||||
../../Utilities/stack_trace.cpp
|
../../Utilities/stack_trace.cpp
|
||||||
|
../../Utilities/stereo_config.cpp
|
||||||
../../Utilities/StrFmt.cpp
|
../../Utilities/StrFmt.cpp
|
||||||
../../Utilities/Thread.cpp
|
../../Utilities/Thread.cpp
|
||||||
../../Utilities/version.cpp
|
../../Utilities/version.cpp
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "GLOverlays.h"
|
#include "GLOverlays.h"
|
||||||
|
|
||||||
#include "Utilities/StrUtil.h"
|
#include "Utilities/StrUtil.h"
|
||||||
|
#include "Utilities/stereo_config.h"
|
||||||
#include "../Program/RSXOverlay.h"
|
#include "../Program/RSXOverlay.h"
|
||||||
#include "Emu/Cell/timers.hpp"
|
#include "Emu/Cell/timers.hpp"
|
||||||
|
|
||||||
@@ -510,7 +511,7 @@ namespace gl
|
|||||||
}
|
}
|
||||||
|
|
||||||
void video_out_calibration_pass::run(gl::command_context& cmd, const areau& viewport, const rsx::simple_array<GLuint>& source, f32 gamma, bool limited_rgb,
|
void video_out_calibration_pass::run(gl::command_context& cmd, const areau& viewport, const rsx::simple_array<GLuint>& source, f32 gamma, bool limited_rgb,
|
||||||
bool stereo_enabled, stereo_render_mode_options stereo_mode, gl::filter input_filter)
|
bool stereo_enabled, gl::filter input_filter)
|
||||||
{
|
{
|
||||||
if (m_input_filter != input_filter)
|
if (m_input_filter != input_filter)
|
||||||
{
|
{
|
||||||
@@ -519,10 +520,16 @@ namespace gl
|
|||||||
m_sampler.set_parameteri(GL_TEXTURE_MAG_FILTER, static_cast<GLenum>(m_input_filter));
|
m_sampler.set_parameteri(GL_TEXTURE_MAG_FILTER, static_cast<GLenum>(m_input_filter));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static stereo_config stereo_cfg = stereo_config(true);
|
||||||
|
stereo_cfg.update_from_config(stereo_enabled);
|
||||||
|
const auto& matrices = stereo_cfg.matrices();
|
||||||
|
|
||||||
program_handle.uniforms["gamma"] = gamma;
|
program_handle.uniforms["gamma"] = gamma;
|
||||||
program_handle.uniforms["limit_range"] = limited_rgb + 0;
|
program_handle.uniforms["limit_range"] = limited_rgb + 0;
|
||||||
program_handle.uniforms["stereo_display_mode"] = stereo_enabled ? static_cast<u8>(stereo_mode) : 0;
|
program_handle.uniforms["stereo_display_mode"] = static_cast<u8>(stereo_cfg.stereo_mode());
|
||||||
program_handle.uniforms["stereo_image_count"] = (source[1] == GL_NONE? 1 : 2);
|
program_handle.uniforms["stereo_image_count"] = (source[1] == GL_NONE ? 1 : 2);
|
||||||
|
program_handle.uniforms["left_anaglyph_matrix"] = matrices.left;
|
||||||
|
program_handle.uniforms["right_anaglyph_matrix"] = matrices.right;
|
||||||
|
|
||||||
saved_sampler_state saved(GL_TEMP_IMAGE_SLOT(0), m_sampler);
|
saved_sampler_state saved(GL_TEMP_IMAGE_SLOT(0), m_sampler);
|
||||||
cmd->bind_texture(GL_TEMP_IMAGE_SLOT(0), GL_TEXTURE_2D, source[0]);
|
cmd->bind_texture(GL_TEMP_IMAGE_SLOT(0), GL_TEXTURE_2D, source[0]);
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ namespace gl
|
|||||||
video_out_calibration_pass();
|
video_out_calibration_pass();
|
||||||
|
|
||||||
void run(gl::command_context& cmd, const areau& viewport, const rsx::simple_array<GLuint>& source, f32 gamma, bool limited_rgb,
|
void run(gl::command_context& cmd, const areau& viewport, const rsx::simple_array<GLuint>& source, f32 gamma, bool limited_rgb,
|
||||||
bool stereo_enabled, stereo_render_mode_options stereo_mode, gl::filter input_filter);
|
bool stereo_enabled, gl::filter input_filter);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rp_ssbo_to_generic_texture final : public overlay_pass
|
struct rp_ssbo_to_generic_texture final : public overlay_pass
|
||||||
|
|||||||
@@ -436,7 +436,7 @@ void GLGSRender::flip(const rsx::display_flip_info_t& info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
gl::screen.bind();
|
gl::screen.bind();
|
||||||
m_video_output_pass.run(cmd, areau(aspect_ratio), images.map(FN(x ? x->id() : GL_NONE)), gamma, limited_range, avconfig.stereo_enabled, g_cfg.video.stereo_render_mode, filter);
|
m_video_output_pass.run(cmd, areau(aspect_ratio), images.map(FN(x ? x->id() : GL_NONE)), gamma, limited_range, avconfig.stereo_enabled, filter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ namespace gl
|
|||||||
void operator = (const color4f& rhs) const { glProgramUniform4f(m_program.id(), location(), rhs.r, rhs.g, rhs.b, rhs.a); }
|
void operator = (const color4f& rhs) const { glProgramUniform4f(m_program.id(), location(), rhs.r, rhs.g, rhs.b, rhs.a); }
|
||||||
void operator = (const areaf& rhs) const { glProgramUniform4f(m_program.id(), location(), rhs.x1, rhs.y1, rhs.x2, rhs.y2); }
|
void operator = (const areaf& rhs) const { glProgramUniform4f(m_program.id(), location(), rhs.x1, rhs.y1, rhs.x2, rhs.y2); }
|
||||||
void operator = (const areai& rhs) const { glProgramUniform4i(m_program.id(), location(), rhs.x1, rhs.y1, rhs.x2, rhs.y2); }
|
void operator = (const areai& rhs) const { glProgramUniform4i(m_program.id(), location(), rhs.x1, rhs.y1, rhs.x2, rhs.y2); }
|
||||||
|
void operator = (const mat3f& rhs) const { glProgramUniformMatrix3fv(m_program.id(), location(), 1, GL_FALSE, &rhs[0].rgb[0]); }
|
||||||
void operator = (const std::span<const int>& rhs) const { glProgramUniform1iv(m_program.id(), location(), ::size32(rhs), rhs.data()); }
|
void operator = (const std::span<const int>& rhs) const { glProgramUniform1iv(m_program.id(), location(), ::size32(rhs), rhs.data()); }
|
||||||
void operator = (const std::span<const handle64_t>& rhs) const { glProgramUniformHandleui64vARB(m_program.id(), location(), ::size32(rhs), rhs.data()); }
|
void operator = (const std::span<const handle64_t>& rhs) const { glProgramUniformHandleui64vARB(m_program.id(), location(), ::size32(rhs), rhs.data()); }
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ layout(location=0) out vec4 ocol;
|
|||||||
#define STEREO_MODE_ANAGLYPH_MAGENTA_CYAN 7
|
#define STEREO_MODE_ANAGLYPH_MAGENTA_CYAN 7
|
||||||
#define STEREO_MODE_ANAGLYPH_TRIOSCOPIC 8
|
#define STEREO_MODE_ANAGLYPH_TRIOSCOPIC 8
|
||||||
#define STEREO_MODE_ANAGLYPH_AMBER_BLUE 9
|
#define STEREO_MODE_ANAGLYPH_AMBER_BLUE 9
|
||||||
|
#define STEREO_MODE_ANAGLYPH_CUSTOM 10
|
||||||
|
|
||||||
#define TRUE 1
|
#define TRUE 1
|
||||||
#define FALSE 0
|
#define FALSE 0
|
||||||
@@ -37,26 +38,28 @@ layout(push_constant) uniform static_data
|
|||||||
int limit_range;
|
int limit_range;
|
||||||
int stereo_display_mode;
|
int stereo_display_mode;
|
||||||
int stereo_image_count;
|
int stereo_image_count;
|
||||||
|
mat3 left_anaglyph_matrix;
|
||||||
|
mat3 right_anaglyph_matrix;
|
||||||
};
|
};
|
||||||
#else
|
#else
|
||||||
uniform float gamma;
|
uniform float gamma;
|
||||||
uniform int limit_range;
|
uniform int limit_range;
|
||||||
uniform int stereo_display_mode;
|
uniform int stereo_display_mode;
|
||||||
uniform int stereo_image_count;
|
uniform int stereo_image_count;
|
||||||
|
uniform mat3 left_anaglyph_matrix;
|
||||||
|
uniform mat3 right_anaglyph_matrix;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
vec3 applyMatrix(vec3 left, vec3 right)
|
||||||
|
{
|
||||||
|
vec3 outColor = left_anaglyph_matrix * left + right_anaglyph_matrix * right;
|
||||||
|
return clamp(outColor, 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
vec4 anaglyph(const in vec4 left, const in vec4 right)
|
vec4 anaglyph(const in vec4 left, const in vec4 right)
|
||||||
{
|
{
|
||||||
switch (stereo_display_mode)
|
vec3 color = applyMatrix(left.rgb, right.rgb);
|
||||||
{
|
return vec4(color, 1.0);
|
||||||
case STEREO_MODE_ANAGLYPH_RED_GREEN: return vec4(left.r, right.g, 0.f, 1.f);
|
|
||||||
case STEREO_MODE_ANAGLYPH_RED_BLUE: return vec4(left.r, 0.f, right.b, 1.f);
|
|
||||||
case STEREO_MODE_ANAGLYPH_RED_CYAN: return vec4(left.r, right.g, right.b, 1.f);
|
|
||||||
case STEREO_MODE_ANAGLYPH_MAGENTA_CYAN: return vec4(left.r, right.g, (left.b + right.b) / 2.f, 1.f);
|
|
||||||
case STEREO_MODE_ANAGLYPH_TRIOSCOPIC: return vec4(right.r, left.g, right.b, 1.f);
|
|
||||||
case STEREO_MODE_ANAGLYPH_AMBER_BLUE: return vec4(left.r, left.g, (right.r + right.g + right.b) / 3.f, 1.f);
|
|
||||||
default: return texture(fs0, tc0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 anaglyph_single_image()
|
vec4 anaglyph_single_image()
|
||||||
@@ -92,6 +95,7 @@ vec4 read_source()
|
|||||||
case STEREO_MODE_ANAGLYPH_MAGENTA_CYAN:
|
case STEREO_MODE_ANAGLYPH_MAGENTA_CYAN:
|
||||||
case STEREO_MODE_ANAGLYPH_TRIOSCOPIC:
|
case STEREO_MODE_ANAGLYPH_TRIOSCOPIC:
|
||||||
case STEREO_MODE_ANAGLYPH_AMBER_BLUE:
|
case STEREO_MODE_ANAGLYPH_AMBER_BLUE:
|
||||||
|
case STEREO_MODE_ANAGLYPH_CUSTOM:
|
||||||
return anaglyph_single_image();
|
return anaglyph_single_image();
|
||||||
case STEREO_MODE_SIDE_BY_SIDE:
|
case STEREO_MODE_SIDE_BY_SIDE:
|
||||||
return (tc0.x < 0.5)
|
return (tc0.x < 0.5)
|
||||||
@@ -120,6 +124,7 @@ vec4 read_source()
|
|||||||
case STEREO_MODE_ANAGLYPH_MAGENTA_CYAN:
|
case STEREO_MODE_ANAGLYPH_MAGENTA_CYAN:
|
||||||
case STEREO_MODE_ANAGLYPH_TRIOSCOPIC:
|
case STEREO_MODE_ANAGLYPH_TRIOSCOPIC:
|
||||||
case STEREO_MODE_ANAGLYPH_AMBER_BLUE:
|
case STEREO_MODE_ANAGLYPH_AMBER_BLUE:
|
||||||
|
case STEREO_MODE_ANAGLYPH_CUSTOM:
|
||||||
return anaglyph_stereo_image();
|
return anaglyph_stereo_image();
|
||||||
case STEREO_MODE_SIDE_BY_SIDE:
|
case STEREO_MODE_SIDE_BY_SIDE:
|
||||||
return (tc0.x < 0.5)
|
return (tc0.x < 0.5)
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#include "../Program/RSXOverlay.h"
|
#include "../Program/RSXOverlay.h"
|
||||||
|
|
||||||
#include "util/fnv_hash.hpp"
|
#include "util/fnv_hash.hpp"
|
||||||
|
#include "Utilities/stereo_config.h"
|
||||||
|
|
||||||
#include "Emu/Cell/timers.hpp"
|
#include "Emu/Cell/timers.hpp"
|
||||||
|
|
||||||
@@ -911,18 +912,28 @@ namespace vk
|
|||||||
|
|
||||||
void video_out_calibration_pass::update_uniforms(vk::command_buffer& cmd, vk::glsl::program* program)
|
void video_out_calibration_pass::update_uniforms(vk::command_buffer& cmd, vk::glsl::program* program)
|
||||||
{
|
{
|
||||||
vkCmdPushConstants(cmd, program->layout(), VK_SHADER_STAGE_FRAGMENT_BIT, 0, 16, config.data);
|
vkCmdPushConstants(cmd, program->layout(), VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(config.data), config.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void video_out_calibration_pass::run(vk::command_buffer& cmd, const areau& viewport, vk::framebuffer* target,
|
void video_out_calibration_pass::run(vk::command_buffer& cmd, const areau& viewport, vk::framebuffer* target,
|
||||||
const rsx::simple_array<vk::viewable_image*>& src, f32 gamma, bool limited_rgb,
|
const rsx::simple_array<vk::viewable_image*>& src, f32 gamma, bool limited_rgb,
|
||||||
bool stereo_enabled, stereo_render_mode_options stereo_mode, VkRenderPass render_pass)
|
bool stereo_enabled, VkRenderPass render_pass)
|
||||||
{
|
{
|
||||||
|
static stereo_config stereo_cfg = stereo_config(true);
|
||||||
|
stereo_cfg.update_from_config(stereo_enabled);
|
||||||
|
const auto& matrices = stereo_cfg.matrices();
|
||||||
|
|
||||||
config.gamma = gamma;
|
config.gamma = gamma;
|
||||||
config.limit_range = limited_rgb? 1 : 0;
|
config.limit_range = limited_rgb ? 1 : 0;
|
||||||
config.stereo_display_mode = stereo_enabled ? static_cast<u8>(stereo_mode) : 0;
|
config.stereo_display_mode = static_cast<u8>(stereo_cfg.stereo_mode());
|
||||||
config.stereo_image_count = std::min(::size32(src), 2u);
|
config.stereo_image_count = std::min(::size32(src), 2u);
|
||||||
|
|
||||||
|
for (u32 i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
std::memcpy(config.left_anaglyph_matrix[i].rgba, matrices.left[i].rgb, sizeof(matrices.left[i].rgb));
|
||||||
|
std::memcpy(config.right_anaglyph_matrix[i].rgba, matrices.right[i].rgb, sizeof(matrices.right[i].rgb));
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<vk::image_view*> views;
|
std::vector<vk::image_view*> views;
|
||||||
views.reserve(2);
|
views.reserve(2);
|
||||||
|
|
||||||
|
|||||||
@@ -209,9 +209,18 @@ namespace vk
|
|||||||
int limit_range;
|
int limit_range;
|
||||||
int stereo_display_mode;
|
int stereo_display_mode;
|
||||||
int stereo_image_count;
|
int stereo_image_count;
|
||||||
|
color4_base<float> left_anaglyph_matrix[3];
|
||||||
|
color4_base<float> right_anaglyph_matrix[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
float data[4];
|
float data[(
|
||||||
|
sizeof(gamma) +
|
||||||
|
sizeof(limit_range) +
|
||||||
|
sizeof(stereo_display_mode) +
|
||||||
|
sizeof(stereo_image_count) +
|
||||||
|
sizeof(left_anaglyph_matrix) +
|
||||||
|
sizeof(right_anaglyph_matrix)
|
||||||
|
) / sizeof(float)];
|
||||||
}
|
}
|
||||||
config = {};
|
config = {};
|
||||||
|
|
||||||
@@ -223,7 +232,7 @@ namespace vk
|
|||||||
|
|
||||||
void run(vk::command_buffer& cmd, const areau& viewport, vk::framebuffer* target,
|
void run(vk::command_buffer& cmd, const areau& viewport, vk::framebuffer* target,
|
||||||
const rsx::simple_array<vk::viewable_image*>& src, f32 gamma, bool limited_rgb,
|
const rsx::simple_array<vk::viewable_image*>& src, f32 gamma, bool limited_rgb,
|
||||||
bool stereo_enabled, stereo_render_mode_options stereo_mode, VkRenderPass render_pass);
|
bool stereo_enabled, VkRenderPass render_pass);
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: Replace with a proper manager
|
// TODO: Replace with a proper manager
|
||||||
|
|||||||
@@ -839,7 +839,7 @@ void VKGSRender::flip(const rsx::display_flip_info_t& info)
|
|||||||
|
|
||||||
vk::get_overlay_pass<vk::video_out_calibration_pass>()->run(
|
vk::get_overlay_pass<vk::video_out_calibration_pass>()->run(
|
||||||
*m_current_command_buffer, areau(aspect_ratio), direct_fbo, calibration_src,
|
*m_current_command_buffer, areau(aspect_ratio), direct_fbo, calibration_src,
|
||||||
avconfig.gamma, !use_full_rgb_range_output, avconfig.stereo_enabled, g_cfg.video.stereo_render_mode, single_target_pass);
|
avconfig.gamma, !use_full_rgb_range_output, avconfig.stereo_enabled, single_target_pass);
|
||||||
|
|
||||||
direct_fbo->release();
|
direct_fbo->release();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -234,6 +234,15 @@ struct cfg_root : cfg::node
|
|||||||
|
|
||||||
} shader_preloading_dialog{ this };
|
} shader_preloading_dialog{ this };
|
||||||
|
|
||||||
|
struct anaglyph_matrices : cfg::node
|
||||||
|
{
|
||||||
|
anaglyph_matrices(cfg::node* _this) : cfg::node(_this, "Custom Anaglyph Matrices") {}
|
||||||
|
|
||||||
|
cfg::node_map_entry left{ this, "Matrix Left" };
|
||||||
|
cfg::node_map_entry right{ this, "Matrix Right" };
|
||||||
|
|
||||||
|
} custom_anaglyph_matrices{ this };
|
||||||
|
|
||||||
} video{ this };
|
} video{ this };
|
||||||
|
|
||||||
struct node_audio : cfg::node
|
struct node_audio : cfg::node
|
||||||
|
|||||||
@@ -681,6 +681,7 @@ void fmt_class_string<stereo_render_mode_options>::format(std::string& out, u64
|
|||||||
case stereo_render_mode_options::anaglyph_magenta_cyan: return "Anaglyph Magenta-Cyan";
|
case stereo_render_mode_options::anaglyph_magenta_cyan: return "Anaglyph Magenta-Cyan";
|
||||||
case stereo_render_mode_options::anaglyph_trioscopic: return "Anaglyph Trioscopic";
|
case stereo_render_mode_options::anaglyph_trioscopic: return "Anaglyph Trioscopic";
|
||||||
case stereo_render_mode_options::anaglyph_amber_blue: return "Anaglyph Amber-Blue";
|
case stereo_render_mode_options::anaglyph_amber_blue: return "Anaglyph Amber-Blue";
|
||||||
|
case stereo_render_mode_options::anaglyph_custom: return "Anaglyph Custom";
|
||||||
}
|
}
|
||||||
|
|
||||||
return unknown;
|
return unknown;
|
||||||
|
|||||||
@@ -361,6 +361,7 @@ enum class stereo_render_mode_options
|
|||||||
anaglyph_magenta_cyan,
|
anaglyph_magenta_cyan,
|
||||||
anaglyph_trioscopic,
|
anaglyph_trioscopic,
|
||||||
anaglyph_amber_blue,
|
anaglyph_amber_blue,
|
||||||
|
anaglyph_custom,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class xfloat_accuracy
|
enum class xfloat_accuracy
|
||||||
|
|||||||
@@ -59,6 +59,7 @@
|
|||||||
</Lib>
|
</Lib>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\Utilities\stereo_config.cpp" />
|
||||||
<ClCompile Include="..\Utilities\cheat_info.cpp" />
|
<ClCompile Include="..\Utilities\cheat_info.cpp" />
|
||||||
<ClCompile Include="..\Utilities\date_time.cpp" />
|
<ClCompile Include="..\Utilities\date_time.cpp" />
|
||||||
<ClCompile Include="..\Utilities\stack_trace.cpp" />
|
<ClCompile Include="..\Utilities\stack_trace.cpp" />
|
||||||
@@ -574,6 +575,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\3rdparty\stblib\stb\stb_image.h" />
|
<ClInclude Include="..\3rdparty\stblib\stb\stb_image.h" />
|
||||||
<ClInclude Include="..\Utilities\address_range.h" />
|
<ClInclude Include="..\Utilities\address_range.h" />
|
||||||
|
<ClInclude Include="..\Utilities\stereo_config.h" />
|
||||||
<ClInclude Include="..\Utilities\cheat_info.h" />
|
<ClInclude Include="..\Utilities\cheat_info.h" />
|
||||||
<ClInclude Include="..\Utilities\deferred_op.hpp" />
|
<ClInclude Include="..\Utilities\deferred_op.hpp" />
|
||||||
<ClInclude Include="..\Utilities\simple_ringbuf.h" />
|
<ClInclude Include="..\Utilities\simple_ringbuf.h" />
|
||||||
|
|||||||
@@ -1435,6 +1435,9 @@
|
|||||||
<ClCompile Include="Loader\iso_validation.cpp">
|
<ClCompile Include="Loader\iso_validation.cpp">
|
||||||
<Filter>Loader</Filter>
|
<Filter>Loader</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\Utilities\stereo_config.cpp">
|
||||||
|
<Filter>Utilities</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Crypto\aes.h">
|
<ClInclude Include="Crypto\aes.h">
|
||||||
@@ -2881,6 +2884,9 @@
|
|||||||
<ClInclude Include="Loader\iso_validation.h">
|
<ClInclude Include="Loader\iso_validation.h">
|
||||||
<Filter>Loader</Filter>
|
<Filter>Loader</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\Utilities\stereo_config.h">
|
||||||
|
<Filter>Utilities</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="Emu\RSX\Program\GLSLSnippets\GPUDeswizzle.glsl">
|
<None Include="Emu\RSX\Program\GLSLSnippets\GPUDeswizzle.glsl">
|
||||||
|
|||||||
@@ -838,6 +838,7 @@
|
|||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="rpcs3.cpp" />
|
<ClCompile Include="rpcs3.cpp" />
|
||||||
<ClCompile Include="rpcs3qt\about_dialog.cpp" />
|
<ClCompile Include="rpcs3qt\about_dialog.cpp" />
|
||||||
|
<ClCompile Include="rpcs3qt\anaglyph_settings_dialog.cpp" />
|
||||||
<ClCompile Include="rpcs3qt\basic_mouse_settings_dialog.cpp" />
|
<ClCompile Include="rpcs3qt\basic_mouse_settings_dialog.cpp" />
|
||||||
<ClCompile Include="rpcs3qt\breakpoint_handler.cpp" />
|
<ClCompile Include="rpcs3qt\breakpoint_handler.cpp" />
|
||||||
<ClCompile Include="rpcs3qt\breakpoint_list.cpp" />
|
<ClCompile Include="rpcs3qt\breakpoint_list.cpp" />
|
||||||
@@ -1197,6 +1198,7 @@
|
|||||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DWITH_DISCORD_RPC -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DNDEBUG -DQT_CONCURRENT_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\wolfssl\wolfssl" "-I.\..\3rdparty\curl\curl\include" "-I.\..\3rdparty\libusb\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtCore" "-I.\release" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtConcurrent"</Command>
|
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DWITH_DISCORD_RPC -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DNDEBUG -DQT_CONCURRENT_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\wolfssl\wolfssl" "-I.\..\3rdparty\curl\curl\include" "-I.\..\3rdparty\libusb\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtCore" "-I.\release" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtConcurrent"</Command>
|
||||||
</CustomBuild>
|
</CustomBuild>
|
||||||
<ClInclude Include="rpcs3.h" />
|
<ClInclude Include="rpcs3.h" />
|
||||||
|
<ClInclude Include="rpcs3qt\anaglyph_settings_dialog.h" />
|
||||||
<ClInclude Include="rpcs3qt\breakpoint_handler.h" />
|
<ClInclude Include="rpcs3qt\breakpoint_handler.h" />
|
||||||
<CustomBuild Include="rpcs3qt\breakpoint_list.h">
|
<CustomBuild Include="rpcs3qt\breakpoint_list.h">
|
||||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||||
|
|||||||
@@ -1311,6 +1311,9 @@
|
|||||||
<ClCompile Include="rpcs3qt\iso_integrity.cpp">
|
<ClCompile Include="rpcs3qt\iso_integrity.cpp">
|
||||||
<Filter>Gui\game list</Filter>
|
<Filter>Gui\game list</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="rpcs3qt\anaglyph_settings_dialog.cpp">
|
||||||
|
<Filter>Gui\settings</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Input\ds4_pad_handler.h">
|
<ClInclude Include="Input\ds4_pad_handler.h">
|
||||||
@@ -1562,6 +1565,9 @@
|
|||||||
<ClInclude Include="rpcs3qt\steam_utils.h">
|
<ClInclude Include="rpcs3qt\steam_utils.h">
|
||||||
<Filter>Gui\utils</Filter>
|
<Filter>Gui\utils</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="rpcs3qt\anaglyph_settings_dialog.h">
|
||||||
|
<Filter>Gui\settings</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="resource.h">
|
<ClInclude Include="resource.h">
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
add_library(rpcs3_ui STATIC
|
add_library(rpcs3_ui STATIC
|
||||||
about_dialog.cpp
|
about_dialog.cpp
|
||||||
|
anaglyph_settings_dialog.cpp
|
||||||
auto_pause_settings_dialog.cpp
|
auto_pause_settings_dialog.cpp
|
||||||
basic_mouse_settings_dialog.cpp
|
basic_mouse_settings_dialog.cpp
|
||||||
breakpoint_handler.cpp
|
breakpoint_handler.cpp
|
||||||
|
|||||||
@@ -0,0 +1,293 @@
|
|||||||
|
#include "stdafx.h"
|
||||||
|
#include "anaglyph_settings_dialog.h"
|
||||||
|
|
||||||
|
#include <QGroupBox>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QPushButton>
|
||||||
|
|
||||||
|
color_wedge_widget::color_wedge_widget(QWidget* parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
{
|
||||||
|
setObjectName("color_wedge_widget");
|
||||||
|
setMinimumSize(300, 300);
|
||||||
|
}
|
||||||
|
|
||||||
|
color_wedge_widget::~color_wedge_widget()
|
||||||
|
{
|
||||||
|
stereo_config::s_live_preview_enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void color_wedge_widget::set_option(stereo_render_mode_options option)
|
||||||
|
{
|
||||||
|
m_stereo_config.set_stereo_mode(option);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void color_wedge_widget::set_custom_matrices(const stereo_config::stereo_matrices& matrices)
|
||||||
|
{
|
||||||
|
m_stereo_config.set_custom_matrices(matrices);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector3D color_wedge_widget::apply_matrix(const QVector3D& left, const QVector3D& right, const stereo_config::stereo_matrices& m)
|
||||||
|
{
|
||||||
|
const mat3f& ml = m.left;
|
||||||
|
const mat3f& mr = m.right;
|
||||||
|
|
||||||
|
QVector3D out;
|
||||||
|
out.setX(ml[0].x * left.x() + ml[1].x * left.y() + ml[2].x * left.z() +
|
||||||
|
mr[0].x * right.x() + mr[1].x * right.y() + mr[2].x * right.z());
|
||||||
|
|
||||||
|
out.setY(ml[0].y * left.x() + ml[1].y * left.y() + ml[2].y * left.z() +
|
||||||
|
mr[0].y * right.x() + mr[1].y * right.y() + mr[2].y * right.z());
|
||||||
|
|
||||||
|
out.setZ(ml[0].z * left.x() + ml[1].z * left.y() + ml[2].z * left.z() +
|
||||||
|
mr[0].z * right.x() + mr[1].z * right.y() + mr[2].z * right.z());
|
||||||
|
|
||||||
|
out.setX(std::clamp(out.x(), 0.0f, 1.0f));
|
||||||
|
out.setY(std::clamp(out.y(), 0.0f, 1.0f));
|
||||||
|
out.setZ(std::clamp(out.z(), 0.0f, 1.0f));
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector3D color_wedge_widget::apply_anaglyph_matrix(const QVector3D& left, const QVector3D& right)
|
||||||
|
{
|
||||||
|
if (m_stereo_config.stereo_mode() == stereo_render_mode_options::disabled)
|
||||||
|
{
|
||||||
|
return left;
|
||||||
|
}
|
||||||
|
|
||||||
|
return apply_matrix(left, right, m_stereo_config.matrices());
|
||||||
|
}
|
||||||
|
|
||||||
|
void color_wedge_widget::paintEvent(QPaintEvent* /*event*/)
|
||||||
|
{
|
||||||
|
const int w = width();
|
||||||
|
const int h = height();
|
||||||
|
|
||||||
|
if (m_img.width() != w || m_img.height() != h)
|
||||||
|
{
|
||||||
|
m_img = QImage(w, h, QImage::Format_RGB32);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector3D out;
|
||||||
|
|
||||||
|
// Loop over pixels
|
||||||
|
for (int y = 0; y < h; ++y)
|
||||||
|
{
|
||||||
|
const float v = float(y) / (h - 1);
|
||||||
|
|
||||||
|
for (int x = 0; x < w; ++x)
|
||||||
|
{
|
||||||
|
const float u = float(x) / (w - 1);
|
||||||
|
|
||||||
|
const QVector3D left(u, v, 1.0f - u);
|
||||||
|
const QVector3D right = left;
|
||||||
|
|
||||||
|
const QVector3D out = apply_anaglyph_matrix(left, right);
|
||||||
|
|
||||||
|
m_img.setPixel(x, y, qRgb(int(out.x() * 255), int(out.y() * 255), int(out.z() * 255)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Paint the image
|
||||||
|
QPainter p(this);
|
||||||
|
p.drawImage(0, 0, m_img);
|
||||||
|
}
|
||||||
|
|
||||||
|
anaglyph_settings_dialog::anaglyph_settings_dialog(QWidget* parent, std::shared_ptr<emu_settings> emu_settings)
|
||||||
|
: QDialog(parent)
|
||||||
|
, m_emu_settings(std::move(emu_settings))
|
||||||
|
{
|
||||||
|
setWindowTitle(tr("Anaglyph Settings"));
|
||||||
|
setObjectName("anaglyph_settings_dialog");
|
||||||
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
|
||||||
|
stereo_render_mode_options current_mode = stereo_render_mode_options::disabled;
|
||||||
|
if (u64 result {}; cfg::try_to_enum_value(&result, &fmt_class_string<stereo_render_mode_options>::format, m_emu_settings->GetSetting(emu_settings_type::StereoRenderMode)))
|
||||||
|
{
|
||||||
|
const auto mode = static_cast<stereo_render_mode_options>(static_cast<std::underlying_type_t<stereo_render_mode_options>>(result));
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case stereo_render_mode_options::anaglyph_red_green:
|
||||||
|
case stereo_render_mode_options::anaglyph_red_blue:
|
||||||
|
case stereo_render_mode_options::anaglyph_red_cyan:
|
||||||
|
case stereo_render_mode_options::anaglyph_magenta_cyan:
|
||||||
|
case stereo_render_mode_options::anaglyph_trioscopic:
|
||||||
|
case stereo_render_mode_options::anaglyph_amber_blue:
|
||||||
|
case stereo_render_mode_options::anaglyph_custom:
|
||||||
|
current_mode = mode;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stereo_config::stereo_matrices custom_matrices {};
|
||||||
|
stereo_config::convert_matrix(custom_matrices.left, m_emu_settings->GetMapSetting(emu_settings_type::CustomAnaglyphMatrixLeft));
|
||||||
|
stereo_config::convert_matrix(custom_matrices.right, m_emu_settings->GetMapSetting(emu_settings_type::CustomAnaglyphMatrixRight));
|
||||||
|
|
||||||
|
m_widget_reference = new color_wedge_widget(this);
|
||||||
|
m_widget_reference->set_option(stereo_render_mode_options::disabled);
|
||||||
|
|
||||||
|
m_widget = new color_wedge_widget(this);
|
||||||
|
m_widget->set_option(current_mode);
|
||||||
|
m_widget->set_custom_matrices(custom_matrices);
|
||||||
|
|
||||||
|
QPushButton* apply_button = new QPushButton(tr("Apply Custom Matrices"));
|
||||||
|
connect(apply_button, &QAbstractButton::clicked, this, [this]()
|
||||||
|
{
|
||||||
|
m_emu_settings->SetMapSetting(emu_settings_type::CustomAnaglyphMatrixLeft, m_widget->get_stereo_config().get_custom_matrix(true));
|
||||||
|
m_emu_settings->SetMapSetting(emu_settings_type::CustomAnaglyphMatrixRight, m_widget->get_stereo_config().get_custom_matrix(false));
|
||||||
|
});
|
||||||
|
apply_button->setEnabled(current_mode == stereo_render_mode_options::anaglyph_custom);
|
||||||
|
|
||||||
|
QCheckBox* live_preview_cb = new QCheckBox(tr("Live Preview"));
|
||||||
|
connect(live_preview_cb, &QCheckBox::checkStateChanged, this, [this](Qt::CheckState state)
|
||||||
|
{
|
||||||
|
stereo_config::s_live_preview_enabled = state == Qt::CheckState::Checked;
|
||||||
|
});
|
||||||
|
|
||||||
|
QComboBox* combo = new QComboBox(this);
|
||||||
|
combo->addItem(tr("Disabled"), static_cast<int>(stereo_render_mode_options::disabled));
|
||||||
|
combo->addItem(tr("Red-Green"), static_cast<int>(stereo_render_mode_options::anaglyph_red_green));
|
||||||
|
combo->addItem(tr("Red-Blue"), static_cast<int>(stereo_render_mode_options::anaglyph_red_blue));
|
||||||
|
combo->addItem(tr("Red-Cyan"), static_cast<int>(stereo_render_mode_options::anaglyph_red_cyan));
|
||||||
|
combo->addItem(tr("Magenta-Cyan"), static_cast<int>(stereo_render_mode_options::anaglyph_magenta_cyan));
|
||||||
|
combo->addItem(tr("Trioscopic"), static_cast<int>(stereo_render_mode_options::anaglyph_trioscopic));
|
||||||
|
combo->addItem(tr("Amber-Blue"), static_cast<int>(stereo_render_mode_options::anaglyph_amber_blue));
|
||||||
|
combo->addItem(tr("Custom"), static_cast<int>(stereo_render_mode_options::anaglyph_custom));
|
||||||
|
combo->setCurrentIndex(combo->findData(static_cast<int>(current_mode)));
|
||||||
|
|
||||||
|
connect(combo, &QComboBox::currentIndexChanged, this, [this, combo, apply_button](int /*index*/)
|
||||||
|
{
|
||||||
|
apply_button->setEnabled(static_cast<stereo_render_mode_options>(combo->currentData().toInt()) == stereo_render_mode_options::anaglyph_custom);
|
||||||
|
m_widget->set_option(static_cast<stereo_render_mode_options>(combo->currentData().toInt()));
|
||||||
|
update_matrices();
|
||||||
|
});
|
||||||
|
|
||||||
|
m_matrix_left = create_matrix_table();
|
||||||
|
m_matrix_right = create_matrix_table();
|
||||||
|
|
||||||
|
update_matrices();
|
||||||
|
|
||||||
|
const auto group_box = [](const QString& title, QWidget* widget)
|
||||||
|
{
|
||||||
|
QHBoxLayout* layout = new QHBoxLayout();
|
||||||
|
layout->addWidget(widget);
|
||||||
|
|
||||||
|
QGroupBox* gb = new QGroupBox(title);
|
||||||
|
gb->setLayout(layout);
|
||||||
|
return gb;
|
||||||
|
};
|
||||||
|
|
||||||
|
QHBoxLayout* lay_h_1 = new QHBoxLayout();
|
||||||
|
lay_h_1->addWidget(combo);
|
||||||
|
lay_h_1->addWidget(apply_button);
|
||||||
|
lay_h_1->addWidget(live_preview_cb);
|
||||||
|
lay_h_1->addSpacerItem(new QSpacerItem(50, 0, QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding));
|
||||||
|
|
||||||
|
QHBoxLayout* lay_h_2 = new QHBoxLayout();
|
||||||
|
lay_h_2->addWidget(group_box(tr("Left matrix"), m_matrix_left));
|
||||||
|
lay_h_2->addWidget(group_box(tr("Right matrix"), m_matrix_right));
|
||||||
|
|
||||||
|
QHBoxLayout* lay_h_3 = new QHBoxLayout();
|
||||||
|
lay_h_3->addWidget(group_box(tr("Reference"), m_widget_reference));
|
||||||
|
lay_h_3->addWidget(group_box(tr("Anaglyph"), m_widget));
|
||||||
|
|
||||||
|
QVBoxLayout* lay = new QVBoxLayout();
|
||||||
|
lay->addLayout(lay_h_1);
|
||||||
|
lay->addLayout(lay_h_2);
|
||||||
|
lay->addLayout(lay_h_3);
|
||||||
|
|
||||||
|
setLayout(lay);
|
||||||
|
adjustSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
QTableWidget* anaglyph_settings_dialog::create_matrix_table()
|
||||||
|
{
|
||||||
|
QTableWidget* table = new QTableWidget(3, 3, this);
|
||||||
|
table->setVerticalHeaderLabels({tr("R in"), tr("G in"), tr("B in")});
|
||||||
|
table->setHorizontalHeaderLabels({tr("R out"), tr("G out"), tr("B out")});
|
||||||
|
for (int r = 0; r < 3; ++r)
|
||||||
|
{
|
||||||
|
for (int c = 0; c < 3; ++c)
|
||||||
|
{
|
||||||
|
table->setItem(r, c, new QTableWidgetItem("0.0"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
connect(table, &QTableWidget::cellChanged, this, [this]()
|
||||||
|
{
|
||||||
|
apply_custom_matrix();
|
||||||
|
});
|
||||||
|
|
||||||
|
table->resizeColumnsToContents();
|
||||||
|
table->resizeRowsToContents();
|
||||||
|
return table;
|
||||||
|
}
|
||||||
|
|
||||||
|
void anaglyph_settings_dialog::read_matrix(mat3f& matrix, QTableWidget* table) const
|
||||||
|
{
|
||||||
|
if (!table) return;
|
||||||
|
|
||||||
|
for (int r = 0; r < 3; ++r)
|
||||||
|
{
|
||||||
|
for (int c = 0; c < 3; ++c)
|
||||||
|
{
|
||||||
|
bool ok = false;
|
||||||
|
const float val = table->item(r, c)->text().toFloat(&ok);
|
||||||
|
matrix[r].rgb[c] = ok ? val : 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void anaglyph_settings_dialog::update_matrix(QTableWidget* table, const mat3f& matrix, bool is_custom)
|
||||||
|
{
|
||||||
|
if (!table) return;
|
||||||
|
|
||||||
|
for (int r = 0; r < 3; ++r)
|
||||||
|
{
|
||||||
|
for (int c = 0; c < 3; ++c)
|
||||||
|
{
|
||||||
|
if (QTableWidgetItem* item = table->item(r, c))
|
||||||
|
{
|
||||||
|
Qt::ItemFlags flags = item->flags();
|
||||||
|
flags.setFlag(Qt::ItemIsEditable, is_custom);
|
||||||
|
|
||||||
|
item->setFlags(flags);
|
||||||
|
item->setText(QString::number(matrix[r].rgb[c]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void anaglyph_settings_dialog::update_matrices()
|
||||||
|
{
|
||||||
|
if (!m_widget) return;
|
||||||
|
|
||||||
|
const stereo_config& stereo_cfg = m_widget->get_stereo_config();
|
||||||
|
const stereo_config::stereo_matrices& matrices = stereo_cfg.matrices();
|
||||||
|
|
||||||
|
stereo_config::set_live_matrices(matrices);
|
||||||
|
|
||||||
|
const bool is_custom = stereo_cfg.stereo_mode() == stereo_render_mode_options::anaglyph_custom;
|
||||||
|
|
||||||
|
m_updating = true;
|
||||||
|
update_matrix(m_matrix_left, matrices.left, is_custom);
|
||||||
|
update_matrix(m_matrix_right, matrices.right, is_custom);
|
||||||
|
m_updating = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void anaglyph_settings_dialog::apply_custom_matrix()
|
||||||
|
{
|
||||||
|
if (!m_widget || m_updating) return;
|
||||||
|
|
||||||
|
stereo_config::stereo_matrices m {};
|
||||||
|
read_matrix(m.left, m_matrix_left);
|
||||||
|
read_matrix(m.right, m_matrix_right);
|
||||||
|
m_widget->set_custom_matrices(m);
|
||||||
|
|
||||||
|
stereo_config::set_live_matrices(m);
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "emu_settings.h"
|
||||||
|
#include "Utilities/stereo_config.h"
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QTableWidget>
|
||||||
|
#include <QVector3D>
|
||||||
|
|
||||||
|
class color_wedge_widget : public QWidget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
color_wedge_widget(QWidget* parent = nullptr);
|
||||||
|
virtual ~color_wedge_widget();
|
||||||
|
|
||||||
|
void set_option(stereo_render_mode_options option);
|
||||||
|
void set_custom_matrices(const stereo_config::stereo_matrices& matrices);
|
||||||
|
|
||||||
|
const stereo_config& get_stereo_config() const { return m_stereo_config; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QVector3D apply_matrix(const QVector3D& left, const QVector3D& right, const stereo_config::stereo_matrices& m);
|
||||||
|
|
||||||
|
QVector3D apply_anaglyph_matrix(const QVector3D& left, const QVector3D& right);
|
||||||
|
|
||||||
|
void paintEvent(QPaintEvent* event) override;
|
||||||
|
|
||||||
|
stereo_config m_stereo_config = stereo_config(false);
|
||||||
|
QImage m_img;
|
||||||
|
};
|
||||||
|
|
||||||
|
class anaglyph_settings_dialog : public QDialog
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
anaglyph_settings_dialog(QWidget* parent, std::shared_ptr<emu_settings> emu_settings);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<emu_settings> m_emu_settings;
|
||||||
|
color_wedge_widget* m_widget_reference = nullptr;
|
||||||
|
color_wedge_widget* m_widget = nullptr;
|
||||||
|
QTableWidget* m_matrix_left = nullptr;
|
||||||
|
QTableWidget* m_matrix_right = nullptr;
|
||||||
|
bool m_updating = false;
|
||||||
|
|
||||||
|
QTableWidget* create_matrix_table();
|
||||||
|
|
||||||
|
void read_matrix(mat3f& matrix, QTableWidget* table) const;
|
||||||
|
|
||||||
|
void update_matrix(QTableWidget* table, const mat3f& matrix, bool is_custom);
|
||||||
|
|
||||||
|
void update_matrices();
|
||||||
|
|
||||||
|
void apply_custom_matrix();
|
||||||
|
};
|
||||||
@@ -254,8 +254,10 @@ bool emu_settings::ValidateSettings(bool cleanup)
|
|||||||
|
|
||||||
if (cfg_node)
|
if (cfg_node)
|
||||||
{
|
{
|
||||||
// Ignore every node in Log subsection
|
// Ignore every node in map subsections
|
||||||
if (level == 0 && cfg_node->get_name() == "Log")
|
if (cfg_node->get_type() == cfg::type::log ||
|
||||||
|
cfg_node->get_type() == cfg::type::map ||
|
||||||
|
cfg_node->get_type() == cfg::type::node_map)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -1503,6 +1505,7 @@ QString emu_settings::GetLocalizedSetting(const QString& original, emu_settings_
|
|||||||
case stereo_render_mode_options::anaglyph_magenta_cyan: return tr("Anaglyph Magenta-Cyan", "3D Display Mode");
|
case stereo_render_mode_options::anaglyph_magenta_cyan: return tr("Anaglyph Magenta-Cyan", "3D Display Mode");
|
||||||
case stereo_render_mode_options::anaglyph_trioscopic: return tr("Anaglyph Green-Magenta (Trioscopic)", "3D Display Mode");
|
case stereo_render_mode_options::anaglyph_trioscopic: return tr("Anaglyph Green-Magenta (Trioscopic)", "3D Display Mode");
|
||||||
case stereo_render_mode_options::anaglyph_amber_blue: return tr("Anaglyph Amber-Blue (ColorCode 3D)", "3D Display Mode");
|
case stereo_render_mode_options::anaglyph_amber_blue: return tr("Anaglyph Amber-Blue (ColorCode 3D)", "3D Display Mode");
|
||||||
|
case stereo_render_mode_options::anaglyph_custom: return tr("Anaglyph Custom", "3D Display Mode");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case emu_settings_type::MidiDevices:
|
case emu_settings_type::MidiDevices:
|
||||||
|
|||||||
@@ -144,6 +144,10 @@ const std::map<emu_settings_type, cfg_location> settings_location =
|
|||||||
{ emu_settings_type::ShaderLoadBgDarkening, get_cfg_location(local_cfg.video.shader_preloading_dialog.darkening_strength) },
|
{ emu_settings_type::ShaderLoadBgDarkening, get_cfg_location(local_cfg.video.shader_preloading_dialog.darkening_strength) },
|
||||||
{ emu_settings_type::ShaderLoadBgBlur, get_cfg_location(local_cfg.video.shader_preloading_dialog.blur_strength) },
|
{ emu_settings_type::ShaderLoadBgBlur, get_cfg_location(local_cfg.video.shader_preloading_dialog.blur_strength) },
|
||||||
|
|
||||||
|
// Anaglyph matrix
|
||||||
|
{ emu_settings_type::CustomAnaglyphMatrixLeft, get_cfg_location(local_cfg.video.custom_anaglyph_matrices.left) },
|
||||||
|
{ emu_settings_type::CustomAnaglyphMatrixRight, get_cfg_location(local_cfg.video.custom_anaglyph_matrices.right) },
|
||||||
|
|
||||||
// Audio
|
// Audio
|
||||||
{ emu_settings_type::AudioRenderer, get_cfg_location(local_cfg.audio.renderer) },
|
{ emu_settings_type::AudioRenderer, get_cfg_location(local_cfg.audio.renderer) },
|
||||||
{ emu_settings_type::DumpToFile, get_cfg_location(local_cfg.audio.dump_to_file) },
|
{ emu_settings_type::DumpToFile, get_cfg_location(local_cfg.audio.dump_to_file) },
|
||||||
|
|||||||
@@ -112,6 +112,10 @@ enum class emu_settings_type
|
|||||||
RecordWithOverlays,
|
RecordWithOverlays,
|
||||||
DisableHWTexelRemapping,
|
DisableHWTexelRemapping,
|
||||||
|
|
||||||
|
// Anaglyph Matrix
|
||||||
|
CustomAnaglyphMatrixLeft,
|
||||||
|
CustomAnaglyphMatrixRight,
|
||||||
|
|
||||||
// Performance Overlay
|
// Performance Overlay
|
||||||
PerfOverlayEnabled,
|
PerfOverlayEnabled,
|
||||||
PerfOverlayFramerateGraphEnabled,
|
PerfOverlayFramerateGraphEnabled,
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
struct GLContext
|
struct GLContext
|
||||||
{
|
{
|
||||||
QSurface *surface = nullptr;
|
QSurface* surface = nullptr;
|
||||||
QOpenGLContext *handle = nullptr;
|
QOpenGLContext* handle = nullptr;
|
||||||
bool owner = false;
|
bool owner = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@ class gl_gs_frame : public gs_frame
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
QSurfaceFormat m_format;
|
QSurfaceFormat m_format;
|
||||||
GLContext *m_primary_context = nullptr;
|
GLContext* m_primary_context = nullptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit gl_gs_frame(QScreen* screen, const QRect& geometry, const QIcon& appIcon, std::shared_ptr<gui_settings> gui_settings, bool force_fullscreen);
|
explicit gl_gs_frame(QScreen* screen, const QRect& geometry, const QIcon& appIcon, std::shared_ptr<gui_settings> gui_settings, bool force_fullscreen);
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
#include "render_creator.h"
|
#include "render_creator.h"
|
||||||
#include "microphone_creator.h"
|
#include "microphone_creator.h"
|
||||||
#include "log_level_dialog.h"
|
#include "log_level_dialog.h"
|
||||||
|
#include "anaglyph_settings_dialog.h"
|
||||||
|
|
||||||
#include "Emu/NP/rpcn_countries.h"
|
#include "Emu/NP/rpcn_countries.h"
|
||||||
#include "Emu/GameInfo.h"
|
#include "Emu/GameInfo.h"
|
||||||
@@ -45,7 +46,7 @@
|
|||||||
|
|
||||||
LOG_CHANNEL(cfg_log, "CFG");
|
LOG_CHANNEL(cfg_log, "CFG");
|
||||||
|
|
||||||
std::pair<QString, int> get_data(const QComboBox* box, int index)
|
static std::pair<QString, int> get_data(const QComboBox* box, int index)
|
||||||
{
|
{
|
||||||
if (!box) return {};
|
if (!box) return {};
|
||||||
|
|
||||||
@@ -57,7 +58,7 @@ std::pair<QString, int> get_data(const QComboBox* box, int index)
|
|||||||
return { var_list[0].toString(), var_list[1].toInt() };
|
return { var_list[0].toString(), var_list[1].toInt() };
|
||||||
}
|
}
|
||||||
|
|
||||||
int find_item(const QComboBox* box, int value)
|
static int find_item(const QComboBox* box, int value)
|
||||||
{
|
{
|
||||||
for (int i = 0; box && i < box->count(); i++)
|
for (int i = 0; box && i < box->count(); i++)
|
||||||
{
|
{
|
||||||
@@ -70,7 +71,7 @@ int find_item(const QComboBox* box, int value)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove_item(QComboBox* box, int data_value, int def_value)
|
static void remove_item(QComboBox* box, int data_value, int def_value)
|
||||||
{
|
{
|
||||||
if (!box) return;
|
if (!box) return;
|
||||||
|
|
||||||
@@ -593,9 +594,15 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> gui_settings, std
|
|||||||
ui->stereoRenderMode->setEnabled(stereo_allowed && stereo_enabled);
|
ui->stereoRenderMode->setEnabled(stereo_allowed && stereo_enabled);
|
||||||
ui->stereoRenderEnabled->setEnabled(stereo_allowed);
|
ui->stereoRenderEnabled->setEnabled(stereo_allowed);
|
||||||
ui->gb_screen_size->setEnabled(stereo_allowed && stereo_enabled);
|
ui->gb_screen_size->setEnabled(stereo_allowed && stereo_enabled);
|
||||||
|
ui->gb_anaglyph_settings->setEnabled(stereo_allowed && stereo_enabled);
|
||||||
};
|
};
|
||||||
connect(ui->resBox, &QComboBox::currentIndexChanged, this, [enable_3D_modes](int){ enable_3D_modes(); });
|
connect(ui->resBox, &QComboBox::currentIndexChanged, this, [enable_3D_modes](int){ enable_3D_modes(); });
|
||||||
connect(ui->stereoRenderEnabled, &QCheckBox::checkStateChanged, this, [enable_3D_modes](Qt::CheckState){ enable_3D_modes(); });
|
connect(ui->stereoRenderEnabled, &QCheckBox::checkStateChanged, this, [enable_3D_modes](Qt::CheckState){ enable_3D_modes(); });
|
||||||
|
connect(ui->pb_anaglyph_settings, &QAbstractButton::clicked, [this]()
|
||||||
|
{
|
||||||
|
anaglyph_settings_dialog* dlg = new anaglyph_settings_dialog(this, m_emu_settings);
|
||||||
|
dlg->open();
|
||||||
|
});
|
||||||
enable_3D_modes();
|
enable_3D_modes();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -603,6 +610,7 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> gui_settings, std
|
|||||||
ui->stereoRenderMode->setCurrentIndex(find_item(ui->stereoRenderMode, static_cast<int>(g_cfg.video.stereo_render_mode.def)));
|
ui->stereoRenderMode->setCurrentIndex(find_item(ui->stereoRenderMode, static_cast<int>(g_cfg.video.stereo_render_mode.def)));
|
||||||
ui->stereoRenderEnabled->setChecked(false);
|
ui->stereoRenderEnabled->setChecked(false);
|
||||||
ui->gb_stereo->setEnabled(false);
|
ui->gb_stereo->setEnabled(false);
|
||||||
|
ui->gb_anaglyph_settings->setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checkboxes: main options
|
// Checkboxes: main options
|
||||||
|
|||||||
@@ -557,6 +557,22 @@
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QComboBox" name="stereoRenderMode"/>
|
<widget class="QComboBox" name="stereoRenderMode"/>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="gb_anaglyph_settings">
|
||||||
|
<property name="title">
|
||||||
|
<string>Anaglyph Settings</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="layout_gb_anaglyph_settings">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pb_anaglyph_settings">
|
||||||
|
<property name="text">
|
||||||
|
<string>Configure</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="gb_screen_size">
|
<widget class="QGroupBox" name="gb_screen_size">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
|
|||||||
Reference in New Issue
Block a user