/************************************************************************************ 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, LLC 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_Kernel.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 "../CommonSrc/Util/OptionMenu.h" #include "../CommonSrc/Util/RenderProfiler.h" #include "Util/Util_Render_Stereo.h" using namespace OVR::Util::Render; #include "Player.h" #include "Sensors/OVR_DeviceConstants.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/" #define WORLDDEMO_ASSET_PATH4 "../Assets/Tuscany/" using namespace OVR; using namespace OVR::OvrPlatform; 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); void UpdateVisionProcessingTime(const ovrTrackingState& trackState); // 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 MirrorSettingChange(OptionVar* = 0) { HmdSettingsChanged = true; NotificationTimeout = ovr_GetTimeInSeconds() + 10.0f;} void BlockShowChange(OptionVar* = 0) { BlocksCenter = ThePlayer.BodyPos; } void EyeHeightChange(OptionVar* = 0) { ThePlayer.HeightScale = ScaleAffectsEyeHeight ? PositionTrackingScale : 1.0f; ThePlayer.BodyPos.y = ThePlayer.GetScaledEyeHeight(); } void HmdSensorToggle(OptionVar* = 0); void HmdSettingChangeFreeRTs(OptionVar* = 0); void MultisampleChange(OptionVar* = 0); void CenterPupilDepthChange(OptionVar* = 0); void DistortionClearColorChange(OptionVar* = 0); void ToggleLogging(OptionVar* = 0); void ResetHmdPose(OptionVar* = 0); protected: RenderDevice* pRender; RendererParams RenderParams; Sizei WindowSize; int ScreenNumber; int FirstScreenInCycle; bool SupportsSrgb; // Last vision processing statistics double LastVisionProcessingTime; int VisionTimesCount; double VisionProcessingSum; double VisionProcessingAverage; struct RenderTarget { Ptr pTex; ovrTexture OvrTex; }; enum RendertargetsEnum { Rendertarget_Left, Rendertarget_Right, Rendertarget_BothEyes, // Used when both eyes are rendered to the same target. Rendertarget_LAST }; RenderTarget RenderTargets[Rendertarget_LAST]; RenderTarget MsaaRenderTargets[Rendertarget_LAST]; RenderTarget* DrawEyeTargets; // the buffers we'll actually render to (could be MSAA) // ***** Oculus HMD Variables ovrHmd Hmd; ovrEyeRenderDesc EyeRenderDesc[2]; Matrix4f Projection[2]; // Projection matrix for eye. Matrix4f OrthoProjection[2]; // Projection for 2D. ovrPosef EyeRenderPose[2]; // Poses we used for rendering. ovrTexture EyeTexture[2]; Sizei EyeRenderSize[2]; // Saved render eye sizes; base for dynamic sizing. // Sensor caps applied. unsigned StartTrackingCaps; bool UsingDebugHmd; // Frame timing logic. enum { SecondsOfFpsMeasurement = 1 }; int FrameCounter; int TotalFrameCounter; float SecondsPerFrame; float FPS; double LastFpsUpdate; // Times a single frame. double LastUpdate; // Loaded data. String MainFilePath; Array > CollisionModels; Array > GroundCollisionModels; // Loading process displays screenshot in first frame // and then proceeds to load until finished. enum LoadingStateType { LoadingState_Frame0, LoadingState_DoLoad, LoadingState_Finished } LoadingState; // Current status flags so that edges can be reported bool HaveVisionTracking; bool HavePositionTracker; bool HaveHMDConnected; 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; // Overlay notifications time out in double NotificationTimeout; // ***** 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 EnableSensor; bool MonoscopicRender; float PositionTrackingScale; bool ScaleAffectsEyeHeight; float DesiredPixelDensity; float FovSideTanMax; float FovSideTanLimit; // Limit value for Fov. // Time-warp. bool TimewarpEnabled; bool TimewarpNoJitEnabled; float TimewarpRenderIntervalInSeconds; bool FreezeEyeUpdate; bool FreezeEyeOneFrameRendered; // Other global settings. float CenterPupilDepthMeters; bool ForceZeroHeadMovement; bool VsyncEnabled; bool MultisampleEnabled; #if defined(OVR_OS_LINUX) bool LinuxFullscreenOnDevice; #endif // DK2 only: bool IsLowPersistence; bool DynamicPrediction; bool DisplaySleep; bool PositionTrackingEnabled; bool PixelLuminanceOverdrive; bool HqAaDistortion; bool MirrorToWindow; // 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; // Logging bool IsLogging; // ***** 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