diff options
Diffstat (limited to 'Samples/OculusWorldDemo')
25 files changed, 4203 insertions, 1838 deletions
diff --git a/Samples/OculusWorldDemo/Assets/Tuscany/Tuscany_OculusCube.tga b/Samples/OculusWorldDemo/Assets/Tuscany/Tuscany_OculusCube.tga Binary files differnew file mode 100644 index 0000000..be8b5de --- /dev/null +++ b/Samples/OculusWorldDemo/Assets/Tuscany/Tuscany_OculusCube.tga diff --git a/Samples/OculusWorldDemo/Assets/Tuscany/Tuscany_blueCube.tga b/Samples/OculusWorldDemo/Assets/Tuscany/Tuscany_blueCube.tga Binary files differnew file mode 100644 index 0000000..fe4768e --- /dev/null +++ b/Samples/OculusWorldDemo/Assets/Tuscany/Tuscany_blueCube.tga diff --git a/Samples/OculusWorldDemo/Assets/Tuscany/Tuscany_redCube.tga b/Samples/OculusWorldDemo/Assets/Tuscany/Tuscany_redCube.tga Binary files differnew file mode 100644 index 0000000..7b90b82 --- /dev/null +++ b/Samples/OculusWorldDemo/Assets/Tuscany/Tuscany_redCube.tga diff --git a/Samples/OculusWorldDemo/Makefile b/Samples/OculusWorldDemo/Makefile deleted file mode 100644 index 6015560..0000000 --- a/Samples/OculusWorldDemo/Makefile +++ /dev/null @@ -1,135 +0,0 @@ -############################################################################# -# -# Filename : Makefile -# Content : Makefile for building linux OculusWorldDemo -# Created : 2013 -# Authors : Simon Hallam and Peter Giokaris -# Copyright : Copyright 2013 OculusVR, Inc. All Rights Reserved -# Instruction : The g++ compiler and stdndard lib packages need to be -# installed on the system. Navigate in a shell to the -# directory where this Makefile is located and enter: -# -# make builds the release version for the -# current architechture -# make clean delete intermediate release object files -# and the executabe file -# make DEBUG=1 builds the debug version for the current -# architechture -# make clean DEBUG=1 deletes intermediate debug object files -# and the executable file -# -# Output : Relative to the directory this Makefile lives in, executable -# files get built at the following locations depending upon the -# architechture of the system you are running: -# -# ./Release/OculusWorldDemo_i386_Release -# ./Release/OculusWorldDemo_x86_64_Release -# ./Release/OculusWorldDemo_i386_Debug -# ./Release/OculusWorldDemo_x86_64_Debug -# -############################################################################# - -####### Detect system architecture - -SYSARCH = i386 -ifeq ($(shell uname -m),x86_64) -SYSARCH = x86_64 -endif - -####### Compiler, tools and options - -CXX = g++ -LINK = g++ -MAKE = make -DELETEFILE = rm -f -DEFINES = -DQT_WEBKIT -DGL_GLEXT_PROTOTYPES - -####### Detect debug or release - -DEBUG = 0 -ifeq ($(DEBUG), 1) - CXXFLAGS = -pipe -DDEBUG -g $(DEFINES) - LFLAGS = - RELEASETYPE = Debug -else - CXXFLAGS = -pipe -O2 $(DEFINES) - LFLAGS = -O1 - RELEASETYPE = Release -endif - -####### Paths - -LIBOVRPATH = ../../LibOVR -COMMONSRCPATH = ../CommonSrc -3RDPARTYPATH = ../../3rdParty -INCPATH = -I. -I.. -I$(COMMONSRCPATH) -I$(LIBOVRPATH)/Include -I$(LIBOVRPATH)/Src -OBJPATH = ./Obj/Linux/$(RELEASETYPE)/$(SYSARCH) -CXX_BUILD = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $(OBJPATH)/ - -####### Files - -LIBS = -L$(LIBOVRPATH)/Lib/Linux/$(RELEASETYPE)/$(SYSARCH) \ - -lovr \ - -ludev \ - -lpthread \ - -lGL \ - -lX11 \ - -lXinerama - -OBJECTS = $(OBJPATH)/OculusWorldDemo.o \ - $(OBJPATH)/Player.o \ - $(OBJPATH)/Platform.o \ - $(OBJPATH)/Linux_Platform.o \ - $(OBJPATH)/Linux_Gamepad.o \ - $(OBJPATH)/Render_Device.o \ - $(OBJPATH)/Render_GL_Device.o \ - $(OBJPATH)/Render_LoadTextureDDS.o \ - $(OBJPATH)/Render_LoadTextureTGA.o \ - $(OBJPATH)/Render_XmlSceneLoader.o - -TARGET = ./Release/OculusWorldDemo_$(SYSARCH)_$(RELEASETYPE) - -####### Rules - -all: $(TARGET) - -$(TARGET): $(LIBOVRPATH)/Lib/Linux/$(RELEASETYPE)/$(SYSARCH)/libovr.a - $(MAKE) -C $(LIBOVRPATH) DEBUG=$(DEBUG) - -$(TARGET): $(OBJECTS) - $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(LIBS) - -$(OBJPATH)/OculusWorldDemo.o: OculusWorldDemo.cpp - $(CXX_BUILD)OculusWorldDemo.o OculusWorldDemo.cpp - -$(OBJPATH)/Player.o: Player.cpp - $(CXX_BUILD)Player.o Player.cpp - -$(OBJPATH)/Platform.o: ../../Samples/CommonSrc/Platform/Platform.cpp - $(CXX_BUILD)Platform.o ../../Samples/CommonSrc/Platform/Platform.cpp - -$(OBJPATH)/Linux_Platform.o: ../../Samples/CommonSrc/Platform/Linux_Platform.cpp - $(CXX_BUILD)Linux_Platform.o ../../Samples/CommonSrc/Platform/Linux_Platform.cpp - -$(OBJPATH)/Linux_Gamepad.o: ../../Samples/CommonSrc/Platform/Linux_Gamepad.cpp - $(CXX_BUILD)Linux_Gamepad.o ../../Samples/CommonSrc/Platform/Linux_Gamepad.cpp - -$(OBJPATH)/Render_Device.o: ../../Samples/CommonSrc/Render/Render_Device.cpp $ - $(CXX_BUILD)Render_Device.o ../../Samples/CommonSrc/Render/Render_Device.cpp - -$(OBJPATH)/Render_GL_Device.o: ../../Samples/CommonSrc/Render/Render_GL_Device.cpp - $(CXX_BUILD)Render_GL_Device.o ../../Samples/CommonSrc/Render/Render_GL_Device.cpp - -$(OBJPATH)/Render_LoadTextureDDS.o: ../../Samples/CommonSrc/Render/Render_LoadTextureDDS.cpp - $(CXX_BUILD)Render_LoadTextureDDS.o ../../Samples/CommonSrc/Render/Render_LoadTextureDDS.cpp - -$(OBJPATH)/Render_LoadTextureTGA.o: ../../Samples/CommonSrc/Render/Render_LoadTextureTGA.cpp - $(CXX_BUILD)Render_LoadTextureTGA.o ../../Samples/CommonSrc/Render/Render_LoadTextureTGA.cpp - -$(OBJPATH)/Render_XmlSceneLoader.o: ../../Samples/CommonSrc/Render/Render_XmlSceneLoader.cpp - $(CXX_BUILD)Render_XmlSceneLoader.o ../../Samples/CommonSrc/Render/Render_XmlSceneLoader.cpp - -clean: - -$(DELETEFILE) $(OBJECTS) - -$(DELETEFILE) $(TARGET) - diff --git a/Samples/OculusWorldDemo/Obj/Linux/Debug/i386/readme b/Samples/OculusWorldDemo/Obj/Linux/Debug/i386/readme deleted file mode 100644 index c9d0bc0..0000000 --- a/Samples/OculusWorldDemo/Obj/Linux/Debug/i386/readme +++ /dev/null @@ -1,2 +0,0 @@ -This document exits to ensure that the required directory structure gets created correctly. - diff --git a/Samples/OculusWorldDemo/Obj/Linux/Debug/x86_64/readme b/Samples/OculusWorldDemo/Obj/Linux/Debug/x86_64/readme deleted file mode 100644 index c9d0bc0..0000000 --- a/Samples/OculusWorldDemo/Obj/Linux/Debug/x86_64/readme +++ /dev/null @@ -1,2 +0,0 @@ -This document exits to ensure that the required directory structure gets created correctly. - diff --git a/Samples/OculusWorldDemo/Obj/Linux/Release/i386/readme b/Samples/OculusWorldDemo/Obj/Linux/Release/i386/readme deleted file mode 100644 index c9d0bc0..0000000 --- a/Samples/OculusWorldDemo/Obj/Linux/Release/i386/readme +++ /dev/null @@ -1,2 +0,0 @@ -This document exits to ensure that the required directory structure gets created correctly. - diff --git a/Samples/OculusWorldDemo/Obj/Linux/Release/x86_64/readme b/Samples/OculusWorldDemo/Obj/Linux/Release/x86_64/readme deleted file mode 100644 index c9d0bc0..0000000 --- a/Samples/OculusWorldDemo/Obj/Linux/Release/x86_64/readme +++ /dev/null @@ -1,2 +0,0 @@ -This document exits to ensure that the required directory structure gets created correctly. - diff --git a/Samples/OculusWorldDemo/OculusWorldDemo.cpp b/Samples/OculusWorldDemo/OculusWorldDemo.cpp index 1a81c8d..e89403f 100644 --- a/Samples/OculusWorldDemo/OculusWorldDemo.cpp +++ b/Samples/OculusWorldDemo/OculusWorldDemo.cpp @@ -1,10 +1,10 @@ /************************************************************************************ Filename : OculusWorldDemo.cpp -Content : First-person view test application for Oculus Rift +Content : First-person view test application for Oculus Rift - Implementation Created : October 4, 2012 -Authors : Michael Antonov, Andrew Reisse, Steve LaValle - Peter Hoff, Dan Goodman, Bryan Croteau +Authors : Michael Antonov, Andrew Reisse, Steve LaValle, Dov Katz + Peter Hoff, Dan Goodman, Bryan Croteau Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. @@ -22,286 +22,82 @@ limitations under the License. *************************************************************************************/ -#include "OVR.h" +#include "OculusWorldDemo.h" -#include "../CommonSrc/Platform/Platform_Default.h" -#include "../CommonSrc/Render/Render_Device.h" -#include "../CommonSrc/Render/Render_XmlSceneLoader.h" -#include "../CommonSrc/Render/Render_FontEmbed_DejaVu48.h" -#include "../CommonSrc/Platform/Gamepad.h" - -#include <Kernel/OVR_SysFile.h> -#include <Kernel/OVR_Log.h> -#include <Kernel/OVR_Timer.h> - -#include "Player.h" - -// Filename to be loaded by default, searching specified paths. -#define WORLDDEMO_ASSET_FILE "Tuscany.xml" -#define WORLDDEMO_ASSET_PATH1 "Assets/Tuscany/" -#define WORLDDEMO_ASSET_PATH2 "../Assets/Tuscany/" -// This path allows the shortcut to work. -#define WORLDDEMO_ASSET_PATH3 "Samples/OculusWorldDemo/Assets/Tuscany/" - - -using namespace OVR; -using namespace OVR::Platform; -using namespace OVR::Render; - -//------------------------------------------------------------------------------------- -// ***** OculusWorldDemo Description - -// This app renders a simple flat-shaded room allowing the user to move along the -// floor and look around with an HMD, mouse and keyboard. The following keys work: -// -// 'W', 'S', 'A', 'D' and Arrow Keys - Move forward, back; strafe left/right. -// F1 - No stereo, no distortion. -// F2 - Stereo, no distortion. -// F3 - Stereo and distortion. -// F4 - Toggle MSAA. -// F9 - Cycle through fullscreen and windowed modes. Necessary for previewing content with Rift. -// -// Important Oculus-specific logic can be found at following locations: -// -// OculusWorldDemoApp::OnStartup - This function will initialize OVR::DeviceManager and HMD, -// creating SensorDevice and attaching it to SensorFusion. -// This needs to be done before obtaining sensor data. -// -// OculusWorldDemoApp::OnIdle - Here we poll SensorFusion for orientation, apply it -// to the scene and handle movement. -// Stereo rendering is also done here, by delegating to -// to Render function for each eye. -// - -//------------------------------------------------------------------------------------- -// ***** OculusWorldDemo Application class - -// An instance of this class is created on application startup (main/WinMain). -// It then works as follows: -// - Graphics and HMD setup is done OculusWorldDemoApp::OnStartup(). This function -// also creates the room model from Slab declarations. -// - Per-frame processing is done in OnIdle(). This function processes -// sensor and movement input and then renders the frame. -// - Additional input processing is done in OnMouse, OnKey. - -class OculusWorldDemoApp : public Application, public MessageHandler -{ -public: - OculusWorldDemoApp(); - ~OculusWorldDemoApp(); - - virtual int OnStartup(int argc, const char** argv); - virtual void OnIdle(); - - virtual void OnMouseMove(int x, int y, int modifiers); - virtual void OnKey(OVR::KeyCode key, int chr, bool down, int modifiers); - virtual void OnResize(int width, int height); - - virtual void OnMessage(const Message& msg); - - void Render(const StereoEyeParams& stereo); - - // Sets temporarily displayed message for adjustments - void SetAdjustMessage(const char* format, ...); - // Overrides current timeout, in seconds (not the future default value); - // intended to be called right after SetAdjustMessage. - void SetAdjustMessageTimeout(float timeout); - - // Stereo setting adjustment functions. - // Called with deltaTime when relevant key is held. - void AdjustFov(float dt); - void AdjustAspect(float dt); - void AdjustIPD(float dt); - void AdjustEyeHeight(float dt); - - void AdjustMotionPrediction(float dt); - - void AdjustDistortion(float dt, int kIndex, const char* label); - void AdjustDistortionK0(float dt) { AdjustDistortion(dt, 0, "K0"); } - void AdjustDistortionK1(float dt) { AdjustDistortion(dt, 1, "K1"); } - void AdjustDistortionK2(float dt) { AdjustDistortion(dt, 2, "K2"); } - void AdjustDistortionK3(float dt) { AdjustDistortion(dt, 3, "K3"); } - - void AdjustDistortion(float val, int kIndex); - void AdjustEsd(float val); - - // Adds room model to scene. - void PopulateScene(const char* fileName); - void PopulatePreloadScene(); - void ClearScene(); - - // Magnetometer calibration procedure - void UpdateManualMagCalibration(); - -protected: - RenderDevice* pRender; - RendererParams RenderParams; - int Width, Height; - int Screen; - int FirstScreenInCycle; - - // *** Oculus HMD Variables - Ptr<DeviceManager> pManager; - Ptr<SensorDevice> pSensor; - Ptr<HMDDevice> pHMD; - Ptr<Profile> pUserProfile; - SensorFusion SFusion; - HMDInfo TheHMDInfo; - - Ptr<LatencyTestDevice> pLatencyTester; - Util::LatencyTest LatencyUtil; - - double LastUpdate; - int FPS; - int FrameCounter; - double NextFPSUpdate; - - Array<Ptr<CollisionModel> > CollisionModels; - Array<Ptr<CollisionModel> > GroundCollisionModels; - - // Loading process displays screenshot in first frame - // and then proceeds to load until finished. - enum LoadingStateType - { - LoadingState_Frame0, - LoadingState_DoLoad, - LoadingState_Finished - }; - - // Player - Player ThePlayer; - Matrix4f View; - Scene MainScene; - Scene LoadingScene; - Scene GridScene; - Scene YawMarkGreenScene; - Scene YawMarkRedScene; - Scene YawLinesScene; - - LoadingStateType LoadingState; - - Ptr<ShaderFill> LitSolid, LitTextures[4]; - - // Stereo view parameters. - StereoConfig SConfig; - PostProcessType PostProcess; - - // LOD - String MainFilePath; - Array<String> LODFilePaths; - int ConsecutiveLowFPSFrames; - int CurrentLODFileIndex; - - float DistortionK0; - float DistortionK1; - float DistortionK2; - float DistortionK3; - - String AdjustMessage; - double AdjustMessageTimeout; - - // Saved distortion state. - float SavedK0, SavedK1, SavedK2, SavedK3; - float SavedESD, SavedAspect, SavedEyeDistance; - - // Allows toggling color around distortion. - Color DistortionClearColor; - - // Stereo settings adjustment state. - typedef void (OculusWorldDemoApp::*AdjustFuncType)(float); - bool ShiftDown; - AdjustFuncType pAdjustFunc; - float AdjustDirection; - - enum SceneRenderMode - { - Scene_World, - Scene_Grid, - Scene_Both, - Scene_YawView - }; - SceneRenderMode SceneMode; - - - enum TextScreen - { - Text_None, - Text_Orientation, - Text_Config, - Text_Help, - Text_Count - }; - TextScreen TextScreen; - - struct DeviceStatusNotificationDesc - { - DeviceHandle Handle; - MessageType Action; - - DeviceStatusNotificationDesc():Action(Message_None) {} - DeviceStatusNotificationDesc(MessageType mt, const DeviceHandle& dev) - : Handle(dev), Action(mt) {} - }; - Array<DeviceStatusNotificationDesc> DeviceStatusNotificationsQueue; - - - Model* CreateModel(Vector3f pos, struct SlabModel* sm); - Model* CreateBoundingModel(CollisionModel &cm); - void PopulateLODFileNames(); - void DropLOD(); - void RaiseLOD(); - void CycleDisplay(); - void GamepadStateChanged(const GamepadState& pad); -}; //------------------------------------------------------------------------------------- +// ***** OculusWorldDemoApp OculusWorldDemoApp::OculusWorldDemoApp() : pRender(0), - LastUpdate(0), + WindowSize(1280,800), + ScreenNumber(0), + FirstScreenInCycle(0), + Hmd(0), + StartSensorCaps(0), + UsingDebugHmd(false), LoadingState(LoadingState_Frame0), + HaveVisionTracking(false), + HmdStatus(0), + // Initial location - SConfig(), - PostProcess(PostProcess_Distortion), - DistortionClearColor(0, 0, 0), - + DistortionClearBlue(0), ShiftDown(false), - pAdjustFunc(0), - AdjustDirection(1.0f), + CtrlDown(false), + HmdSettingsChanged(false), + + // Modifiable options. + RendertargetIsSharedByBothEyes(false), + DynamicRezScalingEnabled(false), + ForceZeroIpd(false), + DesiredPixelDensity(1.0f), + FovSideTanMax(1.0f), // Updated based on Hmd. + TimewarpEnabled(true), + TimewarpRenderIntervalInSeconds(0.0f), + FreezeEyeUpdate(false), + FreezeEyeOneFrameRendered(false), + CenterPupilDepthMeters(0.05f), + ForceZeroHeadMovement(false), + VsyncEnabled(true), + MultisampleEnabled(true), + IsLowPersistence(true), + DynamicPrediction(true), + PositionTrackingEnabled(true), + + // Scene state SceneMode(Scene_World), - TextScreen(Text_None) + GridDisplayMode(GridDisplay_None), + GridMode(Grid_Lens), + TextScreen(Text_None), + BlocksShowType(0), + BlocksCenter(0.0f, 0.0f, 0.0f) { - Width = 1280; - Height = 800; - Screen = 0; - FirstScreenInCycle = 0; - FPS = 0; - FrameCounter = 0; - NextFPSUpdate = 0; + FPS = 0.0f; + SecondsPerFrame = 0.0f; + FrameCounter = 0; + LastFpsUpdate = 0; - ConsecutiveLowFPSFrames = 0; - CurrentLODFileIndex = 0; - - AdjustMessageTimeout = 0; + DistortionClearBlue = false; } OculusWorldDemoApp::~OculusWorldDemoApp() { - RemoveHandlerFromDevices(); + CleanupDrawTextFont(); - if(DejaVu.fill) + if (Hmd) { - DejaVu.fill->Release(); + ovrHmd_Destroy(Hmd); + Hmd = 0; } - pLatencyTester.Clear(); - pSensor.Clear(); - pHMD.Clear(); - + CollisionModels.ClearAndRelease(); GroundCollisionModels.ClearAndRelease(); + + ovr_Shutdown(); } + int OculusWorldDemoApp::OnStartup(int argc, const char** argv) { @@ -311,106 +107,84 @@ int OculusWorldDemoApp::OnStartup(int argc, const char** argv) // Sensor object is created from the HMD, to ensure that it is on the // correct device. - pManager = *DeviceManager::Create(); + ovr_Initialize(); - // We'll handle it's messages in this case. - pManager->SetMessageHandler(this); + Hmd = ovrHmd_Create(0); - - pHMD = *pManager->EnumerateDevices<HMDDevice>().CreateDevice(); - if (pHMD) + if (!Hmd) { - pSensor = *pHMD->GetSensor(); - - // This will initialize HMDInfo with information about configured IPD, - // screen size and other variables needed for correct projection. - // We pass HMD DisplayDeviceName into the renderer to select the - // correct monitor in full-screen mode. - if(pHMD->GetDeviceInfo(&TheHMDInfo)) - { - //RenderParams.MonitorName = hmd.DisplayDeviceName; - SConfig.SetHMDInfo(TheHMDInfo); + // If we didn't detect an Hmd, create a simulated one for debugging. + Hmd = ovrHmd_CreateDebug(ovrHmd_DK1); + UsingDebugHmd = true; + if (!Hmd) + { // Failed Hmd creation. + return 1; } - - // Retrieve relevant profile settings. - pUserProfile = pHMD->GetProfile(); - if (pUserProfile) - { - ThePlayer.UserEyeHeight = pUserProfile->GetEyeHeight(); - ThePlayer.EyePos.y = ThePlayer.UserEyeHeight; - } - } - else - { - // If we didn't detect an HMD, try to create the sensor directly. - // This is useful for debugging sensor interaction; it is not needed in - // a shipping app. - pSensor = *pManager->EnumerateDevices<SensorDevice>().CreateDevice(); - } - - // Create the Latency Tester device and assign it to the LatencyTesterUtil object. - pLatencyTester = *pManager->EnumerateDevices<LatencyTestDevice>().CreateDevice(); - if (pLatencyTester) - { - LatencyUtil.SetDevice(pLatencyTester); - } - // Make the user aware which devices are present. - if(pHMD == NULL && pSensor == NULL) - { - SetAdjustMessage("---------------------------------\nNO HMD DETECTED\nNO SENSOR DETECTED\n---------------------------------"); - } - else if(pHMD == NULL) - { - SetAdjustMessage("----------------------------\nNO HMD DETECTED\n----------------------------"); - } - else if(pSensor == NULL) - { - SetAdjustMessage("---------------------------------\nNO SENSOR DETECTED\n---------------------------------"); - } - else - { - SetAdjustMessage("--------------------------------------------\n" - "Press F9 for Full-Screen on Rift\n" - "--------------------------------------------"); } - // First message should be extra-long. - SetAdjustMessageTimeout(10.0f); + // Get more details about the HMD. + ovrHmd_GetDesc(Hmd, &HmdDesc); + WindowSize = HmdDesc.Resolution; - if(TheHMDInfo.HResolution > 0) - { - Width = TheHMDInfo.HResolution; - Height = TheHMDInfo.VResolution; - } - if(!pPlatform->SetupWindow(Width, Height)) - { + // ***** Setup System Window & rendering. + + if (!SetupWindowAndRendering(argc, argv)) return 1; - } - String Title = "Oculus World Demo"; - if(TheHMDInfo.ProductName[0]) - { - Title += " : "; - Title += TheHMDInfo.ProductName; - } - pPlatform->SetWindowTitle(Title); + // Initialize FovSideTanMax, which allows us to change all Fov sides at once - Fov + // starts at default and is clamped to this value. + FovSideTanLimit = FovPort::Max(HmdDesc.MaxEyeFov[0], HmdDesc.MaxEyeFov[1]).GetMaxSideTan(); + FovSideTanMax = FovPort::Max(HmdDesc.DefaultEyeFov[0], HmdDesc.DefaultEyeFov[1]).GetMaxSideTan(); - // Report relative mouse motion in OnMouseMove - pPlatform->SetMouseMode(Mouse_Relative); + PositionTrackingEnabled = (HmdDesc.Caps & ovrHmdCap_Position) ? true : false; + + + // *** Configure HMD Stereo settings. - if(pSensor) - { - // We need to attach sensor to SensorFusion object for it to receive - // body frame messages and update orientation. SFusion.GetOrientation() - // is used in OnIdle() to orient the view. - SFusion.AttachToSensor(pSensor); + CalculateHmdValues(); - SFusion.SetDelegateMessageHandler(this); + // Query eye height. + ThePlayer.UserEyeHeight = ovrHmd_GetFloat(Hmd, OVR_KEY_EYE_HEIGHT, ThePlayer.UserEyeHeight); + ThePlayer.BodyPos.y = ThePlayer.UserEyeHeight; + // Center pupil for customization; real game shouldn't need to adjust this. + CenterPupilDepthMeters = ovrHmd_GetFloat(Hmd, "CenterPupilDepth", 0.0f); - SFusion.SetPredictionEnabled(true); - } + + ThePlayer.bMotionRelativeToBody = false; // Default to head-steering for DK1 + + if (UsingDebugHmd) + Menu.SetPopupMessage("NO HMD DETECTED"); + else if (!(ovrHmd_GetSensorState(Hmd, 0.0f).StatusFlags & ovrStatus_OrientationTracked)) + Menu.SetPopupMessage("NO SENSOR DETECTED"); + else + Menu.SetPopupMessage("Press F9 for Full-Screen on Rift"); + // Give first message 10 sec timeout, add border lines. + Menu.SetPopupTimeout(10.0f, true); + + PopulateOptionMenu(); + + // *** Identify Scene File & Prepare for Loading + + InitMainFilePath(); + PopulatePreloadScene(); + + LastUpdate = ovr_GetTimeInSeconds(); + + return 0; +} + + +bool OculusWorldDemoApp::SetupWindowAndRendering(int argc, const char** argv) +{ + // *** Window creation + + if (!pPlatform->SetupWindow(WindowSize.w, WindowSize.h)) + return false; + + // Report relative mouse motion in OnMouseMove + pPlatform->SetMouseMode(Mouse_Relative); // *** Initialize Rendering @@ -430,1332 +204,1065 @@ int OculusWorldDemoApp::OnStartup(int argc, const char** argv) } } + String title = "Oculus World Demo "; + title += graphics; + + if (HmdDesc.ProductName[0]) + { + title += " : "; + title += HmdDesc.ProductName; + } + pPlatform->SetWindowTitle(title); + // Enable multi-sampling by default. - RenderParams.Multisample = 4; + RenderParams.Display = DisplayId(HmdDesc.DisplayDeviceName, HmdDesc.DisplayId); + RenderParams.Multisample = 1; + //RenderParams.Fullscreen = true; pRender = pPlatform->SetupGraphics(OVR_DEFAULT_RENDER_DEVICE_SET, graphics, RenderParams); + if (!pRender) + return false; + return true; +} +// Custom formatter for Timewarp interval message. +static String FormatTimewarp(OptionVar* var) +{ + char buff[64]; + float timewarpInterval = *var->AsFloat(); + OVR_sprintf(buff, sizeof(buff), "%.1fms, %.1ffps", + timewarpInterval * 1000.0f, + ( timewarpInterval > 0.000001f ) ? 1.0f / timewarpInterval : 10000.0f); + return String(buff); +} - // *** Configure Stereo settings. +static String FormatMaxFromSideTan(OptionVar* var) +{ + char buff[64]; + float degrees = 2.0f * atan(*var->AsFloat()) * (180.0f / Math<float>::Pi); + OVR_sprintf(buff, sizeof(buff), "%.1f Degrees", degrees); + return String(buff); +} - SConfig.SetFullViewport(Viewport(0, 0, Width, Height)); - SConfig.SetStereoMode(Stereo_LeftRight_Multipass); - // Configure proper Distortion Fit. - // For 7" screen, fit to touch left side of the view, leaving a bit of - // invisible screen on the top (saves on rendering cost). - // For smaller screens (5.5"), fit to the top. - if (TheHMDInfo.HScreenSize > 0.0f) +void OculusWorldDemoApp::PopulateOptionMenu() +{ + // For shortened function member access. + typedef OculusWorldDemoApp OWD; + + // *** Scene Content Sub-Menu + + // Test + /* + Menu.AddEnum("Scene Content.EyePoseMode", &FT_EyePoseState).AddShortcutKey(Key_Y). + AddEnumValue("Separate Pose", 0). + AddEnumValue("Same Pose", 1). + AddEnumValue("Same Pose+TW", 2); + */ + + // Navigate between scenes. + Menu.AddEnum("Scene Content.Rendered Scene ';'", &SceneMode).AddShortcutKey(Key_Semicolon). + AddEnumValue("World", Scene_World). + AddEnumValue("Cubes", Scene_Cubes). + AddEnumValue("Oculus Cubes", Scene_OculusCubes); + // Animating blocks + Menu.AddEnum("Scene Content.Animated Blocks", &BlocksShowType). + AddShortcutKey(Key_B).SetNotify(this, &OWD::BlockShowChange). + AddEnumValue("None", 0). + AddEnumValue("Horizontal Circle", 1). + AddEnumValue("Vertical Circle", 2). + AddEnumValue("Bouncing Blocks", 3); + // Toggle grid + Menu.AddEnum("Scene Content.Grid Display 'G'", &GridDisplayMode).AddShortcutKey(Key_G). + AddEnumValue("No Grid", GridDisplay_None). + AddEnumValue("Grid Only", GridDisplay_GridOnly). + AddEnumValue("Grid And Scene", GridDisplay_GridAndScene); + Menu.AddEnum("Scene Content.Grid Mode 'H'", &GridMode).AddShortcutKey(Key_H). + AddEnumValue("4-pixel RT-centered", Grid_Rendertarget4). + AddEnumValue("16-pixel RT-centered",Grid_Rendertarget16). + AddEnumValue("Lens-centered grid", Grid_Lens); + + // *** Scene Content Sub-Menu + Menu.AddBool( "Render Target.Share RenderTarget", &RendertargetIsSharedByBothEyes). + AddShortcutKey(Key_F8).SetNotify(this, &OWD::HmdSettingChange); + Menu.AddBool( "Render Target.Dynamic Res Scaling", &DynamicRezScalingEnabled). + AddShortcutKey(Key_F8, ShortcutKey::Shift_RequireOn); + Menu.AddBool( "Render Target.Zero IPD 'F7'", &ForceZeroIpd). + AddShortcutKey(Key_F7). + SetNotify(this, &OWD::HmdSettingChangeFreeRTs); + Menu.AddFloat("Render Target.Max Fov", &FovSideTanMax, 0.2f, FovSideTanLimit, 0.02f, + "%.1f Degrees", 1.0f, &FormatMaxFromSideTan). + SetNotify(this, &OWD::HmdSettingChange). + AddShortcutUpKey(Key_I).AddShortcutDownKey(Key_K); + Menu.AddFloat("Render Target.Pixel Density", &DesiredPixelDensity, 0.5f, 1.5, 0.025f, "%3.2f", 1.0f). + SetNotify(this, &OWD::HmdSettingChange); + Menu.AddEnum( "Render Target.Distortion Clear Color", &DistortionClearBlue). + SetNotify(this, &OWD::DistortionClearColorChange). + AddEnumValue("Black", 0). + AddEnumValue("Blue", 1); + + // Timewarp + Menu.AddBool( "Timewarp.TimewarpEnabled 'O'", &TimewarpEnabled).AddShortcutKey(Key_O). + SetNotify(this, &OWD::HmdSettingChange); + Menu.AddBool( "Timewarp.FreezeEyeUpdate 'C'", &FreezeEyeUpdate).AddShortcutKey(Key_C); + Menu.AddFloat("Timewarp.RenderIntervalSeconds", &TimewarpRenderIntervalInSeconds, + 0.0001f, 1.00f, 0.0001f, "%.1f", 1.0f, &FormatTimewarp). + AddShortcutUpKey(Key_J).AddShortcutDownKey(Key_U); + + // First page properties + Menu.AddFloat("User Eye Height", &ThePlayer.UserEyeHeight, 0.2f, 2.5f, 0.02f, + "%4.2f m").SetNotify(this, &OWD::EyeHeightChange). + AddShortcutUpKey(Key_Equal).AddShortcutDownKey(Key_Minus); + Menu.AddFloat("Center Pupil Depth", &CenterPupilDepthMeters, 0.0f, 0.2f, 0.001f, + "%4.3f m").SetNotify(this, &OWD::CenterPupilDepthChange); + Menu.AddBool("Body Relative Motion",&ThePlayer.bMotionRelativeToBody).AddShortcutKey(Key_E); + Menu.AddBool("Zero Head Movement", &ForceZeroHeadMovement) .AddShortcutKey(Key_F7, ShortcutKey::Shift_RequireOn); + Menu.AddBool("VSync 'V'", &VsyncEnabled) .AddShortcutKey(Key_V).SetNotify(this, &OWD::HmdSettingChange); + Menu.AddBool("MultiSample 'F4'", &MultisampleEnabled) .AddShortcutKey(Key_F4).SetNotify(this, &OWD::MultisampleChange); + + // Add DK2 options to menu only for that headset. + if (HmdDesc.Caps & ovrHmdCap_Position) { - if (TheHMDInfo.HScreenSize > 0.140f) // 7" - SConfig.SetDistortionFitPointVP(-1.0f, 0.0f); - else - SConfig.SetDistortionFitPointVP(0.0f, 1.0f); + Menu.AddBool("Low Persistence 'P'", &IsLowPersistence). + AddShortcutKey(Key_P).SetNotify(this, &OWD::HmdSettingChange); + Menu.AddBool("Dynamic Prediction", &DynamicPrediction). + SetNotify(this, &OWD::HmdSettingChange); + Menu.AddBool("Positional Tracking 'X'", &PositionTrackingEnabled). + AddShortcutKey(Key_X).SetNotify(this, &OWD::HmdSettingChange); } +} - pRender->SetSceneRenderScale(SConfig.GetDistortionScale()); - //pRender->SetSceneRenderScale(1.0f); - SConfig.Set2DAreaFov(DegreeToRad(85.0f)); +void OculusWorldDemoApp::CalculateHmdValues() +{ + // Initialize eye rendering information for ovrHmd_Configure. + // The viewport sizes are re-computed in case RenderTargetSize changed due to HW limitations. + ovrEyeDesc eyes[2]; + eyes[0].Eye = ovrEye_Left; + eyes[1].Eye = ovrEye_Right; + eyes[0].Fov = HmdDesc.DefaultEyeFov[0]; + eyes[1].Fov = HmdDesc.DefaultEyeFov[1]; + // Clamp Fov based on our dynamically adjustable FovSideTanMax. + // Most apps should use the default, but reducing Fov does reduce rendering cost. + eyes[0].Fov = FovPort::Min(eyes[0].Fov, FovPort(FovSideTanMax)); + eyes[1].Fov = FovPort::Min(eyes[1].Fov, FovPort(FovSideTanMax)); - // *** Identify Scene File & Prepare for Loading - - // This creates lights and models. - if (argc == 2) - { - MainFilePath = argv[1]; - PopulateLODFileNames(); + + if (ForceZeroIpd) + { + // ForceZeroIpd does three things: + // 1) Sets FOV to maximum symmetrical FOV based on both eyes + // 2) Sets eye ViewAdjust values to 0.0 (effective IPD == 0) + // 3) Uses only the Left texture for rendering. + + eyes[0].Fov = FovPort::Max(eyes[0].Fov, eyes[1].Fov); + eyes[1].Fov = eyes[0].Fov; + + Sizei recommenedTexSize = ovrHmd_GetFovTextureSize(Hmd, ovrEye_Left, + eyes[0].Fov, DesiredPixelDensity); + + eyes[0].TextureSize = EnsureRendertargetAtLeastThisBig(Rendertarget_Left, recommenedTexSize); + eyes[1].TextureSize = eyes[0].TextureSize; + eyes[0].RenderViewport.Pos = Vector2i(0,0); + eyes[0].RenderViewport.Size = Sizei::Min(eyes[0].TextureSize, recommenedTexSize); + eyes[1].RenderViewport = eyes[0].RenderViewport; + + // Store texture pointers that will be passed for rendering. + EyeTexture[0] = RenderTargets[Rendertarget_Left].Tex; + EyeTexture[1] = RenderTargets[Rendertarget_Left].Tex; } + else { - fprintf(stderr, "Usage: OculusWorldDemo [input XML]\n"); - MainFilePath = WORLDDEMO_ASSET_FILE; + // Configure Stereo settings. Default pixel density is 1.0f. + Sizei recommenedTex0Size = ovrHmd_GetFovTextureSize(Hmd, ovrEye_Left, eyes[0].Fov, DesiredPixelDensity); + Sizei recommenedTex1Size = ovrHmd_GetFovTextureSize(Hmd, ovrEye_Right, eyes[1].Fov, DesiredPixelDensity); + + if (RendertargetIsSharedByBothEyes) + { + Sizei rtSize(recommenedTex0Size.w + recommenedTex1Size.w, + Alg::Max(recommenedTex0Size.h, recommenedTex1Size.h)); + + // Use returned size as the actual RT size may be different due to HW limits. + rtSize = EnsureRendertargetAtLeastThisBig(Rendertarget_BothEyes, rtSize); + + // Don't draw more then recommended size; this also ensures that resolution reported + // in the overlay HUD size is updated correctly for FOV/pixel density change. + Sizei leftSize = Sizei::Min(Sizei(rtSize.w/2, rtSize.h), recommenedTex0Size); + Sizei rightSize = Sizei::Min(Sizei(rtSize.w/2, rtSize.h), recommenedTex1Size); + + eyes[0].TextureSize = rtSize; + eyes[1].TextureSize = rtSize; + eyes[0].RenderViewport = Recti(Vector2i(0), leftSize); + eyes[1].RenderViewport = Recti(Vector2i((rtSize.w+1)/2, 0), rightSize); + + // Store texture pointers that will be passed for rendering. + // Same texture is used, but with different viewports. + EyeTexture[0] = RenderTargets[Rendertarget_BothEyes].Tex; + EyeTexture[1] = RenderTargets[Rendertarget_BothEyes].Tex; + EyeTexture[0].Header.RenderViewport = eyes[0].RenderViewport; + EyeTexture[1].Header.RenderViewport = eyes[1].RenderViewport; + } + + else + { + eyes[0].TextureSize = EnsureRendertargetAtLeastThisBig(Rendertarget_Left, recommenedTex0Size); + eyes[1].TextureSize = EnsureRendertargetAtLeastThisBig(Rendertarget_Right, recommenedTex1Size); + eyes[0].RenderViewport = Recti(Sizei::Min(eyes[0].TextureSize, recommenedTex0Size)); + eyes[1].RenderViewport = Recti(Sizei::Min(eyes[1].TextureSize, recommenedTex1Size)); + + // Store texture pointers that will be passed for rendering. + EyeTexture[0] = RenderTargets[Rendertarget_Left].Tex; + EyeTexture[1] = RenderTargets[Rendertarget_Right].Tex; + } } - // Try to modify path for correctness in case specified file is not found. - if (!SysFile(MainFilePath).IsValid()) + + unsigned hmdCaps = ovrHmdCap_Orientation | (VsyncEnabled ? 0 : ovrHmdCap_NoVSync); + unsigned distortionCaps = ovrDistortion_Chromatic; + + ovrRenderAPIConfig config = pRender->Get_ovrRenderAPIConfig(); + + if (TimewarpEnabled) + distortionCaps |= ovrDistortion_TimeWarp; + + if (!ovrHmd_ConfigureRendering( Hmd, &config, hmdCaps, distortionCaps, + eyes, EyeRenderDesc )) { - String prefixPath1(pPlatform->GetContentDirectory() + "/" + WORLDDEMO_ASSET_PATH1), - prefixPath2(WORLDDEMO_ASSET_PATH2), - prefixPath3(WORLDDEMO_ASSET_PATH3); - if (SysFile(prefixPath1 + MainFilePath).IsValid()) - MainFilePath = prefixPath1 + MainFilePath; - else if (SysFile(prefixPath2 + MainFilePath).IsValid()) - MainFilePath = prefixPath2 + MainFilePath; - else if (SysFile(prefixPath3 + MainFilePath).IsValid()) - MainFilePath = prefixPath3 + MainFilePath; + // Fail exit? TBD + return; } - PopulatePreloadScene(); + if (ForceZeroIpd) + { + // Remove IPD adjust + EyeRenderDesc[0].ViewAdjust = Vector3f(0); + EyeRenderDesc[1].ViewAdjust = Vector3f(0); + } - LastUpdate = pPlatform->GetAppTime(); - //pPlatform->PlayMusicFile(L"Loop.wav"); + // ovrHmdCap_LatencyTest - enables internal latency feedback + unsigned sensorCaps = ovrHmdCap_Orientation|ovrHmdCap_YawCorrection|ovrHmdCap_LatencyTest; + if (PositionTrackingEnabled) + sensorCaps |= ovrHmdCap_Position; + if (IsLowPersistence) + sensorCaps |= ovrHmdCap_LowPersistence; + if (DynamicPrediction) + sensorCaps |= ovrHmdCap_DynamicPrediction; - return 0; + if (StartSensorCaps != sensorCaps) + { + ovrHmd_StartSensor(Hmd, sensorCaps, 0); + StartSensorCaps = sensorCaps; + } + + // Calculate projections + Projection[0] = ovrMatrix4f_Projection(EyeRenderDesc[0].Desc.Fov, 0.01f, 10000.0f, true); + Projection[1] = ovrMatrix4f_Projection(EyeRenderDesc[1].Desc.Fov, 0.01f, 10000.0f, true); + + float orthoDistance = 0.8f; // 2D is 0.8 meter from camera + Vector2f orthoScale0 = Vector2f(1.0f) / Vector2f(EyeRenderDesc[0].PixelsPerTanAngleAtCenter); + Vector2f orthoScale1 = Vector2f(1.0f) / Vector2f(EyeRenderDesc[1].PixelsPerTanAngleAtCenter); + + OrthoProjection[0] = ovrMatrix4f_OrthoSubProjection(Projection[0], orthoScale0, orthoDistance, + EyeRenderDesc[0].ViewAdjust.x); + OrthoProjection[1] = ovrMatrix4f_OrthoSubProjection(Projection[1], orthoScale1, orthoDistance, + EyeRenderDesc[1].ViewAdjust.x); } -void OculusWorldDemoApp::OnMessage(const Message& msg) + + +// Returns the actual size present. +Sizei OculusWorldDemoApp::EnsureRendertargetAtLeastThisBig(int rtNum, Sizei requestedSize) { - if (msg.Type == Message_DeviceAdded || msg.Type == Message_DeviceRemoved) + OVR_ASSERT((rtNum >= 0) && (rtNum < Rendertarget_LAST)); + + // Texture size that we already have might be big enough. + Sizei newRTSize; + + RenderTarget& rt = RenderTargets[rtNum]; + if (!rt.pTex) { - if (msg.pDevice == pManager) - { - const MessageDeviceStatus& statusMsg = - static_cast<const MessageDeviceStatus&>(msg); + // Hmmm... someone nuked my texture. Rez change or similar. Make sure we reallocate. + rt.Tex.Header.TextureSize = Sizei(0); + newRTSize = requestedSize; + } + else + { + newRTSize = rt.Tex.Header.TextureSize; + } - { // limit the scope of the lock - Lock::Locker lock(pManager->GetHandlerLock()); - DeviceStatusNotificationsQueue.PushBack( - DeviceStatusNotificationDesc(statusMsg.Type, statusMsg.Handle)); - } + // %50 linear growth each time is a nice balance between being too greedy + // for a 2D surface and too slow to prevent fragmentation. + while ( newRTSize.w < requestedSize.w ) + { + newRTSize.w += newRTSize.w/2; + } + while ( newRTSize.h < requestedSize.h ) + { + newRTSize.h += newRTSize.h/2; + } - switch (statusMsg.Type) - { - case OVR::Message_DeviceAdded: - LogText("DeviceManager reported device added.\n"); - break; - - case OVR::Message_DeviceRemoved: - LogText("DeviceManager reported device removed.\n"); - break; - - default: OVR_ASSERT(0); // unexpected type - } - } + // Put some sane limits on it. 4k x 4k is fine for most modern video cards. + // Nobody should be messing around with surfaces smaller than 4k pixels these days. + newRTSize = Sizei::Max(Sizei::Min(newRTSize, Sizei(4096)), Sizei(64)); + + // Does that require actual reallocation? + if (Sizei(rt.Tex.Header.TextureSize) != newRTSize) + { + rt.pTex = *pRender->CreateTexture(Texture_RGBA | Texture_RenderTarget | (MultisampleEnabled ? 4 : 1), + newRTSize.w, newRTSize.h, NULL); + rt.pTex->SetSampleMode(Sample_ClampBorder | Sample_Linear); + + + // Configure texture for SDK Rendering. + rt.Tex = rt.pTex->Get_ovrTexture(); } + + return newRTSize; } + +//----------------------------------------------------------------------------- +// ***** Message Handlers + void OculusWorldDemoApp::OnResize(int width, int height) { - Width = width; - Height = height; - SConfig.SetFullViewport(Viewport(0, 0, Width, Height)); + WindowSize = Sizei(width, height); + // Re-calculate? } void OculusWorldDemoApp::OnMouseMove(int x, int y, int modifiers) { + OVR_UNUSED(y); if(modifiers & Mod_MouseRelative) { // Get Delta - int dx = x, dy = y; - - const float maxPitch = ((3.1415f / 2) * 0.98f); + int dx = x; // Apply to rotation. Subtract for right body frame rotation, // since yaw rotation is positive CCW when looking down on XZ plane. - ThePlayer.EyeYaw -= (Sensitivity * dx) / 360.0f; - - if(!pSensor) - { - ThePlayer.EyePitch -= (Sensitivity * dy) / 360.0f; - - if(ThePlayer.EyePitch > maxPitch) - { - ThePlayer.EyePitch = maxPitch; - } - if(ThePlayer.EyePitch < -maxPitch) - { - ThePlayer.EyePitch = -maxPitch; - } - } + ThePlayer.BodyYaw -= (Sensitivity * dx) / 360.0f; } } void OculusWorldDemoApp::OnKey(OVR::KeyCode key, int chr, bool down, int modifiers) { - OVR_UNUSED(chr); + if (Menu.OnKey(key, chr, down, modifiers)) + return; + + // Handle player movement keys. + if (ThePlayer.HandleMoveKey(key, down)) + return; switch(key) { case Key_Q: if (down && (modifiers & Mod_Control)) - { pPlatform->Exit(0); - } - break; - - // Handle player movement keys. - // We just update movement state here, while the actual translation is done in OnIdle() - // based on time. - case Key_W: - ThePlayer.MoveForward = down ? (ThePlayer.MoveForward | 1) : (ThePlayer.MoveForward & ~1); - break; - case Key_S: - ThePlayer.MoveBack = down ? (ThePlayer.MoveBack | 1) : (ThePlayer.MoveBack & ~1); - break; - case Key_A: - ThePlayer.MoveLeft = down ? (ThePlayer.MoveLeft | 1) : (ThePlayer.MoveLeft & ~1); - break; - case Key_D: - ThePlayer.MoveRight = down ? (ThePlayer.MoveRight | 1) : (ThePlayer.MoveRight & ~1); - break; - case Key_Up: - ThePlayer.MoveForward = down ? (ThePlayer.MoveForward | 2) : (ThePlayer.MoveForward & ~2); - break; - case Key_Down: - ThePlayer.MoveBack = down ? (ThePlayer.MoveBack | 2) : (ThePlayer.MoveBack & ~2); - break; - case Key_Left: - ThePlayer.MoveLeft = down ? (ThePlayer.MoveLeft | 2) : (ThePlayer.MoveLeft & ~2); break; - case Key_Right: - ThePlayer.MoveRight = down ? (ThePlayer.MoveRight | 2) : (ThePlayer.MoveRight & ~2); - break; - - case Key_Minus: - pAdjustFunc = down ? &OculusWorldDemoApp::AdjustEyeHeight : 0; - AdjustDirection = -1; - break; - case Key_Equal: - pAdjustFunc = down ? &OculusWorldDemoApp::AdjustEyeHeight : 0; - AdjustDirection = 1; - break; - - case Key_B: - if (down) - { - if(SConfig.GetDistortionScale() == 1.0f) - { - if(SConfig.GetHMDInfo().HScreenSize > 0.140f) // 7" - { - SConfig.SetDistortionFitPointVP(-1.0f, 0.0f); - } - else - { - SConfig.SetDistortionFitPointVP(0.0f, 1.0f); - } - } - else - { - // No fitting; scale == 1.0. - SConfig.SetDistortionFitPointVP(0, 0); - } - } - break; - - // Support toggling background color for distortion so that we can see - // the effect on the periphery. - case Key_V: - if (down) - { - if(DistortionClearColor.B == 0) - { - DistortionClearColor = Color(0, 128, 255); - } - else - { - DistortionClearColor = Color(0, 0, 0); - } - - pRender->SetDistortionClearColor(DistortionClearColor); - } - break; - - - case Key_F1: - SConfig.SetStereoMode(Stereo_None); - PostProcess = PostProcess_None; - SetAdjustMessage("StereoMode: None"); - break; - case Key_F2: - SConfig.SetStereoMode(Stereo_LeftRight_Multipass); - PostProcess = PostProcess_None; - SetAdjustMessage("StereoMode: Stereo + No Distortion"); - break; - case Key_F3: - SConfig.SetStereoMode(Stereo_LeftRight_Multipass); - PostProcess = PostProcess_Distortion; - SetAdjustMessage("StereoMode: Stereo + Distortion"); - break; - - case Key_R: - SFusion.Reset(); - SetAdjustMessage("Sensor Fusion Reset"); - break; - - case Key_Space: - if (!down) - { - TextScreen = (enum TextScreen)((TextScreen + 1) % Text_Count); - } + + case Key_Escape: + // Back to primary windowed + if (!down) ChangeDisplay ( true, false, false ); break; - case Key_F4: - if (!down) - { - RenderParams = pRender->GetParams(); - RenderParams.Multisample = RenderParams.Multisample > 1 ? 1 : 4; - pRender->SetParams(RenderParams); - if(RenderParams.Multisample > 1) - { - SetAdjustMessage("Multisampling On"); - } - else - { - SetAdjustMessage("Multisampling Off"); - } - } - break; case Key_F9: -#ifndef OVR_OS_LINUX // On Linux F9 does the same as F11. - if (!down) - { - CycleDisplay(); - } +#ifndef OVR_OS_LINUX + // Cycle through displays, going fullscreen on each one. + if (!down) ChangeDisplay ( false, true, false ); break; +#else + // On Linux, fallthrough to F10/F11 #endif + #ifdef OVR_OS_MAC - case Key_F10: // F11 is reserved on Mac + // F11 is reserved on Mac, F10 doesn't work on Windows + case Key_F10: #else case Key_F11: #endif + if (!down) ChangeDisplay ( false, false, true ); + break; + + case Key_R: if (!down) { - RenderParams = pRender->GetParams(); - RenderParams.Display = DisplayId(SConfig.GetHMDInfo().DisplayDeviceName,SConfig.GetHMDInfo().DisplayId); - pRender->SetParams(RenderParams); - - pPlatform->SetMouseMode(Mouse_Normal); - pPlatform->SetFullscreen(RenderParams, pRender->IsFullscreen() ? Display_Window : Display_FakeFullscreen); - pPlatform->SetMouseMode(Mouse_Relative); // Avoid mode world rotation jump. - // If using an HMD, enable post-process (for distortion) and stereo. - if(RenderParams.IsDisplaySet() && pRender->IsFullscreen()) - { - SConfig.SetStereoMode(Stereo_LeftRight_Multipass); - PostProcess = PostProcess_Distortion; - } + ovrHmd_ResetSensor(Hmd); + Menu.SetPopupMessage("Sensor Fusion Reset"); } break; - case Key_Escape: - if(!down) + case Key_Space: + if (!down) { - // switch to primary screen windowed mode - pPlatform->SetFullscreen(RenderParams, Display_Window); - RenderParams.Display = pPlatform->GetDisplay(0); - pRender->SetParams(RenderParams); - Screen = 0; + TextScreen = (enum TextScreen)((TextScreen + 1) % Text_Count); } break; - // Stereo adjustments. - case Key_BracketLeft: - pAdjustFunc = down ? &OculusWorldDemoApp::AdjustFov : 0; - AdjustDirection = 1; - break; - case Key_BracketRight: - pAdjustFunc = down ? &OculusWorldDemoApp::AdjustFov : 0; - AdjustDirection = -1; - break; - - case Key_Insert: - case Key_Num0: - pAdjustFunc = down ? &OculusWorldDemoApp::AdjustIPD : 0; - AdjustDirection = 1; + // Distortion correction adjustments + case Key_Backslash: break; - case Key_Delete: - case Key_Num9: - pAdjustFunc = down ? &OculusWorldDemoApp::AdjustIPD : 0; - AdjustDirection = -1; - break; - - case Key_PageUp: - pAdjustFunc = down ? &OculusWorldDemoApp::AdjustAspect : 0; - AdjustDirection = 1; - break; - case Key_PageDown: - pAdjustFunc = down ? &OculusWorldDemoApp::AdjustAspect : 0; - AdjustDirection = -1; - break; - - // Distortion correction adjustments - case Key_H: - pAdjustFunc = down ? &OculusWorldDemoApp::AdjustDistortionK0 : NULL; - AdjustDirection = -1; - break; - case Key_Y: - pAdjustFunc = down ? &OculusWorldDemoApp::AdjustDistortionK0 : NULL; - AdjustDirection = 1; - break; - case Key_J: - pAdjustFunc = down ? &OculusWorldDemoApp::AdjustDistortionK1 : NULL; - AdjustDirection = -1; - break; - case Key_U: - pAdjustFunc = down ? &OculusWorldDemoApp::AdjustDistortionK1 : NULL; - AdjustDirection = 1; - break; - case Key_K: - pAdjustFunc = down ? &OculusWorldDemoApp::AdjustDistortionK2 : NULL; - AdjustDirection = -1; - break; - case Key_I: - pAdjustFunc = down ? &OculusWorldDemoApp::AdjustDistortionK2 : NULL; - AdjustDirection = 1; - break; - case Key_L: - pAdjustFunc = down ? &OculusWorldDemoApp::AdjustDistortionK3 : NULL; - AdjustDirection = -1; - break; - case Key_O: - pAdjustFunc = down ? &OculusWorldDemoApp::AdjustDistortionK3 : NULL; - AdjustDirection = 1; - break; - - case Key_Tab: - if (down) - { - float t0 = SConfig.GetDistortionK(0), - t1 = SConfig.GetDistortionK(1), - t2 = SConfig.GetDistortionK(2), - t3 = SConfig.GetDistortionK(3); - float tESD = SConfig.GetEyeToScreenDistance(), - taspect = SConfig.GetAspectMultiplier(), - tipd = SConfig.GetIPD(); - - if(SavedK0 > 0.0f) - { - SConfig.SetDistortionK(0, SavedK0); - SConfig.SetDistortionK(1, SavedK1); - SConfig.SetDistortionK(2, SavedK2); - SConfig.SetDistortionK(3, SavedK3); - SConfig.SetEyeToScreenDistance(SavedESD); - SConfig.SetAspectMultiplier(SavedAspect); - SConfig.SetIPD(SavedEyeDistance); - - if ( ShiftDown ) - { - // Swap saved and current values. Good for doing direct comparisons. - SetAdjustMessage("Swapped current and saved. New settings:\n" - "ESD:\t120 %.3f\t350 Eye:\t490 %.3f\n" - "K0: \t120 %.4f\t350 K2: \t490 %.4f\n" - "K1: \t120 %.4f\t350 K3: \t490 %.4f\n", - SavedESD, SavedEyeDistance, - SavedK0, SavedK2, - SavedK1, SavedK3); - SavedK0 = t0; - SavedK1 = t1; - SavedK2 = t2; - SavedK3 = t3; - SavedESD = tESD; - SavedAspect = taspect; - SavedEyeDistance = tipd; - } - else - { - SetAdjustMessage("Restored:\n" - "ESD:\t120 %.3f\t350 Eye:\t490 %.3f\n" - "K0: \t120 %.4f\t350 K2: \t490 %.4f\n" - "K1: \t120 %.4f\t350 K3: \t490 %.4f\n", - SavedESD, SavedEyeDistance, - SavedK0, SavedK2, - SavedK1, SavedK3); - } - } - else - { - SetAdjustMessage("Setting Saved"); - SavedK0 = t0; - SavedK1 = t1; - SavedK2 = t2; - SavedK3 = t3; - SavedESD = tESD; - SavedAspect = taspect; - SavedEyeDistance = tipd; - } - - } - break; - - case Key_G: - if (down) - { - if(SceneMode == Scene_World) - { - SceneMode = Scene_Grid; - SetAdjustMessage("Grid Only"); - } - else if(SceneMode == Scene_Grid) - { - SceneMode = Scene_Both; - SetAdjustMessage("Grid Overlay"); - } - else if(SceneMode == Scene_Both) - { - SceneMode = Scene_World; - SetAdjustMessage("Grid Off"); - } - } - break; - // Holding down Shift key accelerates adjustment velocity. case Key_Shift: ShiftDown = down; break; - - // Reset the camera position in case we get stuck - case Key_T: - ThePlayer.EyePos = Vector3f(10.0f, ThePlayer.UserEyeHeight, 10.0f); + case Key_Control: + CtrlDown = down; break; - case Key_F5: - if (!down) + // Reset the camera position in case we get stuck + case Key_T: + if (down) { - UPInt numNodes = MainScene.Models.GetSize(); - for(UPInt i = 0; i < numNodes; i++) + struct { + float x, z; + float YawDegrees; + } Positions[] = { - Ptr<OVR::Render::Model> nodePtr = MainScene.Models[i]; - Render::Model* pNode = nodePtr.GetPtr(); - if(pNode->IsCollisionModel) - { - pNode->Visible = !pNode->Visible; - } - } + // x z Yaw + { 7.7f, -1.0f, 180.0f }, // The starting position. + { 10.0f, 10.0f, 90.0f }, // Outside, looking at some trees. + { 19.26f, 5.43f, 22.0f }, // Outside, looking at the fountain. + }; + + static int nextPosition = 0; + nextPosition = (nextPosition + 1) % (sizeof(Positions)/sizeof(Positions[0])); + + ThePlayer.BodyPos = Vector3f(Positions[nextPosition].x, + ThePlayer.UserEyeHeight, Positions[nextPosition].z); + ThePlayer.BodyYaw = DegreeToRad( Positions[nextPosition].YawDegrees ); } break; - case Key_N: - pAdjustFunc = down ? &OculusWorldDemoApp::AdjustMotionPrediction : NULL; - AdjustDirection = -1; + case Key_Num1: + ThePlayer.BodyPos = Vector3f(-1.85f, 6.0f, -0.52f); + ThePlayer.BodyPos.y += ThePlayer.UserEyeHeight; + ThePlayer.BodyYaw = 3.1415f / 2; + ThePlayer.HandleMovement(0, &CollisionModels, &GroundCollisionModels, ShiftDown); break; - case Key_M: - pAdjustFunc = down ? &OculusWorldDemoApp::AdjustMotionPrediction : NULL; - AdjustDirection = 1; + default: break; + } +} -/* - case Key_N: - RaiseLOD(); - break; - case Key_M: - DropLOD(); - break; -*/ +//----------------------------------------------------------------------------- - // Cycle through drift correction options - case Key_Z: - if (down) - { - if (SFusion.IsYawCorrectionEnabled()) - { - SFusion.SetGravityEnabled(false); - SFusion.SetYawCorrectionEnabled(false); - } - else if (SFusion.IsGravityEnabled()) - { - SFusion.SetYawCorrectionEnabled(true); - } - else - { - SFusion.SetGravityEnabled(true); - } - SetAdjustMessage("Tilt Correction %s\nYaw Correction %s", - SFusion.IsGravityEnabled() ? "On" : "Off", - SFusion.IsYawCorrectionEnabled() ? "On" : "Off"); - } - break; - // Show view of yaw angles (for mag calibration/analysis) - case Key_F6: - if (down) - { - if (SceneMode != Scene_YawView) - { - SceneMode = Scene_YawView; - SetAdjustMessage("Magnetometer Yaw Angle Marks"); - } - else - { - SceneMode = Scene_World; - SetAdjustMessage("Magnetometer Marks Off"); - } - } - break; +Matrix4f OculusWorldDemoApp::CalculateViewFromPose(const Posef& pose) +{ + Posef worldPose = ThePlayer.VirtualWorldPoseFromRealPose(pose); - case Key_C: - if (down) - { - // Toggle chromatic aberration correction on/off. - RenderDevice::PostProcessShader shader = pRender->GetPostProcessShader(); + // Rotate and position View Camera + Vector3f up = worldPose.Orientation.Rotate(UpVector); + Vector3f forward = worldPose.Orientation.Rotate(ForwardVector); - if (shader == RenderDevice::PostProcessShader_Distortion) - { - pRender->SetPostProcessShader(RenderDevice::PostProcessShader_DistortionAndChromAb); - SetAdjustMessage("Chromatic Aberration Correction On"); - } - else if (shader == RenderDevice::PostProcessShader_DistortionAndChromAb) - { - pRender->SetPostProcessShader(RenderDevice::PostProcessShader_Distortion); - SetAdjustMessage("Chromatic Aberration Correction Off"); - } - else - OVR_ASSERT(false); - } - break; + // Transform the position of the center eye in the real world (i.e. sitting in your chair) + // into the frame of the player's virtual body. - case Key_P: - if (down) - { - // Toggle motion prediction. - if (SFusion.IsPredictionEnabled()) - { - SFusion.SetPredictionEnabled(false); - SetAdjustMessage("Motion Prediction Off"); - } - else - { - SFusion.SetPredictionEnabled(true); - SetAdjustMessage("Motion Prediction On"); - } - } - break; - default: - break; - } + // It is important to have head movement in scale with IPD. + // If you shrink one, you should also shrink the other. + // So with zero IPD (i.e. everything at infinity), + // head movement should also be zero. + Vector3f viewPos = ForceZeroHeadMovement ? ThePlayer.BodyPos : worldPose.Position; + + Matrix4f view = Matrix4f::LookAtRH(viewPos, viewPos + forward, up); + return view; } + + void OculusWorldDemoApp::OnIdle() { + double curtime = ovr_GetTimeInSeconds(); + // If running slower than 10fps, clamp. Helps when debugging, because then dt can be minutes! + float dt = Alg::Min<float>(float(curtime - LastUpdate), 0.1f); + LastUpdate = curtime; - double curtime = pPlatform->GetAppTime(); - float dt = float(curtime - LastUpdate); - LastUpdate = curtime; - - // Update gamepad. - GamepadState gamepadState; - if (GetPlatformCore()->GetGamepadManager()->GetGamepadState(0, &gamepadState)) - { - GamepadStateChanged(gamepadState); - } + Profiler.RecordSample(RenderProfiler::Sample_FrameStart); if (LoadingState == LoadingState_DoLoad) { PopulateScene(MainFilePath.ToCStr()); LoadingState = LoadingState_Finished; return; - } - - // Check if any new devices were connected. - { - bool queueIsEmpty = false; - while (!queueIsEmpty) - { - DeviceStatusNotificationDesc desc; - - { - Lock::Locker lock(pManager->GetHandlerLock()); - if (DeviceStatusNotificationsQueue.GetSize() == 0) - break; - desc = DeviceStatusNotificationsQueue.Front(); - - // We can't call Clear under the lock since this may introduce a dead lock: - // this thread is locked by HandlerLock and the Clear might cause - // call of Device->Release, which will use Manager->DeviceLock. The bkg - // thread is most likely locked by opposite way: - // Manager->DeviceLock ==> HandlerLock, therefore - a dead lock. - // So, just grab the first element, save a copy of it and remove - // the element (Device->Release won't be called since we made a copy). - - DeviceStatusNotificationsQueue.RemoveAt(0); - queueIsEmpty = (DeviceStatusNotificationsQueue.GetSize() == 0); - } - - bool wasAlreadyCreated = desc.Handle.IsCreated(); - - if (desc.Action == Message_DeviceAdded) - { - switch(desc.Handle.GetType()) - { - case Device_Sensor: - if (desc.Handle.IsAvailable() && !desc.Handle.IsCreated()) - { - if (!pSensor) - { - pSensor = *desc.Handle.CreateDeviceTyped<SensorDevice>(); - if (pSensor) - { - SFusion.AttachToSensor(pSensor); - - SetAdjustMessage("---------------------------\n" - "SENSOR connected\n" - "---------------------------"); - } - else - { - SetAdjustMessage("----------------------------\n" - "SENSOR connect failed\n" - "Unplug and reconnect it.\n" - "----------------------------"); - } - } - else if (!wasAlreadyCreated) - { - LogText("A new SENSOR has been detected, but it is not currently used."); - } - } - break; - case Device_LatencyTester: - if (desc.Handle.IsAvailable() && !desc.Handle.IsCreated()) - { - if (!pLatencyTester) - { - pLatencyTester = *desc.Handle.CreateDeviceTyped<LatencyTestDevice>(); - LatencyUtil.SetDevice(pLatencyTester); - if (!wasAlreadyCreated) - SetAdjustMessage("----------------------------------------\n" - "LATENCY TESTER connected\n" - "----------------------------------------"); - } - } - break; - case Device_HMD: - { - OVR::HMDInfo info; - desc.Handle.GetDeviceInfo(&info); - // if strlen(info.DisplayDeviceName) == 0 then - // this HMD is 'fake' (created using sensor). - if (strlen(info.DisplayDeviceName) > 0 && (!pHMD || !info.IsSameDisplay(TheHMDInfo))) - { - SetAdjustMessage("------------------------\n" - "HMD connected\n" - "------------------------"); - if (!pHMD || !desc.Handle.IsDevice(pHMD)) - pHMD = *desc.Handle.CreateDeviceTyped<HMDDevice>(); - // update stereo config with new HMDInfo - if (pHMD && pHMD->GetDeviceInfo(&TheHMDInfo)) - { - //RenderParams.MonitorName = hmd.DisplayDeviceName; - SConfig.SetHMDInfo(TheHMDInfo); - } - LogText("HMD device added.\n"); - } - break; - } - default:; - } - } - else if (desc.Action == Message_DeviceRemoved) - { - if (desc.Handle.IsDevice(pSensor)) - { - LogText("Sensor reported device removed.\n"); - SFusion.AttachToSensor(NULL); - pSensor.Clear(); - SetAdjustMessage("-------------------------------\n" - "SENSOR disconnected.\n" - "-------------------------------"); - } - else if (desc.Handle.IsDevice(pLatencyTester)) - { - LogText("Latency Tester reported device removed.\n"); - LatencyUtil.SetDevice(NULL); - pLatencyTester.Clear(); - SetAdjustMessage("---------------------------------------------\n" - "LATENCY SENSOR disconnected.\n" - "---------------------------------------------"); - } - else if (desc.Handle.IsDevice(pHMD)) - { - if (pHMD && !pHMD->IsDisconnected()) - { - SetAdjustMessage("---------------------------\n" - "HMD disconnected\n" - "---------------------------"); - // Disconnect HMD. pSensor is used to restore 'fake' HMD device - // (can be NULL). - pHMD = pHMD->Disconnect(pSensor); - - // This will initialize TheHMDInfo with information about configured IPD, - // screen size and other variables needed for correct projection. - // We pass HMD DisplayDeviceName into the renderer to select the - // correct monitor in full-screen mode. - if (pHMD && pHMD->GetDeviceInfo(&TheHMDInfo)) - { - //RenderParams.MonitorName = hmd.DisplayDeviceName; - SConfig.SetHMDInfo(TheHMDInfo); - } - LogText("HMD device removed.\n"); - } - } - } - else - OVR_ASSERT(0); // unexpected action - } - } + } - // If one of Stereo setting adjustment keys is pressed, adjust related state. - if (pAdjustFunc) + if (HmdSettingsChanged) { - (this->*pAdjustFunc)(dt * AdjustDirection * (ShiftDown ? 5.0f : 1.0f)); + CalculateHmdValues(); + HmdSettingsChanged = false; } - // Process latency tester results. - const char* results = LatencyUtil.GetResultsString(); - if (results != NULL) - { - LogText("LATENCY TESTER: %s\n", results); - } + HmdFrameTiming = ovrHmd_BeginFrame(Hmd, 0); - // >>> THIS MUST BE PLACED AS CLOSE AS POSSIBLE TO WHERE THE HMD ORIENTATION IS READ <<< - LatencyUtil.ProcessInputs(); - // Handle Sensor motion. - // We extract Yaw, Pitch, Roll instead of directly using the orientation - // to allow "additional" yaw manipulation with mouse/controller. - if(pSensor) + // Update gamepad. + GamepadState gamepadState; + if (GetPlatformCore()->GetGamepadManager()->GetGamepadState(0, &gamepadState)) { - Quatf hmdOrient = SFusion.GetPredictedOrientation(); + GamepadStateChanged(gamepadState); + } - float yaw = 0.0f; - hmdOrient.GetEulerAngles<Axis_Y, Axis_X, Axis_Z>(&yaw, &ThePlayer.EyePitch, &ThePlayer.EyeRoll); + SensorState ss = ovrHmd_GetSensorState(Hmd, HmdFrameTiming.ScanoutMidpointSeconds); + HmdStatus = ss.StatusFlags; - ThePlayer.EyeYaw += (yaw - ThePlayer.LastSensorYaw); - ThePlayer.LastSensorYaw = yaw; + // Change message status around positional tracking. + bool hadVisionTracking = HaveVisionTracking; + HaveVisionTracking = (ss.StatusFlags & Status_PositionTracked) != 0; + if (HaveVisionTracking && !hadVisionTracking) + Menu.SetPopupMessage("Vision Tracking Acquired"); + if (!HaveVisionTracking && hadVisionTracking) + Menu.SetPopupMessage("Lost Vision Tracking"); + + // Check if any new devices were connected. + ProcessDeviceNotificationQueue(); + // FPS count and timing. + UpdateFrameRateCounter(curtime); - // NOTE: We can get a matrix from orientation as follows: - // Matrix4f hmdMat(hmdOrient); + + // Update pose based on frame! + ThePlayer.HeadPose = ss.Predicted.Transform; + // Movement/rotation with the gamepad. + ThePlayer.BodyYaw -= ThePlayer.GamepadRotate.x * dt; + ThePlayer.HandleMovement(dt, &CollisionModels, &GroundCollisionModels, ShiftDown); - // Test logic - assign quaternion result directly to view: - // Quatf hmdOrient = SFusion.GetOrientation(); - // View = Matrix4f(hmdOrient.Inverted()) * Matrix4f::Translation(-EyePos); - } + // Record after processing time. + Profiler.RecordSample(RenderProfiler::Sample_AfterGameProcessing); - if(curtime >= NextFPSUpdate) - { - NextFPSUpdate = curtime + 1.0; - FPS = FrameCounter; - FrameCounter = 0; - } - FrameCounter++; - if(FPS < 40) - { - ConsecutiveLowFPSFrames++; - } - else + // Determine if we are rendering this frame. Frame rendering may be + // skipped based on FreezeEyeUpdate and Time-warp timing state. + bool bupdateRenderedView = FrameNeedsRendering(curtime); + + if (bupdateRenderedView) { - ConsecutiveLowFPSFrames = 0; - } + // If render texture size is changing, apply dynamic changes to viewport. + ApplyDynamicResolutionScaling(); - if(ConsecutiveLowFPSFrames > 200) - { - DropLOD(); - ConsecutiveLowFPSFrames = 0; - } + pRender->BeginScene(PostProcess_None); - ThePlayer.EyeYaw -= ThePlayer.GamepadRotate.x * dt; - ThePlayer.HandleCollision(dt, &CollisionModels, &GroundCollisionModels, ShiftDown); + if (ForceZeroIpd) + { + // Zero IPD eye rendering: draw into left eye only, + // re-use texture for right eye. + pRender->SetRenderTarget(RenderTargets[Rendertarget_Left].pTex); + pRender->Clear(); + + ovrPosef eyeRenderPose = ovrHmd_BeginEyeRender(Hmd, ovrEye_Left); + + View = CalculateViewFromPose(eyeRenderPose); + RenderEyeView(ovrEye_Left); + ovrHmd_EndEyeRender(Hmd, ovrEye_Left, eyeRenderPose, &EyeTexture[ovrEye_Left]); - if(!pSensor) - { - ThePlayer.EyePitch -= ThePlayer.GamepadRotate.y * dt; + // Second eye gets the same texture (initialized to same value above). + ovrHmd_BeginEyeRender(Hmd, ovrEye_Right); + ovrHmd_EndEyeRender(Hmd, ovrEye_Right, eyeRenderPose, &EyeTexture[ovrEye_Right]); + } - const float maxPitch = ((3.1415f / 2) * 0.98f); - if(ThePlayer.EyePitch > maxPitch) + else if (RendertargetIsSharedByBothEyes) { - ThePlayer.EyePitch = maxPitch; + // Shared render target eye rendering; set up RT once for both eyes. + pRender->SetRenderTarget(RenderTargets[Rendertarget_BothEyes].pTex); + pRender->Clear(); + + for (int eyeIndex = 0; eyeIndex < ovrEye_Count; eyeIndex++) + { + ovrEyeType eye = HmdDesc.EyeRenderOrder[eyeIndex]; + ovrPosef eyeRenderPose = ovrHmd_BeginEyeRender(Hmd, eye); + + View = CalculateViewFromPose(eyeRenderPose); + RenderEyeView(eye); + ovrHmd_EndEyeRender(Hmd, eye, eyeRenderPose, &EyeTexture[eye]); + } } - if(ThePlayer.EyePitch < -maxPitch) + + else { - ThePlayer.EyePitch = -maxPitch; - } - } + // Separate eye rendering - each eye gets its own render target. + for (int eyeIndex = 0; eyeIndex < ovrEye_Count; eyeIndex++) + { + ovrEyeType eye = HmdDesc.EyeRenderOrder[eyeIndex]; + pRender->SetRenderTarget( + RenderTargets[(eye == 0) ? Rendertarget_Left : Rendertarget_Right].pTex); + pRender->Clear(); + + ovrPosef eyeRenderPose = ovrHmd_BeginEyeRender(Hmd, eye); - // Rotate and position View Camera, using YawPitchRoll in BodyFrame coordinates. - // - Matrix4f rollPitchYaw = Matrix4f::RotationY(ThePlayer.EyeYaw) * Matrix4f::RotationX(ThePlayer.EyePitch) * - Matrix4f::RotationZ(ThePlayer.EyeRoll); - Vector3f up = rollPitchYaw.Transform(UpVector); - Vector3f forward = rollPitchYaw.Transform(ForwardVector); + View = CalculateViewFromPose(eyeRenderPose); + RenderEyeView(eye); + ovrHmd_EndEyeRender(Hmd, eye, eyeRenderPose, &EyeTexture[eye]); + } + } + pRender->SetRenderTarget(0); + pRender->FinishScene(); + } - // Minimal head modeling; should be moved as an option to SensorFusion. - float headBaseToEyeHeight = 0.15f; // Vertical height of eye from base of head - float headBaseToEyeProtrusion = 0.09f; // Distance forward of eye from base of head + Profiler.RecordSample(RenderProfiler::Sample_AfterEyeRender); - Vector3f eyeCenterInHeadFrame(0.0f, headBaseToEyeHeight, -headBaseToEyeProtrusion); - Vector3f shiftedEyePos = ThePlayer.EyePos + rollPitchYaw.Transform(eyeCenterInHeadFrame); - shiftedEyePos.y -= eyeCenterInHeadFrame.y; // Bring the head back down to original height - View = Matrix4f::LookAtRH(shiftedEyePos, shiftedEyePos + forward, up); + // TODO: These happen inside ovrHmd_EndFrame; need to hook into it. + //Profiler.RecordSample(RenderProfiler::Sample_BeforeDistortion); + ovrHmd_EndFrame(Hmd); + Profiler.RecordSample(RenderProfiler::Sample_AfterPresent); +} - // Transformation without head modeling. - // View = Matrix4f::LookAtRH(EyePos, EyePos + forward, up); - // This is an alternative to LookAtRH: - // Here we transpose the rotation matrix to get its inverse. - // View = (Matrix4f::RotationY(EyeYaw) * Matrix4f::RotationX(EyePitch) * - // Matrix4f::RotationZ(EyeRoll)).Transposed() * - // Matrix4f::Translation(-EyePos); +// Determine whether this frame needs rendering based on time-warp timing and flags. +bool OculusWorldDemoApp::FrameNeedsRendering(double curtime) +{ + static double lastUpdate = 0.0; + double renderInterval = TimewarpRenderIntervalInSeconds; + double timeSinceLast = curtime - lastUpdate; + bool updateRenderedView = true; - switch(SConfig.GetStereoMode()) + if (TimewarpEnabled) { - case Stereo_None: - Render(SConfig.GetEyeRenderParams(StereoEye_Center)); - break; + if (FreezeEyeUpdate) + { + // Draw one frame after (FreezeEyeUpdate = true) to update message text. + if (FreezeEyeOneFrameRendered) + updateRenderedView = false; + else + FreezeEyeOneFrameRendered = true; + } + else + { + FreezeEyeOneFrameRendered = false; - case Stereo_LeftRight_Multipass: - //case Stereo_LeftDouble_Multipass: - Render(SConfig.GetEyeRenderParams(StereoEye_Left)); - Render(SConfig.GetEyeRenderParams(StereoEye_Right)); - break; + if ( (timeSinceLast < 0.0) || ((float)timeSinceLast > renderInterval) ) + { + // This allows us to do "fractional" speeds, e.g. 45fps rendering on a 60fps display. + lastUpdate += renderInterval; + if ( timeSinceLast > 5.0 ) + { + // renderInterval is probably tiny (i.e. "as fast as possible") + lastUpdate = curtime; + } + updateRenderedView = true; + } + else + { + updateRenderedView = false; + } + } } - - pRender->Present(); - // Force GPU to flush the scene, resulting in the lowest possible latency. - pRender->ForceFlushGPU(); + + return updateRenderedView; } -static const char* HelpText = - "F1 \t100 NoStereo\n" - "F2 \t100 Stereo \t420 Z \t520 Drift Correction\n" - "F3 \t100 StereoHMD \t420 F6 \t520 Yaw Drift Info\n" - "F4 \t100 MSAA \t420 R \t520 Reset SensorFusion\n" - "F9 \t100 FullScreen \t420\n" - "F11 \t100 Fast FullScreen \t500 - + \t660 Adj EyeHeight\n" - "C \t100 Chromatic Ab \t500 [ ] \t660 Adj FOV\n" - "P \t100 Motion Pred \t500 Shift \t660 Adj Faster\n" - "N/M \t180 Adj Motion Pred\n" - "( / ) \t180 Adj EyeDistance" - ; - - -enum DrawTextCenterType -{ - DrawText_NoCenter= 0, - DrawText_VCenter = 0x1, - DrawText_HCenter = 0x2, - DrawText_Center = DrawText_VCenter | DrawText_HCenter -}; - -static void DrawTextBox(RenderDevice* prender, float x, float y, - float textSize, const char* text, - DrawTextCenterType centerType = DrawText_NoCenter) +void OculusWorldDemoApp::ApplyDynamicResolutionScaling() { - float ssize[2] = {0.0f, 0.0f}; - - prender->MeasureText(&DejaVu, text, textSize, ssize); - - // Treat 0 a VCenter. - if (centerType & DrawText_HCenter) + if (!DynamicRezScalingEnabled) { - x = -ssize[0]/2; + // Restore viewport rectangle in case dynamic res scaling was enabled before. + EyeTexture[0].Header.RenderViewport = EyeRenderDesc[0].Desc.RenderViewport; + EyeTexture[1].Header.RenderViewport = EyeRenderDesc[1].Desc.RenderViewport; + return; } - if (centerType & DrawText_VCenter) + + // Demonstrate dynamic-resolution rendering. + // This demo is too simple to actually have a framerate that varies that much, so we'll + // just pretend this is trying to cope with highly dynamic rendering load. + float dynamicRezScale = 1.0f; + { - y = -ssize[1]/2; + // Hacky stuff to make up a scaling... + // This produces value oscillating as follows: 0 -> 1 -> 0. + static double dynamicRezStartTime = ovr_GetTimeInSeconds(); + float dynamicRezPhase = float ( ovr_GetTimeInSeconds() - dynamicRezStartTime ); + const float dynamicRezTimeScale = 4.0f; + + dynamicRezPhase /= dynamicRezTimeScale; + if ( dynamicRezPhase < 1.0f ) + { + dynamicRezScale = dynamicRezPhase; + } + else if ( dynamicRezPhase < 2.0f ) + { + dynamicRezScale = 2.0f - dynamicRezPhase; + } + else + { + // Reset it to prevent creep. + dynamicRezStartTime = ovr_GetTimeInSeconds(); + dynamicRezScale = 0.0f; + } + + // Map oscillation: 0.5 -> 1.0 -> 0.5 + dynamicRezScale = dynamicRezScale * 0.5f + 0.5f; } - prender->FillRect(x-0.02f, y-0.02f, x+ssize[0]+0.02f, y+ssize[1]+0.02f, Color(40,40,100,210)); - prender->RenderText(&DejaVu, text, x, y, textSize, Color(255,255,0,210)); + Sizei sizeLeft = EyeRenderDesc[0].Desc.RenderViewport.Size; + Sizei sizeRight = EyeRenderDesc[1].Desc.RenderViewport.Size; + + // This viewport is used for rendering and passed into ovrHmd_EndEyeRender. + EyeTexture[0].Header.RenderViewport.Size = Sizei(int(sizeLeft.w * dynamicRezScale), + int(sizeLeft.h * dynamicRezScale)); + EyeTexture[1].Header.RenderViewport.Size = Sizei(int(sizeRight.w * dynamicRezScale), + int(sizeRight.h * dynamicRezScale)); } -void OculusWorldDemoApp::Render(const StereoEyeParams& stereo) + +void OculusWorldDemoApp::UpdateFrameRateCounter(double curtime) { - pRender->BeginScene(PostProcess); + FrameCounter++; + float secondsSinceLastMeasurement = (float)( curtime - LastFpsUpdate ); + + if (secondsSinceLastMeasurement >= SecondsOfFpsMeasurement) + { + SecondsPerFrame = (float)( curtime - LastFpsUpdate ) / (float)FrameCounter; + FPS = 1.0f / SecondsPerFrame; + LastFpsUpdate = curtime; + FrameCounter = 0; + } +} - // *** 3D - Configures Viewport/Projection and Render - pRender->ApplyStereoParams(stereo); - pRender->Clear(); +void OculusWorldDemoApp::RenderEyeView(ovrEyeType eye) +{ + Recti renderViewport = EyeTexture[eye].Header.RenderViewport; + Matrix4f viewAdjust = Matrix4f::Translation(Vector3f(EyeRenderDesc[eye].ViewAdjust)); + + + // *** 3D - Configures Viewport/Projection and Render + + pRender->ApplyStereoParams(renderViewport, Projection[eye]); pRender->SetDepthMode(true, true); - if (SceneMode != Scene_Grid) + + Matrix4f baseTranslate = Matrix4f::Translation(ThePlayer.BodyPos); + Matrix4f baseYaw = Matrix4f::RotationY(ThePlayer.BodyYaw.Get()); + + + if (GridDisplayMode != GridDisplay_GridOnly) { - MainScene.Render(pRender, stereo.ViewAdjust * View); - } + if (SceneMode != Scene_OculusCubes) + { + MainScene.Render(pRender, viewAdjust * View); + RenderAnimatedBlocks(eye, ovr_GetTimeInSeconds()); + } + + if (SceneMode == Scene_Cubes) + { + // Draw scene cubes overlay. Red if position tracked, blue otherwise. + Scene sceneCubes = (HmdStatus & ovrStatus_PositionTracked) ? + RedCubesScene : BlueCubesScene; + sceneCubes.Render(pRender, viewAdjust * View * baseTranslate * baseYaw); + } - if (SceneMode == Scene_YawView) + else if (SceneMode == Scene_OculusCubes) + { + OculusCubesScene.Render(pRender, viewAdjust * View * baseTranslate * baseYaw); + } + } + + if (GridDisplayMode != GridDisplay_None) { - Matrix4f trackerOnlyOrient = Matrix4f::RotationY(ThePlayer.LastSensorYaw) - * Matrix4f::RotationX(ThePlayer.EyePitch) - * Matrix4f::RotationZ(ThePlayer.EyeRoll); - YawLinesScene.Render(pRender, stereo.ViewAdjust * trackerOnlyOrient.Inverted()); - //YawMarkRedScene.Render(pRender, stereo.ViewAdjust); + RenderGrid(eye); } - // *** 2D Text & Grid - Configure Orthographic rendering. + + // *** 2D Text - Configure Orthographic rendering. // Render UI in 2D orthographic coordinate system that maps [-1,1] range // to a readable FOV area centered at your eye and properly adjusted. - pRender->ApplyStereoParams2D(stereo); + pRender->ApplyStereoParams(renderViewport, OrthoProjection[eye]); pRender->SetDepthMode(false, false); - float unitPixel = SConfig.Get2DUnitPixel(); - float textHeight= unitPixel * 22; - - if ((SceneMode == Scene_Grid)||(SceneMode == Scene_Both)) - { // Draw grid two pixels thick. - GridScene.Render(pRender, Matrix4f()); - GridScene.Render(pRender, Matrix4f::Translation(unitPixel,unitPixel,0)); - } + // We set this scale up in CreateOrthoSubProjection(). + float textHeight = 22.0f; // Display Loading screen-shot in frame 0. if (LoadingState != LoadingState_Finished) { - LoadingScene.Render(pRender, Matrix4f()); + const float scale = textHeight * 25.0f; + Matrix4f view ( scale, 0.0f, 0.0f, 0.0f, scale, 0.0f, 0.0f, 0.0f, scale ); + LoadingScene.Render(pRender, view); String loadMessage = String("Loading ") + MainFilePath; - DrawTextBox(pRender, 0.0f, 0.0f, textHeight, loadMessage.ToCStr(), DrawText_HCenter); + DrawTextBox(pRender, 0.0f, -textHeight, textHeight, loadMessage.ToCStr(), DrawText_HCenter); LoadingState = LoadingState_DoLoad; } - if(!AdjustMessage.IsEmpty() && AdjustMessageTimeout > pPlatform->GetAppTime()) - { - DrawTextBox(pRender,0.0f,0.4f, textHeight, AdjustMessage.ToCStr(), DrawText_HCenter); - } + // HUD overlay brought up by spacebar. + RenderTextInfoHud(textHeight); + // Menu brought up by + Menu.Render(pRender); +} + + + +// NOTE - try to keep these in sync with the PDF docs! +static const char* HelpText1 = + "Spacebar \t500 Toggle debug info overlay\n" + "W, S \t500 Move forward, back\n" + "A, D \t500 Strafe left, right\n" + "Mouse move \t500 Look left, right\n" + "Left gamepad stick \t500 Move\n" + "Right gamepad stick \t500 Turn\n" + "T \t500 Reset player position"; + +static const char* HelpText2 = + "R \t250 Reset sensor orientation\n" + "G \t250 Cycle grid overlay mode\n" + "-, + \t250 Adjust eye height\n" + "Esc \t250 Cancel full-screen\n" + "F4 \t250 Multisampling toggle\n" + "F9 \t250 Hardware full-screen (low latency)\n" + "F11 \t250 Faked full-screen (easier debugging)\n" + "Ctrl+Q \t250 Quit"; + + +void FormatLatencyReading(char* buff, UPInt size, float val) +{ + if (val < 0.000001f) + OVR_strcpy(buff, size, "N/A "); + else + OVR_sprintf(buff, size, "%4.2fms", val * 1000.0f); +} + + +void OculusWorldDemoApp::RenderTextInfoHud(float textHeight) +{ + // View port & 2D ortho projection must be set before call. + + float hmdYaw, hmdPitch, hmdRoll; switch(TextScreen) { - case Text_Orientation: + case Text_Info: { - char buf[256], gpustat[256]; + char buf[512], gpustat[256]; + + // Average FOVs. + FovPort leftFov = EyeRenderDesc[0].Desc.Fov; + FovPort rightFov = EyeRenderDesc[1].Desc.Fov; + + // Rendered size changes based on selected options & dynamic rendering. + int pixelSizeWidth = EyeTexture[0].Header.RenderViewport.Size.w + + ((!ForceZeroIpd) ? + EyeTexture[1].Header.RenderViewport.Size.w : 0); + int pixelSizeHeight = ( EyeTexture[0].Header.RenderViewport.Size.h + + EyeTexture[1].Header.RenderViewport.Size.h ) / 2; + + // No DK2, no message. + char latency2Text[128] = ""; + { + //float latency2 = ovrHmd_GetMeasuredLatencyTest2(Hmd) * 1000.0f; // show it in ms + //if (latency2 > 0) + // OVR_sprintf(latency2Text, sizeof(latency2Text), "%.2fms", latency2); + + float latencies[3] = { 0.0f, 0.0f, 0.0f }; + if (ovrHmd_GetFloatArray(Hmd, "DK2Latency", latencies, 3) == 3) + { + char latencyText0[32], latencyText1[32], latencyText2[32]; + FormatLatencyReading(latencyText0, sizeof(latencyText0), latencies[0]); + FormatLatencyReading(latencyText1, sizeof(latencyText1), latencies[1]); + FormatLatencyReading(latencyText2, sizeof(latencyText2), latencies[2]); + + OVR_sprintf(latency2Text, sizeof(latency2Text), + " DK2 Latency Ren: %s TWrp: %s\n" + " PostPresent: %s ", + latencyText0, latencyText1, latencyText2); + } + } + + ThePlayer.HeadPose.Orientation.GetEulerAngles<Axis_Y, Axis_X, Axis_Z>(&hmdYaw, &hmdPitch, &hmdRoll); OVR_sprintf(buf, sizeof(buf), - " Yaw:%4.0f Pitch:%4.0f Roll:%4.0f \n" - " FPS: %d Frame: %d \n Pos: %3.2f, %3.2f, %3.2f \n" - " EyeHeight: %3.2f", - RadToDegree(ThePlayer.EyeYaw), RadToDegree(ThePlayer.EyePitch), RadToDegree(ThePlayer.EyeRoll), - FPS, FrameCounter, ThePlayer.EyePos.x, ThePlayer.EyePos.y, ThePlayer.EyePos.z, ThePlayer.UserEyeHeight); + " HMD YPR:%4.0f %4.0f %4.0f Player Yaw: %4.0f\n" + " FPS: %.1f ms/frame: %.1f Frame: %d\n" + " Pos: %3.2f, %3.2f, %3.2f HMD: %s\n" + " EyeHeight: %3.2f, IPD: %3.1fmm\n" //", Lens: %s\n" + " FOV %3.1fx%3.1f, Resolution: %ix%i\n" + "%s", + RadToDegree(hmdYaw), RadToDegree(hmdPitch), RadToDegree(hmdRoll), + RadToDegree(ThePlayer.BodyYaw.Get()), + FPS, SecondsPerFrame * 1000.0f, FrameCounter, + ThePlayer.BodyPos.x, ThePlayer.BodyPos.y, ThePlayer.BodyPos.z, + //GetDebugNameHmdType ( TheHmdRenderInfo.HmdType ), + HmdDesc.ProductName, + ThePlayer.UserEyeHeight, + ovrHmd_GetFloat(Hmd, OVR_KEY_IPD, 0) * 1000.0f, + //( EyeOffsetFromNoseLeft + EyeOffsetFromNoseRight ) * 1000.0f, + //GetDebugNameEyeCupType ( TheHmdRenderInfo.EyeCups ), // Lens/EyeCup not exposed + + (leftFov.GetHorizontalFovDegrees() + rightFov.GetHorizontalFovDegrees()) * 0.5f, + (leftFov.GetVerticalFovDegrees() + rightFov.GetVerticalFovDegrees()) * 0.5f, + + pixelSizeWidth, pixelSizeHeight, + + latency2Text + ); + size_t texMemInMB = pRender->GetTotalTextureMemoryUsage() / 1058576; if (texMemInMB) { - OVR_sprintf(gpustat, sizeof(gpustat), "\n GPU Tex: %u MB", texMemInMB); + OVR_sprintf(gpustat, sizeof(gpustat), " GPU Tex: %u MB", texMemInMB); OVR_strcat(buf, sizeof(buf), gpustat); } - DrawTextBox(pRender, 0.0f, -0.15f, textHeight, buf, DrawText_HCenter); + DrawTextBox(pRender, 0.0f, 0.0f, textHeight, buf, DrawText_Center); } break; - - case Text_Config: - { - char textBuff[2048]; - - OVR_sprintf(textBuff, sizeof(textBuff), - "Fov\t300 %9.4f\n" - "EyeDistance\t300 %9.4f\n" - "DistortionK0\t300 %9.4f\n" - "DistortionK1\t300 %9.4f\n" - "DistortionK2\t300 %9.4f\n" - "DistortionK3\t300 %9.4f\n" - "TexScale\t300 %9.4f", - SConfig.GetYFOVDegrees(), - SConfig.GetIPD(), - SConfig.GetDistortionK(0), - SConfig.GetDistortionK(1), - SConfig.GetDistortionK(2), - SConfig.GetDistortionK(3), - SConfig.GetDistortionScale()); - - DrawTextBox(pRender, 0.0f, 0.0f, textHeight, textBuff, DrawText_Center); - } + + case Text_Timing: + Profiler.DrawOverlay(pRender); break; - - case Text_Help: - DrawTextBox(pRender, 0.0f, -0.1f, textHeight, HelpText, DrawText_Center); - - default: + + case Text_Help1: + DrawTextBox(pRender, 0.0f, 0.0f, textHeight, HelpText1, DrawText_Center); + break; + case Text_Help2: + DrawTextBox(pRender, 0.0f, 0.0f, textHeight, HelpText2, DrawText_Center); + break; + + case Text_None: break; - } - - // Display colored quad if we're doing a latency test. - Color colorToDisplay; - if (LatencyUtil.DisplayScreenColor(colorToDisplay)) - { - pRender->FillRect(-0.4f, -0.4f, 0.4f, 0.4f, colorToDisplay); + default: + OVR_ASSERT ( !"Missing text screen" ); + break; } - - pRender->FinishScene(); } -// Sets temporarily displayed message for adjustments -void OculusWorldDemoApp::SetAdjustMessage(const char* format, ...) -{ - Lock::Locker lock(pManager->GetHandlerLock()); - char textBuff[2048]; - va_list argList; - va_start(argList, format); - OVR_vsprintf(textBuff, sizeof(textBuff), format, argList); - va_end(argList); - - // Message will time out in 4 seconds. - AdjustMessage = textBuff; - AdjustMessageTimeout = pPlatform->GetAppTime() + 4.0f; -} - -void OculusWorldDemoApp::SetAdjustMessageTimeout(float timeout) -{ - AdjustMessageTimeout = pPlatform->GetAppTime() + timeout; -} +//----------------------------------------------------------------------------- +// ***** Callbacks For Menu changes -// ***** View Control Adjustments +// Non-trivial callback go here. -void OculusWorldDemoApp::AdjustFov(float dt) +void OculusWorldDemoApp::HmdSettingChangeFreeRTs(OptionVar*) { - float esd = SConfig.GetEyeToScreenDistance() + 0.01f * dt; - SConfig.SetEyeToScreenDistance(esd); - SetAdjustMessage("ESD:%6.3f FOV: %6.3f", esd, SConfig.GetYFOVDegrees()); + HmdSettingsChanged = true; + // Cause the RTs to be recreated with the new mode. + for ( int rtNum = 0; rtNum < Rendertarget_LAST; rtNum++ ) + RenderTargets[rtNum].pTex = NULL; } -void OculusWorldDemoApp::AdjustAspect(float dt) +void OculusWorldDemoApp::MultisampleChange(OptionVar*) { - float rawAspect = SConfig.GetAspect() / SConfig.GetAspectMultiplier(); - float newAspect = SConfig.GetAspect() + 0.01f * dt; - SConfig.SetAspectMultiplier(newAspect / rawAspect); - SetAdjustMessage("Aspect: %6.3f", newAspect); + HmdSettingChangeFreeRTs(); } -void OculusWorldDemoApp::AdjustDistortion(float dt, int kIndex, const char* label) +void OculusWorldDemoApp::CenterPupilDepthChange(OptionVar*) { - SConfig.SetDistortionK(kIndex, SConfig.GetDistortionK(kIndex) + 0.03f * dt); - SetAdjustMessage("%s: %6.4f", label, SConfig.GetDistortionK(kIndex)); + ovrHmd_SetFloat(Hmd, "CenterPupilDepth", CenterPupilDepthMeters); } -void OculusWorldDemoApp::AdjustIPD(float dt) +void OculusWorldDemoApp::DistortionClearColorChange(OptionVar*) { - SConfig.SetIPD(SConfig.GetIPD() + 0.025f * dt); - SetAdjustMessage("EyeDistance: %6.4f", SConfig.GetIPD()); + float clearColor[2][4] = { { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.5f, 1.0f, 0.0f } }; + ovrHmd_SetFloatArray(Hmd, "DistortionClearColor", + clearColor[(int)DistortionClearBlue], 4); } -void OculusWorldDemoApp::AdjustEyeHeight(float dt) -{ - float dist = 0.5f * dt; - - ThePlayer.UserEyeHeight += dist; - ThePlayer.EyePos.y += dist; - SetAdjustMessage("UserEyeHeight: %4.2f", ThePlayer.UserEyeHeight); -} +//----------------------------------------------------------------------------- -void OculusWorldDemoApp::AdjustMotionPrediction(float dt) +void OculusWorldDemoApp::ProcessDeviceNotificationQueue() { - float motionPred = SFusion.GetPredictionDelta() + 0.01f * dt; - - if (motionPred < 0.0f) - { - motionPred = 0.0f; - } - - SFusion.SetPrediction(motionPred); - - SetAdjustMessage("MotionPrediction: %6.3fs", motionPred); + // TBD: Process device plug & Unplug } -void OculusWorldDemoApp::AdjustDistortion(float val, int kIndex) -{ - SConfig.SetDistortionK(kIndex, val); - SetAdjustMessage("K%d: %6.4f", kIndex, SConfig.GetDistortionK(kIndex)); -} -void OculusWorldDemoApp::AdjustEsd(float val) +//----------------------------------------------------------------------------- +void OculusWorldDemoApp::ChangeDisplay ( bool bBackToWindowed, bool bNextFullscreen, + bool bFullWindowDebugging ) { - SConfig.SetEyeToScreenDistance(val); - float esd = SConfig.GetEyeToScreenDistance(); - SetAdjustMessage("ESD:%6.3f FOV: %6.3f", esd, SConfig.GetYFOVDegrees()); -} + // Exactly one should be set... + OVR_ASSERT ( ( bBackToWindowed ? 1 : 0 ) + ( bNextFullscreen ? 1 : 0 ) + + ( bFullWindowDebugging ? 1 : 0 ) == 1 ); + OVR_UNUSED ( bNextFullscreen ); -// Loads the scene data -void OculusWorldDemoApp::PopulateScene(const char *fileName) -{ - XmlHandler xmlHandler; - if(!xmlHandler.ReadFile(fileName, pRender, &MainScene, &CollisionModels, &GroundCollisionModels)) + if ( bFullWindowDebugging ) { - SetAdjustMessage("---------------------------------\nFILE LOAD FAILED\n---------------------------------"); - SetAdjustMessageTimeout(10.0f); - } - - MainScene.SetAmbient(Vector4f(1.0f, 1.0f, 1.0f, 1.0f)); - - // Distortion debug grid (brought up by 'G' key). - Ptr<Model> gridModel = *Model::CreateGrid(Vector3f(0,0,0), Vector3f(1.0f/10, 0,0), Vector3f(0,1.0f/10,0), - 10, 10, 5, - Color(0, 255, 0, 255), Color(255, 50, 50, 255) ); - GridScene.World.Add(gridModel); - - // Yaw angle marker and lines (brought up by ';' key). - float shifty = -0.5f; - Ptr<Model> yawMarkGreenModel = *Model::CreateBox(Color(0, 255, 0, 255), Vector3f(0.0f, shifty, -2.0f), Vector3f(0.05f, 0.05f, 0.05f)); - YawMarkGreenScene.World.Add(yawMarkGreenModel); - Ptr<Model> yawMarkRedModel = *Model::CreateBox(Color(255, 0, 0, 255), Vector3f(0.0f, shifty, -2.0f), Vector3f(0.05f, 0.05f, 0.05f)); - YawMarkRedScene.World.Add(yawMarkRedModel); - - Ptr<Model> yawLinesModel = *new Model(); - Color c = Color(255, 200, 200, 255); - float r = 1.5f; - yawLinesModel->AddTriangle(yawLinesModel->AddVertex(Vector3f(-0.1f, 0, -r), c), - yawLinesModel->AddVertex(Vector3f(0, 0, -r-0.2f), c), - yawLinesModel->AddVertex(Vector3f(0.1f, 0, -r), c)); - yawLinesModel->AddTriangle(yawLinesModel->AddVertex(Vector3f(-r-0.1f, 0, -r), c), - yawLinesModel->AddVertex(Vector3f(-r, 0, -r-0.2f), c), - yawLinesModel->AddVertex(Vector3f(-r+0.1f, 0, -r), c)); - yawLinesModel->AddTriangle(yawLinesModel->AddVertex(Vector3f(r-0.1f, 0, -r), c), - yawLinesModel->AddVertex(Vector3f(r, 0, -r-0.2f), c), - yawLinesModel->AddVertex(Vector3f(r+0.1f, 0, -r), c)); - yawLinesModel->SetPosition(Vector3f(0.0f,-1.2f,0.0f)); - YawLinesScene.World.Add(yawLinesModel); -} - - -void OculusWorldDemoApp::PopulatePreloadScene() -{ - // Load-screen screen shot image - String fileName = MainFilePath; - fileName.StripExtension(); - - Ptr<File> imageFile = *new SysFile(fileName + "_LoadScreen.tga"); - Ptr<Texture> imageTex; - if (imageFile->IsValid()) - imageTex = *LoadTextureTga(pRender, imageFile); + // Slightly hacky. Doesn't actually go fullscreen, just makes a screen-sized wndow. + // This has higher latency than fullscreen, and is not intended for actual use, + // but makes for much nicer debugging on some systems. + RenderParams = pRender->GetParams(); + RenderParams.Display = DisplayId(HmdDesc.DisplayDeviceName, HmdDesc.DisplayId); + pRender->SetParams(RenderParams); - // Image is rendered as a single quad. - if (imageTex) - { - imageTex->SetSampleMode(Sample_Anisotropic|Sample_Repeat); - Ptr<Model> m = *new Model(Prim_Triangles); - m->AddVertex(-0.5f, 0.5f, 0.0f, Color(255,255,255,255), 0.0f, 0.0f); - m->AddVertex( 0.5f, 0.5f, 0.0f, Color(255,255,255,255), 1.0f, 0.0f); - m->AddVertex( 0.5f, -0.5f, 0.0f, Color(255,255,255,255), 1.0f, 1.0f); - m->AddVertex(-0.5f, -0.5f, 0.0f, Color(255,255,255,255), 0.0f, 1.0f); - m->AddTriangle(2,1,0); - m->AddTriangle(0,3,2); - - Ptr<ShaderFill> fill = *new ShaderFill(*pRender->CreateShaderSet()); - fill->GetShaders()->SetShader(pRender->LoadBuiltinShader(Shader_Vertex, VShader_MVP)); - fill->GetShaders()->SetShader(pRender->LoadBuiltinShader(Shader_Fragment, FShader_Texture)); - fill->SetTexture(0, imageTex); - m->Fill = fill; - - LoadingScene.World.Add(m); + pPlatform->SetMouseMode(Mouse_Normal); + pPlatform->SetFullscreen(RenderParams, pRender->IsFullscreen() ? Display_Window : Display_FakeFullscreen); + pPlatform->SetMouseMode(Mouse_Relative); // Avoid mode world rotation jump. + + // If using an HMD, enable post-process (for distortion) and stereo. + if (RenderParams.IsDisplaySet() && pRender->IsFullscreen()) + { + //SetPostProcessingMode ( PostProcess ); + } } -} - -void OculusWorldDemoApp::ClearScene() -{ - MainScene.Clear(); - GridScene.Clear(); - YawMarkGreenScene.Clear(); - YawMarkRedScene.Clear(); - YawLinesScene.Clear(); -} - -void OculusWorldDemoApp::PopulateLODFileNames() -{ - //OVR::String mainFilePath = MainFilePath; - LODFilePaths.PushBack(MainFilePath); - int LODIndex = 1; - SPInt pos = strcspn(MainFilePath.ToCStr(), "."); - SPInt len = strlen(MainFilePath.ToCStr()); - SPInt diff = len - pos; - - if (diff == 0) - return; - - while(true) + else { - char pathWithoutExt[250]; - char buffer[250]; - for(SPInt i = 0; i < pos; ++i) + int screenCount = pPlatform->GetDisplayCount(); + + int screenNumberToSwitchTo; + if ( bBackToWindowed ) { - pathWithoutExt[i] = MainFilePath[(int)i]; + screenNumberToSwitchTo = -1; } - pathWithoutExt[pos] = '\0'; - OVR_sprintf(buffer, sizeof(buffer), "%s%i.xml", pathWithoutExt, LODIndex); - FILE* fp = 0; -#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) - errno_t err = fopen_s(&fp, buffer, "rb"); - if(!fp || err) + else { -#else - fp = fopen(buffer, "rb"); - if(!fp) - { -#endif - break; + if (!pRender->IsFullscreen()) + { + // Currently windowed. + // Try to find HMD Screen, making it the first screen in the full-screen cycle. + FirstScreenInCycle = 0; + if (!UsingDebugHmd) + { + DisplayId HMD (HmdDesc.DisplayDeviceName, HmdDesc.DisplayId); + for (int i = 0; i< screenCount; i++) + { + if (pPlatform->GetDisplay(i) == HMD) + { + FirstScreenInCycle = i; + break; + } + } + } + ScreenNumber = FirstScreenInCycle; + screenNumberToSwitchTo = ScreenNumber; + } + else + { + // Currently fullscreen, so cycle to the next screen. + ScreenNumber++; + if (ScreenNumber == screenCount) + { + ScreenNumber = 0; + } + screenNumberToSwitchTo = ScreenNumber; + if (ScreenNumber == FirstScreenInCycle) + { + // We have cycled through all the fullscreen displays, so go back to windowed mode. + screenNumberToSwitchTo = -1; + } + } } - fclose(fp); - OVR::String result = buffer; - LODFilePaths.PushBack(result); - LODIndex++; - } -} - -void OculusWorldDemoApp::DropLOD() -{ - if(CurrentLODFileIndex < (int)(LODFilePaths.GetSize() - 1)) - { - ClearScene(); - CurrentLODFileIndex++; - PopulateScene(LODFilePaths[CurrentLODFileIndex].ToCStr()); - } -} -void OculusWorldDemoApp::RaiseLOD() -{ - if(CurrentLODFileIndex > 0) - { - ClearScene(); - CurrentLODFileIndex--; - PopulateScene(LODFilePaths[CurrentLODFileIndex].ToCStr()); - } -} - -//----------------------------------------------------------------------------- -void OculusWorldDemoApp::CycleDisplay() -{ - int screenCount = pPlatform->GetDisplayCount(); - - // If Windowed, switch to the HMD screen first in Full-Screen Mode. - // If already Full-Screen, cycle to next screen until we reach FirstScreenInCycle. - - if (pRender->IsFullscreen()) - { - // Right now, we always need to restore window before going to next screen. + // Always restore windowed mode before going to next screen, even if we were already fullscreen. pPlatform->SetFullscreen(RenderParams, Display_Window); - - Screen++; - if (Screen == screenCount) - Screen = 0; - - RenderParams.Display = pPlatform->GetDisplay(Screen); - - if (Screen != FirstScreenInCycle) + if ( screenNumberToSwitchTo >= 0 ) { + // Go fullscreen. + RenderParams.Display = pPlatform->GetDisplay(screenNumberToSwitchTo); pRender->SetParams(RenderParams); - pPlatform->SetFullscreen(RenderParams, Display_Fullscreen); + pPlatform->SetFullscreen(RenderParams, Display_Fullscreen); } } - else - { - // Try to find HMD Screen, making it the first screen in full-screen Cycle. - FirstScreenInCycle = 0; - - if (pHMD) - { - DisplayId HMD (SConfig.GetHMDInfo().DisplayDeviceName, SConfig.GetHMDInfo().DisplayId); - for (int i = 0; i< screenCount; i++) - { - if (pPlatform->GetDisplay(i) == HMD) - { - FirstScreenInCycle = i; - break; - } - } - } - // Switch full-screen on the HMD. - Screen = FirstScreenInCycle; - RenderParams.Display = pPlatform->GetDisplay(Screen); - pRender->SetParams(RenderParams); - pPlatform->SetFullscreen(RenderParams, Display_Fullscreen); - } + + // Updates render target pointers & sizes. + HmdSettingChangeFreeRTs(); } void OculusWorldDemoApp::GamepadStateChanged(const GamepadState& pad) @@ -1764,6 +1271,15 @@ void OculusWorldDemoApp::GamepadStateChanged(const GamepadState& pad) 0, pad.LY * pad.LY * (pad.LY > 0 ? -1 : 1)); ThePlayer.GamepadRotate = Vector3f(2 * pad.RX, -2 * pad.RY, 0); + + UInt32 gamepadDeltas = (pad.Buttons ^ LastGamepadState.Buttons) & pad.Buttons; + + if (gamepadDeltas) + { + Menu.OnGamepad(gamepadDeltas); + } + + LastGamepadState = pad; } diff --git a/Samples/OculusWorldDemo/OculusWorldDemo.h b/Samples/OculusWorldDemo/OculusWorldDemo.h new file mode 100644 index 0000000..54f0e9d --- /dev/null +++ b/Samples/OculusWorldDemo/OculusWorldDemo.h @@ -0,0 +1,339 @@ +/************************************************************************************ + +Filename : OculusWorldDemo.h +Content : First-person view test application for Oculus Rift - Header file +Created : October 4, 2012 +Authors : Michael Antonov, Andrew Reisse, Steve LaValle, Dov Katz + Peter Hoff, Dan Goodman, Bryan Croteau + +Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#ifndef INC_OculusWorldDemo_h +#define INC_OculusWorldDemo_h + +#include "OVR.h" + +#include "../CommonSrc/Platform/Platform_Default.h" +#include "../CommonSrc/Render/Render_Device.h" +#include "../CommonSrc/Render/Render_XmlSceneLoader.h" +#include "../CommonSrc/Platform/Gamepad.h" + +#include "Util/Util_Render_Stereo.h" +using namespace OVR::Util::Render; + +#include <Kernel/OVR_SysFile.h> +#include <Kernel/OVR_Log.h> +#include <Kernel/OVR_Timer.h> + +#include "Player.h" +#include "OVR_DeviceConstants.h" + +#include "OptionMenu.h" +#include "RenderProfiler.h" + +// Filename to be loaded by default, searching specified paths. +#define WORLDDEMO_ASSET_FILE "Tuscany.xml" + +#define WORLDDEMO_ASSET_PATH1 "Assets/Tuscany/" +#define WORLDDEMO_ASSET_PATH2 "../../../Assets/Tuscany/" +// This path allows the shortcut to work. +#define WORLDDEMO_ASSET_PATH3 "Samples/OculusWorldDemo/Assets/Tuscany/" + +using namespace OVR; +using namespace OVR::Platform; +using namespace OVR::Render; + + +//------------------------------------------------------------------------------------- +// ***** OculusWorldDemo Description + +// This app renders a loaded scene allowing the user to move along the +// floor and look around with an HMD, mouse and keyboard. The following keys work: +// +// 'W', 'S', 'A', 'D' and Arrow Keys - Move forward, back; strafe left/right. +// +// Space - Bring up status and help display. +// Tab - Bring up/hide menu with editable options. +// F4 - Toggle MSAA. +// F9 - Cycle through fullscreen and windowed modes. +// Necessary for previewing content with Rift. +// +// Important Oculus-specific logic can be found at following locations: +// +// OculusWorldDemoApp::OnStartup - This function will initialize the SDK, creating the Hmd +// and delegating to CalculateHmdValues to initialize it. +// +// OculusWorldDemoApp::OnIdle - Here we poll SensorFusion for orientation, apply it +// to the scene and handle movement. +// Stereo rendering is also done here, by delegating to +// to the RenderEyeView() function for each eye. +// + +//------------------------------------------------------------------------------------- +// ***** OculusWorldDemo Application class + +// An instance of this class is created on application startup (main/WinMain). +// It then works as follows: +// - Graphics and HMD setup is done OculusWorldDemoApp::OnStartup(). Much of +// HMD configuration here is moved to CalculateHmdValues. +// OnStartup also creates the room model from Slab declarations. +// +// - Per-frame processing is done in OnIdle(). This function processes +// sensor and movement input and then renders the frame. +// +// - Additional input processing is done in OnMouse, OnKey. + +class OculusWorldDemoApp : public Application +{ +public: + OculusWorldDemoApp(); + ~OculusWorldDemoApp(); + + virtual int OnStartup(int argc, const char** argv); + virtual void OnIdle(); + + virtual void OnMouseMove(int x, int y, int modifiers); + virtual void OnKey(OVR::KeyCode key, int chr, bool down, int modifiers); + virtual void OnResize(int width, int height); + + bool SetupWindowAndRendering(int argc, const char** argv); + + // Adds room model to scene. + void InitMainFilePath(); + void PopulateScene(const char* fileName); + void PopulatePreloadScene(); + void ClearScene(); + void PopulateOptionMenu(); + + + // Computes all of the Hmd values and configures render targets. + void CalculateHmdValues(); + // Returns the actual size present. + Sizei EnsureRendertargetAtLeastThisBig (int rtNum, Sizei size); + + + // Renders full stereo scene for one eye. + void RenderEyeView(ovrEyeType eye); + // Renderes HUD overlay brough up by spacebar; 2D viewport must be set before call. + void RenderTextInfoHud(float textHeight); + void RenderAnimatedBlocks(ovrEyeType eye, double appTime); + void RenderGrid(ovrEyeType eye); + + Matrix4f CalculateViewFromPose(const Posef& pose); + + // Determine whether this frame needs rendering based on timewarp timing and flags. + bool FrameNeedsRendering(double curtime); + void ApplyDynamicResolutionScaling(); + void UpdateFrameRateCounter(double curtime); + + + // Model creation and misc functions. + Model* CreateModel(Vector3f pos, struct SlabModel* sm); + Model* CreateBoundingModel(CollisionModel &cm); + void ChangeDisplay ( bool bBackToWindowed, bool bNextFullscreen, bool bFullWindowDebugging ); + void GamepadStateChanged(const GamepadState& pad); + + // Processes DeviceNotificationStatus queue to handles plug/unplug. + void ProcessDeviceNotificationQueue(); + + + // ***** Callbacks for Menu option changes + + // These contain extra actions to be taken in addition to switching the state. + void HmdSettingChange(OptionVar* = 0) { HmdSettingsChanged = true; } + void BlockShowChange(OptionVar* = 0) { BlocksCenter = ThePlayer.BodyPos; } + void EyeHeightChange(OptionVar* = 0) { ThePlayer.BodyPos.y = ThePlayer.UserEyeHeight; } + + void HmdSettingChangeFreeRTs(OptionVar* = 0); + void MultisampleChange(OptionVar* = 0); + void CenterPupilDepthChange(OptionVar* = 0); + void DistortionClearColorChange(OptionVar* = 0); + + +protected: + RenderDevice* pRender; + RendererParams RenderParams; + Sizei WindowSize; + int ScreenNumber; + int FirstScreenInCycle; + + struct RenderTarget + { + Ptr<Texture> pTex; + ovrTexture Tex; + }; + enum RendertargetsEnum + { + Rendertarget_Left, + Rendertarget_Right, + Rendertarget_BothEyes, // Used when both eyes are rendered to the same target. + Rendertarget_LAST + }; + RenderTarget RenderTargets[Rendertarget_LAST]; + + + // ***** Oculus HMD Variables + + ovrHmd Hmd; + ovrHmdDesc HmdDesc; + ovrEyeRenderDesc EyeRenderDesc[2]; + Matrix4f Projection[2]; // Projection matrix for eye. + Matrix4f OrthoProjection[2]; // Projection for 2D. + ovrTexture EyeTexture[2]; + // Sensor caps applied. + unsigned StartSensorCaps; + bool UsingDebugHmd; + + // Frame timing logic. + enum { SecondsOfFpsMeasurement = 1 }; + int FrameCounter; + double NextFPSUpdate; + float SecondsPerFrame; + float FPS; + double LastFpsUpdate; + + // Times a single frame. + double LastUpdate; + + // Loaded data. + String MainFilePath; + Array<Ptr<CollisionModel> > CollisionModels; + Array<Ptr<CollisionModel> > GroundCollisionModels; + + // Loading process displays screenshot in first frame + // and then proceeds to load until finished. + enum LoadingStateType + { + LoadingState_Frame0, + LoadingState_DoLoad, + LoadingState_Finished + } LoadingState; + + // Set when vision tracking is detected. + bool HaveVisionTracking; + + GamepadState LastGamepadState; + + Player ThePlayer; + Matrix4f View; + Scene MainScene; + Scene LoadingScene; + Scene SmallGreenCube; + + Scene OculusCubesScene; + Scene RedCubesScene; + Scene BlueCubesScene; + + // Last frame asn sensor data reported by BeginFrame(). + ovrFrameTiming HmdFrameTiming; + unsigned HmdStatus; + + + // ***** Modifiable Menu Options + + // This flag is set when HMD settings change, causing HMD to be re-initialized. + bool HmdSettingsChanged; + + // Render Target - affecting state. + bool RendertargetIsSharedByBothEyes; + bool DynamicRezScalingEnabled; + bool ForceZeroIpd; + float DesiredPixelDensity; + float FovSideTanMax; + float FovSideTanLimit; // Limit value for Fov. + // Time-warp. + bool TimewarpEnabled; + float TimewarpRenderIntervalInSeconds; + bool FreezeEyeUpdate; + bool FreezeEyeOneFrameRendered; + + // Other global settings. + float CenterPupilDepthMeters; + // float IPD; + bool ForceZeroHeadMovement; + bool VsyncEnabled; + bool MultisampleEnabled; + // DK2 only + bool IsLowPersistence; + bool DynamicPrediction; + bool PositionTrackingEnabled; + + // Support toggling background color for distortion so that we can see + // the effect on the periphery. + int DistortionClearBlue; + + // Stereo settings adjustment state. + bool ShiftDown; + bool CtrlDown; + + + // ***** Scene Rendering Modes + + enum SceneRenderMode + { + Scene_World, + Scene_Cubes, + Scene_OculusCubes + }; + SceneRenderMode SceneMode; + + enum GridDispayModeType + { + GridDisplay_None, + GridDisplay_GridOnly, + GridDisplay_GridAndScene + }; + GridDispayModeType GridDisplayMode; + + // What type of grid to display. + enum GridModeType + { + Grid_Rendertarget4, + Grid_Rendertarget16, + Grid_Lens, + Grid_Last + }; + GridModeType GridMode; + + // What help screen we display, brought up by 'Spacebar'. + enum TextScreen + { + Text_None, + Text_Info, + Text_Timing, + Text_Help1, + Text_Help2, + Text_Count + }; + TextScreen TextScreen; + + // Whether we are displaying animated blocks and what type. + int BlocksShowType; + Vector3f BlocksCenter; + + + // User configurable options, brought up by 'Tab' key. + // Also handles shortcuts and pop-up overlay messages. + OptionSelectionMenu Menu; + + // Profiler for rendering - displays timing stats. + RenderProfiler Profiler; +}; + + + +#endif // INC_OculusWorldDemo_h diff --git a/Samples/OculusWorldDemo/OculusWorldDemo_Msvc2010.vcxproj.filters b/Samples/OculusWorldDemo/OculusWorldDemo_Msvc2010.vcxproj.filters deleted file mode 100644 index e96dc9e..0000000 --- a/Samples/OculusWorldDemo/OculusWorldDemo_Msvc2010.vcxproj.filters +++ /dev/null @@ -1,89 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="CommonSrc"> - <UniqueIdentifier>{ba6e9e50-0655-4f12-a136-6d2a06015925}</UniqueIdentifier> - </Filter> - <Filter Include="CommonSrc\Platform"> - <UniqueIdentifier>{16e20d8b-eff7-454c-be85-02037c399e97}</UniqueIdentifier> - </Filter> - <Filter Include="CommonSrc\Render"> - <UniqueIdentifier>{1b6d51ae-a405-4f3d-be93-41a50db4f328}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\CommonSrc\Platform\Platform.cpp"> - <Filter>CommonSrc\Platform</Filter> - </ClCompile> - <ClCompile Include="..\CommonSrc\Platform\Win32_Platform.cpp"> - <Filter>CommonSrc\Platform</Filter> - </ClCompile> - <ClCompile Include="..\CommonSrc\Render\Render_Device.cpp"> - <Filter>CommonSrc\Render</Filter> - </ClCompile> - <ClCompile Include="..\CommonSrc\Render\Render_D3D1X_Device.cpp"> - <Filter>CommonSrc\Render</Filter> - </ClCompile> - <ClCompile Include="..\CommonSrc\Render\Render_D3D10_Device.cpp"> - <Filter>CommonSrc\Render</Filter> - </ClCompile> - <ClCompile Include="OculusWorldDemo.cpp" /> - <ClCompile Include="..\CommonSrc\Render\Render_D3D11_Device.cpp"> - <Filter>CommonSrc\Render</Filter> - </ClCompile> - <ClCompile Include="..\CommonSrc\Render\Render_LoadTextureTGA.cpp"> - <Filter>CommonSrc\Render</Filter> - </ClCompile> - <ClCompile Include="Player.cpp" /> - <ClCompile Include="..\..\3rdParty\TinyXml\tinyxml2.cpp" /> - <ClCompile Include="..\CommonSrc\Render\Render_LoadTextureDDS.cpp"> - <Filter>CommonSrc\Render</Filter> - </ClCompile> - <ClCompile Include="..\CommonSrc\Render\Render_XmlSceneLoader.cpp"> - <Filter>CommonSrc\Render</Filter> - </ClCompile> - <ClCompile Include="..\CommonSrc\Platform\Win32_Gamepad.cpp"> - <Filter>CommonSrc\Platform</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ClInclude Include="..\CommonSrc\Platform\Win32_Platform.h"> - <Filter>CommonSrc\Platform</Filter> - </ClInclude> - <ClInclude Include="..\CommonSrc\Platform\Platform.h"> - <Filter>CommonSrc\Platform</Filter> - </ClInclude> - <ClInclude Include="..\CommonSrc\Platform\Platform_Default.h"> - <Filter>CommonSrc\Platform</Filter> - </ClInclude> - <ClInclude Include="..\CommonSrc\Render\Render_Font.h"> - <Filter>CommonSrc\Render</Filter> - </ClInclude> - <ClInclude Include="..\CommonSrc\Render\Render_Device.h"> - <Filter>CommonSrc\Render</Filter> - </ClInclude> - <ClInclude Include="..\CommonSrc\Render\Render_D3D1X_Device.h"> - <Filter>CommonSrc\Render</Filter> - </ClInclude> - <ClInclude Include="..\CommonSrc\Render\Render_D3D10_Device.h"> - <Filter>CommonSrc\Render</Filter> - </ClInclude> - <ClInclude Include="..\CommonSrc\Render\Render_D3D11_Device.h"> - <Filter>CommonSrc\Render</Filter> - </ClInclude> - <ClInclude Include="Player.h" /> - <ClInclude Include="..\..\3rdParty\TinyXml\tinyxml2.h" /> - <ClInclude Include="..\CommonSrc\Render\Render_XmlSceneLoader.h"> - <Filter>CommonSrc\Render</Filter> - </ClInclude> - <ClInclude Include="..\CommonSrc\Platform\Gamepad.h"> - <Filter>CommonSrc\Platform</Filter> - </ClInclude> - <ClInclude Include="..\CommonSrc\Platform\Win32_Gamepad.h"> - <Filter>CommonSrc\Platform</Filter> - </ClInclude> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="OculusWorldDemo.rc" /> - </ItemGroup> -</Project>
\ No newline at end of file diff --git a/Samples/OculusWorldDemo/OculusWorldDemo_Scene.cpp b/Samples/OculusWorldDemo/OculusWorldDemo_Scene.cpp new file mode 100644 index 0000000..5dfe2d2 --- /dev/null +++ b/Samples/OculusWorldDemo/OculusWorldDemo_Scene.cpp @@ -0,0 +1,399 @@ +/************************************************************************************ + +Filename : OculusWorldDemo_Scene.cpp +Content : Logic for loading, and creating rendered scene components, + cube and grid overlays, etc. +Created : October 4, 2012 +Authors : Michael Antonov, Andrew Reisse, Steve LaValle, Dov Katz + Peter Hoff, Dan Goodman, Bryan Croteau + +Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#include "OculusWorldDemo.h" + + +//------------------------------------------------------------------------------------- +// ***** Scene Creation / Loading + +void OculusWorldDemoApp::InitMainFilePath() +{ + + MainFilePath = WORLDDEMO_ASSET_FILE; + + // Try to modify path for correctness in case specified file is not found. + if (!SysFile(MainFilePath).IsValid()) + { + String prefixPath1(pPlatform->GetContentDirectory() + "/" + WORLDDEMO_ASSET_PATH1), + prefixPath2(WORLDDEMO_ASSET_PATH2), + prefixPath3(WORLDDEMO_ASSET_PATH3); + if (SysFile(prefixPath1 + MainFilePath).IsValid()) + MainFilePath = prefixPath1 + MainFilePath; + else if (SysFile(prefixPath2 + MainFilePath).IsValid()) + MainFilePath = prefixPath2 + MainFilePath; + else if (SysFile(prefixPath3 + MainFilePath).IsValid()) + MainFilePath = prefixPath3 + MainFilePath; + } +} + +// Creates a grid of cubes. +void PopulateCubeFieldScene(Scene* scene, Fill* fill, + int cubeCountX, int cubeCountY, int cubeCountZ, Vector3f offset, + float cubeSpacing = 0.5f, float cubeSize = 0.1f) +{ + + Vector3f corner(-(((cubeCountX-1) * cubeSpacing) + cubeSize) * 0.5f, + -(((cubeCountY-1) * cubeSpacing) + cubeSize) * 0.5f, + -(((cubeCountZ-1) * cubeSpacing) + cubeSize) * 0.5f); + corner += offset; + + Vector3f pos = corner; + + for (int i = 0; i < cubeCountX; i++) + { + // Create a new model for each 'plane' of cubes so we don't exceed + // the vert size limit. + Ptr<Model> model = *new Model(); + scene->World.Add(model); + + if (fill) + model->Fill = fill; + + for (int j = 0; j < cubeCountY; j++) + { + for (int k = 0; k < cubeCountZ; k++) + { + model->AddBox(0xFFFFFFFF, pos, Vector3f(cubeSize, cubeSize, cubeSize)); + pos.z += cubeSpacing; + } + + pos.z = corner.z; + pos.y += cubeSpacing; + } + + pos.y = corner.y; + pos.x += cubeSpacing; + } +} + +Fill* CreateTexureFill(RenderDevice* prender, const String& filename) +{ + Ptr<File> imageFile = *new SysFile(filename); + Ptr<Texture> imageTex; + if (imageFile->IsValid()) + imageTex = *LoadTextureTga(prender, imageFile); + + // Image is rendered as a single quad. + ShaderFill* fill = 0; + if (imageTex) + { + imageTex->SetSampleMode(Sample_Anisotropic|Sample_Repeat); + fill = new ShaderFill(*prender->CreateShaderSet()); + fill->GetShaders()->SetShader(prender->LoadBuiltinShader(Shader_Vertex, VShader_MVP)); + fill->GetShaders()->SetShader(prender->LoadBuiltinShader(Shader_Fragment, FShader_Texture)); + fill->SetTexture(0, imageTex); + } + + return fill; +} + + +// Loads the scene data +void OculusWorldDemoApp::PopulateScene(const char *fileName) +{ + XmlHandler xmlHandler; + if(!xmlHandler.ReadFile(fileName, pRender, &MainScene, &CollisionModels, &GroundCollisionModels)) + { + Menu.SetPopupMessage("FILE LOAD FAILED"); + Menu.SetPopupTimeout(10.0f, true); + } + + MainScene.SetAmbient(Color4f(1.0f, 1.0f, 1.0f, 1.0f)); + + // Handy cube. + Ptr<Model> smallGreenCubeModel = *Model::CreateBox(Color(0, 255, 0, 255), Vector3f(0.0f, 0.0f, 0.0f), Vector3f(0.004f, 0.004f, 0.004f)); + SmallGreenCube.World.Add(smallGreenCubeModel); + + String mainFilePathNoExtension = MainFilePath; + mainFilePathNoExtension.StripExtension(); + + + // 10x10x10 cubes. + Ptr<Fill> fillR = *CreateTexureFill(pRender, mainFilePathNoExtension + "_redCube.tga"); + PopulateCubeFieldScene(&RedCubesScene, fillR.GetPtr(), 10, 10, 10, Vector3f(0.0f, 0.0f, 0.0f), 0.4f); + + // 10x10x10 cubes. + Ptr<Fill> fillB = *CreateTexureFill(pRender, mainFilePathNoExtension + "_blueCube.tga"); + PopulateCubeFieldScene(&BlueCubesScene, fillB.GetPtr(), 10, 10, 10, Vector3f(0.0f, 0.0f, 0.0f), 0.4f); + + // Anna: OculusWorldDemo/Assets/Tuscany/Tuscany_OculusCube.tga file needs to be added + Ptr<Fill> imageFill = *CreateTexureFill(pRender, mainFilePathNoExtension + "_OculusCube.tga"); + PopulateCubeFieldScene(&OculusCubesScene, imageFill.GetPtr(), 11, 4, 35, Vector3f(0.0f, 0.0f, -6.0f), 0.5f); + + + float r = 0.01f; + Ptr<Model> purpleCubesModel = *new Model(Prim_Triangles); + for (int i = 0; i < 10; i++) + for (int j = 0; j < 10; j++) + for (int k = 0; k < 10; k++) + purpleCubesModel->AddSolidColorBox(i*0.25f-1.25f-r,j*0.25f-1.25f-r,k*0.25f-1.25f-r, + i*0.25f-1.25f+r,j*0.25f-1.25f+r,k*0.25f-1.25f+r,0xFF9F009F); +} + + +void OculusWorldDemoApp::PopulatePreloadScene() +{ + // Load-screen screen shot image + String fileName = MainFilePath; + fileName.StripExtension(); + + Ptr<File> imageFile = *new SysFile(fileName + "_LoadScreen.tga"); + Ptr<Texture> imageTex; + if (imageFile->IsValid()) + imageTex = *LoadTextureTga(pRender, imageFile); + + // Image is rendered as a single quad. + if (imageTex) + { + imageTex->SetSampleMode(Sample_Anisotropic|Sample_Repeat); + Ptr<Model> m = *new Model(Prim_Triangles); + m->AddVertex(-0.5f, 0.5f, 0.0f, Color(255,255,255,255), 0.0f, 0.0f); + m->AddVertex( 0.5f, 0.5f, 0.0f, Color(255,255,255,255), 1.0f, 0.0f); + m->AddVertex( 0.5f, -0.5f, 0.0f, Color(255,255,255,255), 1.0f, 1.0f); + m->AddVertex(-0.5f, -0.5f, 0.0f, Color(255,255,255,255), 0.0f, 1.0f); + m->AddTriangle(2,1,0); + m->AddTriangle(0,3,2); + + Ptr<ShaderFill> fill = *new ShaderFill(*pRender->CreateShaderSet()); + fill->GetShaders()->SetShader(pRender->LoadBuiltinShader(Shader_Vertex, VShader_MVP)); + fill->GetShaders()->SetShader(pRender->LoadBuiltinShader(Shader_Fragment, FShader_Texture)); + fill->SetTexture(0, imageTex); + m->Fill = fill; + + LoadingScene.World.Add(m); + } +} + +void OculusWorldDemoApp::ClearScene() +{ + MainScene.Clear(); + SmallGreenCube.Clear(); +} + + +//------------------------------------------------------------------------------------- +// ***** Rendering Content + + +void OculusWorldDemoApp::RenderAnimatedBlocks(ovrEyeType eye, double appTime) +{ + Matrix4f viewAdjust = Matrix4f::Translation(Vector3f(EyeRenderDesc[eye].ViewAdjust)); + + switch ( BlocksShowType ) + { + case 0: + // No blocks; + break; + case 1: { + // Horizontal circle around your head. + int const numBlocks = 10; + float const radius = 1.0f; + Matrix4f scaleUp = Matrix4f::Scaling ( 20.0f ); + double scaledTime = appTime * 0.1; + float fracTime = (float)( scaledTime - floor ( scaledTime ) ); + + for ( int j = 0; j < 2; j++ ) + { + for ( int i = 0; i < numBlocks; i++ ) + { + float angle = ( ( (float)i / numBlocks ) + fracTime ) * ( Math<float>::Pi * 2.0f ); + Vector3f pos; + pos.x = BlocksCenter.x + radius * cosf ( angle ); + pos.y = BlocksCenter.y; + pos.z = BlocksCenter.z + radius * sinf ( angle ); + if ( j == 0 ) + { + pos.x = BlocksCenter.x - radius * cosf ( angle ); + pos.y = BlocksCenter.y - 0.5f; + } + Matrix4f mat = Matrix4f::Translation ( pos ); + SmallGreenCube.Render(pRender, viewAdjust * View * mat * scaleUp); + } + } + }break; + + case 2: { + // Vertical circle around your head. + int const numBlocks = 10; + float const radius = 1.0f; + Matrix4f scaleUp = Matrix4f::Scaling ( 20.0f ); + double scaledTime = appTime * 0.1; + float fracTime = (float)( scaledTime - floor ( scaledTime ) ); + + for ( int j = 0; j < 2; j++ ) + { + for ( int i = 0; i < numBlocks; i++ ) + { + float angle = ( ( (float)i / numBlocks ) + fracTime ) * ( Math<float>::Pi * 2.0f ); + Vector3f pos; + pos.x = BlocksCenter.x; + pos.y = BlocksCenter.y + radius * cosf ( angle ); + pos.z = BlocksCenter.z + radius * sinf ( angle ); + if ( j == 0 ) + { + pos.x = BlocksCenter.x - 0.5f; + pos.y = BlocksCenter.y - radius * cosf ( angle ); + } + Matrix4f mat = Matrix4f::Translation ( pos ); + SmallGreenCube.Render(pRender, viewAdjust * View * mat * scaleUp); + } + } + }break; + + case 3:{ + // Bouncing. + int const numBlocks = 10; + Matrix4f scaleUp = Matrix4f::Scaling ( 20.0f ); + + for ( int i = 0; i < numBlocks; i++ ) + { + double scaledTime = 4.0f * appTime / (double)i; + float fracTime = (float)( scaledTime - floor ( scaledTime ) ); + + Vector3f pos = BlocksCenter; + pos.z += (float)i; + pos.y += -1.5f + 4.0f * ( 2.0f * fracTime * ( 1.0f - fracTime ) ); + Matrix4f mat = Matrix4f::Translation ( pos ); + SmallGreenCube.Render(pRender, viewAdjust * View * mat * scaleUp); + } + }break; + + default: + BlocksShowType = 0; + break; + } +} + +void OculusWorldDemoApp::RenderGrid(ovrEyeType eye) +{ + Recti renderViewport = EyeTexture[eye].Header.RenderViewport; + + // Draw actual pixel grid on the RT. + // 1:1 mapping to screen pixels, origin in top-left. + Matrix4f ortho; + ortho.SetIdentity(); + ortho.M[0][0] = 2.0f / (renderViewport.w); // X scale + ortho.M[0][3] = -1.0f; // X offset + ortho.M[1][1] = -2.0f / (renderViewport.h); // Y scale (for Y=down) + ortho.M[1][3] = 1.0f; // Y offset (Y=down) + ortho.M[2][2] = 0; + pRender->SetProjection(ortho); + + pRender->SetDepthMode(false, false); + Color cNormal ( 255, 0, 0 ); + Color cSpacer ( 255, 255, 0 ); + Color cMid ( 0, 128, 255 ); + + int lineStep = 1; + int midX = 0; + int midY = 0; + int limitX = 0; + int limitY = 0; + + switch ( GridMode ) + { + case Grid_Rendertarget4: + lineStep = 4; + midX = renderViewport.w / 2; + midY = renderViewport.h / 2; + limitX = renderViewport.w / 2; + limitY = renderViewport.h / 2; + break; + case Grid_Rendertarget16: + lineStep = 16; + midX = renderViewport.w / 2; + midY = renderViewport.h / 2; + limitX = renderViewport.w / 2; + limitY = renderViewport.h / 2; + break; + case Grid_Lens: + { + lineStep = 48; + Vector2f rendertargetNDC = FovPort(EyeRenderDesc[eye].Desc.Fov).TanAngleToRendertargetNDC(Vector2f(0.0f)); + midX = (int)( ( rendertargetNDC.x * 0.5f + 0.5f ) * (float)renderViewport.w + 0.5f ); + midY = (int)( ( rendertargetNDC.y * 0.5f + 0.5f ) * (float)renderViewport.h + 0.5f ); + limitX = Alg::Max ( renderViewport.w - midX, midX ); + limitY = Alg::Max ( renderViewport.h - midY, midY ); + } + break; + default: OVR_ASSERT ( false ); break; + } + + int spacerMask = (lineStep<<2)-1; + + + for ( int xp = 0; xp < limitX; xp += lineStep ) + { + float x[4]; + float y[4]; + x[0] = (float)( midX + xp ); + y[0] = (float)0; + x[1] = (float)( midX + xp ); + y[1] = (float)renderViewport.h; + x[2] = (float)( midX - xp ); + y[2] = (float)0; + x[3] = (float)( midX - xp ); + y[3] = (float)renderViewport.h; + if ( xp == 0 ) + { + pRender->RenderLines ( 1, cMid, x, y ); + } + else if ( ( xp & spacerMask ) == 0 ) + { + pRender->RenderLines ( 2, cSpacer, x, y ); + } + else + { + pRender->RenderLines ( 2, cNormal, x, y ); + } + } + for ( int yp = 0; yp < limitY; yp += lineStep ) + { + float x[4]; + float y[4]; + x[0] = (float)0; + y[0] = (float)( midY + yp ); + x[1] = (float)renderViewport.w; + y[1] = (float)( midY + yp ); + x[2] = (float)0; + y[2] = (float)( midY - yp ); + x[3] = (float)renderViewport.w; + y[3] = (float)( midY - yp ); + if ( yp == 0 ) + { + pRender->RenderLines ( 1, cMid, x, y ); + } + else if ( ( yp & spacerMask ) == 0 ) + { + pRender->RenderLines ( 2, cSpacer, x, y ); + } + else + { + pRender->RenderLines ( 2, cNormal, x, y ); + } + } +} + diff --git a/Samples/OculusWorldDemo/OptionMenu.cpp b/Samples/OculusWorldDemo/OptionMenu.cpp new file mode 100644 index 0000000..283136d --- /dev/null +++ b/Samples/OculusWorldDemo/OptionMenu.cpp @@ -0,0 +1,896 @@ +/************************************************************************************ + +Filename : OptionMenu.h +Content : Option selection and editing for OculusWorldDemo +Created : March 7, 2014 +Authors : Michael Antonov, Caleb Leak + +Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#include "OptionMenu.h" + +// Embed the font. +#include "../CommonSrc/Render/Render_FontEmbed_DejaVu48.h" + + +//------------------------------------------------------------------------------------- +bool OptionShortcut::MatchKey(KeyCode key, bool shift) const +{ + for (UInt32 i = 0; i < Keys.GetSize(); i++) + { + if (Keys[i].Key != key) + continue; + + if (!shift && Keys[i].ShiftUsage == ShortcutKey::Shift_RequireOn) + continue; + + if (shift && Keys[i].ShiftUsage == ShortcutKey::Shift_RequireOff) + continue; + + if(Keys[i].ShiftUsage == ShortcutKey::Shift_Modify) + { + pNotify->CallNotify(&shift); + } + else + { + pNotify->CallNotify(); + } + return true; + } + return false; +} + +bool OptionShortcut::MatchGamepadButton(UInt32 gamepadButtonMask) const +{ + for (UInt32 i = 0; i < GamepadButtons.GetSize(); i++) + { + if (GamepadButtons[i] & gamepadButtonMask) + { + if (pNotify != NULL) + { + pNotify->CallNotify(); + } + return true; + } + } + return false; +} + + +//------------------------------------------------------------------------------------- +String OptionMenuItem::PopNamespaceFrom(OptionMenuItem* menuItem) +{ + String label = menuItem->Label; + for (UInt32 i = 0; i < label.GetLength(); i++) + { + if (label.GetCharAt(i) == '.') + { + String ns = label.Substring(0, i); + menuItem->Label = label.Substring(i + 1, label.GetLength()); + return ns; + } + } + return ""; +} + +//------------------------------------------------------------------------------------- + +String OptionVar::FormatEnum(OptionVar* var) +{ + UInt32 index = var->GetEnumIndex(); + if (index < var->EnumValues.GetSize()) + return var->EnumValues[index].Name; + return String("<Bad enum index>"); +} + +String OptionVar::FormatInt(OptionVar* var) +{ + char buff[64]; + OVR_sprintf(buff, sizeof(buff), var->FormatString, *var->AsInt()); + return String(buff); +} + +String OptionVar::FormatFloat(OptionVar* var) +{ + char buff[64]; + OVR_sprintf(buff, sizeof(buff), var->FormatString, *var->AsFloat() * var->FormatScale); + return String(buff); +} + +String OptionVar::FormatBool(OptionVar* var) +{ + return *var->AsBool() ? "On" : "Off"; +} + + +OptionVar::OptionVar(const char* name, void* pvar, VarType type, + FormatFunction formatFunction, + UpdateFunction updateFunction) +{ + Label = name; + Type = type; + this->pVar = pvar; + fFormat = formatFunction; + fUpdate = updateFunction; + pNotify = 0; + FormatString= 0; + + MaxFloat = Math<float>::MaxValue; + MinFloat = -Math<float>::MaxValue; + StepFloat = 1.0f; + FormatScale = 1.0f; + + MaxInt = 0x7FFFFFFF; + MinInt = -(MaxInt) - 1; + StepInt = 1; + + ShortcutUp.pNotify = new FunctionNotifyContext<OptionVar, bool>(this, &OptionVar::NextValue); + ShortcutDown.pNotify = new FunctionNotifyContext<OptionVar, bool>(this, &OptionVar::PrevValue); +} + +OptionVar::OptionVar(const char* name, SInt32* pvar, + SInt32 min, SInt32 max, SInt32 stepSize, + const char* formatString, + FormatFunction formatFunction, + UpdateFunction updateFunction) +{ + Label = name; + Type = Type_Int; + this->pVar = pvar; + fFormat = formatFunction ? formatFunction : FormatInt; + fUpdate = updateFunction; + pNotify = 0; + FormatString= formatString; + + MinInt = min; + MaxInt = max; + StepInt = stepSize; + + ShortcutUp.pNotify = new FunctionNotifyContext<OptionVar, bool>(this, &OptionVar::NextValue); + ShortcutDown.pNotify = new FunctionNotifyContext<OptionVar, bool>(this, &OptionVar::PrevValue); +} + +// Float with range and step size. +OptionVar::OptionVar(const char* name, float* pvar, + float minf, float maxf, float stepSize, + const char* formatString, float formatScale, + FormatFunction formatFunction, + UpdateFunction updateFunction) +{ + Label = name; + Type = Type_Float; + this->pVar = pvar; + fFormat = formatFunction ? formatFunction : FormatFloat; + fUpdate = updateFunction; + pNotify = 0; + FormatString= formatString ? formatString : "%.3f"; + + MinFloat = minf; + MaxFloat = maxf; + StepFloat = stepSize; + FormatScale = formatScale; + + ShortcutUp.pNotify = new FunctionNotifyContext<OptionVar, bool>(this, &OptionVar::NextValue); + ShortcutDown.pNotify = new FunctionNotifyContext<OptionVar, bool>(this, &OptionVar::PrevValue); +} + +OptionVar::~OptionVar() +{ + if (pNotify) + delete pNotify; +} + +void OptionVar::NextValue(bool* pFastStep) +{ + bool fastStep = (pFastStep != NULL && *pFastStep); + switch (Type) + { + case Type_Enum: + *AsInt() = ((GetEnumIndex() + 1) % EnumValues.GetSize()); + break; + + case Type_Int: + *AsInt() = Alg::Min<SInt32>(*AsInt() + StepInt * (fastStep ? 5 : 1), MaxInt); + break; + + case Type_Float: + // TODO: Will behave strange with NaN values. + *AsFloat() = Alg::Min<float>(*AsFloat() + StepFloat * (fastStep ? 5.0f : 1.0f), MaxFloat); + break; + + case Type_Bool: + *AsBool() = !*AsBool(); + break; + } + + SignalUpdate(); +} + +void OptionVar::PrevValue(bool* pFastStep) +{ + bool fastStep = (pFastStep != NULL && *pFastStep); + switch (Type) + { + case Type_Enum: + *AsInt() = ((GetEnumIndex() + (UInt32)EnumValues.GetSize() - 1) % EnumValues.GetSize()); + break; + + case Type_Int: + *AsInt() = Alg::Max<SInt32>(*AsInt() - StepInt * (fastStep ? 5 : 1), MinInt); + break; + + case Type_Float: + // TODO: Will behave strange with NaN values. + *AsFloat() = Alg::Max<float>(*AsFloat() - StepFloat * (fastStep ? 5.0f : 1.0f), MinFloat); + break; + + case Type_Bool: + *AsBool() = !*AsBool(); + break; + } + + SignalUpdate(); +} + +String OptionVar::HandleShortcutUpdate() +{ + SignalUpdate(); + return Label + " - " + GetValue(); +} + +String OptionVar::ProcessShortcutKey(KeyCode key, bool shift) +{ + if (ShortcutUp.MatchKey(key, shift) || ShortcutDown.MatchKey(key, shift)) + { + return HandleShortcutUpdate(); + } + + return String(); +} + +String OptionVar::ProcessShortcutButton(UInt32 buttonMask) +{ + if (ShortcutUp.MatchGamepadButton(buttonMask) || ShortcutDown.MatchGamepadButton(buttonMask)) + { + return HandleShortcutUpdate(); + } + return String(); +} + + +OptionVar& OptionVar::AddEnumValue(const char* displayName, SInt32 value) +{ + EnumEntry entry; + entry.Name = displayName; + entry.Value = value; + EnumValues.PushBack(entry); + return *this; +} + +String OptionVar::GetValue() +{ + return fFormat(this); +} + +UInt32 OptionVar::GetEnumIndex() +{ + OVR_ASSERT(Type == Type_Enum); + OVR_ASSERT(EnumValues.GetSize() > 0); + + // TODO: Change this from a linear search to binary or a hash. + for (UInt32 i = 0; i < EnumValues.GetSize(); i++) + { + if (EnumValues[i].Value == *AsInt()) + return i; + } + + // Enum values should always be found. + OVR_ASSERT(false); + return 0; +} + + +//------------------------------------------------------------------------------------- + +OptionSelectionMenu::OptionSelectionMenu(OptionSelectionMenu* parentMenu) +{ + DisplayState = Display_None; + SelectedIndex = 0; + SelectionActive = false; + ParentMenu = parentMenu; + + PopupMessageTimeout = 0.0; + PopupMessageBorder = false; + + // Setup handlers for menu navigation actions. + NavShortcuts[Nav_Up].pNotify = new FunctionNotifyContext<OptionSelectionMenu, bool>(this, &OptionSelectionMenu::HandleUp); + NavShortcuts[Nav_Down].pNotify = new FunctionNotifyContext<OptionSelectionMenu, bool>(this, &OptionSelectionMenu::HandleDown); + NavShortcuts[Nav_Left].pNotify = new FunctionNotifySimple<OptionSelectionMenu>(this, &OptionSelectionMenu::HandleLeft); + NavShortcuts[Nav_Right].pNotify = new FunctionNotifySimple<OptionSelectionMenu>(this, &OptionSelectionMenu::HandleRight); + NavShortcuts[Nav_Select].pNotify = new FunctionNotifySimple<OptionSelectionMenu>(this, &OptionSelectionMenu::HandleSelect); + NavShortcuts[Nav_Back].pNotify = new FunctionNotifySimple<OptionSelectionMenu>(this, &OptionSelectionMenu::HandleBack); + ToggleShortcut.pNotify = new FunctionNotifySimple<OptionSelectionMenu>(this, &OptionSelectionMenu::HandleMenuToggle); + ToggleSingleItemShortcut.pNotify = new FunctionNotifySimple<OptionSelectionMenu>(this, &OptionSelectionMenu::HandleSingleItemToggle); + + // Bind keys and buttons to menu navigation actions. + NavShortcuts[Nav_Up].AddShortcut(ShortcutKey(Key_Up, ShortcutKey::Shift_Modify)); + NavShortcuts[Nav_Up].AddShortcut(Gamepad_Up); + + NavShortcuts[Nav_Down].AddShortcut(ShortcutKey(Key_Down, ShortcutKey::Shift_Modify)); + NavShortcuts[Nav_Down].AddShortcut(Gamepad_Down); + + NavShortcuts[Nav_Left].AddShortcut(ShortcutKey(Key_Left)); + NavShortcuts[Nav_Left].AddShortcut(Gamepad_Left); + + NavShortcuts[Nav_Right].AddShortcut(ShortcutKey(Key_Right)); + NavShortcuts[Nav_Right].AddShortcut(Gamepad_Right); + + NavShortcuts[Nav_Select].AddShortcut(ShortcutKey(Key_Return)); + NavShortcuts[Nav_Select].AddShortcut(Gamepad_A); + + NavShortcuts[Nav_Back].AddShortcut(ShortcutKey(Key_Escape)); + NavShortcuts[Nav_Back].AddShortcut(Gamepad_B); + + ToggleShortcut.AddShortcut(ShortcutKey(Key_Tab, ShortcutKey::Shift_Ignore)); + ToggleShortcut.AddShortcut(Gamepad_Start); + + ToggleSingleItemShortcut.AddShortcut(ShortcutKey(Key_Backspace, ShortcutKey::Shift_Ignore)); +} + +OptionSelectionMenu::~OptionSelectionMenu() +{ + for (UInt32 i = 0; i < Items.GetSize(); i++) + delete Items[i]; +} + +bool OptionSelectionMenu::OnKey(OVR::KeyCode key, int chr, bool down, int modifiers) +{ + bool shift = ((modifiers & Mod_Shift) != 0); + + if (down) + { + String s = ProcessShortcutKey(key, shift); + if (!s.IsEmpty()) + { + PopupMessage = s; + PopupMessageTimeout = ovr_GetTimeInSeconds() + 4.0f; + PopupMessageBorder = false; + return true; + } + } + + if (GetSubmenu() != NULL) + { + return GetSubmenu()->OnKey(key, chr, down, modifiers); + } + + if (down) + { + if (ToggleShortcut.MatchKey(key, shift)) + return true; + + if (ToggleSingleItemShortcut.MatchKey(key, shift)) + return true; + + if (DisplayState == Display_None) + return false; + + for (int i = 0; i < Nav_LAST; i++) + { + if (NavShortcuts[i].MatchKey(key, shift)) + return true; + } + } + + // Let the caller process keystroke + return false; +} + +bool OptionSelectionMenu::OnGamepad(UInt32 buttonMask) +{ + // Check global shortcuts first. + String s = ProcessShortcutButton(buttonMask); + if (!s.IsEmpty()) + { + PopupMessage = s; + PopupMessageTimeout = ovr_GetTimeInSeconds() + 4.0f; + return true; + } + + if (GetSubmenu() != NULL) + { + return GetSubmenu()->OnGamepad(buttonMask); + } + + if (ToggleShortcut.MatchGamepadButton(buttonMask)) + return true; + + if (DisplayState == Display_None) + return false; + + for (int i = 0; i < Nav_LAST; i++) + { + if (NavShortcuts[i].MatchGamepadButton(buttonMask)) + return true; + } + + // Let the caller process keystroke + return false; +} + +String OptionSelectionMenu::ProcessShortcutKey(KeyCode key, bool shift) +{ + String s; + + for (UPInt i = 0; (i < Items.GetSize()) && s.IsEmpty(); i++) + { + s = Items[i]->ProcessShortcutKey(key, shift); + } + + return s; +} + +String OptionSelectionMenu::ProcessShortcutButton(UInt32 buttonMask) +{ + String s; + + for (UPInt i = 0; (i < Items.GetSize()) && s.IsEmpty(); i++) + { + s = Items[i]->ProcessShortcutButton(buttonMask); + } + + return s; +} + +// Fills in inclusive character range; returns false if line not found. +bool FindLineCharRange(const char* text, int searchLine, UPInt charRange[2]) +{ + UPInt i = 0; + + for (int line = 0; line <= searchLine; line ++) + { + if (line == searchLine) + { + charRange[0] = i; + } + + // Find end of line. + while (text[i] != '\n' && text[i] != 0) + { + i++; + } + + if (line == searchLine) + { + charRange[1] = (charRange[0] == i) ? charRange[0] : i-1; + return true; + } + + if (text[i] == 0) + break; + // Skip newline + i++; + } + + return false; +} + + +void OptionSelectionMenu::Render(RenderDevice* prender, String title) +{ + // If we are invisible, render shortcut notifications. + // Both child and parent have visible == true even if only child is shown. + if (DisplayState == Display_None) + { + renderShortcutChangeMessage(prender); + return; + } + + title += Label; + + // Delegate to sub-menu if active. + if (GetSubmenu() != NULL) + { + if (title.GetSize() > 0) + title += " > "; + + GetSubmenu()->Render(prender, title); + return; + } + + Color focusColor(180, 80, 20, 210); + Color pickedColor(120, 55, 10, 140); + Color titleColor(0x18, 0x1A, 0x4D, 210); + Color titleOutlineColor(0x18, 0x18, 0x18, 240); + + float labelsSize[2] = {0.0f, 0.0f}; + float bufferSize[2] = {0.0f, 0.0f}; + float valuesSize[2] = {0.0f, 0.0f}; + float maxValueWidth = 0.0f; + + UPInt selection[2] = { 0, 0 }; + Vector2f labelSelectionRect[2]; + Vector2f valueSelectionRect[2]; + bool havelLabelSelection = false; + bool haveValueSelection = false; + + float textSize = 22.0f; + prender->MeasureText(&DejaVu, " ", textSize, bufferSize); + + String values; + String menuItems; + + int highlightIndex = 0; + if (DisplayState == Display_Menu) + { + highlightIndex = SelectedIndex; + for (UInt32 i = 0; i < Items.GetSize(); i++) + { + if (i > 0) + values += "\n"; + values += Items[i]->GetValue(); + } + + for (UInt32 i = 0; i < Items.GetSize(); i++) + { + if (i > 0) + menuItems += "\n"; + menuItems += Items[i]->GetLabel(); + } + } + else + { + values = Items[SelectedIndex]->GetValue(); + menuItems = Items[SelectedIndex]->GetLabel(); + } + + // Measure labels + const char* menuItemsCStr = menuItems.ToCStr(); + havelLabelSelection = FindLineCharRange(menuItemsCStr, highlightIndex, selection); + prender->MeasureText(&DejaVu, menuItemsCStr, textSize, labelsSize, + selection, labelSelectionRect); + + // Measure label-to-value gap + const char* valuesCStr = values.ToCStr(); + haveValueSelection = FindLineCharRange(valuesCStr, highlightIndex, selection); + prender->MeasureText(&DejaVu, valuesCStr, textSize, valuesSize, selection, valueSelectionRect); + + // Measure max value size (absolute size varies, so just use a reasonable max) + maxValueWidth = prender->MeasureText(&DejaVu, "Max value width", textSize); + maxValueWidth = Alg::Max(maxValueWidth, valuesSize[0]); + + Vector2f borderSize(4.0f, 4.0f); + Vector2f totalDimensions = borderSize * 2 + Vector2f(bufferSize[0], 0) + Vector2f(maxValueWidth, 0) + + Vector2f(labelsSize[0], labelsSize[1]); + + Vector2f fudgeOffset= Vector2f(10.0f, 25.0f); // This offset looks better + Vector2f topLeft = (-totalDimensions / 2.0f) + fudgeOffset; + Vector2f bottomRight = topLeft + totalDimensions; + + // If displaying a single item, shift it down. + if (DisplayState == Display_SingleItem) + { + topLeft.y += textSize * 7; + bottomRight.y += textSize * 7; + } + + prender->FillRect(topLeft.x, topLeft.y, bottomRight.x, bottomRight.y, Color(40,40,100,210)); + + Vector2f labelsPos = topLeft + borderSize; + Vector2f valuesPos = labelsPos + Vector2f(labelsSize[0], 0) + Vector2f(bufferSize[0], 0); + + // Highlight selected label + Vector2f selectionInset = Vector2f(0.3f, 2.0f); + if (DisplayState == Display_Menu) + { + Vector2f labelSelectionTopLeft = labelsPos + labelSelectionRect[0] - selectionInset; + Vector2f labelSelectionBottomRight = labelsPos + labelSelectionRect[1] + selectionInset; + + prender->FillRect(labelSelectionTopLeft.x, labelSelectionTopLeft.y, + labelSelectionBottomRight.x, labelSelectionBottomRight.y, + SelectionActive ? pickedColor : focusColor); + } + + // Highlight selected value if active + if (SelectionActive) + { + Vector2f valueSelectionTopLeft = valuesPos + valueSelectionRect[0] - selectionInset; + Vector2f valueSelectionBottomRight = valuesPos + valueSelectionRect[1] + selectionInset; + prender->FillRect(valueSelectionTopLeft.x, valueSelectionTopLeft.y, + valueSelectionBottomRight.x, valueSelectionBottomRight.y, + focusColor); + } + + // Measure and draw title + if (DisplayState == Display_Menu && title.GetLength() > 0) + { + Vector2f titleDimensions; + prender->MeasureText(&DejaVu, title.ToCStr(), textSize, &titleDimensions.x); + Vector2f titleTopLeft = topLeft - Vector2f(0, borderSize.y) * 2 - Vector2f(0, titleDimensions.y); + titleDimensions.x = totalDimensions.x; + + prender->FillRect(titleTopLeft.x, titleTopLeft.y, + titleTopLeft.x + totalDimensions.x, + titleTopLeft.y + titleDimensions.y + borderSize.y * 2, + titleOutlineColor); + + prender->FillRect(titleTopLeft.x + borderSize.x / 2, titleTopLeft.y + borderSize.y / 2, + titleTopLeft.x + totalDimensions.x - borderSize.x / 2, + titleTopLeft.y + borderSize.y / 2 + titleDimensions.y, + titleColor); + + prender->RenderText(&DejaVu, title.ToCStr(), titleTopLeft.x + borderSize.x, + titleTopLeft.y + borderSize.y, textSize, Color(255,255,0,210)); + } + + prender->RenderText(&DejaVu, menuItemsCStr, labelsPos.x, labelsPos.y, textSize, Color(255,255,0,210)); + + prender->RenderText(&DejaVu, valuesCStr, valuesPos.x, valuesPos.y, textSize, Color(255,255,0,210)); +} + + +void OptionSelectionMenu::renderShortcutChangeMessage(RenderDevice* prender) +{ + if (ovr_GetTimeInSeconds() < PopupMessageTimeout) + { + DrawTextBox(prender, 0, 120, 22.0f, PopupMessage.ToCStr(), + DrawText_Center | (PopupMessageBorder ? DrawText_Border : 0)); + } +} + + +void OptionSelectionMenu::SetPopupMessage(const char* format, ...) +{ + //Lock::Locker lock(pManager->GetHandlerLock()); + char textBuff[2048]; + va_list argList; + va_start(argList, format); + OVR_vsprintf(textBuff, sizeof(textBuff), format, argList); + va_end(argList); + + // Message will time out in 4 seconds. + PopupMessage = textBuff; + PopupMessageTimeout = ovr_GetTimeInSeconds() + 4.0f; + PopupMessageBorder = false; +} + +void OptionSelectionMenu::SetPopupTimeout(double timeoutSeconds, bool border) +{ + PopupMessageTimeout = ovr_GetTimeInSeconds() + timeoutSeconds; + PopupMessageBorder = border; +} + + + +void OptionSelectionMenu::AddItem(OptionMenuItem* menuItem) +{ + String ns = PopNamespaceFrom(menuItem); + + if (ns.GetLength() == 0) + { + Items.PushBack(menuItem); + } + else + { + // Item is part of a submenu, add it to that instead. + GetOrCreateSubmenu(ns)->AddItem(menuItem); + } +} + +//virtual +void OptionSelectionMenu::Select() +{ + SelectedIndex = 0; + SelectionActive = false; + DisplayState = Display_Menu; +} + + +OptionSelectionMenu* OptionSelectionMenu::GetSubmenu() +{ + if (!SelectionActive) + return NULL; + + OptionSelectionMenu* submenu = dynamic_cast<OptionSelectionMenu*>(Items[SelectedIndex]); + return submenu; +} + + +OptionSelectionMenu* OptionSelectionMenu::GetOrCreateSubmenu(String submenuName) +{ + for (UInt32 i = 0; i < Items.GetSize(); i++) + { + OptionSelectionMenu* submenu = dynamic_cast<OptionSelectionMenu*>(Items[i]); + + if (submenu != NULL && submenu->Label == submenuName) + { + return submenu; + } + } + + // Submenu doesn't exist, create it. + OptionSelectionMenu* newSubmenu = new OptionSelectionMenu(this); + newSubmenu->Label = submenuName; + Items.PushBack(newSubmenu); + return newSubmenu; +} + +void OptionSelectionMenu::HandleUp(bool* pFast) +{ + int numItems = (int)Items.GetSize(); + if (SelectionActive) + Items[SelectedIndex]->NextValue(pFast); + else + SelectedIndex = ((SelectedIndex - 1 + numItems) % numItems); +} + +void OptionSelectionMenu::HandleDown(bool* pFast) +{ + if (SelectionActive) + Items[SelectedIndex]->PrevValue(pFast); + else + SelectedIndex = ((SelectedIndex + 1) % Items.GetSize()); +} + +void OptionSelectionMenu::HandleLeft() +{ + if (DisplayState != Display_Menu) + return; + + if (SelectionActive) + SelectionActive = false; + else if (ParentMenu) + { + // Escape to parent menu + ParentMenu->SelectionActive = false; + DisplayState = Display_Menu; + } +} + +void OptionSelectionMenu::HandleRight() +{ + if (DisplayState != Display_Menu) + return; + + if (!SelectionActive) + { + SelectionActive = true; + Items[SelectedIndex]->Select(); + } +} + +void OptionSelectionMenu::HandleSelect() +{ + if (!SelectionActive) + { + SelectionActive = true; + Items[SelectedIndex]->Select(); + } + else + { + Items[SelectedIndex]->NextValue(); + } +} + +void OptionSelectionMenu::HandleBack() +{ + if (DisplayState != Display_Menu) + return; + + if (!SelectionActive) + DisplayState = Display_None; + else + SelectionActive = false; +} + +void OptionSelectionMenu::HandleMenuToggle() +{ + // Mark this & parent With correct visibility. + OptionSelectionMenu* menu = this; + + if (DisplayState == Display_Menu) + DisplayState = Display_None; + else + DisplayState = Display_Menu; + + while (menu) + { + menu->DisplayState = DisplayState; + menu = menu->ParentMenu; + } + // Hide message + PopupMessageTimeout = 0; +} + +void OptionSelectionMenu::HandleSingleItemToggle() +{ + // Mark this & parent With correct visibility. + OptionSelectionMenu* menu = this; + + if (DisplayState == Display_SingleItem) + DisplayState = Display_None; + else + { + DisplayState = Display_SingleItem; + SelectionActive = true; + } + + while (menu) + { + menu->DisplayState = DisplayState; + menu = menu->ParentMenu; + } + // Hide message + PopupMessageTimeout = 0; +} + + +//------------------------------------------------------------------------------------- +// **** Text Rendering / Management + +void DrawTextBox(RenderDevice* prender, float x, float y, + float textSize, const char* text, unsigned centerType) +{ + float ssize[2] = {0.0f, 0.0f}; + + prender->MeasureText(&DejaVu, text, textSize, ssize); + + // Treat 0 a VCenter. + if (centerType & DrawText_HCenter) + { + x -= ssize[0]/2; + } + if (centerType & DrawText_VCenter) + { + y -= ssize[1]/2; + } + + const float borderSize = 4.0f; + float linesHeight = 0.0f; + + if (centerType & DrawText_Border) + linesHeight = 10.0f; + + prender->FillRect(x-borderSize, y-borderSize - linesHeight, + x+ssize[0]+borderSize, y+ssize[1]+borderSize + linesHeight, + Color(40,40,100,210)); + + if (centerType & DrawText_Border) + { + // Add top & bottom lines + float topLineY = y-borderSize - linesHeight * 0.5f, + bottomLineY = y+ssize[1]+borderSize + linesHeight * 0.5f; + + prender->FillRect(x-borderSize * 0.5f, topLineY, + x+ssize[0]+borderSize * 0.5f, topLineY + 2.0f, + Color(255,255,0,210)); + prender->FillRect(x-borderSize * 0.5f, bottomLineY, + x+ssize[0]+borderSize * 0.5f, bottomLineY + 2.0f, + Color(255,255,0,210)); + } + + prender->RenderText(&DejaVu, text, x, y, textSize, Color(255,255,0,210)); +} + +void CleanupDrawTextFont() +{ + if (DejaVu.fill) + { + DejaVu.fill->Release(); + DejaVu.fill = 0; + } +} diff --git a/Samples/OculusWorldDemo/OptionMenu.h b/Samples/OculusWorldDemo/OptionMenu.h new file mode 100644 index 0000000..ba90b08 --- /dev/null +++ b/Samples/OculusWorldDemo/OptionMenu.h @@ -0,0 +1,442 @@ +/************************************************************************************ + +Filename : OptionMenu.h +Content : Option selection and editing for OculusWorldDemo +Created : March 7, 2014 +Authors : Michael Antonov, Caleb Leak + +Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#ifndef INC_OptionMenu_h +#define INC_OptionMenu_h + +#include "OVR.h" + +#include "../CommonSrc/Platform/Platform_Default.h" +#include "../CommonSrc/Render/Render_Device.h" +#include "../CommonSrc/Platform/Gamepad.h" + +#include "Util/Util_Render_Stereo.h" +using namespace OVR::Util::Render; + +#include <Kernel/OVR_SysFile.h> +#include <Kernel/OVR_Log.h> +#include <Kernel/OVR_Timer.h> + +#include "Player.h" +#include "OVR_DeviceConstants.h" + + +using namespace OVR; +using namespace OVR::Platform; +using namespace OVR::Render; + + +//------------------------------------------------------------------------------------- +struct FunctionNotifyBase : public NewOverrideBase +{ + virtual void CallNotify(void*) { } + virtual void CallNotify() { } +}; + +// Simple member pointer wrapper to support calling class members +template<class C, class X> +struct FunctionNotifyContext : public FunctionNotifyBase +{ + typedef void (C::*FnPtr)(X*); + + FunctionNotifyContext(C* p, FnPtr fn) : pClass(p), pFn(fn), pContext(NULL) { } + FunctionNotifyContext(C* p, FnPtr fn, X* pContext) : pClass(p), pFn(fn), pContext(pContext) { } + virtual void CallNotify(void* var) { (void)(pClass->*pFn)(static_cast<X*>(var)); } + virtual void CallNotify() { (void)(pClass->*pFn)(pContext); } +private: + + X* pContext; + C* pClass; + FnPtr pFn; +}; + +template<class C> +struct FunctionNotifySimple : public FunctionNotifyBase +{ + typedef void (C::*FnPtr)(void); + + FunctionNotifySimple(C* p, FnPtr fn) : pClass(p), pFn(fn) { } + virtual void CallNotify(void*) { CallNotify(); } + virtual void CallNotify() { (void)(pClass->*pFn)(); } +private: + + C* pClass; + FnPtr pFn; +}; + + +//------------------------------------------------------------------------------------- +// Describes a shortcut key +struct ShortcutKey +{ + enum ShiftUsageType + { + Shift_Ignore, + Shift_Modify, + Shift_RequireOn, + Shift_RequireOff + }; + + ShortcutKey(KeyCode key = Key_None, ShiftUsageType shiftUsage = Shift_RequireOff) + : Key(key), ShiftUsage(shiftUsage) { } + + KeyCode Key; + ShiftUsageType ShiftUsage; +}; + + +//------------------------------------------------------------------------------------- +struct OptionShortcut +{ + Array<ShortcutKey> Keys; + Array<UInt32> GamepadButtons; + FunctionNotifyBase* pNotify; + + OptionShortcut() : pNotify(NULL) {} + OptionShortcut(FunctionNotifyBase* pNotify) : pNotify(pNotify) {} + ~OptionShortcut() { if (pNotify) delete pNotify; } + + void AddShortcut(ShortcutKey key) { Keys.PushBack(key); } + void AddShortcut(UInt32 gamepadButton) { GamepadButtons.PushBack(gamepadButton); } + + bool MatchKey(KeyCode key, bool shift) const; + bool MatchGamepadButton(UInt32 gamepadButtonMask) const; +}; + + +//------------------------------------------------------------------------------------- + +// Base class for a menu item. Internally, this can also be OptionSelectionMenu itself +// to support nested menus. Users shouldn't need to use this class. +class OptionMenuItem : public NewOverrideBase +{ +public: + virtual ~OptionMenuItem() { } + + virtual void Select() { } + + virtual void NextValue(bool* pFastStep = NULL) { OVR_UNUSED1(pFastStep); } + virtual void PrevValue(bool* pFastStep = NULL) { OVR_UNUSED1(pFastStep); } + + virtual String GetLabel() { return Label; } + virtual String GetValue() { return ""; } + + // Returns empty string if shortcut not handled + virtual String ProcessShortcutKey(KeyCode key, bool shift) = 0; + virtual String ProcessShortcutButton(UInt32 buttonMask) = 0; + +protected: + String Label; + String PopNamespaceFrom(OptionMenuItem* menuItem); +}; + + +//------------------------------------------------------------------------------------- + +// OptionVar implements a basic menu item, which binds to an external variable, +// displaying and editing its state. +class OptionVar : public OptionMenuItem +{ +public: + + enum VarType + { + Type_Enum, + Type_Int, + Type_Float, + Type_Bool + }; + + typedef String (*FormatFunction)(OptionVar*); + typedef void (*UpdateFunction)(OptionVar*); + + static String FormatEnum(OptionVar* var); + static String FormatInt(OptionVar* var); + static String FormatFloat(OptionVar* var); + static String FormatTan(OptionVar* var); + static String FormatBool(OptionVar* var); + + OptionVar(const char* name, void* pVar, VarType type, + FormatFunction formatFunction, + UpdateFunction updateFunction = NULL); + + // Integer with range and step size. + OptionVar(const char* name, SInt32* pVar, + SInt32 min, SInt32 max, SInt32 stepSize=1, + const char* formatString = "%d", + FormatFunction formatFunction = 0, // Default int formatting. + UpdateFunction updateFunction = NULL); + + // Float with range and step size. + OptionVar(const char* name, float* pvar, + float minf, float maxf, float stepSize = 1.0f, + const char* formatString = "%.3f", float formatScale = 1.0f, + FormatFunction formatFunction = 0, // Default float formatting. + UpdateFunction updateFunction = 0 ); + + virtual ~OptionVar(); + + SInt32* AsInt() { return reinterpret_cast<SInt32*>(pVar); } + bool* AsBool() { return reinterpret_cast<bool*>(pVar); } + float* AsFloat() { return reinterpret_cast<float*>(pVar); } + VarType GetType() { return Type; } + + // Step through values (wrap for enums). + virtual void NextValue(bool* pFastStep); + virtual void PrevValue(bool* pFastStep); + + // Executes shortcut message and returns notification string. + // Returns empty string for no action. + String HandleShortcutUpdate(); + virtual String ProcessShortcutKey(KeyCode key, bool shift); + virtual String ProcessShortcutButton(UInt32 buttonMask); + + OptionVar& AddEnumValue(const char* displayName, SInt32 value); + + template<class C> + OptionVar& SetNotify(C* p, void (C::*fn)(OptionVar*)) + { + OVR_ASSERT(pNotify == 0); // Can't set notifier twice. + pNotify = new FunctionNotifyContext<C, OptionVar>(p, fn, this); + return *this; + } + + + //String Format(); + virtual String GetValue(); + + OptionVar& AddShortcutUpKey(const ShortcutKey& shortcut) + { ShortcutUp.AddShortcut(shortcut); return *this; } + OptionVar& AddShortcutUpKey(KeyCode key, + ShortcutKey::ShiftUsageType shiftUsage = ShortcutKey::Shift_Modify) + { ShortcutUp.AddShortcut(ShortcutKey(key, shiftUsage)); return *this; } + OptionVar& AddShortcutUpButton(UInt32 gamepadButton) + { ShortcutUp.AddShortcut(gamepadButton); return *this; } + + OptionVar& AddShortcutDownKey(const ShortcutKey& shortcut) + { ShortcutDown.AddShortcut(shortcut); return *this; } + OptionVar& AddShortcutDownKey(KeyCode key, + ShortcutKey::ShiftUsageType shiftUsage = ShortcutKey::Shift_Modify) + { ShortcutDown.AddShortcut(ShortcutKey(key, shiftUsage)); return *this; } + OptionVar& AddShortcutDownButton(UInt32 gamepadButton) + { ShortcutDown.AddShortcut(gamepadButton); return *this; } + + OptionVar& AddShortcutKey(const ShortcutKey& shortcut) + { return AddShortcutUpKey(shortcut); } + OptionVar& AddShortcutKey(KeyCode key, + ShortcutKey::ShiftUsageType shiftUsage = ShortcutKey::Shift_RequireOff) + { return AddShortcutUpKey(key, shiftUsage); } + OptionVar& AddShortcutButton(UInt32 gamepadButton) + { return AddShortcutUpButton(gamepadButton); } + +private: + + void SignalUpdate() + { + if (fUpdate) fUpdate(this); + if (pNotify) pNotify->CallNotify(this); + } + + struct EnumEntry + { + // Human readable name for enum. + String Name; + SInt32 Value; + }; + + // Array of possible enum values. + Array<EnumEntry> EnumValues; + // Gets the index of the current enum value. + UInt32 GetEnumIndex(); + + FormatFunction fFormat; + UpdateFunction fUpdate; + FunctionNotifyBase* pNotify; + + VarType Type; + void* pVar; + const char* FormatString; + + OptionShortcut ShortcutUp; + OptionShortcut ShortcutDown; + + float MinFloat; + float MaxFloat; + float StepFloat; + float FormatScale; // Multiply float by this before rendering + + SInt32 MinInt; + SInt32 MaxInt; + SInt32 StepInt; +}; + + +//------------------------------------------------------------------------------------- +// ***** OptionSelectionMenu + +// Implements an overlay option menu, brought up by the 'Tab' key. +// Items are added to the menu with AddBool, AddEnum, AddFloat on startup, +// and are editable by using arrow keys (underlying variable is modified). +// +// Call Render() to render the menu every frame. +// +// Menu also support displaying popup messages with a timeout, displayed +// when menu body isn't up. + +class OptionSelectionMenu : public OptionMenuItem +{ +public: + OptionSelectionMenu(OptionSelectionMenu* parentMenu = NULL); + ~OptionSelectionMenu(); + + + bool OnKey(OVR::KeyCode key, int chr, bool down, int modifiers); + bool OnGamepad(UInt32 buttonMask); + + void Render(RenderDevice* prender, String title = ""); + + void AddItem(OptionMenuItem* menuItem); + + // Adds a boolean toggle. Returns added item to allow customization. + OptionVar& AddBool(const char* name, bool* pvar, + OptionVar::UpdateFunction updateFunction = 0, + OptionVar::FormatFunction formatFunction = OptionVar::FormatBool) + { + OptionVar* p = new OptionVar(name, pvar, OptionVar::Type_Bool, + formatFunction, updateFunction); + AddItem(p); + return *p; + } + + // Adds a boolean toggle. Returns added item to allow customization. + OptionVar& AddEnum(const char* name, void* pvar, + OptionVar::UpdateFunction updateFunction = 0) + { + OptionVar* p = new OptionVar(name, pvar, OptionVar::Type_Enum, + OptionVar::FormatEnum, updateFunction); + AddItem(p); + return *p; + } + + + // Adds a Float variable. Returns added item to allow customization. + OptionVar& AddFloat( const char* name, float* pvar, + float minf, float maxf, float stepSize = 1.0f, + const char* formatString = "%.3f", float formatScale = 1.0f, + OptionVar::FormatFunction formatFunction = 0, // Default float formatting. + OptionVar::UpdateFunction updateFunction = 0 ) + { + OptionVar* p = new OptionVar(name, pvar, minf, maxf, stepSize, + formatString, formatScale, + formatFunction, updateFunction); + AddItem(p); + return *p; + } + + virtual void Select(); + virtual String GetLabel() { return Label + " >"; } + + virtual String ProcessShortcutKey(KeyCode key, bool shift); + virtual String ProcessShortcutButton(UInt32 buttonMask); + + // Sets a message to display with a time-out. Default time-out is 4 seconds. + // This uses the same overlay approach as used for shortcut notifications. + void SetPopupMessage(const char* format, ...); + // Overrides current timeout, in seconds (not the future default value); + // intended to be called right after SetPopupMessage. + void SetPopupTimeout(double timeoutSeconds, bool border = false); + +protected: + + void renderShortcutChangeMessage(RenderDevice* prender); + +public: + OptionSelectionMenu* GetSubmenu(); + OptionSelectionMenu* GetOrCreateSubmenu(String submenuName); + + enum DisplayStateType + { + Display_None, + Display_Menu, + Display_SingleItem + }; + + DisplayStateType DisplayState; + OptionSelectionMenu* ParentMenu; + + ArrayPOD<OptionMenuItem*> Items; + int SelectedIndex; + bool SelectionActive; + + String PopupMessage; + double PopupMessageTimeout; + bool PopupMessageBorder; + + // Possible menu navigation actions. + enum NavigationActions + { + Nav_Up, + Nav_Down, + Nav_Left, + Nav_Right, + Nav_Select, + Nav_Back, + Nav_LAST + }; + + // Handlers for navigation actions. + void HandleUp(bool* pFast); + void HandleDown(bool* pFast); + void HandleLeft(); + void HandleRight(); + void HandleSelect(); + void HandleBack(); + + void HandleMenuToggle(); + void HandleSingleItemToggle(); + + OptionShortcut NavShortcuts[Nav_LAST]; + OptionShortcut ToggleShortcut; + OptionShortcut ToggleSingleItemShortcut; +}; + + +//------------------------------------------------------------------------------------- +// Text Rendering Utility +enum DrawTextCenterType +{ + DrawText_NoCenter= 0, + DrawText_VCenter = 0x01, + DrawText_HCenter = 0x02, + DrawText_Center = DrawText_VCenter | DrawText_HCenter, + DrawText_Border = 0x10, +}; + +void DrawTextBox(RenderDevice* prender, float x, float y, + float textSize, const char* text, + unsigned centerType = DrawText_NoCenter); + +void CleanupDrawTextFont(); + + +#endif // INC_OptionMenu_h diff --git a/Samples/OculusWorldDemo/Player.cpp b/Samples/OculusWorldDemo/Player.cpp index b910307..b2bf00e 100644 --- a/Samples/OculusWorldDemo/Player.cpp +++ b/Samples/OculusWorldDemo/Player.cpp @@ -23,135 +23,138 @@ limitations under the License. #include "Player.h" #include <Kernel/OVR_Alg.h> -Player::Player(void) - : UserEyeHeight(1.8f), - EyePos(7.7f, 1.8f, -1.0f), - EyeYaw(YawInitial), EyePitch(0), EyeRoll(0), - LastSensorYaw(0) +Player::Player() + : UserEyeHeight(1.76f - 0.15f), // 1.76 meters height (ave US male, Wikipedia), less 15 centimeters (TomF's top-of-head-to-eye distance). + BodyPos(7.7f, 1.76f - 0.15f, -1.0f), + BodyYaw(YawInitial) { MoveForward = MoveBack = MoveLeft = MoveRight = 0; GamepadMove = Vector3f(0); GamepadRotate = Vector3f(0); } +Player::~Player() +{ +} + +Vector3f Player::GetPosition() +{ + return BodyPos + Quatf(Vector3f(0,1,0), BodyYaw.Get()).Rotate(HeadPose.Position); +} + +Quatf Player::GetOrientation(bool baseOnly) +{ + Quatf baseQ = Quatf(Vector3f(0,1,0), BodyYaw.Get()); + return baseOnly ? baseQ : baseQ * HeadPose.Orientation; +} -Player::~Player(void) +Posef Player::VirtualWorldPoseFromRealPose(const Posef &sensorHeadPose) { + Quatf baseQ = Quatf(Vector3f(0,1,0), BodyYaw.Get()); + + return Posef(baseQ * sensorHeadPose.Orientation, + BodyPos + baseQ.Rotate(sensorHeadPose.Position)); } -void Player::HandleCollision(double dt, Array<Ptr<CollisionModel> >* collisionModels, - Array<Ptr<CollisionModel> >* groundCollisionModels, bool shiftDown) + +void Player::HandleMovement(double dt, Array<Ptr<CollisionModel> >* collisionModels, + Array<Ptr<CollisionModel> >* groundCollisionModels, bool shiftDown) { - if(MoveForward || MoveBack || MoveLeft || MoveRight || GamepadMove.LengthSq() > 0) + // Handle keyboard movement. + // This translates BasePos based on the orientation and keys pressed. + // Note that Pitch and Roll do not affect movement (they only affect view). + Vector3f controllerMove; + if(MoveForward || MoveBack || MoveLeft || MoveRight) { - Vector3f orientationVector; - // Handle keyboard movement. - // This translates EyePos based on Yaw vector direction and keys pressed. - // Note that Pitch and Roll do not affect movement (they only affect view). - if(MoveForward || MoveBack || MoveLeft || MoveRight) + if (MoveForward) { - Vector3f localMoveVector(0, 0, 0); - Matrix4f yawRotate = Matrix4f::RotationY(EyeYaw); - - if (MoveForward) - { - localMoveVector = ForwardVector; - } - else if (MoveBack) - { - localMoveVector = -ForwardVector; - } - - if (MoveRight) - { - localMoveVector += RightVector; - } - else if (MoveLeft) - { - localMoveVector -= RightVector; - } + controllerMove += ForwardVector; + } + else if (MoveBack) + { + controllerMove -= ForwardVector; + } - // Normalize vector so we don't move faster diagonally. - localMoveVector.Normalize(); - orientationVector = yawRotate.Transform(localMoveVector); + if (MoveRight) + { + controllerMove += RightVector; } - else if (GamepadMove.LengthSq() > 0) + else if (MoveLeft) { - Matrix4f yawRotate = Matrix4f::RotationY(EyeYaw); - GamepadMove.Normalize(); - orientationVector = yawRotate.Transform(GamepadMove); + controllerMove -= RightVector; } + } + else if (GamepadMove.LengthSq() > 0) + { + controllerMove = GamepadMove; + } + controllerMove = GetOrientation(bMotionRelativeToBody).Rotate(controllerMove); + controllerMove.y = 0; // Project to the horizontal plane + if (controllerMove.LengthSq() > 0) + { + // Normalize vector so we don't move faster diagonally. + controllerMove.Normalize(); + controllerMove *= OVR::Alg::Min<float>(MoveSpeed * (float)dt * (shiftDown ? 3.0f : 1.0f), 1.0f); + } - float moveLength = OVR::Alg::Min<float>(MoveSpeed * (float)dt * (shiftDown ? 3.0f : 1.0f), 1.0f); + // Compute total move direction vector and move length + Vector3f orientationVector = controllerMove; + float moveLength = orientationVector.Length(); + if (moveLength > 0) + orientationVector.Normalize(); + + float checkLengthForward = moveLength; + Planef collisionPlaneForward; + bool gotCollision = false; + + for(unsigned int i = 0; i < collisionModels->GetSize(); ++i) + { + // Checks for collisions at model base level, which should prevent us from + // slipping under walls + if (collisionModels->At(i)->TestRay(BodyPos, orientationVector, checkLengthForward, + &collisionPlaneForward)) + { + gotCollision = true; + break; + } + } - float checkLengthForward = moveLength; - Planef collisionPlaneForward; - float checkLengthLeft = moveLength; - Planef collisionPlaneLeft; - float checkLengthRight = moveLength; - Planef collisionPlaneRight; - bool gotCollision = false; - bool gotCollisionLeft = false; - bool gotCollisionRight = false; + if (gotCollision) + { + // Project orientationVector onto the plane + Vector3f slideVector = orientationVector - collisionPlaneForward.N + * (orientationVector.Dot(collisionPlaneForward.N)); - for(unsigned int i = 0; i < collisionModels->GetSize(); ++i) + // Make sure we aren't in a corner + for(unsigned int j = 0; j < collisionModels->GetSize(); ++j) { - // Checks for collisions at eye level, which should prevent us from - // slipping under walls - if (collisionModels->At(i)->TestRay(EyePos, orientationVector, checkLengthForward, - &collisionPlaneForward)) - { - gotCollision = true; - } - - Matrix4f leftRotation = Matrix4f::RotationY(45 * (Math<float>::Pi / 180.0f)); - Vector3f leftVector = leftRotation.Transform(orientationVector); - if (collisionModels->At(i)->TestRay(EyePos, leftVector, checkLengthLeft, - &collisionPlaneLeft)) - { - gotCollisionLeft = true; - } - Matrix4f rightRotation = Matrix4f::RotationY(-45 * (Math<float>::Pi / 180.0f)); - Vector3f rightVector = rightRotation.Transform(orientationVector); - if (collisionModels->At(i)->TestRay(EyePos, rightVector, checkLengthRight, - &collisionPlaneRight)) + if (collisionModels->At(j)->TestPoint(BodyPos - Vector3f(0.0f, RailHeight, 0.0f) + + (slideVector * (moveLength))) ) { - gotCollisionRight = true; + moveLength = 0; + break; } } - - if (gotCollision) + if (moveLength != 0) { - // Project orientationVector onto the plane - Vector3f slideVector = orientationVector - collisionPlaneForward.N - * (orientationVector.Dot(collisionPlaneForward.N)); - - // Make sure we aren't in a corner - for(unsigned int j = 0; j < collisionModels->GetSize(); ++j) - { - if (collisionModels->At(j)->TestPoint(EyePos - Vector3f(0.0f, RailHeight, 0.0f) + - (slideVector * (moveLength))) ) - { - moveLength = 0; - } - } - if (moveLength != 0) - { - orientationVector = slideVector; - } + orientationVector = slideVector; } - // Checks for collisions at foot level, which allows us to follow terrain - orientationVector *= moveLength; - EyePos += orientationVector; + } + // Checks for collisions at foot level, which allows us to follow terrain + orientationVector *= moveLength; + BodyPos += orientationVector; - Planef collisionPlaneDown; - float finalDistanceDown = 10; + Planef collisionPlaneDown; + float finalDistanceDown = 10; + // Only apply down if there is collision model (otherwise we get jitter). + if (groundCollisionModels->GetSize()) + { for(unsigned int i = 0; i < groundCollisionModels->GetSize(); ++i) { float checkLengthDown = 10; - if (groundCollisionModels->At(i)->TestRay(EyePos, Vector3f(0.0f, -1.0f, 0.0f), - checkLengthDown, &collisionPlaneDown)) + if (groundCollisionModels->At(i)->TestRay(BodyPos, Vector3f(0.0f, -1.0f, 0.0f), + checkLengthDown, &collisionPlaneDown)) { finalDistanceDown = Alg::Min(finalDistanceDown, checkLengthDown); } @@ -160,7 +163,32 @@ void Player::HandleCollision(double dt, Array<Ptr<CollisionModel> >* collisionMo // Maintain the minimum camera height if (UserEyeHeight - finalDistanceDown < 1.0f) { - EyePos.y += UserEyeHeight - finalDistanceDown; + BodyPos.y += UserEyeHeight - finalDistanceDown; } } + +} + + + +// Handle directional movement. Returns 'true' if movement was processed. +bool Player::HandleMoveKey(OVR::KeyCode key, bool down) +{ + switch(key) + { + // Handle player movement keys. + // We just update movement state here, while the actual translation is done in OnIdle() + // based on time. + case OVR::Key_W: MoveForward = down ? (MoveForward | 1) : (MoveForward & ~1); return true; + case OVR::Key_S: MoveBack = down ? (MoveBack | 1) : (MoveBack & ~1); return true; + case OVR::Key_A: MoveLeft = down ? (MoveLeft | 1) : (MoveLeft & ~1); return true; + case OVR::Key_D: MoveRight = down ? (MoveRight | 1) : (MoveRight & ~1); return true; + case OVR::Key_Up: MoveForward = down ? (MoveForward | 2) : (MoveForward & ~2); return true; + case OVR::Key_Down: MoveBack = down ? (MoveBack | 2) : (MoveBack & ~2); return true; + case OVR::Key_Left: MoveLeft = down ? (MoveLeft | 2) : (MoveLeft & ~2); return true; + case OVR::Key_Right: MoveRight = down ? (MoveRight | 2) : (MoveRight & ~2); return true; + } + return false; } + + diff --git a/Samples/OculusWorldDemo/Player.h b/Samples/OculusWorldDemo/Player.h index e57e67c..f8d29d5 100644 --- a/Samples/OculusWorldDemo/Player.h +++ b/Samples/OculusWorldDemo/Player.h @@ -1,7 +1,7 @@ /************************************************************************************ Filename : Player.h -Content : Player location and hit-testing logic +Content : Avatar movement and collision detection Created : October 4, 2012 Copyright : Copyright 2012 Oculus, Inc. All Rights reserved. @@ -25,23 +25,20 @@ limitations under the License. #define OVR_WorldDemo_Player_h #include "OVR.h" +#include "Kernel/OVR_KeyCodes.h" #include "../CommonSrc/Render/Render_Device.h" using namespace OVR; using namespace OVR::Render; //------------------------------------------------------------------------------------- -// The RHS coordinate system is defines as follows (as seen in perspective view): -// Y - Up -// Z - Back -// X - Right -const Vector3f UpVector(0.0f, 1.0f, 0.0f); -const Vector3f ForwardVector(0.0f, 0.0f, -1.0f); +// The RHS coordinate system is assumed. const Vector3f RightVector(1.0f, 0.0f, 0.0f); +const Vector3f UpVector(0.0f, 1.0f, 0.0f); +const Vector3f ForwardVector(0.0f, 0.0f, -1.0f); // -1 because HMD looks along -Z at identity orientation -// We start out looking in the positive Z (180 degree rotation). -const float YawInitial = 3.141592f; -const float Sensitivity = 1.0f; +const float YawInitial = 0.0f; +const float Sensitivity = 0.3f; // low sensitivity to ease people into it gently. const float MoveSpeed = 3.0f; // m/s // These are used for collision detection @@ -58,24 +55,37 @@ public: float UserEyeHeight; - // Position and look. The following apply: - Vector3f EyePos; - float EyeYaw; // Rotation around Y, CCW positive when looking at RHS (X,Z) plane. - float EyePitch; // Pitch. If sensor is plugged in, only read from sensor. - float EyeRoll; // Roll, only accessible from Sensor. - float LastSensorYaw; // Stores previous Yaw value from to support computing delta. + // Where the avatar coordinate system (and body) is positioned and oriented in the virtual world + // Modified by gamepad/mouse input + Vector3f BodyPos; + Anglef BodyYaw; + + // Where the player head is positioned and oriented in the real world + Posef HeadPose; + + // Where the avatar head is positioned and oriented in the virtual world + Vector3f GetPosition(); + Quatf GetOrientation(bool baseOnly = false); + + // Returns virtual world position based on a real world head pose. + // Allows predicting eyes separately based on scanout time. + Posef VirtualWorldPoseFromRealPose(const Posef &sensorHeadPose); + + // Handle directional movement. Returns 'true' if movement was processed. + bool HandleMoveKey(OVR::KeyCode key, bool down); - // Movement state; different bits may be set based on the state of keys. + // Movement state; different bits may be set based on the state of keys. UByte MoveForward; UByte MoveBack; UByte MoveLeft; UByte MoveRight; Vector3f GamepadMove, GamepadRotate; + bool bMotionRelativeToBody; Player(); ~Player(); - void HandleCollision(double dt, Array<Ptr<CollisionModel> >* collisionModels, - Array<Ptr<CollisionModel> >* groundCollisionModels, bool shiftDown); + void HandleMovement(double dt, Array<Ptr<CollisionModel> >* collisionModels, + Array<Ptr<CollisionModel> >* groundCollisionModels, bool shiftDown); }; #endif diff --git a/Samples/OculusWorldDemo/OculusWorldDemo_Msvc2010.vcxproj b/Samples/OculusWorldDemo/Projects/Win/VS2010/OculusWorldDemo.vcxproj index a881ab8..2167237 100644 --- a/Samples/OculusWorldDemo/OculusWorldDemo_Msvc2010.vcxproj +++ b/Samples/OculusWorldDemo/Projects/Win/VS2010/OculusWorldDemo.vcxproj @@ -19,7 +19,7 @@ </ProjectConfiguration> </ItemGroup> <PropertyGroup Label="Globals"> - <ProjectGuid>{8051B877-2992-4F64-8C3B-FAF88B6D83AA}</ProjectGuid> + <ProjectGuid>{456DA1F5-7D65-4B77-8336-277F3921639B}</ProjectGuid> <Keyword>Win32Proj</Keyword> <RootNamespace>OculusWorldDemo</RootNamespace> <ProjectName>OculusWorldDemo</ProjectName> @@ -65,23 +65,27 @@ <PropertyGroup Label="UserMacros" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <LinkIncremental>true</LinkIncremental> - <IntDir>$(Configuration)\Obj\</IntDir> - <OutDir>$(ProjectDir)$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)../../../Obj/Win/VS2010/$(Configuration)/$(PlatformName)/</IntDir> + <OutDir>$(ProjectDir)../../../Bin/Win/VS2010/$(Configuration)/$(PlatformName)/</OutDir> + <TargetName>OculusWorldDemo</TargetName> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <LinkIncremental>true</LinkIncremental> - <IntDir>$(Configuration)\Obj\</IntDir> - <OutDir>$(ProjectDir)$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)../../../Obj/Win/VS2010/$(Configuration)/$(PlatformName)/</IntDir> + <OutDir>$(ProjectDir)../../../Bin/Win/VS2010/$(Configuration)/$(PlatformName)/</OutDir> + <TargetName>OculusWorldDemo</TargetName> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <LinkIncremental>false</LinkIncremental> - <IntDir>$(Configuration)\Obj\</IntDir> - <OutDir>$(ProjectDir)$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)../../../Obj/Win/VS2010/$(Configuration)/$(PlatformName)/</IntDir> + <OutDir>$(ProjectDir)../../../Bin/Win/VS2010/$(Configuration)/$(PlatformName)/</OutDir> + <TargetName>OculusWorldDemo</TargetName> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <LinkIncremental>false</LinkIncremental> - <IntDir>$(Configuration)\Obj\</IntDir> - <OutDir>$(ProjectDir)$(Configuration)\</OutDir> + <IntDir>$(ProjectDir)../../../Obj/Win/VS2010/$(Configuration)/$(PlatformName)/</IntDir> + <OutDir>$(ProjectDir)../../../Bin/Win/VS2010/$(Configuration)/$(PlatformName)/</OutDir> + <TargetName>OculusWorldDemo</TargetName> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ClCompile> @@ -90,16 +94,17 @@ <WarningLevel>Level4</WarningLevel> <Optimization>Disabled</Optimization> <PreprocessorDefinitions>OVR_BUILD_DEBUG;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>../../LibOVR/Include;../../3rdParty/TinyXml;../../LibOVR/Src;../../3rdParty/glext;$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <AdditionalIncludeDirectories>../../../../../LibOVR/Include;../../../../../3rdParty/glext;../../../../../LibOVR/Src;$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <DebugInformationFormat>OldStyle</DebugInformationFormat> <MultiProcessorCompilation>true</MultiProcessorCompilation> <MinimalRebuild>false</MinimalRebuild> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> </ClCompile> <Link> <SubSystem>Windows</SubSystem> <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>libovrd.lib;dxgi.lib;d3d10.lib;d3d11.lib;d3dcompiler.lib;opengl32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> - <AdditionalLibraryDirectories>../../LibOVR/Lib/Win32;$(DXSDK_DIR)/Lib/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalLibraryDirectories>../../../../../LibOVR/Lib/$(Platform)/VS2010/;$(DXSDK_DIR)/Lib/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalDependencies>opengl32.lib;libovrd.lib;dxgi.lib;d3d10_1.lib;d3d11.lib;d3dcompiler.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> @@ -108,17 +113,18 @@ </PrecompiledHeader> <WarningLevel>Level4</WarningLevel> <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>OVR_BUILD_DEBUG;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>../../LibOVR/Include;../../LibOVR/Src;../../3rdParty/glext;$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>OVR_BUILD_DEBUG;_WIN64;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../../../../LibOVR/Include;../../../../../3rdParty/glext;../../../../../LibOVR/Src;$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <DebugInformationFormat>OldStyle</DebugInformationFormat> <MultiProcessorCompilation>true</MultiProcessorCompilation> <MinimalRebuild>false</MinimalRebuild> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> </ClCompile> <Link> <SubSystem>Windows</SubSystem> <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>libovr64d.lib;dxgi.lib;d3d10.lib;d3d11.lib;d3dcompiler.lib;opengl32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> - <AdditionalLibraryDirectories>../../LibOVR/Lib/x64;$(DXSDK_DIR)/Lib/x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalLibraryDirectories>../../../../../LibOVR/Lib/$(Platform)/VS2010/;$(DXSDK_DIR)/Lib/x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalDependencies>opengl32.lib;libovr64d.lib;dxgi.lib;d3d10_1.lib;d3d11.lib;d3dcompiler.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> @@ -130,7 +136,7 @@ <FunctionLevelLinking>true</FunctionLevelLinking> <IntrinsicFunctions>true</IntrinsicFunctions> <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>../../LibOVR/Include;../../3rdParty/TinyXml;../../LibOVR/Src;../../3rdParty/glext;$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <AdditionalIncludeDirectories>../../../../../LibOVR/Include;../../../../../3rdParty/glext;../../../../../LibOVR/Src;$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <RuntimeLibrary>MultiThreaded</RuntimeLibrary> <MultiProcessorCompilation>true</MultiProcessorCompilation> <DebugInformationFormat>OldStyle</DebugInformationFormat> @@ -140,8 +146,8 @@ <GenerateDebugInformation>false</GenerateDebugInformation> <EnableCOMDATFolding>true</EnableCOMDATFolding> <OptimizeReferences>true</OptimizeReferences> - <AdditionalLibraryDirectories>../../LibOVR/Lib/Win32;$(DXSDK_DIR)/Lib/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> - <AdditionalDependencies>libovr.lib;dxgi.lib;d3d10.lib;d3d11.lib;d3dcompiler.lib;opengl32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>../../../../../LibOVR/Lib/$(Platform)/VS2010/;$(DXSDK_DIR)/Lib/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalDependencies>opengl32.lib;libovr.lib;dxgi.lib;d3d10_1.lib;d3d11.lib;d3dcompiler.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> @@ -152,8 +158,8 @@ <Optimization>MaxSpeed</Optimization> <FunctionLevelLinking>true</FunctionLevelLinking> <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>../../LibOVR/Include;../../LibOVR/Src;../../3rdParty/glext;$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_WIN64;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../../../../LibOVR/Include;../../../../../3rdParty/glext;../../../../../LibOVR/Src;$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <RuntimeLibrary>MultiThreaded</RuntimeLibrary> <MultiProcessorCompilation>true</MultiProcessorCompilation> <DebugInformationFormat>OldStyle</DebugInformationFormat> @@ -163,47 +169,57 @@ <GenerateDebugInformation>true</GenerateDebugInformation> <EnableCOMDATFolding>true</EnableCOMDATFolding> <OptimizeReferences>true</OptimizeReferences> - <AdditionalLibraryDirectories>../../LibOVR/Lib/x64;$(DXSDK_DIR)/Lib/x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> - <AdditionalDependencies>libovr64.lib;dxgi.lib;d3d10.lib;d3d11.lib;d3dcompiler.lib;opengl32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>../../../../../LibOVR/Lib/$(Platform)/VS2010/;$(DXSDK_DIR)/Lib/x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalDependencies>opengl32.lib;libovr64.lib;dxgi.lib;d3d10_1.lib;d3d11.lib;d3dcompiler.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemGroup> - <ClCompile Include="..\CommonSrc\Platform\Platform.cpp" /> - <ClCompile Include="..\CommonSrc\Platform\Win32_Gamepad.cpp" /> - <ClCompile Include="..\CommonSrc\Platform\Win32_Platform.cpp" /> - <ClCompile Include="..\CommonSrc\Render\Render_LoadTextureDDS.cpp" /> - <ClCompile Include="..\CommonSrc\Render\Render_LoadTextureTGA.cpp" /> - <ClCompile Include="..\CommonSrc\Render\Render_Device.cpp" /> - <ClCompile Include="..\CommonSrc\Render\Render_D3D10_Device.cpp" /> - <ClCompile Include="..\CommonSrc\Render\Render_D3D11_Device.cpp" /> - <ClCompile Include="..\CommonSrc\Render\Render_D3D1X_Device.cpp"> + <ClCompile Include="..\..\..\..\CommonSrc\Platform\Platform.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Platform\Win32_Gamepad.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Platform\Win32_Platform.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_GL_Device.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_GL_Win32_Device.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_LoadTextureDDS.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_LoadTextureTGA.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_Device.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_D3D10_Device.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_D3D11_Device.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_D3D1X_Device.cpp"> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> </ClCompile> - <ClCompile Include="..\..\3rdParty\TinyXml\tinyxml2.cpp" /> - <ClCompile Include="..\CommonSrc\Render\Render_XmlSceneLoader.cpp" /> - <ClCompile Include="OculusWorldDemo.cpp" /> - <ClCompile Include="Player.cpp" /> + <ClCompile Include="..\..\..\..\..\3rdParty\TinyXml\tinyxml2.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_XmlSceneLoader.cpp" /> + <ClCompile Include="..\..\..\OculusWorldDemo.cpp" /> + <ClCompile Include="..\..\..\OculusWorldDemo_Scene.cpp" /> + <ClCompile Include="..\..\..\OptionMenu.cpp" /> + <ClCompile Include="..\..\..\Player.cpp" /> + <ClCompile Include="..\..\..\RenderProfiler.cpp" /> </ItemGroup> <ItemGroup> - <ClInclude Include="..\CommonSrc\Platform\Gamepad.h" /> - <ClInclude Include="..\CommonSrc\Platform\Platform.h" /> - <ClInclude Include="..\CommonSrc\Platform\Platform_Default.h" /> - <ClInclude Include="..\CommonSrc\Platform\Win32_Gamepad.h" /> - <ClInclude Include="..\CommonSrc\Platform\Win32_Platform.h" /> - <ClInclude Include="..\CommonSrc\Render\Render_Font.h" /> - <ClInclude Include="..\CommonSrc\Render\Render_Device.h" /> - <ClInclude Include="..\CommonSrc\Render\Render_D3D10_Device.h" /> - <ClInclude Include="..\CommonSrc\Render\Render_D3D11_Device.h" /> - <ClInclude Include="..\CommonSrc\Render\Render_D3D1X_Device.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Platform\Gamepad.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Platform\Platform.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Platform\Platform_Default.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Platform\Win32_Gamepad.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Platform\Win32_Platform.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_Font.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_Device.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_D3D10_Device.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_D3D11_Device.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_D3D1X_Device.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_GL_Device.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_GL_Win32_Device.h" /> + <ClInclude Include="..\..\..\OptionMenu.h" /> <ClInclude Include="..\..\3rdParty\TinyXml\tinyxml2.h" /> - <ClInclude Include="..\CommonSrc\Render\Render_XmlSceneLoader.h" /> - <ClInclude Include="Player.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_XmlSceneLoader.h" /> + <ClInclude Include="..\..\..\OculusWorldDemo.h" /> + <ClInclude Include="..\..\..\Player.h" /> + <ClInclude Include="..\..\..\RenderProfiler.h" /> </ItemGroup> <ItemGroup> - <ResourceCompile Include="OculusWorldDemo.rc" /> + <ResourceCompile Include="..\..\..\OculusWorldDemo.rc" /> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> diff --git a/Samples/OculusWorldDemo/Projects/Win/VS2010/OculusWorldDemo.vcxproj.filters b/Samples/OculusWorldDemo/Projects/Win/VS2010/OculusWorldDemo.vcxproj.filters new file mode 100644 index 0000000..67678ea --- /dev/null +++ b/Samples/OculusWorldDemo/Projects/Win/VS2010/OculusWorldDemo.vcxproj.filters @@ -0,0 +1,107 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="CommonSrc"> + <UniqueIdentifier>{ba6e9e50-0655-4f12-a136-6d2a06015925}</UniqueIdentifier> + </Filter> + <Filter Include="CommonSrc\Platform"> + <UniqueIdentifier>{16e20d8b-eff7-454c-be85-02037c399e97}</UniqueIdentifier> + </Filter> + <Filter Include="CommonSrc\Render"> + <UniqueIdentifier>{1b6d51ae-a405-4f3d-be93-41a50db4f328}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\..\..\CommonSrc\Platform\Platform.cpp"> + <Filter>CommonSrc\Platform</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\CommonSrc\Platform\Win32_Platform.cpp"> + <Filter>CommonSrc\Platform</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_Device.cpp"> + <Filter>CommonSrc\Render</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_D3D1X_Device.cpp"> + <Filter>CommonSrc\Render</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_D3D10_Device.cpp"> + <Filter>CommonSrc\Render</Filter> + </ClCompile> + <ClCompile Include="..\..\..\OculusWorldDemo.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_D3D11_Device.cpp"> + <Filter>CommonSrc\Render</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_LoadTextureTGA.cpp"> + <Filter>CommonSrc\Render</Filter> + </ClCompile> + <ClCompile Include="..\..\..\Player.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_LoadTextureDDS.cpp"> + <Filter>CommonSrc\Render</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_XmlSceneLoader.cpp"> + <Filter>CommonSrc\Render</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\CommonSrc\Platform\Win32_Gamepad.cpp"> + <Filter>CommonSrc\Platform</Filter> + </ClCompile> + <ClCompile Include="..\..\..\OculusWorldDemo_Scene.cpp" /> + <ClCompile Include="..\..\..\OptionMenu.cpp" /> + <ClCompile Include="..\..\..\RenderProfiler.cpp" /> + <ClCompile Include="..\..\..\..\..\3rdParty\TinyXml\tinyxml2.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_GL_Device.cpp"> + <Filter>CommonSrc\Render</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_GL_Win32_Device.cpp"> + <Filter>CommonSrc\Render</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\..\..\CommonSrc\Platform\Win32_Platform.h"> + <Filter>CommonSrc\Platform</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\CommonSrc\Platform\Platform.h"> + <Filter>CommonSrc\Platform</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\CommonSrc\Platform\Platform_Default.h"> + <Filter>CommonSrc\Platform</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_Font.h"> + <Filter>CommonSrc\Render</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_Device.h"> + <Filter>CommonSrc\Render</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_D3D1X_Device.h"> + <Filter>CommonSrc\Render</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_D3D10_Device.h"> + <Filter>CommonSrc\Render</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_D3D11_Device.h"> + <Filter>CommonSrc\Render</Filter> + </ClInclude> + <ClInclude Include="..\..\3rdParty\TinyXml\tinyxml2.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_XmlSceneLoader.h"> + <Filter>CommonSrc\Render</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\CommonSrc\Platform\Gamepad.h"> + <Filter>CommonSrc\Platform</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\CommonSrc\Platform\Win32_Gamepad.h"> + <Filter>CommonSrc\Platform</Filter> + </ClInclude> + <ClInclude Include="..\..\..\OculusWorldDemo.h" /> + <ClInclude Include="..\..\..\RenderProfiler.h" /> + <ClInclude Include="..\..\..\Player.h" /> + <ClInclude Include="..\..\..\OptionMenu.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_GL_Device.h"> + <Filter>CommonSrc\Render</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_GL_Win32_Device.h"> + <Filter>CommonSrc\Render</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\..\..\OculusWorldDemo.rc" /> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Samples/OculusWorldDemo/Projects/Win/VS2012/OculusWorldDemo.vcxproj b/Samples/OculusWorldDemo/Projects/Win/VS2012/OculusWorldDemo.vcxproj new file mode 100644 index 0000000..1dae2b3 --- /dev/null +++ b/Samples/OculusWorldDemo/Projects/Win/VS2012/OculusWorldDemo.vcxproj @@ -0,0 +1,232 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{4F8C2B89-7CF1-4763-8EEF-E969FB760E32}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>OculusWorldDemo</RootNamespace> + <ProjectName>OculusWorldDemo</ProjectName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v110</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v110</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v110</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v110</PlatformToolset> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <IntDir>$(ProjectDir)../../../Obj/Win/VS2012/$(Configuration)/$(PlatformName)/</IntDir> + <OutDir>$(ProjectDir)../../../Bin/Win/VS2012/$(Configuration)/$(PlatformName)/</OutDir> + <TargetName>OculusWorldDemo</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <IntDir>$(ProjectDir)../../../Obj/Win/VS2012/$(Configuration)/$(PlatformName)/</IntDir> + <OutDir>$(ProjectDir)../../../Bin/Win/VS2012/$(Configuration)/$(PlatformName)/</OutDir> + <TargetName>OculusWorldDemo</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + <IntDir>$(ProjectDir)../../../Obj/Win/VS2012/$(Configuration)/$(PlatformName)/</IntDir> + <OutDir>$(ProjectDir)../../../Bin/Win/VS2012/$(Configuration)/$(PlatformName)/</OutDir> + <TargetName>OculusWorldDemo</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + <IntDir>$(ProjectDir)../../../Obj/Win/VS2012/$(Configuration)/$(PlatformName)/</IntDir> + <OutDir>$(ProjectDir)../../../Bin/Win/VS2012/$(Configuration)/$(PlatformName)/</OutDir> + <TargetName>OculusWorldDemo</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level4</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>OVR_BUILD_DEBUG;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../../../../LibOVR/Include;../../../../../LibOVR/Src;../../../../../3rdParty/glext;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <DebugInformationFormat>OldStyle</DebugInformationFormat> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + <MinimalRebuild>false</MinimalRebuild> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>../../../../../LibOVR/Lib/$(Platform)/VS2012/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalDependencies>opengl32.lib;libovrd.lib;dxgi.lib;d3d10_1.lib;d3d11.lib;d3dcompiler.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level4</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>OVR_BUILD_DEBUG;_WIN64;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../../../../LibOVR/Include;../../../../../LibOVR/Src;../../../../../3rdParty/glext;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <DebugInformationFormat>OldStyle</DebugInformationFormat> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + <MinimalRebuild>false</MinimalRebuild> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>../../../../../LibOVR/Lib/$(Platform)/VS2012/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalDependencies>opengl32.lib;libovr64d.lib;dxgi.lib;d3d10_1.lib;d3d11.lib;d3dcompiler.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level4</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../../../../LibOVR/Include;../../../../../LibOVR/Src;../../../../../3rdParty/glext;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + <DebugInformationFormat>OldStyle</DebugInformationFormat> + <AdditionalOptions>/d2Zi+ %(AdditionalOptions)</AdditionalOptions> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>false</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalLibraryDirectories>../../../../../LibOVR/Lib/$(Platform)/VS2012/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalDependencies>opengl32.lib;libovr.lib;dxgi.lib;d3d10_1.lib;d3d11.lib;d3dcompiler.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level4</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../../../../LibOVR/Include;../../../../../LibOVR/Src;../../../../../3rdParty/glext;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + <DebugInformationFormat>OldStyle</DebugInformationFormat> + <AdditionalOptions>/d2Zi+ %(AdditionalOptions)</AdditionalOptions> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalLibraryDirectories>../../../../../LibOVR/Lib/$(Platform)/VS2012/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalDependencies>opengl32.lib;libovr64.lib;dxgi.lib;d3d10_1.lib;d3d11.lib;d3dcompiler.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\..\CommonSrc\Platform\Platform.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Platform\Win32_Gamepad.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Platform\Win32_Platform.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_GL_Device.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_GL_Win32_Device.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_LoadTextureDDS.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_LoadTextureTGA.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_Device.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_D3D10_Device.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_D3D11_Device.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_D3D1X_Device.cpp"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\..\3rdParty\TinyXml\tinyxml2.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_XmlSceneLoader.cpp" /> + <ClCompile Include="..\..\..\OculusWorldDemo.cpp" /> + <ClCompile Include="..\..\..\OculusWorldDemo_Scene.cpp" /> + <ClCompile Include="..\..\..\OptionMenu.cpp" /> + <ClCompile Include="..\..\..\Player.cpp" /> + <ClCompile Include="..\..\..\RenderProfiler.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\..\..\CommonSrc\Platform\Gamepad.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Platform\Platform.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Platform\Platform_Default.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Platform\Win32_Gamepad.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Platform\Win32_Platform.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_Font.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_Device.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_D3D10_Device.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_D3D11_Device.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_D3D1X_Device.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_GL_Device.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_GL_Win32_Device.h" /> + <ClInclude Include="..\..\3rdParty\TinyXml\tinyxml2.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_XmlSceneLoader.h" /> + <ClInclude Include="..\..\..\OculusWorldDemo.h" /> + <ClInclude Include="..\..\..\Player.h" /> + <ClInclude Include="..\..\..\RenderProfiler.h" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\..\..\OculusWorldDemo.rc" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/Samples/OculusWorldDemo/Projects/Win/VS2012/OculusWorldDemo.vcxproj.filters b/Samples/OculusWorldDemo/Projects/Win/VS2012/OculusWorldDemo.vcxproj.filters new file mode 100644 index 0000000..7246205 --- /dev/null +++ b/Samples/OculusWorldDemo/Projects/Win/VS2012/OculusWorldDemo.vcxproj.filters @@ -0,0 +1,106 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="CommonSrc"> + <UniqueIdentifier>{ba6e9e50-0655-4f12-a136-6d2a06015925}</UniqueIdentifier> + </Filter> + <Filter Include="CommonSrc\Platform"> + <UniqueIdentifier>{16e20d8b-eff7-454c-be85-02037c399e97}</UniqueIdentifier> + </Filter> + <Filter Include="CommonSrc\Render"> + <UniqueIdentifier>{1b6d51ae-a405-4f3d-be93-41a50db4f328}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\..\..\CommonSrc\Platform\Platform.cpp"> + <Filter>CommonSrc\Platform</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\CommonSrc\Platform\Win32_Platform.cpp"> + <Filter>CommonSrc\Platform</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_Device.cpp"> + <Filter>CommonSrc\Render</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_D3D1X_Device.cpp"> + <Filter>CommonSrc\Render</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_D3D10_Device.cpp"> + <Filter>CommonSrc\Render</Filter> + </ClCompile> + <ClCompile Include="..\..\..\OculusWorldDemo.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_D3D11_Device.cpp"> + <Filter>CommonSrc\Render</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_LoadTextureTGA.cpp"> + <Filter>CommonSrc\Render</Filter> + </ClCompile> + <ClCompile Include="..\..\..\Player.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_LoadTextureDDS.cpp"> + <Filter>CommonSrc\Render</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_XmlSceneLoader.cpp"> + <Filter>CommonSrc\Render</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\CommonSrc\Platform\Win32_Gamepad.cpp"> + <Filter>CommonSrc\Platform</Filter> + </ClCompile> + <ClCompile Include="..\..\..\OculusWorldDemo_Scene.cpp" /> + <ClCompile Include="..\..\..\OptionMenu.cpp" /> + <ClCompile Include="..\..\..\RenderProfiler.cpp" /> + <ClCompile Include="..\..\..\..\..\3rdParty\TinyXml\tinyxml2.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_GL_Win32_Device.cpp"> + <Filter>CommonSrc\Render</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_GL_Device.cpp"> + <Filter>CommonSrc\Render</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\..\..\CommonSrc\Platform\Win32_Platform.h"> + <Filter>CommonSrc\Platform</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\CommonSrc\Platform\Platform.h"> + <Filter>CommonSrc\Platform</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\CommonSrc\Platform\Platform_Default.h"> + <Filter>CommonSrc\Platform</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_Font.h"> + <Filter>CommonSrc\Render</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_Device.h"> + <Filter>CommonSrc\Render</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_D3D1X_Device.h"> + <Filter>CommonSrc\Render</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_D3D10_Device.h"> + <Filter>CommonSrc\Render</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_D3D11_Device.h"> + <Filter>CommonSrc\Render</Filter> + </ClInclude> + <ClInclude Include="..\..\3rdParty\TinyXml\tinyxml2.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_XmlSceneLoader.h"> + <Filter>CommonSrc\Render</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\CommonSrc\Platform\Gamepad.h"> + <Filter>CommonSrc\Platform</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\CommonSrc\Platform\Win32_Gamepad.h"> + <Filter>CommonSrc\Platform</Filter> + </ClInclude> + <ClInclude Include="..\..\..\OculusWorldDemo.h" /> + <ClInclude Include="..\..\..\RenderProfiler.h" /> + <ClInclude Include="..\..\..\Player.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_GL_Device.h"> + <Filter>CommonSrc\Render</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_GL_Win32_Device.h"> + <Filter>CommonSrc\Render</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\..\..\OculusWorldDemo.rc" /> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Samples/OculusWorldDemo/Projects/Win/VS2013/OculusWorldDemo.vcxproj b/Samples/OculusWorldDemo/Projects/Win/VS2013/OculusWorldDemo.vcxproj new file mode 100644 index 0000000..b894075 --- /dev/null +++ b/Samples/OculusWorldDemo/Projects/Win/VS2013/OculusWorldDemo.vcxproj @@ -0,0 +1,232 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{CA4E4127-1BAD-447C-BFF9-5AF940EEC376}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>OculusWorldDemo</RootNamespace> + <ProjectName>OculusWorldDemo</ProjectName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v120</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v120</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v120</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v120</PlatformToolset> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <IntDir>$(ProjectDir)../../../Obj/Win/VS2013/$(Configuration)/$(PlatformName)/</IntDir> + <OutDir>$(ProjectDir)../../../Bin/Win/VS2013/$(Configuration)/$(PlatformName)/</OutDir> + <TargetName>OculusWorldDemo</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <IntDir>$(ProjectDir)../../../Obj/Win/VS2013/$(Configuration)/$(PlatformName)/</IntDir> + <OutDir>$(ProjectDir)../../../Bin/Win/VS2013/$(Configuration)/$(PlatformName)/</OutDir> + <TargetName>OculusWorldDemo</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + <IntDir>$(ProjectDir)../../../Obj/Win/VS2013/$(Configuration)/$(PlatformName)/</IntDir> + <OutDir>$(ProjectDir)../../../Bin/Win/VS2013/$(Configuration)/$(PlatformName)/</OutDir> + <TargetName>OculusWorldDemo</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + <IntDir>$(ProjectDir)../../../Obj/Win/VS2013/$(Configuration)/$(PlatformName)/</IntDir> + <OutDir>$(ProjectDir)../../../Bin/Win/VS2013/$(Configuration)/$(PlatformName)/</OutDir> + <TargetName>OculusWorldDemo</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level4</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>OVR_BUILD_DEBUG;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../../../../LibOVR/Include;../../../../../LibOVR/Src;../../../../../3rdParty/glext;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <DebugInformationFormat>OldStyle</DebugInformationFormat> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + <MinimalRebuild>false</MinimalRebuild> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>../../../../../LibOVR/Lib/$(Platform)/VS2013/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalDependencies>opengl32.lib;libovrd.lib;dxgi.lib;d3d10_1.lib;d3d11.lib;d3dcompiler.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level4</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>OVR_BUILD_DEBUG;_WIN64;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../../../../LibOVR/Include;../../../../../LibOVR/Src;../../../../../3rdParty/glext;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <DebugInformationFormat>OldStyle</DebugInformationFormat> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + <MinimalRebuild>false</MinimalRebuild> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>../../../../../LibOVR/Lib/$(Platform)/VS2013/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalDependencies>opengl32.lib;libovr64d.lib;dxgi.lib;d3d10_1.lib;d3d11.lib;d3dcompiler.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level4</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../../../../LibOVR/Include;../../../../../LibOVR/Src;../../../../../3rdParty/glext;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + <DebugInformationFormat>OldStyle</DebugInformationFormat> + <AdditionalOptions>/d2Zi+ %(AdditionalOptions)</AdditionalOptions> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>false</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalLibraryDirectories>../../../../../LibOVR/Lib/$(Platform)/VS2013/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalDependencies>opengl32.lib;libovr.lib;dxgi.lib;d3d10_1.lib;d3d11.lib;d3dcompiler.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level4</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>_WIN64;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../../../../LibOVR/Include;../../../../../LibOVR/Src;../../../../../3rdParty/glext;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + <DebugInformationFormat>OldStyle</DebugInformationFormat> + <AdditionalOptions>/d2Zi+ %(AdditionalOptions)</AdditionalOptions> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalLibraryDirectories>../../../../../LibOVR/Lib/$(Platform)/VS2013/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalDependencies>opengl32.lib;libovr64.lib;dxgi.lib;d3d10_1.lib;d3d11.lib;d3dcompiler.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\..\CommonSrc\Platform\Platform.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Platform\Win32_Gamepad.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Platform\Win32_Platform.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_GL_Device.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_GL_Win32_Device.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_LoadTextureDDS.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_LoadTextureTGA.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_Device.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_D3D10_Device.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_D3D11_Device.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_D3D1X_Device.cpp"> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> + </ClCompile> + <ClCompile Include="..\..\..\..\..\3rdParty\TinyXml\tinyxml2.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_XmlSceneLoader.cpp" /> + <ClCompile Include="..\..\..\OculusWorldDemo.cpp" /> + <ClCompile Include="..\..\..\OculusWorldDemo_Scene.cpp" /> + <ClCompile Include="..\..\..\OptionMenu.cpp" /> + <ClCompile Include="..\..\..\Player.cpp" /> + <ClCompile Include="..\..\..\RenderProfiler.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\..\..\CommonSrc\Platform\Gamepad.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Platform\Platform.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Platform\Platform_Default.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Platform\Win32_Gamepad.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Platform\Win32_Platform.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_Font.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_Device.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_D3D10_Device.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_D3D11_Device.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_D3D1X_Device.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_GL_Device.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_GL_Win32_Device.h" /> + <ClInclude Include="..\..\3rdParty\TinyXml\tinyxml2.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_XmlSceneLoader.h" /> + <ClInclude Include="..\..\..\OculusWorldDemo.h" /> + <ClInclude Include="..\..\..\Player.h" /> + <ClInclude Include="..\..\..\RenderProfiler.h" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\..\..\OculusWorldDemo.rc" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/Samples/OculusWorldDemo/Projects/Win/VS2013/OculusWorldDemo.vcxproj.filters b/Samples/OculusWorldDemo/Projects/Win/VS2013/OculusWorldDemo.vcxproj.filters new file mode 100644 index 0000000..93fff72 --- /dev/null +++ b/Samples/OculusWorldDemo/Projects/Win/VS2013/OculusWorldDemo.vcxproj.filters @@ -0,0 +1,106 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="CommonSrc"> + <UniqueIdentifier>{ba6e9e50-0655-4f12-a136-6d2a06015925}</UniqueIdentifier> + </Filter> + <Filter Include="CommonSrc\Platform"> + <UniqueIdentifier>{16e20d8b-eff7-454c-be85-02037c399e97}</UniqueIdentifier> + </Filter> + <Filter Include="CommonSrc\Render"> + <UniqueIdentifier>{1b6d51ae-a405-4f3d-be93-41a50db4f328}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\..\..\CommonSrc\Platform\Platform.cpp"> + <Filter>CommonSrc\Platform</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\CommonSrc\Platform\Win32_Platform.cpp"> + <Filter>CommonSrc\Platform</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_Device.cpp"> + <Filter>CommonSrc\Render</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_D3D1X_Device.cpp"> + <Filter>CommonSrc\Render</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_D3D10_Device.cpp"> + <Filter>CommonSrc\Render</Filter> + </ClCompile> + <ClCompile Include="..\..\..\OculusWorldDemo.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_D3D11_Device.cpp"> + <Filter>CommonSrc\Render</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_LoadTextureTGA.cpp"> + <Filter>CommonSrc\Render</Filter> + </ClCompile> + <ClCompile Include="..\..\..\Player.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_LoadTextureDDS.cpp"> + <Filter>CommonSrc\Render</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_XmlSceneLoader.cpp"> + <Filter>CommonSrc\Render</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\CommonSrc\Platform\Win32_Gamepad.cpp"> + <Filter>CommonSrc\Platform</Filter> + </ClCompile> + <ClCompile Include="..\..\..\OculusWorldDemo_Scene.cpp" /> + <ClCompile Include="..\..\..\OptionMenu.cpp" /> + <ClCompile Include="..\..\..\RenderProfiler.cpp" /> + <ClCompile Include="..\..\..\..\..\3rdParty\TinyXml\tinyxml2.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_GL_Win32_Device.cpp"> + <Filter>CommonSrc\Render</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_GL_Device.cpp"> + <Filter>CommonSrc\Render</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\..\..\CommonSrc\Platform\Win32_Platform.h"> + <Filter>CommonSrc\Platform</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\CommonSrc\Platform\Platform.h"> + <Filter>CommonSrc\Platform</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\CommonSrc\Platform\Platform_Default.h"> + <Filter>CommonSrc\Platform</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_Font.h"> + <Filter>CommonSrc\Render</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_Device.h"> + <Filter>CommonSrc\Render</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_D3D1X_Device.h"> + <Filter>CommonSrc\Render</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_D3D10_Device.h"> + <Filter>CommonSrc\Render</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_D3D11_Device.h"> + <Filter>CommonSrc\Render</Filter> + </ClInclude> + <ClInclude Include="..\..\3rdParty\TinyXml\tinyxml2.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_XmlSceneLoader.h"> + <Filter>CommonSrc\Render</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\CommonSrc\Platform\Gamepad.h"> + <Filter>CommonSrc\Platform</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\CommonSrc\Platform\Win32_Gamepad.h"> + <Filter>CommonSrc\Platform</Filter> + </ClInclude> + <ClInclude Include="..\..\..\OculusWorldDemo.h" /> + <ClInclude Include="..\..\..\RenderProfiler.h" /> + <ClInclude Include="..\..\..\Player.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_GL_Win32_Device.h"> + <Filter>CommonSrc\Render</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_GL_Device.h"> + <Filter>CommonSrc\Render</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\..\..\OculusWorldDemo.rc" /> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Samples/OculusWorldDemo/Release/readme b/Samples/OculusWorldDemo/Release/readme deleted file mode 100644 index c9d0bc0..0000000 --- a/Samples/OculusWorldDemo/Release/readme +++ /dev/null @@ -1,2 +0,0 @@ -This document exits to ensure that the required directory structure gets created correctly. - diff --git a/Samples/OculusWorldDemo/RenderProfiler.cpp b/Samples/OculusWorldDemo/RenderProfiler.cpp new file mode 100644 index 0000000..00bbdd9 --- /dev/null +++ b/Samples/OculusWorldDemo/RenderProfiler.cpp @@ -0,0 +1,99 @@ +/************************************************************************************ + +Filename : RenderProfiler.cpp +Content : Profiling for render. +Created : March 10, 2014 +Authors : Caleb Leak + +Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#include "RenderProfiler.h" + +using namespace OVR; + +RenderProfiler::RenderProfiler() +{ + memset(SampleHistory, 0, sizeof(SampleHistory)); + memset(SampleAverage, 0, sizeof(SampleAverage)); + SampleCurrentFrame = 0; +} + +void RenderProfiler::RecordSample(SampleType sampleType) +{ + if (sampleType == Sample_FrameStart) + { + // Recompute averages and subtract off frame start time. + for (int sample = 1; sample < Sample_LAST; sample++) + { + SampleHistory[SampleCurrentFrame][sample] -= SampleHistory[SampleCurrentFrame][0]; + + // Recompute the average for the current sample type. + SampleAverage[sample] = 0.0; + for (int frame = 0; frame < NumFramesOfTimerHistory; frame++) + { + SampleAverage[sample] += SampleHistory[frame][sample]; + } + SampleAverage[sample] /= NumFramesOfTimerHistory; + } + + SampleCurrentFrame = ((SampleCurrentFrame + 1) % NumFramesOfTimerHistory); + } + + SampleHistory[SampleCurrentFrame][sampleType] = ovr_GetTimeInSeconds(); +} + +const double* RenderProfiler::GetLastSampleSet() const +{ + return SampleHistory[(SampleCurrentFrame - 1 + NumFramesOfTimerHistory) % NumFramesOfTimerHistory]; +} + +void RenderProfiler::DrawOverlay(RenderDevice* prender) +{ + char buf[256 * Sample_LAST]; + OVR_strcpy ( buf, sizeof(buf), "Timing stats" ); // No trailing \n is deliberate. + + /*int timerLastFrame = TimerCurrentFrame - 1; + if ( timerLastFrame < 0 ) + { + timerLastFrame = NumFramesOfTimerHistory - 1; + }*/ + // Timer 0 is always the time at the start of the frame. + + const double* averages = GetAverages(); + const double* lastSampleSet = GetLastSampleSet(); + + for ( int timerNum = 1; timerNum < Sample_LAST; timerNum++ ) + { + char const *pName = ""; + switch ( timerNum ) + { + case Sample_AfterGameProcessing: pName = "AfterGameProcessing"; break; + case Sample_AfterEyeRender : pName = "AfterEyeRender "; break; +// case Sample_BeforeDistortion : pName = "BeforeDistortion "; break; +// case Sample_AfterDistortion : pName = "AfterDistortion "; break; + case Sample_AfterPresent : pName = "AfterPresent "; break; +// case Sample_AfterFlush : pName = "AfterFlush "; break; + default: OVR_ASSERT ( false ); + } + char bufTemp[256]; + OVR_sprintf ( bufTemp, sizeof(bufTemp), "\nRaw: %.2lfms\t400Ave: %.2lfms\t800%s", + lastSampleSet[timerNum] * 1000.0, averages[timerNum] * 1000.0, pName ); + OVR_strcat ( buf, sizeof(buf), bufTemp ); + } + + DrawTextBox(prender, 0.0f, 0.0f, 22.0f, buf, DrawText_Center); +}
\ No newline at end of file diff --git a/Samples/OculusWorldDemo/RenderProfiler.h b/Samples/OculusWorldDemo/RenderProfiler.h new file mode 100644 index 0000000..96ec50a --- /dev/null +++ b/Samples/OculusWorldDemo/RenderProfiler.h @@ -0,0 +1,71 @@ +/************************************************************************************ + +Filename : RenderProfiler.h +Content : Profiling for render. +Created : March 10, 2014 +Authors : Caleb Leak + +Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#ifndef INC_RenderProfiler_h +#define INC_RenderProfiler_h + +#include "OVR.h" + +// TODO: Refactor option menu so dependencies are in a separate file. +#include "OptionMenu.h" + +//------------------------------------------------------------------------------------- +// ***** RenderProfiler + +// Tracks reported timing sample in a frame and dislays them an overlay from DrawOverlay(). +class RenderProfiler +{ +public: + enum { NumFramesOfTimerHistory = 10 }; + + enum SampleType + { + Sample_FrameStart , + Sample_AfterGameProcessing , + Sample_AfterEyeRender , + // Sample_BeforeDistortion , + // Sample_AfterDistortion , + Sample_AfterPresent , + // Sample_AfterFlush , + + Sample_LAST + }; + + RenderProfiler(); + + // Records the current time for the given sample type. + void RecordSample(SampleType sampleType); + + const double* GetAverages() const { return SampleAverage; } + const double* GetLastSampleSet() const; + + void DrawOverlay(RenderDevice* prender); + +private: + + double SampleHistory[NumFramesOfTimerHistory][Sample_LAST]; + double SampleAverage[Sample_LAST]; + int SampleCurrentFrame; +}; + +#endif // INC_RenderProfiler_h |