Skip to content

Commit

Permalink
Merge pull request #12449 from hrydgard/reintroduce-cardboard
Browse files Browse the repository at this point in the history
Reintroduce Cardboard VR
  • Loading branch information
hrydgard authored Oct 25, 2019
2 parents 3be09e6 + 0d76906 commit 86de0a4
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 16 deletions.
4 changes: 4 additions & 0 deletions Core/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,10 @@ struct ConfigTranslator {
typedef ConfigTranslator<GPUBackend, GPUBackendToString, GPUBackendFromString> GPUBackendTranslator;

static ConfigSetting graphicsSettings[] = {
ConfigSetting("EnableCardboardVR", &g_Config.bEnableCardboardVR, false, true, true),
ConfigSetting("CardboardScreenSize", &g_Config.iCardboardScreenSize, 50, true, true),
ConfigSetting("CardboardXShift", &g_Config.iCardboardXShift, 0, true, true),
ConfigSetting("CardboardYShift", &g_Config.iCardboardXShift, 0, true, true),
ConfigSetting("ShowFPSCounter", &g_Config.iShowFPSCounter, 0, true, true),
ReportedConfigSetting("GraphicsBackend", &g_Config.iGPUBackend, &DefaultGPUBackend, &GPUBackendTranslator::To, &GPUBackendTranslator::From, true, false),
ConfigSetting("FailedGraphicsBackends", &g_Config.sFailedGPUBackends, ""),
Expand Down
5 changes: 5 additions & 0 deletions Core/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,11 @@ struct Config {
bool bAutoFrameSkip;
bool bFrameSkipUnthrottle;

bool bEnableCardboardVR; // Cardboard Master Switch
int iCardboardScreenSize; // Screen Size (in %)
int iCardboardXShift; // X-Shift of Screen (in %)
int iCardboardYShift; // Y-Shift of Screen (in %)

int iWindowX;
int iWindowY;
int iWindowWidth; // Windows and other windowed environments
Expand Down
93 changes: 79 additions & 14 deletions GPU/Common/FramebufferCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -782,6 +782,9 @@ void FramebufferManagerCommon::DrawFramebufferToOutput(const u8 *srcPixels, GEBu
float v0 = 0.0f, v1 = 1.0f;
MakePixelTexture(srcPixels, srcPixelFormat, srcStride, 512, 272, u1, v1);

struct CardboardSettings cardboardSettings;
GetCardboardSettings(&cardboardSettings);

// This might draw directly at the backbuffer (if so, applyPostShader is set) so if there's a post shader, we need to apply it here.
// Should try to unify this path with the regular path somehow, but this simple solution works for most of the post shaders
// (it always runs at output resolution so FXAA may look odd).
Expand All @@ -807,9 +810,18 @@ void FramebufferManagerCommon::DrawFramebufferToOutput(const u8 *srcPixels, GEBu

DrawTextureFlags flags = g_Config.iBufFilter == SCALE_LINEAR ? DRAWTEX_LINEAR : DRAWTEX_NEAREST;
flags = flags | DRAWTEX_TO_BACKBUFFER;
// Fullscreen Image
SetViewport2D(0, 0, pixelWidth_, pixelHeight_);
DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, uvRotation, flags);
if (cardboardSettings.enabled) {
// Left Eye Image
SetViewport2D(cardboardSettings.leftEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight);
DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, ROTATION_LOCKED_HORIZONTAL, flags | DRAWTEX_KEEP_TEX);
// Right Eye Image
SetViewport2D(cardboardSettings.rightEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight);
DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, ROTATION_LOCKED_HORIZONTAL, flags);
} else {
// Fullscreen Image
SetViewport2D(0, 0, pixelWidth_, pixelHeight_);
DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, uvRotation, flags);
}

gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE);
}
Expand Down Expand Up @@ -854,6 +866,9 @@ void FramebufferManagerCommon::CopyDisplayToOutput() {
u32 offsetX = 0;
u32 offsetY = 0;

CardboardSettings cardboardSettings;
GetCardboardSettings(&cardboardSettings);

VirtualFramebuffer *vfb = GetVFBAt(displayFramebufPtr_);
if (!vfb) {
// Let's search for a framebuf within this range. Note that we also look for
Expand Down Expand Up @@ -969,9 +984,19 @@ void FramebufferManagerCommon::CopyDisplayToOutput() {
// flip V.
if (needBackBufferYSwap_)
std::swap(v0, v1);
// Fullscreen Image
SetViewport2D(0, 0, pixelWidth_, pixelHeight_);
DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, uvRotation, flags);
if (cardboardSettings.enabled) {
// Left Eye Image
SetViewport2D(cardboardSettings.leftEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight);
DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, ROTATION_LOCKED_HORIZONTAL, flags | DRAWTEX_KEEP_TEX);

// Right Eye Image
SetViewport2D(cardboardSettings.rightEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight);
DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, ROTATION_LOCKED_HORIZONTAL, flags);
} else {
// Fullscreen Image
SetViewport2D(0, 0, pixelWidth_, pixelHeight_);
DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, uvRotation, flags);
}
} else if (usePostShader_ && extraFBOs_.size() == 1 && !postShaderAtOutputResolution_) {
// An additional pass, post-processing shader to the extra FBO.
shaderManager_->DirtyLastShader(); // dirty lastShader_
Expand All @@ -987,8 +1012,8 @@ void FramebufferManagerCommon::CopyDisplayToOutput() {
DrawTextureFlags flags = g_Config.iBufFilter == SCALE_LINEAR ? DRAWTEX_LINEAR : DRAWTEX_NEAREST;
DrawActiveTexture(0, 0, fbo_w, fbo_h, fbo_w, fbo_h, 0.0f, 0.0f, 1.0f, 1.0f, ROTATION_LOCKED_HORIZONTAL, flags);

draw_->SetScissorRect(0, 0, pixelWidth_, pixelHeight_);
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR });
draw_->SetScissorRect(0, 0, pixelWidth_, pixelHeight_);

// Use the extra FBO, with applied post-processing shader, as a texture.
// fbo_bind_as_texture(extraFBOs_[0], FB_COLOR_BIT, 0);
Expand All @@ -1005,10 +1030,19 @@ void FramebufferManagerCommon::CopyDisplayToOutput() {
Bind2DShader();
flags = (!postShaderIsUpscalingFilter_ && g_Config.iBufFilter == SCALE_LINEAR) ? DRAWTEX_LINEAR : DRAWTEX_NEAREST;
flags = flags | DRAWTEX_TO_BACKBUFFER;
// Fullscreen Image
SetViewport2D(0, 0, pixelWidth_, pixelHeight_);
draw_->SetScissorRect(0, 0, pixelWidth_, pixelHeight_);
DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, uvRotation, flags);
if (g_Config.bEnableCardboardVR) {
// Left Eye Image
SetViewport2D(cardboardSettings.leftEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight);
DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, ROTATION_LOCKED_HORIZONTAL, flags | DRAWTEX_KEEP_TEX);

// Right Eye Image
SetViewport2D(cardboardSettings.rightEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight);
DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, ROTATION_LOCKED_HORIZONTAL, flags);
} else {
// Fullscreen Image
SetViewport2D(0, 0, pixelWidth_, pixelHeight_);
DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, uvRotation, flags);
}
} else {
shaderManager_->DirtyLastShader(); // dirty lastShader_ BEFORE drawing
draw_->BindFramebufferAsRenderTarget(nullptr, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR });
Expand All @@ -1024,9 +1058,19 @@ void FramebufferManagerCommon::CopyDisplayToOutput() {
PostShaderUniforms uniforms{};
CalculatePostShaderUniforms(vfb->bufferWidth, vfb->bufferHeight, vfb->renderWidth, vfb->renderHeight, &uniforms);
BindPostShader(uniforms);
// Fullscreen Image
SetViewport2D(0, 0, pixelWidth_, pixelHeight_);
DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, uvRotation, flags);
if (g_Config.bEnableCardboardVR) {
// Left Eye Image
SetViewport2D(cardboardSettings.leftEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight);
DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, ROTATION_LOCKED_HORIZONTAL, flags | DRAWTEX_KEEP_TEX);

// Right Eye Image
SetViewport2D(cardboardSettings.rightEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight);
DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, ROTATION_LOCKED_HORIZONTAL, flags);
} else {
// Fullscreen Image
SetViewport2D(0, 0, pixelWidth_, pixelHeight_);
DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, uvRotation, flags);
}
}
}
else if (useBufferedRendering_) {
Expand Down Expand Up @@ -1805,6 +1849,27 @@ void FramebufferManagerCommon::CalculatePostShaderUniforms(int bufferWidth, int
uniforms->video = textureCache_->VideoIsPlaying();
}

void FramebufferManagerCommon::GetCardboardSettings(CardboardSettings *cardboardSettings) {
// Calculate Cardboard Settings
float cardboardScreenScale = g_Config.iCardboardScreenSize / 100.0f;
float cardboardScreenWidth = pixelWidth_ / 2.0f * cardboardScreenScale;
float cardboardScreenHeight = pixelHeight_ / 2.0f * cardboardScreenScale;
float cardboardMaxXShift = (pixelWidth_ / 2.0f - cardboardScreenWidth) / 2.0f;
float cardboardUserXShift = g_Config.iCardboardXShift / 100.0f * cardboardMaxXShift;
float cardboardLeftEyeX = cardboardMaxXShift + cardboardUserXShift;
float cardboardRightEyeX = pixelWidth_ / 2.0f + cardboardMaxXShift - cardboardUserXShift;
float cardboardMaxYShift = pixelHeight_ / 2.0f - cardboardScreenHeight / 2.0f;
float cardboardUserYShift = g_Config.iCardboardYShift / 100.0f * cardboardMaxYShift;
float cardboardScreenY = cardboardMaxYShift + cardboardUserYShift;

cardboardSettings->enabled = g_Config.bEnableCardboardVR;
cardboardSettings->leftEyeXPosition = cardboardLeftEyeX;
cardboardSettings->rightEyeXPosition = cardboardRightEyeX;
cardboardSettings->screenYPosition = cardboardScreenY;
cardboardSettings->screenWidth = cardboardScreenWidth;
cardboardSettings->screenHeight = cardboardScreenHeight;
}

Draw::Framebuffer *FramebufferManagerCommon::GetTempFBO(TempFBO reason, u16 w, u16 h, Draw::FBColorDepth depth) {
u64 key = ((u64)reason << 48) | ((u64)depth << 32) | ((u32)w << 16) | h;
auto it = tempFBOs_.find(key);
Expand Down
12 changes: 12 additions & 0 deletions GPU/Common/FramebufferCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,15 @@ namespace Draw {
class Framebuffer;
}

struct CardboardSettings {
bool enabled;
float leftEyeXPosition;
float rightEyeXPosition;
float screenYPosition;
float screenWidth;
float screenHeight;
};

class VulkanFBO;

struct PostShaderUniforms {
Expand Down Expand Up @@ -316,6 +325,9 @@ class FramebufferManagerCommon {
virtual void Bind2DShader() = 0;
virtual void BindPostShader(const PostShaderUniforms &uniforms) = 0;

// Cardboard Settings Calculator
void GetCardboardSettings(CardboardSettings *cardboardSettings);

bool UpdateSize();
void SetNumExtraFBOs(int num);

Expand Down
14 changes: 13 additions & 1 deletion UI/EmuScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -964,6 +964,11 @@ void EmuScreen::CreateViews() {
if (g_Config.bShowDeveloperMenu) {
root_->Add(new Button(dev->T("DevMenu")))->OnClick.Handle(this, &EmuScreen::OnDevTools);
}

cardboardDisableButton_ = root_->Add(new Button(sc->T("Cardboard VR OFF"), new AnchorLayoutParams(bounds.centerX(), NONE, NONE, 30, true)));
cardboardDisableButton_->OnClick.Handle(this, &EmuScreen::OnDisableCardboard);
cardboardDisableButton_->SetVisibility(V_GONE);

saveStatePreview_ = new AsyncImageFileView("", IS_FIXED, nullptr, new AnchorLayoutParams(bounds.centerX(), 100, NONE, NONE, true));
saveStatePreview_->SetFixedSize(160, 90);
saveStatePreview_->SetColor(0x90FFFFFF);
Expand Down Expand Up @@ -1029,6 +1034,11 @@ UI::EventReturn EmuScreen::OnDevTools(UI::EventParams &params) {
return UI::EVENT_DONE;
}

UI::EventReturn EmuScreen::OnDisableCardboard(UI::EventParams &params) {
g_Config.bEnableCardboardVR = false;
return UI::EVENT_DONE;
}

void EmuScreen::update() {
UIScreen::update();

Expand Down Expand Up @@ -1282,6 +1292,7 @@ void EmuScreen::render() {
return;

if (hasVisibleUI()) {
cardboardDisableButton_->SetVisibility(g_Config.bEnableCardboardVR ? UI::V_VISIBLE : UI::V_GONE);
screenManager()->getUIContext()->BeginFrame();
renderUI();
}
Expand Down Expand Up @@ -1310,7 +1321,8 @@ bool EmuScreen::hasVisibleUI() {
return true;
if (!osm.IsEmpty() || g_Config.bShowTouchControls || g_Config.iShowFPSCounter != 0)
return true;

if (g_Config.bEnableCardboardVR)
return true;
// Debug UI.
if (g_Config.bShowDebugStats || g_Config.bShowDeveloperMenu || g_Config.bShowAudioDebug || g_Config.bShowFrameProfiler)
return true;
Expand Down
3 changes: 3 additions & 0 deletions UI/EmuScreen.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class EmuScreen : public UIScreen {
protected:
void CreateViews() override;
UI::EventReturn OnDevTools(UI::EventParams &params);
UI::EventReturn OnDisableCardboard(UI::EventParams &params);

private:
void bootGame(const std::string &filename);
Expand Down Expand Up @@ -102,4 +103,6 @@ class EmuScreen : public UIScreen {
UI::VisibilityTween *loadingViewVisible_ = nullptr;
UI::Spinner *loadingSpinner_ = nullptr;
UI::TextView *loadingTextView_ = nullptr;

UI::Button *cardboardDisableButton_ = nullptr;
};
12 changes: 12 additions & 0 deletions UI/GameSettingsScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,18 @@ void GameSettingsScreen::CreateViews() {
static const char *bufFilters[] = { "Linear", "Nearest", };
graphicsSettings->Add(new PopupMultiChoice(&g_Config.iBufFilter, gr->T("Screen Scaling Filter"), bufFilters, 1, ARRAY_SIZE(bufFilters), gr->GetName(), screenManager()));

#if PPSSPP_PLATFORM(ANDROID) || PPSSPP_PLATFORM(IOS)
graphicsSettings->Add(new ItemHeader(gr->T("Cardboard VR Settings", "Cardboard VR Settings")));
CheckBox *cardboardMode = graphicsSettings->Add(new CheckBox(&g_Config.bEnableCardboardVR, gr->T("Enable Cardboard VR", "Enable Cardboard VR")));
cardboardMode->SetDisabledPtr(&g_Config.bSoftwareRendering);
PopupSliderChoice * cardboardScreenSize = graphicsSettings->Add(new PopupSliderChoice(&g_Config.iCardboardScreenSize, 30, 100, gr->T("Cardboard Screen Size", "Screen Size (in % of the viewport)"), 1, screenManager(), gr->T("% of viewport")));
cardboardScreenSize->SetDisabledPtr(&g_Config.bSoftwareRendering);
PopupSliderChoice *cardboardXShift = graphicsSettings->Add(new PopupSliderChoice(&g_Config.iCardboardXShift, -100, 100, gr->T("Cardboard Screen X Shift", "X Shift (in % of the void)"), 1, screenManager(), gr->T("% of the void")));
cardboardXShift->SetDisabledPtr(&g_Config.bSoftwareRendering);
PopupSliderChoice *cardboardYShift = graphicsSettings->Add(new PopupSliderChoice(&g_Config.iCardboardYShift, -100, 100, gr->T("Cardboard Screen Y Shift", "Y Shift (in % of the void)"), 1, screenManager(), gr->T("% of the void")));
cardboardYShift->SetDisabledPtr(&g_Config.bSoftwareRendering);
#endif

graphicsSettings->Add(new ItemHeader(gr->T("Hack Settings", "Hack Settings (these WILL cause glitches)")));

static const char *bloomHackOptions[] = { "Off", "Safe", "Balanced", "Aggressive" };
Expand Down
1 change: 0 additions & 1 deletion android/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,3 @@ ui_atlas.zim.png
#assets/ui_atlas.zim
#jni/ui_atlas.cpp
#jni/ui_atlas.h
.cxx

0 comments on commit 86de0a4

Please sign in to comment.