OGL: Add Top-and-Bottom stereoscopy mode.

This commit is contained in:
Jules Blok 2014-10-31 16:24:35 +01:00
parent 1261bd02ca
commit f74d1b16ed
5 changed files with 47 additions and 26 deletions

View File

@ -453,9 +453,9 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string &title, con
{
wxGridSizer* const szr_stereo = new wxGridSizer(2, 5, 5);
const wxString stereo_choices[] = { "Off", "Side-by-Side", "Anaglyph" };
const wxString stereo_choices[] = { "Off", "Side-by-Side", "Top-and-Bottom", "Anaglyph" };
szr_stereo->Add(new wxStaticText(page_enh, -1, _("Stereo 3D Mode:")), 1, wxALIGN_CENTER_VERTICAL, 0);
szr_stereo->Add(CreateChoice(page_enh, vconfig.iStereoMode, wxGetTranslation(stereo_3d_desc), 3, stereo_choices));
szr_stereo->Add(CreateChoice(page_enh, vconfig.iStereoMode, wxGetTranslation(stereo_3d_desc), 4, stereo_choices));
wxSlider* const sep_slider = new wxSlider(page_enh, wxID_ANY, vconfig.iStereoSeparation, 30, 90, wxDefaultPosition, wxDefaultSize, wxSL_VALUE_LABEL);
sep_slider->Bind(wxEVT_SLIDER, &VideoConfigDiag::Event_StereoSep, this);

View File

@ -1514,19 +1514,10 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co
sourceRc.right -= fbStride - fbWidth;
if (g_ActiveConfig.iStereoMode == STEREO_SBS)
if (g_ActiveConfig.iStereoMode == STEREO_SBS || g_ActiveConfig.iStereoMode == STEREO_TAB)
{
// Resize target to half its original size
int width = drawRc.GetWidth();
drawRc.left += width / 4;
drawRc.right -= width / 4;
// Create two target rectangle offset to the sides of the backbuffer
TargetRectangle leftRc = drawRc, rightRc = drawRc;
leftRc.left -= s_backbuffer_width / 4;
leftRc.right -= s_backbuffer_width / 4;
rightRc.left += s_backbuffer_width / 4;
rightRc.right += s_backbuffer_width / 4;
TargetRectangle leftRc, rightRc;
ConvertStereoRectangle(flipped_trc, leftRc, rightRc);
m_post_processor->BlitFromTexture(sourceRc, leftRc, xfbSource->texture, xfbSource->texWidth, xfbSource->texHeight, 0);
m_post_processor->BlitFromTexture(sourceRc, rightRc, xfbSource->texture, xfbSource->texWidth, xfbSource->texHeight, 1);
@ -1544,19 +1535,10 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co
// for msaa mode, we must resolve the efb content to non-msaa
GLuint tex = FramebufferManager::ResolveAndGetRenderTarget(rc);
if (g_ActiveConfig.iStereoMode == STEREO_SBS)
if (g_ActiveConfig.iStereoMode == STEREO_SBS || g_ActiveConfig.iStereoMode == STEREO_TAB)
{
// Resize target to half its original size
int width = flipped_trc.GetWidth();
flipped_trc.left += width / 4;
flipped_trc.right -= width / 4;
// Create two target rectangle offset to the sides of the backbuffer
TargetRectangle leftRc = flipped_trc, rightRc = flipped_trc;
leftRc.left -= s_backbuffer_width / 4;
leftRc.right -= s_backbuffer_width / 4;
rightRc.left += s_backbuffer_width / 4;
rightRc.right += s_backbuffer_width / 4;
TargetRectangle leftRc, rightRc;
ConvertStereoRectangle(flipped_trc, leftRc, rightRc);
m_post_processor->BlitFromTexture(targetRc, leftRc, tex, s_target_width, s_target_height, 0);
m_post_processor->BlitFromTexture(targetRc, rightRc, tex, s_target_width, s_target_height, 1);

View File

@ -240,6 +240,42 @@ bool Renderer::CalculateTargetSize(unsigned int framebuffer_width, unsigned int
return false;
}
void Renderer::ConvertStereoRectangle(const TargetRectangle& rc, TargetRectangle& leftRc, TargetRectangle& rightRc)
{
// Resize target to half its original size
TargetRectangle drawRc = rc;
if (g_ActiveConfig.iStereoMode == STEREO_TAB)
{
// The height may be negative due to flipped rectangles
int height = rc.bottom - rc.top;
drawRc.top += height / 4;
drawRc.bottom -= height / 4;
}
else
{
int width = rc.right - rc.left;
drawRc.left += width / 4;
drawRc.right -= width / 4;
}
// Create two target rectangle offset to the sides of the backbuffer
leftRc = drawRc, rightRc = drawRc;
if (g_ActiveConfig.iStereoMode == STEREO_TAB)
{
leftRc.top -= s_backbuffer_height / 4;
leftRc.bottom -= s_backbuffer_height / 4;
rightRc.top += s_backbuffer_height / 4;
rightRc.bottom += s_backbuffer_height / 4;
}
else
{
leftRc.left -= s_backbuffer_width / 4;
leftRc.right -= s_backbuffer_width / 4;
rightRc.left += s_backbuffer_width / 4;
rightRc.right += s_backbuffer_width / 4;
}
}
void Renderer::SetScreenshot(const std::string& filename)
{
std::lock_guard<std::mutex> lk(s_criticalScreenshot);

View File

@ -83,6 +83,8 @@ public:
static const TargetRectangle& GetTargetRectangle() { return target_rc; }
static void UpdateDrawRectangle(int backbuffer_width, int backbuffer_height);
// Use this to convert a single target rectangle to two stereo rectangles
static void ConvertStereoRectangle(const TargetRectangle& rc, TargetRectangle& leftRc, TargetRectangle& rightRc);
// Use this to upscale native EFB coordinates to IDEAL internal resolution
static int EFBToScaledX(int x);

View File

@ -48,6 +48,7 @@ enum StereoMode
{
STEREO_OFF = 0,
STEREO_SBS,
STEREO_TAB,
STEREO_ANAGLYPH
};