diff options
136 files changed, 5747 insertions, 3176 deletions
diff --git a/LibOVR/Include/OVRVersion.h b/LibOVR/Include/OVRVersion.h index 5c2de3c..14f83e6 100644 --- a/LibOVR/Include/OVRVersion.h +++ b/LibOVR/Include/OVRVersion.h @@ -27,7 +27,7 @@ limitations under the License. #define OVR_MAJOR_VERSION 0 #define OVR_MINOR_VERSION 3 -#define OVR_BUILD_VERSION 1 -#define OVR_VERSION_STRING "0.3.1" +#define OVR_BUILD_VERSION 2 +#define OVR_VERSION_STRING "0.3.2" #endif diff --git a/LibOVR/Projects/Win32/VS2010/LibOVR.vcxproj b/LibOVR/Projects/Win32/VS2010/LibOVR.vcxproj index f293cb9..7bab8ca 100644 --- a/LibOVR/Projects/Win32/VS2010/LibOVR.vcxproj +++ b/LibOVR/Projects/Win32/VS2010/LibOVR.vcxproj @@ -68,6 +68,8 @@ <ClInclude Include="..\..\..\Src\OVR_JSON.h" /> <ClInclude Include="..\..\..\Src\OVR_LatencyTestImpl.h" /> <ClInclude Include="..\..\..\Src\OVR_Profile.h" /> + <ClInclude Include="..\..\..\Src\OVR_Recording.h" /> + <ClInclude Include="..\..\..\Src\OVR_RecordingDefs.h" /> <ClInclude Include="..\..\..\Src\OVR_Sensor2Impl.h" /> <ClInclude Include="..\..\..\Src\OVR_Sensor2ImplUtil.h" /> <ClInclude Include="..\..\..\Src\OVR_SensorCalibration.h" /> @@ -137,6 +139,7 @@ <ClCompile Include="..\..\..\Src\OVR_JSON.cpp" /> <ClCompile Include="..\..\..\Src\OVR_LatencyTestImpl.cpp" /> <ClCompile Include="..\..\..\Src\OVR_Profile.cpp" /> + <ClCompile Include="..\..\..\Src\OVR_Recording.cpp" /> <ClCompile Include="..\..\..\Src\OVR_Sensor2Impl.cpp" /> <ClCompile Include="..\..\..\Src\OVR_SensorCalibration.cpp" /> <ClCompile Include="..\..\..\Src\OVR_SensorFilter.cpp" /> @@ -250,7 +253,7 @@ </CustomBuild> </ItemGroup> <PropertyGroup Label="Globals"> - <ProjectGuid>{720F6C5E-6DCF-495A-B25E-10540EA081A2}</ProjectGuid> + <ProjectGuid>{934B40C7-F40A-4E4C-97A7-B9659BE0A441}</ProjectGuid> <Keyword>Win32Proj</Keyword> <RootNamespace>LibOVR</RootNamespace> <ProjectName>LibOVR</ProjectName> @@ -342,7 +345,7 @@ <MinimalRebuild>false</MinimalRebuild> <OmitDefaultLibName>true</OmitDefaultLibName> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - <AdditionalIncludeDirectories>../../../../3rdParty/glext/;$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <AdditionalIncludeDirectories>$(DXSDK_DIR)/Include;../../../../3rdParty/glext/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> </ClCompile> <Link> <SubSystem>Windows</SubSystem> @@ -364,7 +367,7 @@ <MinimalRebuild>false</MinimalRebuild> <OmitDefaultLibName>true</OmitDefaultLibName> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> - <AdditionalIncludeDirectories>../../../../3rdParty/glext/;$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <AdditionalIncludeDirectories>$(DXSDK_DIR)/Include;../../../../3rdParty/glext/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <OmitFramePointers>false</OmitFramePointers> </ClCompile> <Link> @@ -388,7 +391,7 @@ <MultiProcessorCompilation>true</MultiProcessorCompilation> <OmitDefaultLibName>true</OmitDefaultLibName> <DebugInformationFormat>OldStyle</DebugInformationFormat> - <AdditionalIncludeDirectories>../../../../3rdParty/glext/;$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <AdditionalIncludeDirectories>$(DXSDK_DIR)/Include;../../../../3rdParty/glext/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <WholeProgramOptimization>false</WholeProgramOptimization> </ClCompile> <Link> @@ -414,7 +417,7 @@ <MultiProcessorCompilation>true</MultiProcessorCompilation> <OmitDefaultLibName>true</OmitDefaultLibName> <DebugInformationFormat>OldStyle</DebugInformationFormat> - <AdditionalIncludeDirectories>../../../../3rdParty/glext/;$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <AdditionalIncludeDirectories>$(DXSDK_DIR)/Include;../../../../3rdParty/glext/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <WholeProgramOptimization>false</WholeProgramOptimization> </ClCompile> <Link> diff --git a/LibOVR/Projects/Win32/VS2010/LibOVR.vcxproj.filters b/LibOVR/Projects/Win32/VS2010/LibOVR.vcxproj.filters index c1a53cd..344a7cd 100644 --- a/LibOVR/Projects/Win32/VS2010/LibOVR.vcxproj.filters +++ b/LibOVR/Projects/Win32/VS2010/LibOVR.vcxproj.filters @@ -129,6 +129,7 @@ <ClCompile Include="..\..\..\Src\CAPI\GL\CAPI_GL_Util.cpp"> <Filter>CAPI\GL</Filter> </ClCompile> + <ClCompile Include="..\..\..\Src\OVR_Recording.cpp" /> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\..\Src\OVR_Device.h" /> @@ -282,6 +283,8 @@ <ClInclude Include="..\..\..\Src\CAPI\GL\CAPI_GL_Util.h"> <Filter>CAPI\GL</Filter> </ClInclude> + <ClInclude Include="..\..\..\Src\OVR_Recording.h" /> + <ClInclude Include="..\..\..\Src\OVR_RecordingDefs.h" /> </ItemGroup> <ItemGroup> <Filter Include="Util"> @@ -300,7 +303,7 @@ <UniqueIdentifier>{191043aa-7805-44f0-a0a4-02799289365c}</UniqueIdentifier> </Filter> <Filter Include="CAPI\GL"> - <UniqueIdentifier>{d1b72f17-b0a8-420d-8625-13c4948df7ed}</UniqueIdentifier> + <UniqueIdentifier>{fe5d391d-40b2-48a6-8615-6654c19b3a71}</UniqueIdentifier> </Filter> </ItemGroup> <ItemGroup> diff --git a/LibOVR/Projects/Win32/VS2012/LibOVR.vcxproj b/LibOVR/Projects/Win32/VS2012/LibOVR.vcxproj index a0718bf..78a6ae1 100644 --- a/LibOVR/Projects/Win32/VS2012/LibOVR.vcxproj +++ b/LibOVR/Projects/Win32/VS2012/LibOVR.vcxproj @@ -68,6 +68,8 @@ <ClInclude Include="..\..\..\Src\OVR_JSON.h" /> <ClInclude Include="..\..\..\Src\OVR_LatencyTestImpl.h" /> <ClInclude Include="..\..\..\Src\OVR_Profile.h" /> + <ClInclude Include="..\..\..\Src\OVR_Recording.h" /> + <ClInclude Include="..\..\..\Src\OVR_RecordingDefs.h" /> <ClInclude Include="..\..\..\Src\OVR_Sensor2Impl.h" /> <ClInclude Include="..\..\..\Src\OVR_Sensor2ImplUtil.h" /> <ClInclude Include="..\..\..\Src\OVR_SensorCalibration.h" /> @@ -137,6 +139,7 @@ <ClCompile Include="..\..\..\Src\OVR_JSON.cpp" /> <ClCompile Include="..\..\..\Src\OVR_LatencyTestImpl.cpp" /> <ClCompile Include="..\..\..\Src\OVR_Profile.cpp" /> + <ClCompile Include="..\..\..\Src\OVR_Recording.cpp" /> <ClCompile Include="..\..\..\Src\OVR_Sensor2Impl.cpp" /> <ClCompile Include="..\..\..\Src\OVR_SensorCalibration.cpp" /> <ClCompile Include="..\..\..\Src\OVR_SensorFilter.cpp" /> diff --git a/LibOVR/Projects/Win32/VS2012/LibOVR.vcxproj.filters b/LibOVR/Projects/Win32/VS2012/LibOVR.vcxproj.filters index 579bddc..615f346 100644 --- a/LibOVR/Projects/Win32/VS2012/LibOVR.vcxproj.filters +++ b/LibOVR/Projects/Win32/VS2012/LibOVR.vcxproj.filters @@ -129,6 +129,7 @@ <ClCompile Include="..\..\..\Src\CAPI\GL\CAPI_GL_Util.cpp"> <Filter>CAPI\GL</Filter> </ClCompile> + <ClCompile Include="..\..\..\Src\OVR_Recording.cpp" /> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\..\Src\OVR_Device.h" /> @@ -282,6 +283,8 @@ <ClInclude Include="..\..\..\Src\CAPI\GL\CAPI_GL_Util.h"> <Filter>CAPI\GL</Filter> </ClInclude> + <ClInclude Include="..\..\..\Src\OVR_Recording.h" /> + <ClInclude Include="..\..\..\Src\OVR_RecordingDefs.h" /> </ItemGroup> <ItemGroup> <Filter Include="Util"> @@ -300,7 +303,7 @@ <UniqueIdentifier>{191043aa-7805-44f0-a0a4-02799289365c}</UniqueIdentifier> </Filter> <Filter Include="CAPI\GL"> - <UniqueIdentifier>{c86c7070-6bf4-4ae4-b9bf-4c21d2ba9516}</UniqueIdentifier> + <UniqueIdentifier>{0e2e7bad-69a3-464a-9256-12114645638c}</UniqueIdentifier> </Filter> </ItemGroup> <ItemGroup> diff --git a/LibOVR/Projects/Win32/VS2013/LibOVR.vcxproj b/LibOVR/Projects/Win32/VS2013/LibOVR.vcxproj index a5f9297..b6637c9 100644 --- a/LibOVR/Projects/Win32/VS2013/LibOVR.vcxproj +++ b/LibOVR/Projects/Win32/VS2013/LibOVR.vcxproj @@ -68,6 +68,8 @@ <ClInclude Include="..\..\..\Src\OVR_JSON.h" /> <ClInclude Include="..\..\..\Src\OVR_LatencyTestImpl.h" /> <ClInclude Include="..\..\..\Src\OVR_Profile.h" /> + <ClInclude Include="..\..\..\Src\OVR_Recording.h" /> + <ClInclude Include="..\..\..\Src\OVR_RecordingDefs.h" /> <ClInclude Include="..\..\..\Src\OVR_Sensor2Impl.h" /> <ClInclude Include="..\..\..\Src\OVR_Sensor2ImplUtil.h" /> <ClInclude Include="..\..\..\Src\OVR_SensorCalibration.h" /> @@ -137,6 +139,7 @@ <ClCompile Include="..\..\..\Src\OVR_JSON.cpp" /> <ClCompile Include="..\..\..\Src\OVR_LatencyTestImpl.cpp" /> <ClCompile Include="..\..\..\Src\OVR_Profile.cpp" /> + <ClCompile Include="..\..\..\Src\OVR_Recording.cpp" /> <ClCompile Include="..\..\..\Src\OVR_Sensor2Impl.cpp" /> <ClCompile Include="..\..\..\Src\OVR_SensorCalibration.cpp" /> <ClCompile Include="..\..\..\Src\OVR_SensorFilter.cpp" /> diff --git a/LibOVR/Projects/Win32/VS2013/LibOVR.vcxproj.filters b/LibOVR/Projects/Win32/VS2013/LibOVR.vcxproj.filters index becf605..90d8b15 100644 --- a/LibOVR/Projects/Win32/VS2013/LibOVR.vcxproj.filters +++ b/LibOVR/Projects/Win32/VS2013/LibOVR.vcxproj.filters @@ -129,6 +129,7 @@ <ClCompile Include="..\..\..\Src\CAPI\GL\CAPI_GL_Util.cpp"> <Filter>CAPI\GL</Filter> </ClCompile> + <ClCompile Include="..\..\..\Src\OVR_Recording.cpp" /> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\..\Src\OVR_CAPI.h" /> @@ -282,6 +283,8 @@ <ClInclude Include="..\..\..\Src\CAPI\GL\CAPI_GL_Util.h"> <Filter>CAPI\GL</Filter> </ClInclude> + <ClInclude Include="..\..\..\Src\OVR_Recording.h" /> + <ClInclude Include="..\..\..\Src\OVR_RecordingDefs.h" /> </ItemGroup> <ItemGroup> <CustomBuild Include="..\..\..\Src\CAPI\Shaders\DistortionTimewarpChroma_vs.vsh"> @@ -326,7 +329,7 @@ <UniqueIdentifier>{470c25c2-99a2-439b-9f6b-761e8c70f84e}</UniqueIdentifier> </Filter> <Filter Include="CAPI\GL"> - <UniqueIdentifier>{b8c0476b-d36b-4d31-8141-4d42f78b9e51}</UniqueIdentifier> + <UniqueIdentifier>{47ac92b1-d962-4180-90a5-846feef19a6b}</UniqueIdentifier> </Filter> </ItemGroup> </Project>
\ No newline at end of file diff --git a/LibOVR/Src/CAPI/CAPI_DistortionRenderer.cpp b/LibOVR/Src/CAPI/CAPI_DistortionRenderer.cpp index 8c0f8b8..613d8fb 100644 --- a/LibOVR/Src/CAPI/CAPI_DistortionRenderer.cpp +++ b/LibOVR/Src/CAPI/CAPI_DistortionRenderer.cpp @@ -26,6 +26,8 @@ limitations under the License. #include "CAPI_DistortionRenderer.h" +#if defined (OVR_OS_WIN32) + // TBD: Move to separate config file that handles back-ends. #define OVR_D3D_VERSION 11 #include "D3D1X/CAPI_D3D1X_DistortionRenderer.h" @@ -39,6 +41,8 @@ limitations under the License. #include "D3D1X/CAPI_D3D9_DistortionRenderer.h" #undef OVR_D3D_VERSION +#endif + #include "GL/CAPI_GL_DistortionRenderer.h" namespace OVR { namespace CAPI { @@ -53,9 +57,15 @@ DistortionRenderer::CreateFunc DistortionRenderer::APICreateRegistry[ovrRenderAP 0, // None &GL::DistortionRenderer::Create, 0, // Android_GLES +#if defined (OVR_OS_WIN32) &D3D9::DistortionRenderer::Create, &D3D10::DistortionRenderer::Create, &D3D11::DistortionRenderer::Create +#else + 0, + 0, + 0 +#endif }; diff --git a/LibOVR/Src/CAPI/CAPI_DistortionRenderer.h b/LibOVR/Src/CAPI/CAPI_DistortionRenderer.h index d1b8011..a256bc6 100644 --- a/LibOVR/Src/CAPI/CAPI_DistortionRenderer.h +++ b/LibOVR/Src/CAPI/CAPI_DistortionRenderer.h @@ -60,7 +60,7 @@ public: // Under D3D, apiConfig includes D3D Device pointer, back buffer and other // needed structures. virtual bool Initialize(const ovrRenderAPIConfig* apiConfig, - unsigned hmdCaps, unsigned distortionCaps) = 0; + unsigned distortionCaps) = 0; // Submits one eye texture for rendering. This is in the separate method to // allow "submit as you render" scenarios on horizontal screens where one @@ -72,7 +72,11 @@ public: virtual void EndFrame(bool swapBuffers, unsigned char* latencyTesterDrawColor, unsigned char* latencyTester2DrawColor) = 0; + // Stores the current graphics pipeline state so it can be restored later. + void SaveGraphicsState() { if (!(RState.EnabledHmdCaps & ovrHmdCap_NoRestore)) GfxState->Save(); } + // Restores the saved graphics pipeline state. + void RestoreGraphicsState() { if (!(RState.EnabledHmdCaps & ovrHmdCap_NoRestore)) GfxState->Restore(); } // *** Creation Factory logic @@ -86,10 +90,24 @@ public: static CreateFunc APICreateRegistry[ovrRenderAPI_Count]; protected: + + class GraphicsState : public RefCountBase<GraphicsState> + { + public: + GraphicsState() : IsValid(false) {} + virtual ~GraphicsState() {} + virtual void Save() = 0; + virtual void Restore() = 0; + + protected: + bool IsValid; + }; + const ovrRenderAPIType RenderAPI; const ovrHmd HMD; FrameTimeManager& TimeManager; - const HMDRenderState& RState; + const HMDRenderState& RState; + Ptr<GraphicsState> GfxState; }; }} // namespace OVR::CAPI diff --git a/LibOVR/Src/CAPI/CAPI_FrameTimeManager.cpp b/LibOVR/Src/CAPI/CAPI_FrameTimeManager.cpp index de7eeeb..3e776c3 100644 --- a/LibOVR/Src/CAPI/CAPI_FrameTimeManager.cpp +++ b/LibOVR/Src/CAPI/CAPI_FrameTimeManager.cpp @@ -233,10 +233,9 @@ void FrameTimeManager::Init(HmdRenderInfo& renderInfo) } void FrameTimeManager::ResetFrameTiming(unsigned frameIndex, - bool vsyncEnabled, bool dynamicPrediction, + bool dynamicPrediction, bool sdkRender) -{ - VsyncEnabled = vsyncEnabled; +{ DynamicPrediction = dynamicPrediction; SdkRender = sdkRender; @@ -397,6 +396,8 @@ void FrameTimeManager::Timing::InitTimingFromInputs(const FrameTimeManager::Timi TimeWarpStartEndTimes[1][0] = MidpointTime; TimeWarpStartEndTimes[1][1] = MidpointTime; break; + default: + break; } } @@ -474,7 +475,7 @@ double FrameTimeManager::GetEyePredictionTime(ovrEyeType eye) return ovr_GetTimeInSeconds() + ScreenSwitchingDelay + NoVSyncToScanoutDelay; } -Posef FrameTimeManager::GetEyePredictionPose(ovrHmd hmd, ovrEyeType eye) +Transformf FrameTimeManager::GetEyePredictionPose(ovrHmd hmd, ovrEyeType eye) { double eyeRenderTime = GetEyePredictionTime(eye); ovrSensorState eyeState = ovrHmd_GetSensorState(hmd, eyeRenderTime); diff --git a/LibOVR/Src/CAPI/CAPI_FrameTimeManager.h b/LibOVR/Src/CAPI/CAPI_FrameTimeManager.h index 07a2963..4693697 100644 --- a/LibOVR/Src/CAPI/CAPI_FrameTimeManager.h +++ b/LibOVR/Src/CAPI/CAPI_FrameTimeManager.h @@ -179,7 +179,7 @@ public: // Called with each new ConfigureRendering. void ResetFrameTiming(unsigned frameIndex, - bool vsyncEnabled, bool dynamicPrediction, bool sdkRender); + bool dynamicPrediction, bool sdkRender); void SetVsync(bool enabled) { VsyncEnabled = enabled; } @@ -192,7 +192,7 @@ public: Timing GetFrameTiming(unsigned frameIndex); double GetEyePredictionTime(ovrEyeType eye); - Posef GetEyePredictionPose(ovrHmd hmd, ovrEyeType eye); + Transformf GetEyePredictionPose(ovrHmd hmd, ovrEyeType eye); void GetTimewarpPredictions(ovrEyeType eye, double timewarpStartEnd[2]); void GetTimewarpMatrices(ovrHmd hmd, ovrEyeType eye, ovrPosef renderPose, ovrMatrix4f twmOut[2]); diff --git a/LibOVR/Src/CAPI/CAPI_HMDRenderState.cpp b/LibOVR/Src/CAPI/CAPI_HMDRenderState.cpp index bdfa0c7..00bdea2 100644 --- a/LibOVR/Src/CAPI/CAPI_HMDRenderState.cpp +++ b/LibOVR/Src/CAPI/CAPI_HMDRenderState.cpp @@ -24,16 +24,11 @@ limitations under the License. ************************************************************************************/ - - - #include "CAPI_HMDRenderState.h" - namespace OVR { namespace CAPI { - //------------------------------------------------------------------------------------- // ***** HMDRenderState @@ -47,14 +42,14 @@ HMDRenderState::HMDRenderState(ovrHmd hmd, Profile* userProfile, const OVR::HMDI Distortion[1] = CalculateDistortionRenderDesc(StereoEye_Right, RenderInfo, 0); ClearColor[0] = ClearColor[1] = ClearColor[2] = ClearColor[3] =0.0f; + + EnabledHmdCaps = 0; } HMDRenderState::~HMDRenderState() { - } - ovrHmdDesc HMDRenderState::GetDesc() { ovrHmdDesc d; @@ -71,7 +66,9 @@ ovrHmdDesc HMDRenderState::GetDesc() d.DisplayDeviceName = HMDInfo.DisplayDeviceName; d.DisplayId = HMDInfo.DisplayId; - d.Caps = ovrHmdCap_YawCorrection | ovrHmdCap_Orientation | ovrHmdCap_Present; + d.HmdCaps = ovrHmdCap_Present | ovrHmdCap_NoVSync; + d.SensorCaps = ovrSensorCap_YawCorrection | ovrSensorCap_Orientation; + d.DistortionCaps = ovrDistortionCap_Chromatic | ovrDistortionCap_TimeWarp | ovrDistortionCap_Vignette; if (strstr(HMDInfo.ProductName, "DK1")) { @@ -79,8 +76,10 @@ ovrHmdDesc HMDRenderState::GetDesc() } else if (strstr(HMDInfo.ProductName, "DK2")) { - d.Type = ovrHmd_DK2; - d.Caps |= ovrHmdCap_Position | ovrHmdCap_LowPersistence; + d.Type = ovrHmd_DK2; + d.HmdCaps |= ovrHmdCap_LowPersistence | + ovrHmdCap_LatencyTest | ovrHmdCap_DynamicPrediction; + d.SensorCaps |= ovrSensorCap_Position; } DistortionRenderDesc& leftDistortion = Distortion[0]; @@ -116,30 +115,27 @@ ovrSizei HMDRenderState::GetFOVTextureSize(int eye, ovrFovPort fov, float pixels return CalculateIdealPixelSize(seye, Distortion[eye], fov, pixelsPerDisplayPixel); } -ovrEyeRenderDesc HMDRenderState::calcRenderDesc(const ovrEyeDesc& eyeDesc) +ovrEyeRenderDesc HMDRenderState::calcRenderDesc(ovrEyeType eyeType, const ovrFovPort& fov) { HmdRenderInfo& hmdri = RenderInfo; - StereoEye eye = (eyeDesc.Eye == ovrEye_Left) ? StereoEye_Left : StereoEye_Right; + StereoEye eye = (eyeType == ovrEye_Left) ? StereoEye_Left : StereoEye_Right; ovrEyeRenderDesc e0; - - e0.Desc = eyeDesc; + + e0.Eye = eyeType; + e0.Fov = fov; e0.ViewAdjust = CalculateEyeVirtualCameraOffset(hmdri, eye, false); e0.DistortedViewport = GetFramebufferViewport(eye, hmdri); e0.PixelsPerTanAngleAtCenter = Distortion[0].PixelsPerTanAngleAtCenter; - // If RenderViewport is uninitialized, set it to texture size. - if (Sizei(e0.Desc.RenderViewport.Size) == Sizei(0)) - e0.Desc.RenderViewport.Size = e0.Desc.TextureSize; - return e0; } void HMDRenderState::setupRenderDesc( ovrEyeRenderDesc eyeRenderDescOut[2], - const ovrEyeDesc eyeDescIn[2] ) + const ovrFovPort eyeFovIn[2] ) { - eyeRenderDescOut[0] = EyeRenderDesc[0] = calcRenderDesc(eyeDescIn[0]); - eyeRenderDescOut[1] = EyeRenderDesc[1] = calcRenderDesc(eyeDescIn[1]); + eyeRenderDescOut[0] = EyeRenderDesc[0] = calcRenderDesc(ovrEye_Left, eyeFovIn[0]); + eyeRenderDescOut[1] = EyeRenderDesc[1] = calcRenderDesc(ovrEye_Right, eyeFovIn[1]); } diff --git a/LibOVR/Src/CAPI/CAPI_HMDRenderState.h b/LibOVR/Src/CAPI/CAPI_HMDRenderState.h index 408af51..a4e8d21 100644 --- a/LibOVR/Src/CAPI/CAPI_HMDRenderState.h +++ b/LibOVR/Src/CAPI/CAPI_HMDRenderState.h @@ -57,10 +57,10 @@ public: ovrHmdDesc GetDesc(); ovrSizei GetFOVTextureSize(int eye, ovrFovPort fov, float pixelsPerDisplayPixel); - ovrEyeRenderDesc calcRenderDesc(const ovrEyeDesc& eyeDesc); + ovrEyeRenderDesc calcRenderDesc(ovrEyeType eyeType, const ovrFovPort& fov); void setupRenderDesc(ovrEyeRenderDesc eyeRenderDescOut[2], - const ovrEyeDesc eyeDescIn[2]); + const ovrFovPort eyeFovIn[2]); public: // HMDInfo shouldn't change, as its string pointers are passed out. @@ -71,7 +71,7 @@ public: HmdRenderInfo RenderInfo; DistortionRenderDesc Distortion[2]; - ovrEyeRenderDesc EyeRenderDesc[2]; + ovrEyeRenderDesc EyeRenderDesc[2]; // Clear color used for distortion float ClearColor[4]; @@ -80,7 +80,7 @@ public: ovrPosef EyeRenderPoses[2]; // Capabilities passed to Configure. - unsigned HMDCaps; + unsigned EnabledHmdCaps; unsigned DistortionCaps; }; diff --git a/LibOVR/Src/CAPI/CAPI_HMDState.cpp b/LibOVR/Src/CAPI/CAPI_HMDState.cpp index 156b84a..fd98225 100644 --- a/LibOVR/Src/CAPI/CAPI_HMDState.cpp +++ b/LibOVR/Src/CAPI/CAPI_HMDState.cpp @@ -35,7 +35,8 @@ namespace OVR { namespace CAPI { HMDState::HMDState(HMDDevice* device) - : pHMD(device), HMDInfoW(device), HMDInfo(HMDInfoW.h), + : pHMD(device), HMDInfoW(device), HMDInfo(HMDInfoW.h), + EnabledHmdCaps(0), HmdCapsAppliedToSensor(0), SensorStarted(0), SensorCreated(0), SensorCaps(0), AddSensorCount(0), AddLatencyTestCount(0), AddLatencyTestDisplayCount(0), RenderState(getThis(), pHMD->GetProfile(), HMDInfoW.h), @@ -66,6 +67,7 @@ HMDState::HMDState(HMDDevice* device) HMDState::HMDState(ovrHmdType hmdType) : pHMD(0), HMDInfoW(hmdType), HMDInfo(HMDInfoW.h), + EnabledHmdCaps(0), SensorStarted(0), SensorCreated(0), SensorCaps(0), AddSensorCount(0), AddLatencyTestCount(0), AddLatencyTestDisplayCount(0), RenderState(getThis(), 0, HMDInfoW.h), // No profile. @@ -97,7 +99,7 @@ HMDState::~HMDState() OVR_ASSERT(GlobalState::pInstance); StopSensor(); - ConfigureRendering(0,0,0,0,0); + ConfigureRendering(0,0,0,0); OVR_CAPI_VISION_CODE( OVR_ASSERT(pPoseTracker == 0); ) @@ -105,6 +107,7 @@ HMDState::~HMDState() } + //------------------------------------------------------------------------------------- // *** Sensor @@ -112,143 +115,102 @@ bool HMDState::StartSensor(unsigned supportedCaps, unsigned requiredCaps) { Lock::Locker lockScope(&DevicesLock); - // TBD: Implement an optimized path that allows you to change caps such as yaw. - if (SensorStarted) - { - - if ((SensorCaps ^ ovrHmdCap_LowPersistence) == supportedCaps) - { - // TBD: Fast persistance switching; redesign to make this better. - if (HMDInfo.HmdType == HmdType_CrystalCoveProto || HMDInfo.HmdType == HmdType_DK2) - { - // switch to full persistence - updateLowPersistenceMode((supportedCaps & ovrHmdCap_LowPersistence) != 0); - SensorCaps = supportedCaps; - return true; - } - } - - if ((SensorCaps ^ ovrHmdCap_DynamicPrediction) == supportedCaps) - { - // TBD: Fast persistance switching; redesign to make this better. - if (HMDInfo.HmdType == HmdType_DK2) - { - // switch to full persistence - TimeManager.ResetFrameTiming(TimeManager.GetFrameTiming().FrameIndex, - (supportedCaps & ovrHmdCap_NoVSync) ? false : true, - (supportedCaps & ovrHmdCap_DynamicPrediction) ? true : false, - RenderingConfigured); - SensorCaps = supportedCaps; - return true; - } - } - - StopSensor(); - } - - supportedCaps |= requiredCaps; + bool crystalCoveOrBetter = (HMDInfo.HmdType == HmdType_CrystalCoveProto) || + (HMDInfo.HmdType == HmdType_DK2); + bool sensorCreatedJustNow = false; // TBD: In case of sensor not being immediately available, it would be good to check // yaw config availability to match it with ovrHmdCap_YawCorrection requirement. // - if (requiredCaps & ovrHmdCap_Position) + if (!crystalCoveOrBetter) { - if (HMDInfo.HmdType != HmdType_CrystalCoveProto && HMDInfo.HmdType != HmdType_DK2) + if (requiredCaps & ovrSensorCap_Position) { - pLastError = "ovrHmdCap_Position not supported on this HMD."; - return false; + pLastError = "ovrSensorCap_Position not supported on this HMD."; + return false; } } - if (requiredCaps & ovrHmdCap_LowPersistence) - { - if (HMDInfo.HmdType != HmdType_CrystalCoveProto && HMDInfo.HmdType != HmdType_DK2) - { - pLastError = "ovrHmdCap_LowPersistence not supported on this HMD."; - return false; - } - } + supportedCaps |= requiredCaps; - SensorCreated = false; - pSensor.Clear(); - if (pHMD) + if (pHMD && !pSensor) { // Zero AddSensorCount before creation, in case it fails (or succeeds but then // immediately gets disconnected) followed by another Add notification. - AddSensorCount = 0; - pSensor = *pHMD->GetSensor(); - } + AddSensorCount = 0; + pSensor = *pHMD->GetSensor(); + sensorCreatedJustNow= true; - if (!pSensor) - { - if (requiredCaps & ovrHmdCap_Orientation) + if (pSensor) { - pLastError = "Failed to create sensor."; - return false; - } - // Succeed, waiting for sensor become available later. - LogText("StartSensor succeeded - waiting for sensor.\n"); - } - else - { - pSensor->SetReportRate(500); - SFusion.AttachToSensor(pSensor); - applyProfileToSensorFusion(); - - if (requiredCaps & ovrHmdCap_YawCorrection) + pSensor->SetReportRate(500); + SFusion.AttachToSensor(pSensor); + applyProfileToSensorFusion(); + } + else { - if (!SFusion.HasMagCalibration()) + if (requiredCaps & ovrSensorCap_Orientation) { - pLastError = "ovrHmdCap_YawCorrection not available."; - SFusion.AttachToSensor(0); - SFusion.Reset(); - pSensor.Clear(); + pLastError = "Failed to create sensor."; return false; } - } + } + } - SFusion.SetYawCorrectionEnabled((supportedCaps & ovrHmdCap_YawCorrection) != 0); - LogText("Sensor created.\n"); - if (supportedCaps & ovrHmdCap_LowPersistence) - { - updateLowPersistenceMode(true); - } - else - { - if (HMDInfo.HmdType == HmdType_CrystalCoveProto || HMDInfo.HmdType == HmdType_DK2) - { - // switch to full persistence - updateLowPersistenceMode(false); - } - } - - if (HMDInfo.HmdType == HmdType_DK2) + if ((requiredCaps & ovrSensorCap_YawCorrection) && !pSensor->IsMagCalibrated()) + { + pLastError = "ovrHmdCap_YawCorrection not available."; + if (sensorCreatedJustNow) { - updateLatencyTestForHmd((supportedCaps & ovrHmdCap_LatencyTest) != 0); - } + SFusion.AttachToSensor(0); + SFusion.Reset(); + pSensor.Clear(); + } + return false; + } + + SFusion.SetYawCorrectionEnabled((supportedCaps & ovrSensorCap_YawCorrection) != 0); + + if (pSensor && sensorCreatedJustNow) + { + LogText("Sensor created.\n"); + SensorCreated = true; + } + + updateDK2FeaturesTiedToSensor(sensorCreatedJustNow); + #ifdef OVR_CAPI_VISIONSUPPORT - if (supportedCaps & ovrHmdCap_Position) + + if (crystalCoveOrBetter && (supportedCaps & ovrSensorCap_Position)) + { + if (!pPoseTracker) { pPoseTracker = new Vision::PoseTracker(SFusion); if (pPoseTracker) { pPoseTracker->AssociateHMD(pSensor); + LogText("Sensor Pose tracker created.\n"); } - LogText("Sensor Pose tracker created.\n"); } + // TBD: How do we verify that position tracking is actually available // i.e. camera is plugged in? + } + else if (pPoseTracker) + { + // TBD: Internals not thread safe - must fix!! + delete pPoseTracker; + pPoseTracker = 0; + LogText("Sensor Pose tracker destroyed.\n"); + } #endif // OVR_CAPI_VISIONSUPPORT - SensorCreated = true; - } - SensorCaps = supportedCaps; - SensorStarted = true; + SensorStarted = true; return true; } @@ -274,6 +236,7 @@ void HMDState::StopSensor() SFusion.AttachToSensor(0); SFusion.Reset(); pSensor.Clear(); + HmdCapsAppliedToSensor = 0; AddSensorCount = 0; SensorCaps = 0; SensorCreated = false; @@ -319,7 +282,8 @@ ovrSensorState HMDState::PredictedSensorState(double absTime) // Not needed yet; SFusion.AttachToSensor(0); // This seems to reset orientation anyway... pSensor.Clear(); - SensorCreated = false; + SensorCreated = false; + HmdCapsAppliedToSensor = 0; } } else @@ -361,11 +325,11 @@ bool HMDState::checkCreateSensor() { pSensor->SetReportRate(500); SFusion.AttachToSensor(pSensor); - SFusion.SetYawCorrectionEnabled((SensorCaps & ovrHmdCap_YawCorrection) != 0); + SFusion.SetYawCorrectionEnabled((SensorCaps & ovrSensorCap_YawCorrection) != 0); applyProfileToSensorFusion(); #ifdef OVR_CAPI_VISIONSUPPORT - if (SensorCaps & ovrHmdCap_Position) + if (SensorCaps & ovrSensorCap_Position) { pPoseTracker = new Vision::PoseTracker(SFusion); if (pPoseTracker) @@ -407,20 +371,31 @@ bool HMDState::GetSensorDesc(ovrSensorDesc* descOut) void HMDState::applyProfileToSensorFusion() { - Profile* profile = pHMD ? pHMD->GetProfile() : 0; - SFusion.SetUserHeadDimensions ( profile, RenderState.RenderInfo ); + if (!pHMD) + return; + Profile* profile = pHMD->GetProfile(); + if (!profile) + { + OVR_ASSERT(false); + return; + } + SFusion.SetUserHeadDimensions ( *profile, RenderState.RenderInfo ); } void HMDState::updateLowPersistenceMode(bool lowPersistence) const { OVR_ASSERT(pSensor); DisplayReport dr; - pSensor->GetDisplayReport(&dr); + + if (pSensor.GetPtr()) + { + pSensor->GetDisplayReport(&dr); - dr.Persistence = (UInt16) (dr.TotalRows * (lowPersistence ? 0.18f : 1.0f)); - dr.Brightness = lowPersistence ? 255 : 0; + dr.Persistence = (UInt16) (dr.TotalRows * (lowPersistence ? 0.18f : 1.0f)); + dr.Brightness = lowPersistence ? 255 : 0; - pSensor->SetDisplayReport(dr); + pSensor->SetDisplayReport(dr); + } } void HMDState::updateLatencyTestForHmd(bool latencyTesting) @@ -445,6 +420,63 @@ void HMDState::updateLatencyTestForHmd(bool latencyTesting) } } + +void HMDState::updateDK2FeaturesTiedToSensor(bool sensorCreatedJustNow) +{ + Lock::Locker lockScope(&DevicesLock); + + if (!SensorCreated || (HMDInfo.HmdType != HmdType_DK2)) + return; + + // Only send display reports if state changed or sensor initializing first time. + if (sensorCreatedJustNow || + ((HmdCapsAppliedToSensor ^ EnabledHmdCaps) & ovrHmdCap_LowPersistence)) + { + updateLowPersistenceMode((EnabledHmdCaps & ovrHmdCap_LowPersistence) ? true : false); + } + + if (sensorCreatedJustNow || ((HmdCapsAppliedToSensor ^ EnabledHmdCaps) & ovrHmdCap_LatencyTest)) + { + updateLatencyTestForHmd((EnabledHmdCaps & ovrHmdCap_LatencyTest) != 0); + } + + HmdCapsAppliedToSensor = EnabledHmdCaps & (ovrHmdCap_LowPersistence|ovrHmdCap_LatencyTest); +} + + + +void HMDState::SetEnabledHmdCaps(unsigned hmdCaps) +{ + + if (HMDInfo.HmdType == HmdType_DK2) + { + if ((EnabledHmdCaps ^ hmdCaps) & ovrHmdCap_DynamicPrediction) + { + // DynamicPrediction change + TimeManager.ResetFrameTiming(TimeManager.GetFrameTiming().FrameIndex, + (hmdCaps & ovrHmdCap_DynamicPrediction) ? true : false, + RenderingConfigured); + } + } + + if ((EnabledHmdCaps ^ hmdCaps) & ovrHmdCap_NoVSync) + { + TimeManager.SetVsync((hmdCaps & ovrHmdCap_NoVSync) ? false : true); + } + + + EnabledHmdCaps = hmdCaps & ovrHmdCap_Writable_Mask; + RenderState.EnabledHmdCaps = EnabledHmdCaps; + + // Unfortunately, LowPersistance and other flags are tied to sensor. + // This flag will apply the state of sensor is created; otherwise this will be delayed + // till StartSensor. + // Such behavior is less then ideal, but should be resolved with the service model. + + updateDK2FeaturesTiedToSensor(false); +} + + //------------------------------------------------------------------------------------- // ***** Property Access @@ -623,7 +655,7 @@ bool HMDState::ProcessLatencyTest(unsigned char rgbColorOut[3]) void HMDState::ProcessLatencyTest2(unsigned char rgbColorOut[3], double startTime) { // Check create. - if (!(SensorCaps & ovrHmdCap_LatencyTest)) + if (!(EnabledHmdCaps & ovrHmdCap_LatencyTest)) return; if (pLatencyTesterDisplay && !LatencyUtil2.HasDisplayDevice()) @@ -667,9 +699,8 @@ void HMDState::ProcessLatencyTest2(unsigned char rgbColorOut[3], double startTim // *** Rendering bool HMDState::ConfigureRendering(ovrEyeRenderDesc eyeRenderDescOut[2], - const ovrEyeDesc eyeDescIn[2], - const ovrRenderAPIConfig* apiConfig, - unsigned hmdCaps, + const ovrFovPort eyeFovIn[2], + const ovrRenderAPIConfig* apiConfig, unsigned distortionCaps) { ThreadChecker::Scope checkScope(&RenderAPIThreadChecker, "ovrHmd_ConfigureRendering"); @@ -693,13 +724,12 @@ bool HMDState::ConfigureRendering(ovrEyeRenderDesc eyeRenderDescOut[2], // Step 1: do basic setup configuration - RenderState.setupRenderDesc(eyeRenderDescOut, eyeDescIn); - RenderState.HMDCaps = hmdCaps; // Any cleaner way? + RenderState.setupRenderDesc(eyeRenderDescOut, eyeFovIn); + RenderState.EnabledHmdCaps = EnabledHmdCaps; // This is a copy... Any cleaner way? RenderState.DistortionCaps = distortionCaps; TimeManager.ResetFrameTiming(0, - (hmdCaps & ovrHmdCap_NoVSync) ? false : true, - (hmdCaps & ovrHmdCap_DynamicPrediction) ? true : false, + (EnabledHmdCaps & ovrHmdCap_DynamicPrediction) ? true : false, true); LastFrameTimeSeconds = 0.0f; @@ -714,7 +744,7 @@ bool HMDState::ConfigureRendering(ovrEyeRenderDesc eyeRenderDescOut[2], } if (!pRenderer || - !pRenderer->Initialize(apiConfig, hmdCaps, distortionCaps)) + !pRenderer->Initialize(apiConfig, distortionCaps)) { RenderingConfigured = false; return false; diff --git a/LibOVR/Src/CAPI/CAPI_HMDState.h b/LibOVR/Src/CAPI/CAPI_HMDState.h index d178042..0a1466f 100644 --- a/LibOVR/Src/CAPI/CAPI_HMDState.h +++ b/LibOVR/Src/CAPI/CAPI_HMDState.h @@ -94,7 +94,7 @@ public: { // pFunctionName may be not null here if function is called internally on the same thread. OVR_ASSERT_LOG((FirstThread == GetCurrentThreadId()), - ("%s (threadId=%d) called at the same times as %s (threadId=%d)\n", + ("%s (threadId=%p) called at the same times as %s (threadId=%p)\n", functionName, GetCurrentThreadId(), pFunctionName, FirstThread) ); } } @@ -146,6 +146,12 @@ public: ovrSensorState PredictedSensorState(double absTime); bool GetSensorDesc(ovrSensorDesc* descOut); + // Changes HMD Caps. + // Capability bits that are not directly or logically tied to one system (such as sensor) + // are grouped here. ovrHmdCap_VSync, for example, affects rendering and timing. + void SetEnabledHmdCaps(unsigned caps); + + bool ProcessLatencyTest(unsigned char rgbColorOut[3]); void ProcessLatencyTest2(unsigned char rgbColorOut[3], double startTime); @@ -153,9 +159,8 @@ public: // *** Rendering Setup bool ConfigureRendering(ovrEyeRenderDesc eyeRenderDescOut[2], - const ovrEyeDesc eyeDescIn[2], - const ovrRenderAPIConfig* apiConfig, - unsigned hmdCaps, + const ovrFovPort eyeFovIn[2], + const ovrRenderAPIConfig* apiConfig, unsigned distortionCaps); ovrPosef BeginEyeRender(ovrEyeType eye); @@ -191,23 +196,23 @@ public: { OVR_UNUSED1(functionName); // for Release build. OVR_ASSERT_LOG(BeginFrameCalled == true, - ("%s called outside ovrHmd_BeginFrame.")); + ("%s called outside ovrHmd_BeginFrame.", functionName)); OVR_ASSERT_LOG(BeginFrameThreadId == OVR::GetCurrentThreadId(), - ("%s called on a different thread then ovrHmd_BeginFrame.")); + ("%s called on a different thread then ovrHmd_BeginFrame.", functionName)); } void checkRenderingConfigured(const char* functionName) { OVR_UNUSED1(functionName); // for Release build. OVR_ASSERT_LOG(RenderingConfigured == true, - ("%s called without ovrHmd_ConfigureRendering.")); + ("%s called without ovrHmd_ConfigureRendering.", functionName)); } void checkBeginFrameTimingScope(const char* functionName) { OVR_UNUSED1(functionName); // for Release build. OVR_ASSERT_LOG(BeginFrameTimingCalled == true, - ("%s called outside ovrHmd_BeginFrameTiming.")); + ("%s called outside ovrHmd_BeginFrameTiming.", functionName)); } @@ -215,6 +220,8 @@ public: void updateLowPersistenceMode(bool lowPersistence) const; void updateLatencyTestForHmd(bool latencyTesting); + + void updateDK2FeaturesTiedToSensor(bool sensorCreatedJustNow); // Get properties by name. float getFloatValue(const char* propertyName, float defaultVal); @@ -251,6 +258,12 @@ public: const char* pLastError; + // Caps enabled for the HMD. + unsigned EnabledHmdCaps; + // These are the flags actually applied to the Sensor device, + // used to track whether SetDisplayReport calls are necessary. + unsigned HmdCapsAppliedToSensor; + // *** Sensor diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.cpp b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.cpp index 53f8948..878d777 100644 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.cpp +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.cpp @@ -88,8 +88,8 @@ static PrecompiledShader DistortionPixelShaderLookup[DistortionPixelShaderCount] void DistortionShaderBitIndexCheck() { - OVR_COMPILER_ASSERT(ovrDistortion_Chromatic == 1); - OVR_COMPILER_ASSERT(ovrDistortion_TimeWarp == 2); + OVR_COMPILER_ASSERT(ovrDistortionCap_Chromatic == 1); + OVR_COMPILER_ASSERT(ovrDistortionCap_TimeWarp == 2); } @@ -135,6 +135,10 @@ DistortionRenderer::DistortionRenderer(ovrHmd hmd, FrameTimeManager& timeManager const HMDRenderState& renderState) : CAPI::DistortionRenderer(ovrRenderAPI_D3D11, hmd, timeManager, renderState) { + EyeTextureSize[0] = Sizei(0); + EyeRenderViewport[0] = Recti(); + EyeTextureSize[1] = Sizei(0); + EyeRenderViewport[1] = Recti(); } DistortionRenderer::~DistortionRenderer() @@ -152,11 +156,8 @@ CAPI::DistortionRenderer* DistortionRenderer::Create(ovrHmd hmd, bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig, - unsigned hmdCaps, unsigned distortionCaps) + unsigned distortionCaps) { - // TBD: Decide if hmdCaps are needed here or are a part of RenderState - OVR_UNUSED(hmdCaps); - const ovrD3D1X(Config)* config = (const ovrD3D1X(Config)*)apiConfig; if (!config) @@ -178,6 +179,8 @@ bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig, RParams.RTSize = config->D3D_NS.Header.RTSize; RParams.Multisample = config->D3D_NS.Header.Multisample; + GfxState = *new GraphicsState(RParams.pContext); + DistortionCaps = distortionCaps; //DistortionWarper.SetVsync((hmdCaps & ovrHmdCap_NoVSync) ? false : true); @@ -217,11 +220,14 @@ void DistortionRenderer::SubmitEye(int eyeId, ovrTexture* eyeTexture) { // Use tex->D3D_NS.Header.RenderViewport to update UVs for rendering in case they changed. // TBD: This may be optimized through some caching. - ovrEyeDesc ed = RState.EyeRenderDesc[eyeId].Desc; - ed.TextureSize = tex->D3D_NS.Header.TextureSize; - ed.RenderViewport = tex->D3D_NS.Header.RenderViewport; + EyeTextureSize[eyeId] = tex->D3D_NS.Header.TextureSize; + EyeRenderViewport[eyeId] = tex->D3D_NS.Header.RenderViewport; + + const ovrEyeRenderDesc& erd = RState.EyeRenderDesc[eyeId]; - ovrHmd_GetRenderScaleAndOffset(HMD, ed, DistortionCaps, UVScaleOffset[eyeId]); + ovrHmd_GetRenderScaleAndOffset(erd.Fov, + EyeTextureSize[eyeId], EyeRenderViewport[eyeId], + UVScaleOffset[eyeId]); pEyeTextures[eyeId]->UpdatePlaceholderTexture(tex->D3D_NS.pTexture, tex->D3D_NS.pSRView, tex->D3D_NS.Header.TextureSize); @@ -231,32 +237,9 @@ void DistortionRenderer::SubmitEye(int eyeId, ovrTexture* eyeTexture) void DistortionRenderer::EndFrame(bool swapBuffers, unsigned char* latencyTesterDrawColor, unsigned char* latencyTester2DrawColor) { - -#if 0 - - // MA: This causes orientation and positional stutter!! NOT USABLE. - if (!TimeManager.NeedDistortionTimeMeasurement() && - (RState.DistortionCaps & ovrDistortion_TimeWarp)) - { - // Wait for timewarp distortion if it is time - FlushGpuAndWaitTillTime(TimeManager.GetFrameTiming().TimewarpPointTime); - } - - // Always measure distortion time so that TimeManager can better - // estimate latency-reducing time-warp wait timing. - { - GpuProfiler.BeginQuery(); - - renderDistortion(pEyeTextures[0], pEyeTextures[1]); - - GpuProfiler.EndQuery(); - TimeManager.AddDistortionTimeMeasurement(GpuProfiler.GetTiming(false)); - } -#else - if (!TimeManager.NeedDistortionTimeMeasurement()) { - if (RState.DistortionCaps & ovrDistortion_TimeWarp) + if (RState.DistortionCaps & ovrDistortionCap_TimeWarp) { // Wait for timewarp distortion if it is time and Gpu idle FlushGpuAndWaitTillTime(TimeManager.GetFrameTiming().TimewarpPointTime); @@ -276,7 +259,6 @@ void DistortionRenderer::EndFrame(bool swapBuffers, unsigned char* latencyTester WaitUntilGpuIdle(); TimeManager.AddDistortionTimeMeasurement(ovr_GetTimeInSeconds() - distortionStartTime); } -#endif if(latencyTesterDrawColor) { @@ -291,7 +273,7 @@ void DistortionRenderer::EndFrame(bool swapBuffers, unsigned char* latencyTester { if (RParams.pSwapChain) { - UINT swapInterval = (RState.HMDCaps & ovrHmdCap_NoVSync) ? 0 : 1; + UINT swapInterval = (RState.EnabledHmdCaps & ovrHmdCap_NoVSync) ? 0 : 1; RParams.pSwapChain->Present(swapInterval, 0); // Force GPU to flush the scene, resulting in the lowest possible latency. @@ -380,9 +362,11 @@ void DistortionRenderer::initBuffersAndShaders() // double startT = ovr_GetTimeInSeconds(); - if (!ovrHmd_CreateDistortionMesh( HMD, RState.EyeRenderDesc[eyeNum].Desc, + if (!ovrHmd_CreateDistortionMesh( HMD, + RState.EyeRenderDesc[eyeNum].Eye, + RState.EyeRenderDesc[eyeNum].Fov, RState.DistortionCaps, - UVScaleOffset[eyeNum], &meshData) ) + &meshData) ) { OVR_ASSERT(false); continue; @@ -413,9 +397,9 @@ void DistortionRenderer::initBuffersAndShaders() } DistortionMeshVBs[eyeNum] = *new Buffer(&RParams); - DistortionMeshVBs[eyeNum]->Data ( Buffer_Vertex, pVBVerts, sizeof(DistortionVertex) * meshData.VertexCount ); + DistortionMeshVBs[eyeNum]->Data(Buffer_Vertex | Buffer_ReadOnly, pVBVerts, sizeof(DistortionVertex)* meshData.VertexCount); DistortionMeshIBs[eyeNum] = *new Buffer(&RParams); - DistortionMeshIBs[eyeNum]->Data ( Buffer_Index, meshData.pIndexData, ( sizeof(INT16) * meshData.IndexCount ) ); + DistortionMeshIBs[eyeNum]->Data(Buffer_Index | Buffer_ReadOnly, meshData.pIndexData, (sizeof(INT16)* meshData.IndexCount)); OVR_FREE ( pVBVerts ); ovrHmd_DestroyDistortionMesh( &meshData ); @@ -451,7 +435,7 @@ void DistortionRenderer::renderDistortion(Texture* leftEyeTexture, Texture* righ DistortionShader->SetUniform2f("EyeToSourceUVScale", UVScaleOffset[eyeNum][0].x, UVScaleOffset[eyeNum][0].y); DistortionShader->SetUniform2f("EyeToSourceUVOffset", UVScaleOffset[eyeNum][1].x, UVScaleOffset[eyeNum][1].y); - if (DistortionCaps & ovrDistortion_TimeWarp) + if (DistortionCaps & ovrDistortionCap_TimeWarp) { ovrMatrix4f timeWarpMatrices[2]; ovrHmd_GetEyeTimewarpMatrices(HMD, (ovrEyeType)eyeNum, @@ -770,4 +754,51 @@ void DistortionRenderer::destroy() LatencyTesterQuadVB.Clear(); } + +DistortionRenderer::GraphicsState::GraphicsState(ID3D1xDeviceContext* c) +: context(c) +, rasterizerState(NULL) +{ + for (int i = 0; i < 8; ++i) + samplerStates[i] = NULL; +} + + +void DistortionRenderer::GraphicsState::Save() +{ + if (rasterizerState != NULL) + rasterizerState->Release(); + + context->RSGetState(&rasterizerState); + + for (int i = 0; i < 8; ++i) + { + if (samplerStates[i] != NULL) + samplerStates[i]->Release(); + } + + context->PSGetSamplers(0, 8, samplerStates); +} + + +void DistortionRenderer::GraphicsState::Restore() +{ + if (rasterizerState != NULL) + { + context->RSSetState(rasterizerState); + rasterizerState->Release(); + rasterizerState = NULL; + } + + for (int i = 0; i < 8; ++i) + { + if (samplerStates[i] == NULL) + continue; + + context->PSSetSamplers(0, 1, &samplerStates[i]); + samplerStates[i]->Release(); + samplerStates[i] = NULL; + } +} + }}} // OVR::CAPI::D3D1X diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.h b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.h index f151d73..c4d2619 100644 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.h +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.h @@ -57,7 +57,7 @@ public: // ***** Public DistortionRenderer interface virtual bool Initialize(const ovrRenderAPIConfig* apiConfig, - unsigned hmdCaps, unsigned distortionCaps); + unsigned distortionCaps); virtual void SubmitEye(int eyeId, ovrTexture* eyeTexture); @@ -70,6 +70,21 @@ public: // Note, it exits when time expires, even if GPU is not in idle state yet. double FlushGpuAndWaitTillTime(double absTime); +protected: + + class GraphicsState : public CAPI::DistortionRenderer::GraphicsState + { + public: + GraphicsState(ID3D1xDeviceContext* context); + virtual void Save(); + virtual void Restore(); + + protected: + ID3D1xRasterizerState* rasterizerState; + ID3D1xSamplerState* samplerStates[8]; + ID3D1xDeviceContext* context; + }; + private: // Helpers void initBuffersAndShaders(); @@ -102,6 +117,8 @@ private: // U,V scale and offset needed for timewarp. ovrVector2f UVScaleOffset[2][2]; + ovrSizei EyeTextureSize[2]; + ovrRecti EyeRenderViewport[2]; //Ptr<Buffer> mpFullScreenVertexBuffer; diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.h b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.h index f8d7bd3..7bbc685 100644 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.h +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.h @@ -41,6 +41,7 @@ limitations under the License. #include "../../Kernel/OVR_Array.h" #include "../../Kernel/OVR_Math.h" +#if defined(OVR_OS_WIN32) #include <Windows.h> #include <comdef.h> // for _COM_SMARTPTR_TYPEDEF() @@ -78,6 +79,7 @@ limitations under the License. #include <d3d11.h> #include <D3D11Shader.h> #endif +#endif namespace OVR { namespace CAPI { namespace D3D_NS { diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.cpp b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.cpp index 21b885e..e8cf767 100644 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.cpp +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.cpp @@ -57,11 +57,8 @@ DistortionRenderer::~DistortionRenderer() /******************************************************************************/ bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig, - unsigned hmdCaps, unsigned arg_distortionCaps) + unsigned arg_distortionCaps) { - // TBD: Decide if hmdCaps are needed here or are a part of RenderState - OVR_UNUSED(hmdCaps); - ///QUESTION - what is returned bool for??? Are we happy with this true, if not config. const ovrD3D9Config * config = (const ovrD3D9Config*)apiConfig; if (!config) return true; @@ -69,14 +66,17 @@ bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig, //Glean all the required variables from the input structures device = config->D3D9.pDevice; + swapChain = config->D3D9.pSwapChain; screenSize = config->D3D9.Header.RTSize; distortionCaps = arg_distortionCaps; + GfxState = *new GraphicsState(device); + CreateVertexDeclaration(); CreateDistortionShaders(); Create_Distortion_Models(); - return (true); + return true; } @@ -89,23 +89,22 @@ void DistortionRenderer::SubmitEye(int eyeId, ovrTexture* eyeTexture) //Write in values eachEye[eyeId].texture = tex->D3D9.pTexture; - //Its only at this point we discover what the viewport of the texture is. - //because presumably we allow users to realtime adjust the resolution. - //Which begs the question - why did we ask them what viewport they were - //using before, which gave them a set of UV offsets. In fact, our - //asking for eye mesh must be entirely independed of these viewports, - //presumably only to get the parameters. - - ovrEyeDesc ed = RState.EyeRenderDesc[eyeId].Desc; - ed.TextureSize = tex->D3D9.Header.TextureSize; - ed.RenderViewport = tex->D3D9.Header.RenderViewport; + // Its only at this point we discover what the viewport of the texture is. + // because presumably we allow users to realtime adjust the resolution. + eachEye[eyeId].TextureSize = tex->D3D9.Header.TextureSize; + eachEye[eyeId].RenderViewport = tex->D3D9.Header.RenderViewport; - ovrHmd_GetRenderScaleAndOffset(HMD, ed, distortionCaps, eachEye[eyeId].UVScaleOffset); + const ovrEyeRenderDesc& erd = RState.EyeRenderDesc[eyeId]; + + ovrHmd_GetRenderScaleAndOffset( erd.Fov, + eachEye[eyeId].TextureSize, eachEye[eyeId].RenderViewport, + eachEye[eyeId].UVScaleOffset ); } /******************************************************************/ -void DistortionRenderer::EndFrame(bool swapBuffers, unsigned char* latencyTesterDrawColor, unsigned char* latencyTester2DrawColor) +void DistortionRenderer::EndFrame(bool swapBuffers, + unsigned char* latencyTesterDrawColor, unsigned char* latencyTester2DrawColor) { OVR_UNUSED(swapBuffers); OVR_UNUSED(latencyTesterDrawColor); @@ -115,7 +114,7 @@ void DistortionRenderer::EndFrame(bool swapBuffers, unsigned char* latencyTester if (!TimeManager.NeedDistortionTimeMeasurement()) { - if (RState.DistortionCaps & ovrDistortion_TimeWarp) + if (RState.DistortionCaps & ovrDistortionCap_TimeWarp) { // Wait for timewarp distortion if it is time and Gpu idle WaitTillTimeAndFlushGpu(TimeManager.GetFrameTiming().TimewarpPointTime); @@ -149,101 +148,130 @@ void DistortionRenderer::EndFrame(bool swapBuffers, unsigned char* latencyTester if (swapBuffers) { - device->Present( NULL, NULL, NULL, NULL ); - - /// if (RParams.pSwapChain) + if (swapChain) { - /// UINT swapInterval = (RState.HMDCaps & ovrHmdCap_NoVSync) ? 0 : 1; - /// RParams.pSwapChain->Present(swapInterval, 0); - - // Force GPU to flush the scene, resulting in the lowest possible latency. - // It's critical that this flush is *after* present. - /// WaitUntilGpuIdle(); + swapChain->Present(NULL, NULL, NULL, NULL, 0); } - /// else + else { - // TBD: Generate error - swapbuffer option used with null swapchain. + device->Present( NULL, NULL, NULL, NULL ); } + + // Force GPU to flush the scene, resulting in the lowest possible latency. + // It's critical that this flush is *after* present. + WaitUntilGpuIdle(); } } void DistortionRenderer::WaitUntilGpuIdle() { -#if 0 - // Flush and Stall CPU while waiting for GPU to complete rendering all of the queued draw calls - D3D1x_QUERY_DESC queryDesc = { D3D1X_(QUERY_EVENT), 0 }; - Ptr<ID3D1xQuery> query; - BOOL done = FALSE; - - if (RParams.pDevice->CreateQuery(&queryDesc, &query.GetRawRef()) == S_OK) + if(device) { - D3DSELECT_10_11(query->End(), - RParams.pContext->End(query)); - - // GetData will returns S_OK for both done == TRUE or FALSE. - // Exit on failure to avoid infinite loop. - do { } - while(!done && - !FAILED(D3DSELECT_10_11(query->GetData(&done, sizeof(BOOL), 0), - RParams.pContext->GetData(query, &done, sizeof(BOOL), 0))) - ); - } -#endif + IDirect3DQuery9* pEventQuery=NULL ; + device->CreateQuery(D3DQUERYTYPE_EVENT, &pEventQuery) ; + + if(pEventQuery!=NULL) + { + pEventQuery->Issue(D3DISSUE_END) ; + while(S_FALSE == pEventQuery->GetData(NULL, 0, D3DGETDATA_FLUSH)) ; + } + } } double DistortionRenderer::WaitTillTimeAndFlushGpu(double absTime) { - -OVR_UNUSED(absTime); -#if 0 double initialTime = ovr_GetTimeInSeconds(); if (initialTime >= absTime) return 0.0; - // Flush and Stall CPU while waiting for GPU to complete rendering all of the queued draw calls - D3D1x_QUERY_DESC queryDesc = { D3D1X_(QUERY_EVENT), 0 }; - Ptr<ID3D1xQuery> query; - BOOL done = FALSE; - bool callGetData = false; - - if (RParams.pDevice->CreateQuery(&queryDesc, &query.GetRawRef()) == S_OK) - { - D3DSELECT_10_11(query->End(), - RParams.pContext->End(query)); - callGetData = true; - } + WaitUntilGpuIdle(); double newTime = initialTime; volatile int i; while (newTime < absTime) { - if (callGetData) - { - // GetData will returns S_OK for both done == TRUE or FALSE. - // Stop calling GetData on failure. - callGetData = !FAILED(D3DSELECT_10_11(query->GetData(&done, sizeof(BOOL), 0), - RParams.pContext->GetData(query, &done, sizeof(BOOL), 0))) && !done; - } - else - { - for (int j = 0; j < 50; j++) - i = 0; - } + for (int j = 0; j < 50; j++) + i = 0; newTime = ovr_GetTimeInSeconds(); } // How long we waited return newTime - initialTime; -#endif - return 0; //dummy } +DistortionRenderer::GraphicsState::GraphicsState(IDirect3DDevice9* d) +: device(d) +, numSavedStates(0) +{ +} + +void DistortionRenderer::GraphicsState::RecordAndSetState(int which, int type, DWORD newValue) +{ + SavedStateType * sst = &savedState[numSavedStates++]; + sst->which = which; + sst->type = type; + if (which == 0) + { + device->GetSamplerState(0, (D3DSAMPLERSTATETYPE)type, &sst->valueToRevertTo); + device->SetSamplerState(0, (D3DSAMPLERSTATETYPE)type, newValue); + } + else + { + device->GetRenderState((D3DRENDERSTATETYPE)type, &sst->valueToRevertTo); + device->SetRenderState((D3DRENDERSTATETYPE)type, newValue); + } +} + +void DistortionRenderer::GraphicsState::Save() +{ + //Record and set rasterizer and sampler states. + + numSavedStates=0; + + RecordAndSetState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); + RecordAndSetState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ); + RecordAndSetState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR ); + RecordAndSetState(0, D3DSAMP_BORDERCOLOR, 0x000000 ); + RecordAndSetState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER ); + RecordAndSetState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER ); + + RecordAndSetState(1, D3DRS_MULTISAMPLEANTIALIAS, FALSE ); + RecordAndSetState(1, D3DRS_DITHERENABLE, FALSE ); + RecordAndSetState(1, D3DRS_ZENABLE, FALSE ); + RecordAndSetState(1, D3DRS_ZWRITEENABLE, TRUE ); + RecordAndSetState(1, D3DRS_ZFUNC, D3DCMP_LESSEQUAL ); + RecordAndSetState(1, D3DRS_CULLMODE , D3DCULL_CCW ); + RecordAndSetState(1, D3DRS_ALPHABLENDENABLE , FALSE ); + RecordAndSetState(1, D3DRS_DEPTHBIAS , 0 ); + RecordAndSetState(1, D3DRS_SRCBLEND , D3DBLEND_SRCALPHA ); + RecordAndSetState(1, D3DRS_DESTBLEND , D3DBLEND_INVSRCALPHA ); + RecordAndSetState(1, D3DRS_FILLMODE, D3DFILL_SOLID ); + RecordAndSetState(1, D3DRS_ALPHATESTENABLE, FALSE); + RecordAndSetState(1, D3DRS_DEPTHBIAS , 0 ); + RecordAndSetState(1, D3DRS_LIGHTING, FALSE ); + RecordAndSetState(1, D3DRS_FOGENABLE, FALSE ); +} +void DistortionRenderer::GraphicsState::Restore() +{ + for (int i = 0; i<numSavedStates; i++) + { + SavedStateType * sst = &savedState[i]; + if (sst->which == 0) + { + device->SetSamplerState(0, (D3DSAMPLERSTATETYPE)sst->type, sst->valueToRevertTo); + } + else + { + device->SetRenderState((D3DRENDERSTATETYPE)sst->type, sst->valueToRevertTo); + } + } +} }}} // OVR::CAPI::D3D1X diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.h b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.h index 9332b83..f24eb31 100644 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.h +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.h @@ -24,13 +24,17 @@ limitations under the License. ************************************************************************************/ +#include "../../Kernel/OVR_Types.h" + #undef new +#if defined (OVR_OS_WIN32) #if _MSC_VER < 1700 #include <d3dx9.h> #else #include <d3d9.h> #endif +#endif #if defined(OVR_DEFINE_NEW) #define new OVR_DEFINE_NEW @@ -57,7 +61,7 @@ public: // ***** Public DistortionRenderer interface virtual bool Initialize(const ovrRenderAPIConfig* apiConfig, - unsigned hmdCaps, unsigned distortionCaps); + unsigned distortionCaps); virtual void SubmitEye(int eyeId, ovrTexture* eyeTexture); @@ -70,6 +74,32 @@ public: // Note, it exits when time expires, even if GPU is not in idle state yet. double WaitTillTimeAndFlushGpu(double absTime); +protected: + + class GraphicsState : public CAPI::DistortionRenderer::GraphicsState + { + public: + GraphicsState(IDirect3DDevice9* d); + virtual void Save(); + virtual void Restore(); + + protected: + void RecordAndSetState(int which, int type, DWORD newValue); + + //Structure to store our state changes + static const int MAX_SAVED_STATES=100; + struct SavedStateType + { + int which; //0 for samplerstate, 1 for renderstate + int type; + DWORD valueToRevertTo; + } savedState[MAX_SAVED_STATES]; + + //Keep track of how many we've done, for reverting + int numSavedStates; + IDirect3DDevice9* device; + }; + private: //Functions @@ -83,6 +113,7 @@ private: //Data, structures and pointers IDirect3DDevice9 * device; + IDirect3DSwapChain9 * swapChain; IDirect3DVertexDeclaration9 * vertexDecl; IDirect3DPixelShader9 * pixelShader; IDirect3DVertexShader9 * vertexShader; @@ -92,29 +123,17 @@ private: struct FOR_EACH_EYE { + FOR_EACH_EYE() : TextureSize(0), RenderViewport(Sizei(0)) { } + IDirect3DVertexBuffer9 * dxVerts; IDirect3DIndexBuffer9 * dxIndices; int numVerts; int numIndices; IDirect3DTexture9 * texture; ovrVector2f UVScaleOffset[2]; + Sizei TextureSize; + Recti RenderViewport; } eachEye[2]; - - - //Structure to store our state changes - #define MAX_SAVED_STATES 100 - struct SavedStateType - { - int which; //0 for samplerstate, 1 for renderstate - int type; - DWORD valueToRevertTo; - } savedState[MAX_SAVED_STATES]; - - //Keep track of how many we've done, for reverting - int numSavedStates; - - - }; }}} // OVR::CAPI::D3D9 diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_Util.cpp b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_Util.cpp index ea36100..e6bdcb6 100644 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_Util.cpp +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_Util.cpp @@ -32,7 +32,6 @@ limitations under the License. namespace OVR { namespace CAPI { namespace D3D9 { - #define PRECOMPILE_FLAG 0 #if !PRECOMPILE_FLAG //To make these, you need to run it with PRECOMPILE_FLAG, which also uses them, so good for debugging. @@ -182,21 +181,25 @@ void DistortionRenderer::Create_Distortion_Models(void) { //Make the distortion models for (int eye=0;eye<2;eye++) - { - ovrVector2f dummy_UVScaleOffset[2]; //because it needs to be updated by a later call + { FOR_EACH_EYE * e = &eachEye[eye]; ovrDistortionMesh meshData; - ovrHmd_CreateDistortionMesh(HMD, RState.EyeRenderDesc[eye].Desc, distortionCaps, - dummy_UVScaleOffset, &meshData); + ovrHmd_CreateDistortionMesh(HMD, + RState.EyeRenderDesc[eye].Eye, + RState.EyeRenderDesc[eye].Fov, + distortionCaps, + &meshData); e->numVerts = meshData.VertexCount; e->numIndices = meshData.IndexCount; - device->CreateVertexBuffer( (e->numVerts)*sizeof(ovrDistortionVertex),0, 0,D3DPOOL_MANAGED, &e->dxVerts, NULL ); + device->CreateVertexBuffer( (e->numVerts)*sizeof(ovrDistortionVertex),0, 0, + D3DPOOL_MANAGED, &e->dxVerts, NULL ); ovrDistortionVertex * dxv; e->dxVerts->Lock( 0, 0, (void**)&dxv, 0 ); for (int v=0;v<e->numVerts;v++) dxv[v] = meshData.pVertexData[v]; - device->CreateIndexBuffer( (e->numIndices)*sizeof(u_short),0, D3DFMT_INDEX16,D3DPOOL_MANAGED, &e->dxIndices, NULL ); + device->CreateIndexBuffer( (e->numIndices)*sizeof(u_short),0, D3DFMT_INDEX16, + D3DPOOL_MANAGED, &e->dxIndices, NULL ); unsigned short* dxi; e->dxIndices->Lock( 0, 0, (void**)&dxi, 0 ); for (int i=0;i<e->numIndices;i++) dxi[i] = meshData.pIndexData[i]; @@ -207,30 +210,6 @@ void DistortionRenderer::Create_Distortion_Models(void) /**********************************************************/ void DistortionRenderer::RenderBothDistortionMeshes(void) { - //Record and set render state - numSavedStates=0; - RecordAndSetState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); - RecordAndSetState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ); - RecordAndSetState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR ); - RecordAndSetState(0, D3DSAMP_BORDERCOLOR, 0x000000 ); - RecordAndSetState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER ); - RecordAndSetState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER ); - RecordAndSetState(1, D3DRS_MULTISAMPLEANTIALIAS, FALSE ); - RecordAndSetState(1, D3DRS_DITHERENABLE, FALSE ); - RecordAndSetState(1, D3DRS_ZENABLE, FALSE ); - RecordAndSetState(1, D3DRS_ZWRITEENABLE, TRUE ); - RecordAndSetState(1, D3DRS_ZFUNC, D3DCMP_LESSEQUAL ); - RecordAndSetState(1, D3DRS_CULLMODE , D3DCULL_CCW ); - RecordAndSetState(1, D3DRS_ALPHABLENDENABLE , FALSE ); - RecordAndSetState(1, D3DRS_DEPTHBIAS , 0 ); - RecordAndSetState(1, D3DRS_SRCBLEND , D3DBLEND_SRCALPHA ); - RecordAndSetState(1, D3DRS_DESTBLEND , D3DBLEND_INVSRCALPHA ); - RecordAndSetState(1, D3DRS_FILLMODE, D3DFILL_SOLID ); - RecordAndSetState(1, D3DRS_ALPHATESTENABLE, FALSE); - RecordAndSetState(1, D3DRS_DEPTHBIAS , 0 ); - RecordAndSetState(1, D3DRS_LIGHTING, FALSE ); - RecordAndSetState(1, D3DRS_FOGENABLE, FALSE ); - for (int eye=0; eye<2; eye++) { FOR_EACH_EYE * e = &eachEye[eye]; @@ -243,7 +222,7 @@ void DistortionRenderer::RenderBothDistortionMeshes(void) device->SetTexture( 0, e->texture); //Choose which vertex shader, with associated additional inputs - if (distortionCaps & ovrDistortion_TimeWarp) + if (distortionCaps & ovrDistortionCap_TimeWarp) { device->SetVertexShader( vertexShaderTimewarp ); @@ -251,6 +230,10 @@ void DistortionRenderer::RenderBothDistortionMeshes(void) ovrHmd_GetEyeTimewarpMatrices(HMD, (ovrEyeType)eye, RState.EyeRenderPoses[eye], timeWarpMatrices); + //Need to transpose the matrices + timeWarpMatrices[0] = Matrix4f(timeWarpMatrices[0]).Transposed(); + timeWarpMatrices[1] = Matrix4f(timeWarpMatrices[1]).Transposed(); + // Feed identity like matrices in until we get proper timewarp calculation going on device->SetVertexShaderConstantF(4, (float *) &timeWarpMatrices[0],4); device->SetVertexShaderConstantF(20,(float *) &timeWarpMatrices[1],4); @@ -260,58 +243,12 @@ void DistortionRenderer::RenderBothDistortionMeshes(void) device->SetVertexShader( vertexShader ); } - //Set up vertex shader constants device->SetVertexShaderConstantF( 0, ( FLOAT* )&(e->UVScaleOffset[0]), 1 ); device->SetVertexShaderConstantF( 2, ( FLOAT* )&(e->UVScaleOffset[1]), 1 ); device->DrawIndexedPrimitive( D3DPT_TRIANGLELIST,0,0,e->numVerts,0,e->numIndices/3); } - - //Revert render state - RevertAllStates(); - -} - -/*********************************************************************************/ -void DistortionRenderer::RecordAndSetState(int which, int type, DWORD newValue) -{ - SavedStateType * sst = &savedState[numSavedStates++]; - sst->which = which; - sst->type = type; - if (which==0) - { - device->GetSamplerState( 0, (D3DSAMPLERSTATETYPE)type, &sst->valueToRevertTo); - device->SetSamplerState( 0, (D3DSAMPLERSTATETYPE)type, newValue); - } - else - { - device->GetRenderState( (D3DRENDERSTATETYPE)type, &sst->valueToRevertTo); - device->SetRenderState( (D3DRENDERSTATETYPE)type, newValue); - } -} -/*********************************************************************************/ -void DistortionRenderer::RevertAllStates(void) -{ - for (int i=0;i<numSavedStates;i++) - { - SavedStateType * sst = &savedState[i]; - if (sst->which==0) - { - device->SetSamplerState( 0, (D3DSAMPLERSTATETYPE)sst->type, sst->valueToRevertTo); - } - else - { - device->SetRenderState( (D3DRENDERSTATETYPE)sst->type, sst->valueToRevertTo); - } - } } - - - - - - - }}}
\ No newline at end of file diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.cpp b/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.cpp index a953d73..21b6509 100644 --- a/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.cpp +++ b/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.cpp @@ -15,422 +15,12 @@ otherwise accompanies this software in either electronic or hard copy form. #include "CAPI_GL_DistortionRenderer.h" +#include "CAPI_GL_DistortionShaders.h" + #include "../../OVR_CAPI_GL.h" namespace OVR { namespace CAPI { namespace GL { - -static const char SimpleQuad_vs[] = - "uniform vec2 PositionOffset;\n" - "uniform vec2 Scale;\n" - - "attribute vec3 Position;\n" - - "void main()\n" - "{\n" - " gl_Position = vec4(Position.xy * Scale + PositionOffset, 0.5, 1.0);\n" - "}\n"; - -const OVR::CAPI::GL::ShaderBase::Uniform SimpleQuad_vs_refl[] = -{ - { "PositionOffset", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 0, 8 }, - { "Scale", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 8, 8 }, -}; - -static const char SimpleQuad_fs[] = - "uniform vec4 Color;\n" - - "void main()\n" - "{\n" - " gl_FragColor = Color;\n" - "}\n"; - -const OVR::CAPI::GL::ShaderBase::Uniform SimpleQuad_fs_refl[] = -{ - { "Color", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 0, 16 }, -}; - - -static const char Distortion_vs[] = - "uniform vec2 EyeToSourceUVScale;\n" - "uniform vec2 EyeToSourceUVOffset;\n" - - "attribute vec2 Position;\n" - "attribute vec4 Color;\n" - "attribute vec2 TexCoord0;\n" - - "varying vec4 oColor;\n" - "varying vec2 oTexCoord0;\n" - - "void main()\n" - "{\n" - " gl_Position.x = Position.x;\n" - " gl_Position.y = Position.y;\n" - " gl_Position.z = 0.5;\n" - " gl_Position.w = 1.0;\n" - // Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion). - // Scale them into the correct [0-1],[0-1] UV lookup space (depending on eye) - " oTexCoord0 = TexCoord0 * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - " oTexCoord0.y = 1-oTexCoord0.y;\n" - " oColor = Color;\n" // Used for vignette fade. - "}\n"; - -const OVR::CAPI::GL::ShaderBase::Uniform Distortion_vs_refl[] = -{ - { "EyeToSourceUVScale", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 0, 8 }, - { "EyeToSourceUVOffset", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 8, 8 }, -}; - -static const char Distortion_fs[] = - "uniform sampler2D Texture0;\n" - - "varying vec4 oColor;\n" - "varying vec2 oTexCoord0;\n" - - "void main()\n" - "{\n" - " gl_FragColor = texture2D(Texture0, oTexCoord0);\n" - " gl_FragColor.a = 1.0;\n" - "}\n"; - - -static const char DistortionTimewarp_vs[] = - "uniform vec2 EyeToSourceUVScale;\n" - "uniform vec2 EyeToSourceUVOffset;\n" - "uniform mat4 EyeRotationStart;\n" - "uniform mat4 EyeRotationEnd;\n" - - "attribute vec2 Position;\n" - "attribute vec4 Color;\n" - "attribute vec2 TexCoord0;\n" - - "varying vec4 oColor;\n" - "varying vec2 oTexCoord0;\n" - - "void main()\n" - "{\n" - " gl_Position.x = Position.x;\n" - " gl_Position.y = Position.y;\n" - " gl_Position.z = 0.0;\n" - " gl_Position.w = 1.0;\n" - - // Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion). - // These are now "real world" vectors in direction (x,y,1) relative to the eye of the HMD. - " vec3 TanEyeAngle = vec3 ( TexCoord0.x, TexCoord0.y, 1.0 );\n" - - // Accurate time warp lerp vs. faster -#if 1 - // Apply the two 3x3 timewarp rotations to these vectors. - " vec3 TransformedStart = (EyeRotationStart * vec4(TanEyeAngle, 0)).xyz;\n" - " vec3 TransformedEnd = (EyeRotationEnd * vec4(TanEyeAngle, 0)).xyz;\n" - // And blend between them. - " vec3 Transformed = mix ( TransformedStart, TransformedEnd, Color.a );\n" -#else - " mat3 EyeRotation = mix ( EyeRotationStart, EyeRotationEnd, Color.a );\n" - " vec3 Transformed = EyeRotation * TanEyeAngle;\n" -#endif - - // Project them back onto the Z=1 plane of the rendered images. - " float RecipZ = 1.0 / Transformed.z;\n" - " vec2 Flattened = vec2 ( Transformed.x * RecipZ, Transformed.y * RecipZ );\n" - - // These are now still in TanEyeAngle space. - // Scale them into the correct [0-1],[0-1] UV lookup space (depending on eye) - " vec2 SrcCoord = Flattened * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - " oTexCoord0 = SrcCoord;\n" - " oTexCoord0.y = 1-oTexCoord0.y;\n" - " oColor = Color.r;\n" // Used for vignette fade. - "}\n"; - -const OVR::CAPI::GL::ShaderBase::Uniform DistortionTimewarp_vs_refl[] = -{ - { "EyeToSourceUVScale", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 0, 8 }, - { "EyeToSourceUVOffset", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 8, 8 }, -}; - - -static const char DistortionPositionalTimewarp_vs[] = - "#version 150\n" - - "uniform sampler2D Texture0;\n" - "uniform vec2 EyeToSourceUVScale;\n" - "uniform vec2 EyeToSourceUVOffset;\n" - "uniform vec2 DepthProjector;\n" - "uniform vec2 DepthDimSize;\n" - "uniform mat4 EyeRotationStart;\n" - "uniform mat4 EyeRotationEnd;\n" - - "in vec2 Position;\n" - "in vec4 Color;\n" - "in vec2 TexCoord0;\n" - "in vec2 TexCoord1;\n" - "in vec2 TexCoord2;\n" - - "out vec4 oColor;\n" - "out vec2 oTexCoord0;\n" - - "vec4 PositionFromDepth(vec2 inTexCoord)\n" - "{\n" - " vec2 eyeToSourceTexCoord = inTexCoord * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - " eyeToSourceTexCoord.y = 1 - eyeToSourceTexCoord.y;\n" - " float depth = texelFetch(Texture0, ivec2(eyeToSourceTexCoord * DepthDimSize), 0).x;\n" - " float linearDepth = DepthProjector.y / (depth - DepthProjector.x);\n" - " vec4 retVal = vec4(inTexCoord, 1, 1);\n" - " retVal.xyz *= linearDepth;\n" - " return retVal;\n" - "}\n" - - "vec2 TimewarpTexCoordToWarpedPos(vec2 inTexCoord, float a)\n" - "{\n" - // Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion). - // These are now "real world" vectors in direction (x,y,1) relative to the eye of the HMD. - // Apply the 4x4 timewarp rotation to these vectors. - " vec4 inputPos = PositionFromDepth(inTexCoord);\n" - " vec3 transformed = mix ( EyeRotationStart * inputPos, EyeRotationEnd * inputPos, a ).xyz;\n" - // Project them back onto the Z=1 plane of the rendered images. - " vec2 flattened = transformed.xy / transformed.z;\n" - // Scale them into ([0,0.5],[0,1]) or ([0.5,0],[0,1]) UV lookup space (depending on eye) - " vec2 noDepthUV = flattened * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - //" float depth = texture2DLod(Texture0, noDepthUV, 0).r;\n" - " return noDepthUV.xy;\n" - "}\n" - - "void main()\n" - "{\n" - " gl_Position.x = Position.x;\n" - " gl_Position.y = Position.y;\n" - " gl_Position.z = 0.0;\n" - " gl_Position.w = 1.0;\n" - - // warped positions are a bit more involved, hence a separate function - " oTexCoord0 = TimewarpTexCoordToWarpedPos(TexCoord0, Color.a);\n" - " oTexCoord0.y = 1-oTexCoord0.y;\n" - - " oColor = vec4(Color.r); // Used for vignette fade.\n" - "}\n"; - -const OVR::CAPI::GL::ShaderBase::Uniform DistortionPositionalTimewarp_vs_refl[] = -{ - { "EyeToSourceUVScale", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 0, 8 }, - { "EyeToSourceUVOffset", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 8, 8 }, -}; - - -static const char DistortionChroma_vs[] = - "uniform vec2 EyeToSourceUVScale;\n" - "uniform vec2 EyeToSourceUVOffset;\n" - - "attribute vec2 Position;\n" - "attribute vec4 Color;\n" - "attribute vec2 TexCoord0;\n" - "attribute vec2 TexCoord1;\n" - "attribute vec2 TexCoord2;\n" - - "varying vec4 oColor;\n" - "varying vec2 oTexCoord0;\n" - "varying vec2 oTexCoord1;\n" - "varying vec2 oTexCoord2;\n" - - "void main()\n" - "{\n" - " gl_Position.x = Position.x;\n" - " gl_Position.y = Position.y;\n" - " gl_Position.z = 0.5;\n" - " gl_Position.w = 1.0;\n" - - // Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion). - // Scale them into the correct [0-1],[0-1] UV lookup space (depending on eye) - " oTexCoord0 = TexCoord0 * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - " oTexCoord0.y = 1-oTexCoord0.y;\n" - " oTexCoord1 = TexCoord1 * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - " oTexCoord1.y = 1-oTexCoord1.y;\n" - " oTexCoord2 = TexCoord2 * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - " oTexCoord2.y = 1-oTexCoord2.y;\n" - - " oColor = Color;\n" // Used for vignette fade. - "}\n"; - -const OVR::CAPI::GL::ShaderBase::Uniform DistortionChroma_vs_refl[] = -{ - { "EyeToSourceUVScale", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 0, 8 }, - { "EyeToSourceUVOffset", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 8, 8 }, -}; - -static const char DistortionChroma_fs[] = - "uniform sampler2D Texture0;\n" - - "varying vec4 oColor;\n" - "varying vec2 oTexCoord0;\n" - "varying vec2 oTexCoord1;\n" - "varying vec2 oTexCoord2;\n" - - "void main()\n" - "{\n" - " float ResultR = texture2D(Texture0, oTexCoord0).r;\n" - " float ResultG = texture2D(Texture0, oTexCoord1).g;\n" - " float ResultB = texture2D(Texture0, oTexCoord2).b;\n" - - " gl_FragColor = vec4(ResultR * oColor.r, ResultG * oColor.g, ResultB * oColor.b, 1.0);\n" - "}\n"; - - -static const char DistortionTimewarpChroma_vs[] = - "uniform vec2 EyeToSourceUVScale;\n" - "uniform vec2 EyeToSourceUVOffset;\n" - "uniform mat4 EyeRotationStart;\n" - "uniform mat4 EyeRotationEnd;\n" - - "attribute vec2 Position;\n" - "attribute vec4 Color;\n" - "attribute vec2 TexCoord0;\n" - "attribute vec2 TexCoord1;\n" - "attribute vec2 TexCoord2;\n" - - "varying vec4 oColor;\n" - "varying vec2 oTexCoord0;\n" - "varying vec2 oTexCoord1;\n" - "varying vec2 oTexCoord2;\n" - - "void main()\n" - "{\n" - " gl_Position.x = Position.x;\n" - " gl_Position.y = Position.y;\n" - " gl_Position.z = 0.0;\n" - " gl_Position.w = 1.0;\n" - - // Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion). - // These are now "real world" vectors in direction (x,y,1) relative to the eye of the HMD. - " vec3 TanEyeAngleR = vec3 ( TexCoord0.x, TexCoord0.y, 1.0 );\n" - " vec3 TanEyeAngleG = vec3 ( TexCoord1.x, TexCoord1.y, 1.0 );\n" - " vec3 TanEyeAngleB = vec3 ( TexCoord2.x, TexCoord2.y, 1.0 );\n" - - // Accurate time warp lerp vs. faster -#if 1 - // Apply the two 3x3 timewarp rotations to these vectors. - " vec3 TransformedRStart = (EyeRotationStart * vec4(TanEyeAngleR, 0)).xyz;\n" - " vec3 TransformedGStart = (EyeRotationStart * vec4(TanEyeAngleG, 0)).xyz;\n" - " vec3 TransformedBStart = (EyeRotationStart * vec4(TanEyeAngleB, 0)).xyz;\n" - " vec3 TransformedREnd = (EyeRotationEnd * vec4(TanEyeAngleR, 0)).xyz;\n" - " vec3 TransformedGEnd = (EyeRotationEnd * vec4(TanEyeAngleG, 0)).xyz;\n" - " vec3 TransformedBEnd = (EyeRotationEnd * vec4(TanEyeAngleB, 0)).xyz;\n" - - // And blend between them. - " vec3 TransformedR = mix ( TransformedRStart, TransformedREnd, Color.a );\n" - " vec3 TransformedG = mix ( TransformedGStart, TransformedGEnd, Color.a );\n" - " vec3 TransformedB = mix ( TransformedBStart, TransformedBEnd, Color.a );\n" -#else - " mat3 EyeRotation = mix ( EyeRotationStart, EyeRotationEnd, Color.a );\n" - " vec3 TransformedR = EyeRotation * TanEyeAngleR;\n" - " vec3 TransformedG = EyeRotation * TanEyeAngleG;\n" - " vec3 TransformedB = EyeRotation * TanEyeAngleB;\n" -#endif - - // Project them back onto the Z=1 plane of the rendered images. - " float RecipZR = 1.0 / TransformedR.z;\n" - " float RecipZG = 1.0 / TransformedG.z;\n" - " float RecipZB = 1.0 / TransformedB.z;\n" - " vec2 FlattenedR = vec2 ( TransformedR.x * RecipZR, TransformedR.y * RecipZR );\n" - " vec2 FlattenedG = vec2 ( TransformedG.x * RecipZG, TransformedG.y * RecipZG );\n" - " vec2 FlattenedB = vec2 ( TransformedB.x * RecipZB, TransformedB.y * RecipZB );\n" - - // These are now still in TanEyeAngle space. - // Scale them into the correct [0-1],[0-1] UV lookup space (depending on eye) - " vec2 SrcCoordR = FlattenedR * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - " vec2 SrcCoordG = FlattenedG * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - " vec2 SrcCoordB = FlattenedB * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - - " oTexCoord0 = SrcCoordR;\n" - " oTexCoord0.y = 1-oTexCoord0.y;\n" - " oTexCoord1 = SrcCoordG;\n" - " oTexCoord1.y = 1-oTexCoord1.y;\n" - " oTexCoord2 = SrcCoordB;\n" - " oTexCoord2.y = 1-oTexCoord2.y;\n" - - " oColor = Color.r;\n" // Used for vignette fade. - "}\n"; - -const OVR::CAPI::GL::ShaderBase::Uniform DistortionTimewarpChroma_vs_refl[] = -{ - { "EyeToSourceUVScale", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 0, 8 }, - { "EyeToSourceUVOffset", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 8, 8 }, - { "EyeRotationStart", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 16, 64 }, - { "EyeRotationEnd", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 80, 64 }, -}; - - -static const char DistortionPositionalTimewarpChroma_vs[] = - "#version 150\n" - "uniform sampler2D Texture0;\n" - "uniform sampler2D Texture1;\n" - "uniform vec2 EyeToSourceUVScale;\n" - "uniform vec2 EyeToSourceUVOffset;\n" - "uniform vec2 DepthProjector;\n" - "uniform vec2 DepthDimSize;\n" - "uniform mat4 EyeRotationStart;\n" - "uniform mat4 EyeRotationEnd;\n" - - "in vec2 Position;\n" - "in vec4 Color;\n" - "in vec2 TexCoord0;\n" - "in vec2 TexCoord1;\n" - "in vec2 TexCoord2;\n" - - "out vec4 oColor;\n" - "out vec2 oTexCoord0;\n" - "out vec2 oTexCoord1;\n" - "out vec2 oTexCoord2;\n" - - "vec4 PositionFromDepth(vec2 inTexCoord)\n" - "{\n" - " vec2 eyeToSourceTexCoord = inTexCoord * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - " eyeToSourceTexCoord.y = 1 - eyeToSourceTexCoord.y;\n" - " float depth = texelFetch(Texture1, ivec2(eyeToSourceTexCoord * DepthDimSize), 0).x;\n" - " float linearDepth = DepthProjector.y / (depth - DepthProjector.x);\n" - " vec4 retVal = vec4(inTexCoord, 1, 1);\n" - " retVal.xyz *= linearDepth;\n" - " return retVal;\n" - "}\n" - - "vec2 TimewarpTexCoordToWarpedPos(vec2 inTexCoord, float a)\n" - "{\n" - // Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion). - // These are now "real world" vectors in direction (x,y,1) relative to the eye of the HMD. - // Apply the 4x4 timewarp rotation to these vectors. - " vec4 inputPos = PositionFromDepth(inTexCoord);\n" - " vec3 transformed = mix ( EyeRotationStart * inputPos, EyeRotationEnd * inputPos, a ).xyz;\n" - // Project them back onto the Z=1 plane of the rendered images. - " vec2 flattened = transformed.xy / transformed.z;\n" - // Scale them into ([0,0.5],[0,1]) or ([0.5,0],[0,1]) UV lookup space (depending on eye) - " vec2 noDepthUV = flattened * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - //" float depth = texture2DLod(Texture1, noDepthUV, 0).r;\n" - " return noDepthUV.xy;\n" - "}\n" - - "void main()\n" - "{\n" - " gl_Position.x = Position.x;\n" - " gl_Position.y = Position.y;\n" - " gl_Position.z = 0.0;\n" - " gl_Position.w = 1.0;\n" - - // warped positions are a bit more involved, hence a separate function - " oTexCoord0 = TimewarpTexCoordToWarpedPos(TexCoord0, Color.a);\n" - " oTexCoord0.y = 1-oTexCoord0.y;\n" - " oTexCoord1 = TimewarpTexCoordToWarpedPos(TexCoord1, Color.a);\n" - " oTexCoord1.y = 1-oTexCoord1.y;\n" - " oTexCoord2 = TimewarpTexCoordToWarpedPos(TexCoord2, Color.a);\n" - " oTexCoord2.y = 1-oTexCoord2.y;\n" - - " oColor = vec4(Color.r); // Used for vignette fade.\n" - "}\n"; - -const OVR::CAPI::GL::ShaderBase::Uniform DistortionPositionalTimewarpChroma_vs_refl[] = -{ - { "EyeToSourceUVScale", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 0, 8 }, - { "EyeToSourceUVOffset", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 8, 8 }, -}; - - // Distortion pixel shader lookup. // Bit 0: Chroma Correction // Bit 1: Timewarp @@ -461,8 +51,6 @@ static ShaderInfo DistortionVertexShaderLookup[DistortionVertexShaderCount] = SI_REFL__(DistortionChroma_vs), SI_REFL__(DistortionTimewarp_vs), SI_REFL__(DistortionTimewarpChroma_vs) - //SI_REFL__(DistortionPositionalTimewarp_vs), - //SI_REFL__(DistortionPositionalTimewarpChroma_vs) }; static ShaderInfo DistortionPixelShaderLookup[DistortionPixelShaderCount] = @@ -473,8 +61,8 @@ static ShaderInfo DistortionPixelShaderLookup[DistortionPixelShaderCount] = void DistortionShaderBitIndexCheck() { - OVR_COMPILER_ASSERT(ovrDistortion_Chromatic == 1); - OVR_COMPILER_ASSERT(ovrDistortion_TimeWarp == 2); + OVR_COMPILER_ASSERT(ovrDistortionCap_Chromatic == 1); + OVR_COMPILER_ASSERT(ovrDistortionCap_TimeWarp == 2); } @@ -504,7 +92,10 @@ struct LatencyVertex DistortionRenderer::DistortionRenderer(ovrHmd hmd, FrameTimeManager& timeManager, const HMDRenderState& renderState) : CAPI::DistortionRenderer(ovrRenderAPI_OpenGL, hmd, timeManager, renderState) + , LatencyVAO(0) { + DistortionMeshVAOs[0] = 0; + DistortionMeshVAOs[1] = 0; } DistortionRenderer::~DistortionRenderer() @@ -517,17 +108,17 @@ CAPI::DistortionRenderer* DistortionRenderer::Create(ovrHmd hmd, FrameTimeManager& timeManager, const HMDRenderState& renderState) { +#if !defined(OVR_OS_MAC) InitGLExtensions(); - +#endif return new DistortionRenderer(hmd, timeManager, renderState); } bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig, - unsigned hmdCaps, unsigned distortionCaps) + unsigned distortionCaps) { - // TBD: Decide if hmdCaps are needed here or are a part of RenderState - OVR_UNUSED(hmdCaps); + GfxState = *new GraphicsState(); const ovrGLConfig* config = (const ovrGLConfig*)apiConfig; @@ -539,15 +130,20 @@ bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig, memset(&RParams, 0, sizeof(RParams)); return true; } - - if (!config->OGL.WglContext || !config->OGL.GdiDc) - return false; - RParams.GdiDc = config->OGL.GdiDc; RParams.Multisample = config->OGL.Header.Multisample; RParams.RTSize = config->OGL.Header.RTSize; - RParams.WglContext = config->OGL.WglContext; - RParams.Window = config->OGL.Window; +#if defined(OVR_OS_WIN32) + RParams.Window = (config->OGL.Window) ? config->OGL.Window : GetActiveWindow(); +#elif defined(OVR_OS_LINUX) + RParams.Disp = (config->OGL.Disp) ? config->OGL.Disp : XOpenDisplay(NULL); + RParams.Win = config->OGL.Win; + if (!RParams.Win) + { + int unused; + XGetInputFocus(RParams.Disp, &RParams.Win, &unused); + } +#endif DistortionCaps = distortionCaps; @@ -564,37 +160,36 @@ bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig, void DistortionRenderer::SubmitEye(int eyeId, ovrTexture* eyeTexture) { - //Doesn't do a lot in here?? + // Doesn't do a lot in here?? const ovrGLTexture* tex = (const ovrGLTexture*)eyeTexture; - //Write in values + // Write in values eachEye[eyeId].texture = tex->OGL.TexId; if (tex) { - //Its only at this point we discover what the viewport of the texture is. - //because presumably we allow users to realtime adjust the resolution. - //Which begs the question - why did we ask them what viewport they were - //using before, which gave them a set of UV offsets. In fact, our - //asking for eye mesh must be entirely independed of these viewports, - //presumably only to get the parameters. - - ovrEyeDesc ed = RState.EyeRenderDesc[eyeId].Desc; - ed.TextureSize = tex->OGL.Header.TextureSize; - ed.RenderViewport = tex->OGL.Header.RenderViewport; - - ovrHmd_GetRenderScaleAndOffset(HMD, ed, DistortionCaps, eachEye[eyeId].UVScaleOffset); - + // Its only at this point we discover what the viewport of the texture is. + // because presumably we allow users to realtime adjust the resolution. + eachEye[eyeId].TextureSize = tex->OGL.Header.TextureSize; + eachEye[eyeId].RenderViewport = tex->OGL.Header.RenderViewport; + + const ovrEyeRenderDesc& erd = RState.EyeRenderDesc[eyeId]; + + ovrHmd_GetRenderScaleAndOffset( erd.Fov, + eachEye[eyeId].TextureSize, eachEye[eyeId].RenderViewport, + eachEye[eyeId].UVScaleOffset ); + pEyeTextures[eyeId]->UpdatePlaceholderTexture(tex->OGL.TexId, tex->OGL.Header.TextureSize); } } -void DistortionRenderer::EndFrame(bool swapBuffers, unsigned char* latencyTesterDrawColor, unsigned char* latencyTester2DrawColor) -{ +void DistortionRenderer::EndFrame(bool swapBuffers, + unsigned char* latencyTesterDrawColor, unsigned char* latencyTester2DrawColor) +{ if (!TimeManager.NeedDistortionTimeMeasurement()) { - if (RState.DistortionCaps & ovrDistortion_TimeWarp) + if (RState.DistortionCaps & ovrDistortionCap_TimeWarp) { // Wait for timewarp distortion if it is time and Gpu idle FlushGpuAndWaitTillTime(TimeManager.GetFrameTiming().TimewarpPointTime); @@ -626,18 +221,38 @@ void DistortionRenderer::EndFrame(bool swapBuffers, unsigned char* latencyTester if (swapBuffers) { - bool useVsync = ((RState.HMDCaps & ovrHmdCap_NoVSync) == 0); - BOOL success; + bool useVsync = ((RState.EnabledHmdCaps & ovrHmdCap_NoVSync) == 0); int swapInterval = (useVsync) ? 1 : 0; +#if defined(OVR_OS_WIN32) if (wglGetSwapIntervalEXT() != swapInterval) - wglSwapIntervalEXT(swapInterval); + wglSwapIntervalEXT(swapInterval); - success = SwapBuffers(RParams.GdiDc); + HDC dc = GetDC(RParams.Window); + BOOL success = SwapBuffers(dc); + ReleaseDC(RParams.Window, dc); OVR_ASSERT(success); + OVR_UNUSED(success); +#elif defined(OVR_OS_MAC) + CGLContextObj context = CGLGetCurrentContext(); + GLint currentSwapInterval = 0; + CGLGetParameter(context, kCGLCPSwapInterval, ¤tSwapInterval); + if (currentSwapInterval != swapInterval) + CGLSetParameter(context, kCGLCPSwapInterval, &swapInterval); + + CGLFlushDrawable(context); +#elif defined(OVR_OS_LINUX) + static const char* extensions = glXQueryExtensionsString(RParams.Disp, 0); + static bool supportsVSync = (extensions != NULL && strstr(extensions, "GLX_EXT_swap_control")); + if (supportsVSync) + { + GLuint currentSwapInterval = 0; + glXQueryDrawable(RParams.Disp, RParams.Win, GLX_SWAP_INTERVAL_EXT, ¤tSwapInterval); + if (currentSwapInterval != swapInterval) + glXSwapIntervalEXT(RParams.Disp, RParams.Win, swapInterval); + } - // Force GPU to flush the scene, resulting in the lowest possible latency. - // It's critical that this flush is *after* present. - WaitUntilGpuIdle(); + glXSwapBuffers(RParams.Disp, RParams.Win); +#endif } } @@ -670,6 +285,109 @@ double DistortionRenderer::FlushGpuAndWaitTillTime(double absTime) // How long we waited return newTime - initialTime; } + + +DistortionRenderer::GraphicsState::GraphicsState() +{ + const char* glVersionString = (const char*)glGetString(GL_VERSION); + OVR_DEBUG_LOG(("GL_VERSION STRING: %s", (const char*)glVersionString)); + char prefix[64]; + bool foundVersion = false; + + for (int i = 10; i < 30; ++i) + { + int major = i / 10; + int minor = i % 10; + OVR_sprintf(prefix, 64, "%d.%d", major, minor); + if (strstr(glVersionString, prefix) == glVersionString) + { + GlMajorVersion = major; + GlMinorVersion = minor; + foundVersion = true; + break; + } + } + + if (!foundVersion) + { + glGetIntegerv(GL_MAJOR_VERSION, &GlMajorVersion); + glGetIntegerv(GL_MAJOR_VERSION, &GlMinorVersion); + } + + OVR_ASSERT(GlMajorVersion >= 2); + + if (GlMajorVersion >= 3) + { + SupportsVao = true; + } + else + { + const char* extensions = (const char*)glGetString(GL_EXTENSIONS); + SupportsVao = (strstr("GL_ARB_vertex_array_object", extensions) != NULL); + } +} + + +void DistortionRenderer::GraphicsState::ApplyBool(GLenum Name, GLint Value) +{ + if (Value != 0) + glEnable(Name); + else + glDisable(Name); +} + + +void DistortionRenderer::GraphicsState::Save() +{ + glGetIntegerv(GL_VIEWPORT, Viewport); + glGetFloatv(GL_COLOR_CLEAR_VALUE, ClearColor); + glGetIntegerv(GL_DEPTH_TEST, &DepthTest); + glGetIntegerv(GL_CULL_FACE, &CullFace); + glGetIntegerv(GL_CURRENT_PROGRAM, &Program); + glGetIntegerv(GL_ACTIVE_TEXTURE, &ActiveTexture); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &TextureBinding); + glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &VertexArray); + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &FrameBufferBinding); + glGetIntegerv(GL_BLEND, &Blend); + glGetIntegerv(GL_COLOR_WRITEMASK, ColorWritemask); + glGetIntegerv(GL_DITHER, &Dither); + glGetIntegerv(GL_RASTERIZER_DISCARD, &RasterizerDiscard); + if (GlMajorVersion >= 3 && GlMajorVersion >= 2) + glGetIntegerv(GL_SAMPLE_MASK, &SampleMask); + glGetIntegerv(GL_SCISSOR_TEST, &ScissorTest); + + IsValid = true; +} + + +void DistortionRenderer::GraphicsState::Restore() +{ + // Don't allow restore-before-save. + if (!IsValid) + return; + + glViewport(Viewport[0], Viewport[1], Viewport[2], Viewport[3]); + glClearColor(ClearColor[0], ClearColor[1], ClearColor[2], ClearColor[3]); + + ApplyBool(GL_DEPTH_TEST, DepthTest); + ApplyBool(GL_CULL_FACE, CullFace); + + glUseProgram(Program); + glActiveTexture(ActiveTexture); + glBindTexture(GL_TEXTURE_2D, TextureBinding); + if (SupportsVao) + glBindVertexArray(VertexArray); + glBindFramebuffer(GL_FRAMEBUFFER, FrameBufferBinding); + + ApplyBool(GL_BLEND, Blend); + + glColorMask((GLboolean)ColorWritemask[0], (GLboolean)ColorWritemask[1], (GLboolean)ColorWritemask[2], (GLboolean)ColorWritemask[3]); + ApplyBool(GL_DITHER, Dither); + ApplyBool(GL_RASTERIZER_DISCARD, RasterizerDiscard); + if (GlMajorVersion >= 3 && GlMajorVersion >= 2) + ApplyBool(GL_SAMPLE_MASK, SampleMask); + ApplyBool(GL_SCISSOR_TEST, ScissorTest); +} void DistortionRenderer::initBuffersAndShaders() @@ -681,9 +399,11 @@ void DistortionRenderer::initBuffersAndShaders() // double startT = ovr_GetTimeInSeconds(); - if (!ovrHmd_CreateDistortionMesh( HMD, RState.EyeRenderDesc[eyeNum].Desc, + if (!ovrHmd_CreateDistortionMesh( HMD, + RState.EyeRenderDesc[eyeNum].Eye, + RState.EyeRenderDesc[eyeNum].Fov, RState.DistortionCaps, - UVScaleOffset[eyeNum], &meshData) ) + &meshData) ) { OVR_ASSERT(false); continue; @@ -711,9 +431,9 @@ void DistortionRenderer::initBuffersAndShaders() } DistortionMeshVBs[eyeNum] = *new Buffer(&RParams); - DistortionMeshVBs[eyeNum]->Data ( Buffer_Vertex, pVBVerts, sizeof(DistortionVertex) * meshData.VertexCount ); + DistortionMeshVBs[eyeNum]->Data ( Buffer_Vertex | Buffer_ReadOnly, pVBVerts, sizeof(DistortionVertex) * meshData.VertexCount ); DistortionMeshIBs[eyeNum] = *new Buffer(&RParams); - DistortionMeshIBs[eyeNum]->Data ( Buffer_Index, meshData.pIndexData, ( sizeof(INT16) * meshData.IndexCount ) ); + DistortionMeshIBs[eyeNum]->Data ( Buffer_Index | Buffer_ReadOnly, meshData.pIndexData, ( sizeof(SInt16) * meshData.IndexCount ) ); OVR_FREE ( pVBVerts ); ovrHmd_DestroyDistortionMesh( &meshData ); @@ -723,8 +443,22 @@ void DistortionRenderer::initBuffersAndShaders() } void DistortionRenderer::renderDistortion(Texture* leftEyeTexture, Texture* rightEyeTexture) -{ +{ + GraphicsState* glState = (GraphicsState*)GfxState.GetPtr(); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); setViewport( Recti(0,0, RParams.RTSize.w, RParams.RTSize.h) ); + + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glDisable(GL_BLEND); + + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); + glDisable(GL_DITHER); + glDisable(GL_RASTERIZER_DISCARD); + if (glState->GlMajorVersion >= 3 && glState->GlMajorVersion >= 2) + glDisable(GL_SAMPLE_MASK); + glDisable(GL_SCISSOR_TEST); glClearColor( RState.ClearColor[0], @@ -732,19 +466,17 @@ void DistortionRenderer::renderDistortion(Texture* leftEyeTexture, Texture* righ RState.ClearColor[2], RState.ClearColor[3] ); - glClearDepth(0); - - glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + glClear(GL_COLOR_BUFFER_BIT); for (int eyeNum = 0; eyeNum < 2; eyeNum++) { ShaderFill distortionShaderFill(DistortionShader); distortionShaderFill.SetTexture(0, eyeNum == 0 ? leftEyeTexture : rightEyeTexture); - DistortionShader->SetUniform2f("EyeToSourceUVScale", UVScaleOffset[eyeNum][0].x, UVScaleOffset[eyeNum][0].y); - DistortionShader->SetUniform2f("EyeToSourceUVOffset", UVScaleOffset[eyeNum][1].x, UVScaleOffset[eyeNum][1].y); + DistortionShader->SetUniform2f("EyeToSourceUVScale", eachEye[eyeNum].UVScaleOffset[0].x, eachEye[eyeNum].UVScaleOffset[0].y); + DistortionShader->SetUniform2f("EyeToSourceUVOffset", eachEye[eyeNum].UVScaleOffset[1].x, eachEye[eyeNum].UVScaleOffset[1].y); - if (DistortionCaps & ovrDistortion_TimeWarp) + if (DistortionCaps & ovrDistortionCap_TimeWarp) { ovrMatrix4f timeWarpMatrices[2]; ovrHmd_GetEyeTimewarpMatrices(HMD, (ovrEyeType)eyeNum, @@ -755,12 +487,12 @@ void DistortionRenderer::renderDistortion(Texture* leftEyeTexture, Texture* righ DistortionShader->SetUniform4x4f("EyeRotationEnd", Matrix4f(timeWarpMatrices[1]).Transposed()); renderPrimitives(&distortionShaderFill, DistortionMeshVBs[eyeNum], DistortionMeshIBs[eyeNum], - NULL, 0, (int)DistortionMeshVBs[eyeNum]->GetSize(), Prim_Triangles, true); + 0, (int)DistortionMeshIBs[eyeNum]->GetSize()/2, Prim_Triangles, &DistortionMeshVAOs[eyeNum], true); } else { renderPrimitives(&distortionShaderFill, DistortionMeshVBs[eyeNum], DistortionMeshIBs[eyeNum], - NULL, 0, (int)DistortionMeshVBs[eyeNum]->GetSize(), Prim_Triangles, true); + 0, (int)DistortionMeshIBs[eyeNum]->GetSize()/2, Prim_Triangles, &DistortionMeshVAOs[eyeNum], true); } } } @@ -818,7 +550,7 @@ void DistortionRenderer::renderLatencyQuad(unsigned char* latencyTesterDrawColor for(int eyeNum = 0; eyeNum < 2; eyeNum++) { SimpleQuadShader->SetUniform2f("PositionOffset", eyeNum == 0 ? -0.4f : 0.4f, 0.0f); - renderPrimitives(&quadFill, LatencyTesterQuadVB, NULL, NULL, 0, numQuadVerts, Prim_TriangleStrip, false); + renderPrimitives(&quadFill, LatencyTesterQuadVB, NULL, 0, numQuadVerts, Prim_TriangleStrip, &LatencyVAO, false); } } @@ -843,16 +575,16 @@ void DistortionRenderer::renderLatencyPixel(unsigned char* latencyTesterPixelCol Vector2f scale(2.0f / RParams.RTSize.w, 2.0f / RParams.RTSize.h); SimpleQuadShader->SetUniform2f("Scale", scale.x, scale.y); SimpleQuadShader->SetUniform2f("PositionOffset", 1.0f, 1.0f); - renderPrimitives(&quadFill, LatencyTesterQuadVB, NULL, NULL, 0, numQuadVerts, Prim_TriangleStrip, false); + renderPrimitives(&quadFill, LatencyTesterQuadVB, NULL, 0, numQuadVerts, Prim_TriangleStrip, &LatencyVAO, false); } void DistortionRenderer::renderPrimitives( const ShaderFill* fill, Buffer* vertices, Buffer* indices, - Matrix4f* viewMatrix, int offset, int count, - PrimitiveType rprim, bool useDistortionVertex) + int offset, int count, + PrimitiveType rprim, GLuint* vao, bool isDistortionMesh) { - ShaderSet* shaders = (ShaderSet*) ((ShaderFill*)fill)->GetShaders(); + GraphicsState* glState = (GraphicsState*)GfxState.GetPtr(); GLenum prim; switch (rprim) @@ -867,128 +599,173 @@ void DistortionRenderer::renderPrimitives( prim = GL_TRIANGLE_STRIP; break; default: - assert(0); + OVR_ASSERT(false); return; } fill->Set(); - if (shaders->ProjLoc >= 0) - glUniformMatrix4fv(shaders->ProjLoc, 1, 0, &StdUniforms.Proj.M[0][0]); - if (shaders->ViewLoc >= 0 && viewMatrix != NULL) - glUniformMatrix4fv(shaders->ViewLoc, 1, 0, &viewMatrix->Transposed().M[0][0]); - - //if (shaders->UsesLighting && Lighting->Version != shaders->LightingVer) - //{ - // shaders->LightingVer = Lighting->Version; - // Lighting->Set(shaders); - //} - - glBindBuffer(GL_ARRAY_BUFFER, ((Buffer*)vertices)->GLBuffer); - for (int i = 0; i < 5; i++) - glEnableVertexAttribArray(i); GLuint prog = fill->GetShaders()->Prog; - if (useDistortionVertex) + if (vao != NULL) { - GLint posLoc = glGetAttribLocation(prog, "Position"); - GLint colLoc = glGetAttribLocation(prog, "Color"); - GLint tc0Loc = glGetAttribLocation(prog, "TexCoord0"); - GLint tc1Loc = glGetAttribLocation(prog, "TexCoord1"); - GLint tc2Loc = glGetAttribLocation(prog, "TexCoord2"); - - glVertexAttribPointer(posLoc, 2, GL_FLOAT, false, sizeof(DistortionVertex), (char*)offset + offsetof(DistortionVertex, Pos)); - glVertexAttribPointer(colLoc, 4, GL_UNSIGNED_BYTE, true, sizeof(DistortionVertex), (char*)offset + offsetof(DistortionVertex, Col)); - glVertexAttribPointer(tc0Loc, 2, GL_FLOAT, false, sizeof(DistortionVertex), (char*)offset + offsetof(DistortionVertex, TexR)); - glVertexAttribPointer(tc1Loc, 2, GL_FLOAT, false, sizeof(DistortionVertex), (char*)offset + offsetof(DistortionVertex, TexG)); - glVertexAttribPointer(tc2Loc, 2, GL_FLOAT, false, sizeof(DistortionVertex), (char*)offset + offsetof(DistortionVertex, TexB)); - } - else - { - GLint posLoc = glGetAttribLocation(prog, "Position"); + if (*vao != 0) + { + glBindVertexArray(*vao); - glVertexAttribPointer(posLoc, 3, GL_FLOAT, false, sizeof(LatencyVertex), (char*)offset + offsetof(LatencyVertex, Pos)); + if (isDistortionMesh) + glDrawElements(prim, count, GL_UNSIGNED_SHORT, NULL); + else + glDrawArrays(prim, 0, count); + } + else + { + if (glState->SupportsVao) + { + glGenVertexArrays(1, vao); + glBindVertexArray(*vao); + } + + int attributeCount = (isDistortionMesh) ? 5 : 1; + int* locs = new int[attributeCount]; + + glBindBuffer(GL_ARRAY_BUFFER, ((Buffer*)vertices)->GLBuffer); + + if (isDistortionMesh) + { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ((Buffer*)indices)->GLBuffer); + + locs[0] = glGetAttribLocation(prog, "Position"); + locs[1] = glGetAttribLocation(prog, "Color"); + locs[2] = glGetAttribLocation(prog, "TexCoord0"); + locs[3] = glGetAttribLocation(prog, "TexCoord1"); + locs[4] = glGetAttribLocation(prog, "TexCoord2"); + + glVertexAttribPointer(locs[0], 2, GL_FLOAT, false, sizeof(DistortionVertex), reinterpret_cast<char*>(offset)+offsetof(DistortionVertex, Pos)); + glVertexAttribPointer(locs[1], 4, GL_UNSIGNED_BYTE, true, sizeof(DistortionVertex), reinterpret_cast<char*>(offset)+offsetof(DistortionVertex, Col)); + glVertexAttribPointer(locs[2], 2, GL_FLOAT, false, sizeof(DistortionVertex), reinterpret_cast<char*>(offset)+offsetof(DistortionVertex, TexR)); + glVertexAttribPointer(locs[3], 2, GL_FLOAT, false, sizeof(DistortionVertex), reinterpret_cast<char*>(offset)+offsetof(DistortionVertex, TexG)); + glVertexAttribPointer(locs[4], 2, GL_FLOAT, false, sizeof(DistortionVertex), reinterpret_cast<char*>(offset)+offsetof(DistortionVertex, TexB)); + } + else + { + locs[0] = glGetAttribLocation(prog, "Position"); + + glVertexAttribPointer(locs[0], 3, GL_FLOAT, false, sizeof(LatencyVertex), reinterpret_cast<char*>(offset)+offsetof(LatencyVertex, Pos)); + } + + for (int i = 0; i < attributeCount; ++i) + glEnableVertexAttribArray(locs[i]); + + if (isDistortionMesh) + glDrawElements(prim, count, GL_UNSIGNED_SHORT, NULL); + else + glDrawArrays(prim, 0, count); + + + if (!glState->SupportsVao) + { + for (int i = 0; i < attributeCount; ++i) + glDisableVertexAttribArray(locs[i]); + } + + delete[] locs; + } } - - if (indices) - { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ((Buffer*)indices)->GLBuffer); - glDrawElements(prim, count, GL_UNSIGNED_SHORT, NULL); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - } - else - { - glDrawArrays(prim, 0, count); - } - - for (int i = 0; i < 5; i++) - glDisableVertexAttribArray(i); } void DistortionRenderer::setViewport(const Recti& vp) { - int wh; - if (CurRenderTarget) - wh = CurRenderTarget->Height; - else - { - RECT rect; - BOOL success = GetWindowRect(RParams.Window, &rect); - OVR_ASSERT(success); - OVR_UNUSED(success); - wh = rect.bottom - rect.top; - } - glViewport(vp.x, wh-vp.y-vp.h, vp.w, vp.h); - - //glEnable(GL_SCISSOR_TEST); - //glScissor(vp.x, wh-vp.y-vp.h, vp.w, vp.h); + glViewport(vp.x, vp.y, vp.w, vp.h); } void DistortionRenderer::initShaders() { + GraphicsState* glState = (GraphicsState*)GfxState.GetPtr(); + + const char* shaderPrefix = + (glState->GlMajorVersion < 3 || (glState->GlMajorVersion == 3 && glState->GlMinorVersion < 2)) ? + glsl2Prefix : glsl3Prefix; + { - ShaderInfo vsShaderByteCode = DistortionVertexShaderLookup[DistortionVertexShaderBitMask & DistortionCaps]; - Ptr<GL::VertexShader> vtxShader = *new GL::VertexShader( + ShaderInfo vsInfo = DistortionVertexShaderLookup[DistortionVertexShaderBitMask & DistortionCaps]; + + size_t vsSize = strlen(shaderPrefix)+vsInfo.ShaderSize; + char* vsSource = new char[vsSize]; + OVR_strcpy(vsSource, vsSize, shaderPrefix); + OVR_strcat(vsSource, vsSize, vsInfo.ShaderData); + + Ptr<GL::VertexShader> vs = *new GL::VertexShader( &RParams, - (void*)vsShaderByteCode.ShaderData, vsShaderByteCode.ShaderSize, - vsShaderByteCode.ReflectionData, vsShaderByteCode.ReflectionSize); + (void*)vsSource, vsSize, + vsInfo.ReflectionData, vsInfo.ReflectionSize); DistortionShader = *new ShaderSet; - DistortionShader->SetShader(vtxShader); + DistortionShader->SetShader(vs); - ShaderInfo psShaderByteCode = DistortionPixelShaderLookup[DistortionPixelShaderBitMask & DistortionCaps]; + delete[](vsSource); + + ShaderInfo psInfo = DistortionPixelShaderLookup[DistortionPixelShaderBitMask & DistortionCaps]; + + size_t psSize = strlen(shaderPrefix)+psInfo.ShaderSize; + char* psSource = new char[psSize]; + OVR_strcpy(psSource, psSize, shaderPrefix); + OVR_strcat(psSource, psSize, psInfo.ShaderData); Ptr<GL::FragmentShader> ps = *new GL::FragmentShader( &RParams, - (void*)psShaderByteCode.ShaderData, psShaderByteCode.ShaderSize, - psShaderByteCode.ReflectionData, psShaderByteCode.ReflectionSize); + (void*)psSource, psSize, + psInfo.ReflectionData, psInfo.ReflectionSize); DistortionShader->SetShader(ps); + + delete[](psSource); } - { - Ptr<GL::VertexShader> vtxShader = *new GL::VertexShader( + { + size_t vsSize = strlen(shaderPrefix)+sizeof(SimpleQuad_vs); + char* vsSource = new char[vsSize]; + OVR_strcpy(vsSource, vsSize, shaderPrefix); + OVR_strcat(vsSource, vsSize, SimpleQuad_vs); + + Ptr<GL::VertexShader> vs = *new GL::VertexShader( &RParams, - (void*)SimpleQuad_vs, sizeof(SimpleQuad_vs), - SimpleQuad_vs_refl, sizeof(SimpleQuad_vs_refl) / sizeof(SimpleQuad_vs_refl[0])); + (void*)vsSource, vsSize, + SimpleQuad_vs_refl, sizeof(SimpleQuad_vs_refl) / sizeof(SimpleQuad_vs_refl[0])); SimpleQuadShader = *new ShaderSet; - SimpleQuadShader->SetShader(vtxShader); + SimpleQuadShader->SetShader(vs); + + delete[](vsSource); + + size_t psSize = strlen(shaderPrefix)+sizeof(SimpleQuad_fs); + char* psSource = new char[psSize]; + OVR_strcpy(psSource, psSize, shaderPrefix); + OVR_strcat(psSource, psSize, SimpleQuad_fs); Ptr<GL::FragmentShader> ps = *new GL::FragmentShader( &RParams, - (void*)SimpleQuad_fs, sizeof(SimpleQuad_fs), + (void*)psSource, psSize, SimpleQuad_fs_refl, sizeof(SimpleQuad_fs_refl) / sizeof(SimpleQuad_fs_refl[0])); - SimpleQuadShader->SetShader(ps); + SimpleQuadShader->SetShader(ps); + + delete[](psSource); } } void DistortionRenderer::destroy() { + GraphicsState* glState = (GraphicsState*)GfxState.GetPtr(); + for(int eyeNum = 0; eyeNum < 2; eyeNum++) { + if (glState->SupportsVao) + glDeleteVertexArrays(1, &DistortionMeshVAOs[eyeNum]); + + DistortionMeshVAOs[eyeNum] = 0; + DistortionMeshVBs[eyeNum].Clear(); DistortionMeshIBs[eyeNum].Clear(); } @@ -1001,6 +778,7 @@ void DistortionRenderer::destroy() } LatencyTesterQuadVB.Clear(); + LatencyVAO = 0; } }}} // OVR::CAPI::GL diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.h b/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.h index 8e0b72e..60f1a9f 100644 --- a/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.h +++ b/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.h @@ -45,7 +45,7 @@ public: // ***** Public DistortionRenderer interface virtual bool Initialize(const ovrRenderAPIConfig* apiConfig, - unsigned hmdCaps, unsigned distortionCaps); + unsigned distortionCaps); virtual void SubmitEye(int eyeId, ovrTexture* eyeTexture); @@ -57,12 +57,54 @@ public: // Note, it exits when time expires, even if GPU is not in idle state yet. double FlushGpuAndWaitTillTime(double absTime); -private: +protected: + + + class GraphicsState : public CAPI::DistortionRenderer::GraphicsState + { + public: + GraphicsState(); + virtual void Save(); + virtual void Restore(); + + protected: + void ApplyBool(GLenum Name, GLint Value); + + public: + GLint GlMajorVersion; + GLint GlMinorVersion; + bool SupportsVao; + + GLint Viewport[4]; + GLfloat ClearColor[4]; + GLint DepthTest; + GLint CullFace; + GLint Program; + GLint ActiveTexture; + GLint TextureBinding; + GLint VertexArray; + GLint FrameBufferBinding; + + GLint Blend; + GLint ColorWritemask[4]; + GLint Dither; + GLint Fog; + GLint Lighting; + GLint RasterizerDiscard; + GLint RenderMode; + GLint SampleMask; + GLint ScissorTest; + GLfloat ZoomX; + GLfloat ZoomY; + }; + // TBD: Should we be using oe from RState instead? unsigned DistortionCaps; struct FOR_EACH_EYE { + FOR_EACH_EYE() : TextureSize(0), RenderViewport(Sizei(0)) { } + #if 0 IDirect3DVertexBuffer9 * dxVerts; IDirect3DIndexBuffer9 * dxIndices; @@ -70,9 +112,11 @@ private: int numVerts; int numIndices; - GLuint texture; + GLuint texture; - ovrVector2f UVScaleOffset[2]; + ovrVector2f UVScaleOffset[2]; + Sizei TextureSize; + Recti RenderViewport; } eachEye[2]; // GL context and utility variables. @@ -89,8 +133,8 @@ private: void renderDistortion(Texture* leftEyeTexture, Texture* rightEyeTexture); void renderPrimitives(const ShaderFill* fill, Buffer* vertices, Buffer* indices, - Matrix4f* viewMatrix, int offset, int count, - PrimitiveType rprim, bool useDistortionVertex); + int offset, int count, + PrimitiveType rprim, GLuint* vao, bool isDistortionMesh); void createDrawQuad(); void renderLatencyQuad(unsigned char* latencyTesterDrawColor); @@ -98,11 +142,9 @@ private: Ptr<Texture> pEyeTextures[2]; - // U,V scale and offset needed for timewarp. - ovrVector2f UVScaleOffset[2][2]; - Ptr<Buffer> DistortionMeshVBs[2]; // one per-eye Ptr<Buffer> DistortionMeshIBs[2]; // one per-eye + GLuint DistortionMeshVAOs[2]; // one per-eye Ptr<ShaderSet> DistortionShader; @@ -111,13 +153,24 @@ private: Matrix4f Proj; Matrix4f View; } StdUniforms; - + + GLuint LatencyVAO; Ptr<Buffer> LatencyTesterQuadVB; Ptr<ShaderSet> SimpleQuadShader; Ptr<Texture> CurRenderTarget; Array<Ptr<Texture> > DepthBuffers; GLuint CurrentFbo; + + GLint SavedViewport[4]; + GLfloat SavedClearColor[4]; + GLint SavedDepthTest; + GLint SavedCullFace; + GLint SavedProgram; + GLint SavedActiveTexture; + GLint SavedBoundTexture; + GLint SavedVertexArray; + GLint SavedBoundFrameBuffer; }; }}} // OVR::CAPI::GL diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionShaders.h b/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionShaders.h new file mode 100644 index 0000000..03fd174 --- /dev/null +++ b/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionShaders.h @@ -0,0 +1,326 @@ +/************************************************************************************ + + Filename : CAPI_GL_Shaders.h + Content : Distortion shader header for GL + Created : November 11, 2013 + Authors : David Borel, Volga Aksoy + + Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved. + + Use of this software is subject to the terms of the Oculus Inc license + agreement provided at the time of installation or download, or which + otherwise accompanies this software in either electronic or hard copy form. + + ************************************************************************************/ + + +#ifndef OVR_CAPI_GL_Shaders_h +#define OVR_CAPI_GL_Shaders_h + + +#include "CAPI_GL_Util.h" + +namespace OVR { namespace CAPI { namespace GL { + + static const char glsl2Prefix[] = + "#version 110\n" + "#extension GL_ARB_shader_texture_lod : enable\n" + "#define _FRAGCOLOR_DECLARATION\n" + "#define _VS_IN attribute\n" + "#define _VS_OUT varying\n" + "#define _FS_IN varying\n" + "#define _TEXTURELOD texture2DLod\n" + "#define _FRAGCOLOR gl_FragColor\n"; + + static const char glsl3Prefix[] = + "#version 150\n" + "#define _FRAGCOLOR_DECLARATION out vec4 FragColor;\n" + "#define _VS_IN in\n" + "#define _VS_OUT out\n" + "#define _FS_IN in\n" + "#define _TEXTURELOD textureLod\n" + "#define _FRAGCOLOR FragColor\n"; + + static const char SimpleQuad_vs[] = + "uniform vec2 PositionOffset;\n" + "uniform vec2 Scale;\n" + + "_VS_IN vec3 Position;\n" + + "void main()\n" + "{\n" + " gl_Position = vec4(Position.xy * Scale + PositionOffset, 0.5, 1.0);\n" + "}\n"; + + const OVR::CAPI::GL::ShaderBase::Uniform SimpleQuad_vs_refl[] = + { + { "PositionOffset", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 0, 8 }, + { "Scale", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 8, 8 }, + }; + + static const char SimpleQuad_fs[] = + "uniform vec4 Color;\n" + + "_FRAGCOLOR_DECLARATION\n" + + "void main()\n" + "{\n" + " _FRAGCOLOR = Color;\n" + "}\n"; + + const OVR::CAPI::GL::ShaderBase::Uniform SimpleQuad_fs_refl[] = + { + { "Color", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 0, 16 }, + }; + + + static const char Distortion_vs[] = + "uniform vec2 EyeToSourceUVScale;\n" + "uniform vec2 EyeToSourceUVOffset;\n" + + "_VS_IN vec2 Position;\n" + "_VS_IN vec4 Color;\n" + "_VS_IN vec2 TexCoord0;\n" + + "_VS_OUT vec4 oColor;\n" + "_VS_OUT vec2 oTexCoord0;\n" + + "void main()\n" + "{\n" + " gl_Position.x = Position.x;\n" + " gl_Position.y = Position.y;\n" + " gl_Position.z = 0.5;\n" + " gl_Position.w = 1.0;\n" + // Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion). + // Scale them into the correct [0-1],[0-1] UV lookup space (depending on eye) + " oTexCoord0 = TexCoord0 * EyeToSourceUVScale + EyeToSourceUVOffset;\n" + " oTexCoord0.y = 1.0 - oTexCoord0.y;\n" + " oColor = Color;\n" // Used for vignette fade. + "}\n"; + + const OVR::CAPI::GL::ShaderBase::Uniform Distortion_vs_refl[] = + { + { "EyeToSourceUVScale", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 0, 8 }, + { "EyeToSourceUVOffset", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 8, 8 }, + }; + + static const char Distortion_fs[] = + "uniform sampler2D Texture0;\n" + + "_FS_IN vec4 oColor;\n" + "_FS_IN vec2 oTexCoord0;\n" + + "_FRAGCOLOR_DECLARATION\n" + + "void main()\n" + "{\n" + " _FRAGCOLOR = _TEXTURELOD(Texture0, oTexCoord0, 0.0);\n" + " _FRAGCOLOR.a = 1.0;\n" + "}\n"; + + + static const char DistortionTimewarp_vs[] = + "uniform vec2 EyeToSourceUVScale;\n" + "uniform vec2 EyeToSourceUVOffset;\n" + "uniform mat4 EyeRotationStart;\n" + "uniform mat4 EyeRotationEnd;\n" + + "_VS_IN vec2 Position;\n" + "_VS_IN vec4 Color;\n" + "_VS_IN vec2 TexCoord0;\n" + + "_FS_IN vec4 oColor;\n" + "_FS_IN vec2 oTexCoord0;\n" + + "void main()\n" + "{\n" + " gl_Position.x = Position.x;\n" + " gl_Position.y = Position.y;\n" + " gl_Position.z = 0.0;\n" + " gl_Position.w = 1.0;\n" + + // Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion). + // These are now "real world" vectors in direction (x,y,1) relative to the eye of the HMD. + " vec3 TanEyeAngle = vec3 ( TexCoord0.x, TexCoord0.y, 1.0 );\n" + + // Accurate time warp lerp vs. faster +#if 1 + // Apply the two 3x3 timewarp rotations to these vectors. + " vec3 TransformedStart = (EyeRotationStart * vec4(TanEyeAngle, 0)).xyz;\n" + " vec3 TransformedEnd = (EyeRotationEnd * vec4(TanEyeAngle, 0)).xyz;\n" + // And blend between them. + " vec3 Transformed = mix ( TransformedStart, TransformedEnd, Color.a );\n" +#else + " mat4 EyeRotation = mix ( EyeRotationStart, EyeRotationEnd, Color.a );\n" + " vec3 Transformed = EyeRotation * TanEyeAngle;\n" +#endif + + // Project them back onto the Z=1 plane of the rendered images. + " float RecipZ = 1.0 / Transformed.z;\n" + " vec2 Flattened = vec2 ( Transformed.x * RecipZ, Transformed.y * RecipZ );\n" + + // These are now still in TanEyeAngle space. + // Scale them into the correct [0-1],[0-1] UV lookup space (depending on eye) + " vec2 SrcCoord = Flattened * EyeToSourceUVScale + EyeToSourceUVOffset;\n" + " oTexCoord0 = SrcCoord;\n" + " oTexCoord0.y = 1.0-oTexCoord0.y;\n" + " oColor = vec4(Color.r, Color.r, Color.r, Color.r);\n" // Used for vignette fade. + "}\n"; + + + const OVR::CAPI::GL::ShaderBase::Uniform DistortionTimewarp_vs_refl[] = + { + { "EyeToSourceUVScale", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 0, 8 }, + { "EyeToSourceUVOffset", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 8, 8 }, + }; + + static const char DistortionChroma_vs[] = + "uniform vec2 EyeToSourceUVScale;\n" + "uniform vec2 EyeToSourceUVOffset;\n" + + "_VS_IN vec2 Position;\n" + "_VS_IN vec4 Color;\n" + "_VS_IN vec2 TexCoord0;\n" + "_VS_IN vec2 TexCoord1;\n" + "_VS_IN vec2 TexCoord2;\n" + + "_VS_OUT vec4 oColor;\n" + "_VS_OUT vec2 oTexCoord0;\n" + "_VS_OUT vec2 oTexCoord1;\n" + "_VS_OUT vec2 oTexCoord2;\n" + + "void main()\n" + "{\n" + " gl_Position.x = Position.x;\n" + " gl_Position.y = Position.y;\n" + " gl_Position.z = 0.5;\n" + " gl_Position.w = 1.0;\n" + + // Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion). + // Scale them into the correct [0-1],[0-1] UV lookup space (depending on eye) + " oTexCoord0 = TexCoord0 * EyeToSourceUVScale + EyeToSourceUVOffset;\n" + " oTexCoord0.y = 1.0-oTexCoord0.y;\n" + " oTexCoord1 = TexCoord1 * EyeToSourceUVScale + EyeToSourceUVOffset;\n" + " oTexCoord1.y = 1.0-oTexCoord1.y;\n" + " oTexCoord2 = TexCoord2 * EyeToSourceUVScale + EyeToSourceUVOffset;\n" + " oTexCoord2.y = 1.0-oTexCoord2.y;\n" + + " oColor = Color;\n" // Used for vignette fade. + "}\n"; + + const OVR::CAPI::GL::ShaderBase::Uniform DistortionChroma_vs_refl[] = + { + { "EyeToSourceUVScale", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 0, 8 }, + { "EyeToSourceUVOffset", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 8, 8 }, + }; + + static const char DistortionChroma_fs[] = + "uniform sampler2D Texture0;\n" + + "_FS_IN vec4 oColor;\n" + "_FS_IN vec2 oTexCoord0;\n" + "_FS_IN vec2 oTexCoord1;\n" + "_FS_IN vec2 oTexCoord2;\n" + + "_FRAGCOLOR_DECLARATION\n" + + "void main()\n" + "{\n" + " float ResultR = _TEXTURELOD(Texture0, oTexCoord0, 0.0).r;\n" + " float ResultG = _TEXTURELOD(Texture0, oTexCoord1, 0.0).g;\n" + " float ResultB = _TEXTURELOD(Texture0, oTexCoord2, 0.0).b;\n" + + " _FRAGCOLOR = vec4(ResultR * oColor.r, ResultG * oColor.g, ResultB * oColor.b, 1.0);\n" + "}\n"; + + + static const char DistortionTimewarpChroma_vs[] = + "uniform vec2 EyeToSourceUVScale;\n" + "uniform vec2 EyeToSourceUVOffset;\n" + "uniform mat4 EyeRotationStart;\n" + "uniform mat4 EyeRotationEnd;\n" + + "_VS_IN vec2 Position;\n" + "_VS_IN vec4 Color;\n" + "_VS_IN vec2 TexCoord0;\n" + "_VS_IN vec2 TexCoord1;\n" + "_VS_IN vec2 TexCoord2;\n" + + "_VS_OUT vec4 oColor;\n" + "_VS_OUT vec2 oTexCoord0;\n" + "_VS_OUT vec2 oTexCoord1;\n" + "_VS_OUT vec2 oTexCoord2;\n" + + "void main()\n" + "{\n" + " gl_Position.x = Position.x;\n" + " gl_Position.y = Position.y;\n" + " gl_Position.z = 0.0;\n" + " gl_Position.w = 1.0;\n" + + // Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion). + // These are now "real world" vectors in direction (x,y,1) relative to the eye of the HMD. + " vec3 TanEyeAngleR = vec3 ( TexCoord0.x, TexCoord0.y, 1.0 );\n" + " vec3 TanEyeAngleG = vec3 ( TexCoord1.x, TexCoord1.y, 1.0 );\n" + " vec3 TanEyeAngleB = vec3 ( TexCoord2.x, TexCoord2.y, 1.0 );\n" + + // Accurate time warp lerp vs. faster +#if 1 + // Apply the two 3x3 timewarp rotations to these vectors. + " vec3 TransformedRStart = (EyeRotationStart * vec4(TanEyeAngleR, 0)).xyz;\n" + " vec3 TransformedGStart = (EyeRotationStart * vec4(TanEyeAngleG, 0)).xyz;\n" + " vec3 TransformedBStart = (EyeRotationStart * vec4(TanEyeAngleB, 0)).xyz;\n" + " vec3 TransformedREnd = (EyeRotationEnd * vec4(TanEyeAngleR, 0)).xyz;\n" + " vec3 TransformedGEnd = (EyeRotationEnd * vec4(TanEyeAngleG, 0)).xyz;\n" + " vec3 TransformedBEnd = (EyeRotationEnd * vec4(TanEyeAngleB, 0)).xyz;\n" + + // And blend between them. + " vec3 TransformedR = mix ( TransformedRStart, TransformedREnd, Color.a );\n" + " vec3 TransformedG = mix ( TransformedGStart, TransformedGEnd, Color.a );\n" + " vec3 TransformedB = mix ( TransformedBStart, TransformedBEnd, Color.a );\n" +#else + " mat3 EyeRotation;\n" + " EyeRotation[0] = mix ( EyeRotationStart[0], EyeRotationEnd[0], Color.a ).xyz;\n" + " EyeRotation[1] = mix ( EyeRotationStart[1], EyeRotationEnd[1], Color.a ).xyz;\n" + " EyeRotation[2] = mix ( EyeRotationStart[2], EyeRotationEnd[2], Color.a ).xyz;\n" + " vec3 TransformedR = EyeRotation * TanEyeAngleR;\n" + " vec3 TransformedG = EyeRotation * TanEyeAngleG;\n" + " vec3 TransformedB = EyeRotation * TanEyeAngleB;\n" +#endif + + // Project them back onto the Z=1 plane of the rendered images. + " float RecipZR = 1.0 / TransformedR.z;\n" + " float RecipZG = 1.0 / TransformedG.z;\n" + " float RecipZB = 1.0 / TransformedB.z;\n" + " vec2 FlattenedR = vec2 ( TransformedR.x * RecipZR, TransformedR.y * RecipZR );\n" + " vec2 FlattenedG = vec2 ( TransformedG.x * RecipZG, TransformedG.y * RecipZG );\n" + " vec2 FlattenedB = vec2 ( TransformedB.x * RecipZB, TransformedB.y * RecipZB );\n" + + // These are now still in TanEyeAngle space. + // Scale them into the correct [0-1],[0-1] UV lookup space (depending on eye) + " vec2 SrcCoordR = FlattenedR * EyeToSourceUVScale + EyeToSourceUVOffset;\n" + " vec2 SrcCoordG = FlattenedG * EyeToSourceUVScale + EyeToSourceUVOffset;\n" + " vec2 SrcCoordB = FlattenedB * EyeToSourceUVScale + EyeToSourceUVOffset;\n" + + " oTexCoord0 = SrcCoordR;\n" + " oTexCoord0.y = 1.0-oTexCoord0.y;\n" + " oTexCoord1 = SrcCoordG;\n" + " oTexCoord1.y = 1.0-oTexCoord1.y;\n" + " oTexCoord2 = SrcCoordB;\n" + " oTexCoord2.y = 1.0-oTexCoord2.y;\n" + + " oColor = vec4(Color.r, Color.r, Color.r, Color.r);\n" // Used for vignette fade. + "}\n"; + + + const OVR::CAPI::GL::ShaderBase::Uniform DistortionTimewarpChroma_vs_refl[] = + { + { "EyeToSourceUVScale", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 0, 8 }, + { "EyeToSourceUVOffset", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 8, 8 }, + { "EyeRotationStart", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 16, 64 }, + { "EyeRotationEnd", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 80, 64 }, + }; + +}}} // OVR::CAPI::GL + +#endif // OVR_CAPI_GL_Shaders_h diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_Util.cpp b/LibOVR/Src/CAPI/GL/CAPI_GL_Util.cpp index b82939a..910e28c 100644 --- a/LibOVR/Src/CAPI/GL/CAPI_GL_Util.cpp +++ b/LibOVR/Src/CAPI/GL/CAPI_GL_Util.cpp @@ -23,16 +23,25 @@ limitations under the License. #include "CAPI_GL_Util.h" #include "../../Kernel/OVR_Log.h" +#include <string.h> namespace OVR { namespace CAPI { namespace GL { -// GL Hooks for PC. +// GL Hooks for non-Mac. +#if !defined(OVR_OS_MAC) + #if defined(OVR_OS_WIN32) PFNWGLGETPROCADDRESS wglGetProcAddress; +PFNGLENABLEPROC glEnable; +PFNGLDISABLEPROC glDisable; +PFNGLGETFLOATVPROC glGetFloatv; +PFNGLGETINTEGERVPROC glGetIntegerv; +PFNGLGETSTRINGPROC glGetString; +PFNGLCOLORMASKPROC glColorMask; PFNGLCLEARPROC glClear; PFNGLCLEARCOLORPROC glClearColor; PFNGLCLEARDEPTHPROC glClearDepth; @@ -48,12 +57,15 @@ PFNGLBINDTEXTUREPROC glBindTexture; PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT; PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT; -PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT; + +#elif defined(OVR_OS_LINUX) + +PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT; + +#endif + PFNGLDELETESHADERPROC glDeleteShader; -PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT; -PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT; -PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT; -PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT; +PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer; PFNGLACTIVETEXTUREPROC glActiveTexture; PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray; PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; @@ -88,92 +100,108 @@ PFNGLUNIFORM4FVPROC glUniform4fv; PFNGLUNIFORM3FVPROC glUniform3fv; PFNGLUNIFORM2FVPROC glUniform2fv; PFNGLUNIFORM1FVPROC glUniform1fv; -PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D; -PFNGLRENDERBUFFERSTORAGEEXTPROC glRenderbufferStorageEXT; -PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT; -PFNGLGENRENDERBUFFERSEXTPROC glGenRenderbuffersEXT; -PFNGLDELETERENDERBUFFERSEXTPROC glDeleteRenderbuffersEXT; - PFNGLGENVERTEXARRAYSPROC glGenVertexArrays; +PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays; +PFNGLBINDVERTEXARRAYPROC glBindVertexArray; + + +#if defined(OVR_OS_WIN32) + +void* GetFunction(const char* functionName) +{ + return wglGetProcAddress(functionName); +} + +#else + +void (*GetFunction(const char *functionName))( void ) +{ + return glXGetProcAddress((GLubyte*)functionName); +} + +#endif void InitGLExtensions() { - HINSTANCE hInst = LoadLibrary( L"Opengl32.dll" ); + if (glGenVertexArrays) + return; + +#if defined(OVR_OS_WIN32) + HINSTANCE hInst = LoadLibrary(L"Opengl32.dll"); if (!hInst) return; - glClear = (PFNGLCLEARPROC)GetProcAddress( hInst, "glClear" ); - glClearColor = (PFNGLCLEARCOLORPROC)GetProcAddress( hInst, "glClearColor" ); - glClearDepth = (PFNGLCLEARDEPTHPROC)GetProcAddress( hInst, "glClearDepth" ); - glViewport = (PFNGLVIEWPORTPROC)GetProcAddress( hInst, "glViewport" ); - glDrawElements = (PFNGLDRAWELEMENTSPROC)GetProcAddress( hInst, "glDrawElements" ); - glTexParameteri = (PFNGLTEXPARAMETERIPROC)GetProcAddress( hInst, "glTexParameteri" ); - glFlush = (PFNGLFLUSHPROC)GetProcAddress( hInst, "glFlush" ); - glFinish = (PFNGLFINISHPROC)GetProcAddress( hInst, "glFinish" ); - glDrawArrays = (PFNGLDRAWARRAYSPROC)GetProcAddress( hInst, "glDrawArrays" ); - glGenTextures = (PFNGLGENTEXTURESPROC)GetProcAddress( hInst,"glGenTextures" ); - glDeleteTextures = (PFNGLDELETETEXTURESPROC)GetProcAddress( hInst,"glDeleteTextures" ); - glBindTexture = (PFNGLBINDTEXTUREPROC)GetProcAddress( hInst,"glBindTexture" ); - - wglGetProcAddress = (PFNWGLGETPROCADDRESS)GetProcAddress( hInst, "wglGetProcAddress" ); - - if (glGenFramebuffersEXT) - return; - - wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC) wglGetProcAddress("wglGetSwapIntervalEXT"); - wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC) wglGetProcAddress("wglSwapIntervalEXT"); - glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC) wglGetProcAddress("glGenFramebuffersEXT"); - glDeleteShader = (PFNGLDELETESHADERPROC) wglGetProcAddress("glDeleteShader"); - glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) wglGetProcAddress("glCheckFramebufferStatusEXT"); - glFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) wglGetProcAddress("glFramebufferRenderbufferEXT"); - glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) wglGetProcAddress("glFramebufferTexture2DEXT"); - glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC) wglGetProcAddress("glBindFramebufferEXT"); - glActiveTexture = (PFNGLACTIVETEXTUREPROC) wglGetProcAddress("glActiveTexture"); - glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) wglGetProcAddress("glDisableVertexAttribArray"); - glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) wglGetProcAddress("glVertexAttribPointer"); - glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) wglGetProcAddress("glEnableVertexAttribArray"); - glBindBuffer = (PFNGLBINDBUFFERPROC) wglGetProcAddress("glBindBuffer"); - glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC) wglGetProcAddress("glUniformMatrix3fv"); - glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) wglGetProcAddress("glUniformMatrix4fv"); - glDeleteBuffers = (PFNGLDELETEBUFFERSPROC) wglGetProcAddress("glDeleteBuffers"); - glBufferData = (PFNGLBUFFERDATAPROC) wglGetProcAddress("glBufferData"); - glGenBuffers = (PFNGLGENBUFFERSPROC) wglGetProcAddress("glGenBuffers"); - glMapBuffer = (PFNGLMAPBUFFERPROC) wglGetProcAddress("glMapBuffer"); - glUnmapBuffer = (PFNGLUNMAPBUFFERPROC) wglGetProcAddress("glUnmapBuffer"); - glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) wglGetProcAddress("glGetShaderInfoLog"); - glGetShaderiv = (PFNGLGETSHADERIVPROC) wglGetProcAddress("glGetShaderiv"); - glCompileShader = (PFNGLCOMPILESHADERPROC) wglGetProcAddress("glCompileShader"); - glShaderSource = (PFNGLSHADERSOURCEPROC) wglGetProcAddress("glShaderSource"); - glCreateShader = (PFNGLCREATESHADERPROC) wglGetProcAddress("glCreateShader"); - glCreateProgram = (PFNGLCREATEPROGRAMPROC) wglGetProcAddress("glCreateProgram"); - glAttachShader = (PFNGLATTACHSHADERPROC) wglGetProcAddress("glAttachShader"); - glDetachShader = (PFNGLDETACHSHADERPROC) wglGetProcAddress("glDetachShader"); - glDeleteProgram = (PFNGLDELETEPROGRAMPROC) wglGetProcAddress("glDeleteProgram"); - glUniform1i = (PFNGLUNIFORM1IPROC) wglGetProcAddress("glUniform1i"); - glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) wglGetProcAddress("glGetUniformLocation"); - glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC) wglGetProcAddress("glGetActiveUniform"); - glUseProgram = (PFNGLUSEPROGRAMPROC) wglGetProcAddress("glUseProgram"); - glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) wglGetProcAddress("glGetProgramInfoLog"); - glGetProgramiv = (PFNGLGETPROGRAMIVPROC) wglGetProcAddress("glGetProgramiv"); - glLinkProgram = (PFNGLLINKPROGRAMPROC) wglGetProcAddress("glLinkProgram"); - glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC) wglGetProcAddress("glBindAttribLocation"); - glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC) wglGetProcAddress("glGetAttribLocation"); - glUniform4fv = (PFNGLUNIFORM4FVPROC) wglGetProcAddress("glUniform4fv"); - glUniform3fv = (PFNGLUNIFORM3FVPROC) wglGetProcAddress("glUniform3fv"); - glUniform2fv = (PFNGLUNIFORM2FVPROC) wglGetProcAddress("glUniform2fv"); - glUniform1fv = (PFNGLUNIFORM1FVPROC) wglGetProcAddress("glUniform1fv"); - glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC) wglGetProcAddress("glCompressedTexImage2D"); - glRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC) wglGetProcAddress("glRenderbufferStorageEXT"); - glBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC) wglGetProcAddress("glBindRenderbufferEXT"); - glGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC) wglGetProcAddress("glGenRenderbuffersEXT"); - glDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC) wglGetProcAddress("glDeleteRenderbuffersEXT"); - - - glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC) wglGetProcAddress("glGenVertexArrays"); -} - + glGetFloatv = (PFNGLGETFLOATVPROC) GetProcAddress(hInst, "glGetFloatv"); + glGetIntegerv = (PFNGLGETINTEGERVPROC) GetProcAddress(hInst, "glGetIntegerv"); + glGetString = (PFNGLGETSTRINGPROC) GetProcAddress(hInst, "glGetString"); + glEnable = (PFNGLENABLEPROC) GetProcAddress(hInst, "glEnable"); + glDisable = (PFNGLDISABLEPROC) GetProcAddress(hInst, "glDisable"); + glColorMask = (PFNGLCOLORMASKPROC) GetProcAddress(hInst, "glColorMask"); + glClear = (PFNGLCLEARPROC) GetProcAddress(hInst, "glClear" ); + glClearColor = (PFNGLCLEARCOLORPROC) GetProcAddress(hInst, "glClearColor"); + glClearDepth = (PFNGLCLEARDEPTHPROC) GetProcAddress(hInst, "glClearDepth"); + glViewport = (PFNGLVIEWPORTPROC) GetProcAddress(hInst, "glViewport"); + glFlush = (PFNGLFLUSHPROC) GetProcAddress(hInst, "glFlush"); + glFinish = (PFNGLFINISHPROC) GetProcAddress(hInst, "glFinish"); + glDrawArrays = (PFNGLDRAWARRAYSPROC) GetProcAddress(hInst, "glDrawArrays"); + glDrawElements = (PFNGLDRAWELEMENTSPROC) GetProcAddress(hInst, "glDrawElements"); + glGenTextures = (PFNGLGENTEXTURESPROC) GetProcAddress(hInst,"glGenTextures"); + glDeleteTextures = (PFNGLDELETETEXTURESPROC) GetProcAddress(hInst,"glDeleteTextures"); + glBindTexture = (PFNGLBINDTEXTUREPROC) GetProcAddress(hInst,"glBindTexture"); + glTexParameteri = (PFNGLTEXPARAMETERIPROC) GetProcAddress(hInst, "glTexParameteri"); + + wglGetProcAddress = (PFNWGLGETPROCADDRESS) GetProcAddress(hInst, "wglGetProcAddress"); + + wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC) GetFunction("wglGetSwapIntervalEXT"); + wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC) GetFunction("wglSwapIntervalEXT"); +#elif defined(OVR_OS_LINUX) + glXSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC) GetFunction("glXSwapIntervalEXT"); #endif + glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) GetFunction("glBindFramebufferEXT"); + glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC) GetFunction("glGenVertexArrays"); + glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC) GetFunction("glDeleteVertexArrays"); + glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC) GetFunction("glBindVertexArray"); + glGenBuffers = (PFNGLGENBUFFERSPROC) GetFunction("glGenBuffers"); + glDeleteBuffers = (PFNGLDELETEBUFFERSPROC) GetFunction("glDeleteBuffers"); + glBindBuffer = (PFNGLBINDBUFFERPROC) GetFunction("glBindBuffer"); + glBufferData = (PFNGLBUFFERDATAPROC) GetFunction("glBufferData"); + glMapBuffer = (PFNGLMAPBUFFERPROC) GetFunction("glMapBuffer"); + glUnmapBuffer = (PFNGLUNMAPBUFFERPROC) GetFunction("glUnmapBuffer"); + glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) GetFunction("glDisableVertexAttribArray"); + glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) GetFunction("glVertexAttribPointer"); + glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) GetFunction("glEnableVertexAttribArray"); + glActiveTexture = (PFNGLACTIVETEXTUREPROC) GetFunction("glActiveTexture"); + glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC) GetFunction("glUniformMatrix3fv"); + glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) GetFunction("glUniformMatrix4fv"); + glUniform1i = (PFNGLUNIFORM1IPROC) GetFunction("glUniform1i"); + glUniform1fv = (PFNGLUNIFORM1FVPROC) GetFunction("glUniform1fv"); + glUniform2fv = (PFNGLUNIFORM2FVPROC) GetFunction("glUniform2fv"); + glUniform3fv = (PFNGLUNIFORM3FVPROC) GetFunction("glUniform3fv"); + glUniform2fv = (PFNGLUNIFORM2FVPROC) GetFunction("glUniform2fv"); + glUniform4fv = (PFNGLUNIFORM4FVPROC) GetFunction("glUniform4fv"); + glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) GetFunction("glGetUniformLocation"); + glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC) GetFunction("glGetActiveUniform"); + glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) GetFunction("glGetShaderInfoLog"); + glGetShaderiv = (PFNGLGETSHADERIVPROC) GetFunction("glGetShaderiv"); + glCompileShader = (PFNGLCOMPILESHADERPROC) GetFunction("glCompileShader"); + glShaderSource = (PFNGLSHADERSOURCEPROC) GetFunction("glShaderSource"); + glCreateShader = (PFNGLCREATESHADERPROC) GetFunction("glCreateShader"); + glDeleteShader = (PFNGLDELETESHADERPROC) GetFunction("glDeleteShader"); + glCreateProgram = (PFNGLCREATEPROGRAMPROC) GetFunction("glCreateProgram"); + glDeleteProgram = (PFNGLDELETEPROGRAMPROC) GetFunction("glDeleteProgram"); + glUseProgram = (PFNGLUSEPROGRAMPROC) GetFunction("glUseProgram"); + glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) GetFunction("glGetProgramInfoLog"); + glGetProgramiv = (PFNGLGETPROGRAMIVPROC) GetFunction("glGetProgramiv"); + glLinkProgram = (PFNGLLINKPROGRAMPROC) GetFunction("glLinkProgram"); + glAttachShader = (PFNGLATTACHSHADERPROC) GetFunction("glAttachShader"); + glDetachShader = (PFNGLDETACHSHADERPROC) GetFunction("glDetachShader"); + glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC) GetFunction("glBindAttribLocation"); + glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC) GetFunction("glGetAttribLocation"); +} + +#endif + Buffer::Buffer(RenderParams* rp) : pParams(rp), Size(0), Use(0), GLBuffer(0) { } @@ -203,7 +231,6 @@ bool Buffer::Data(int use, const void* buffer, size_t size) glBindBuffer(Use, GLBuffer); glBufferData(Use, size, buffer, mode); - glBindBuffer(Use, 0); return 1; } @@ -215,7 +242,6 @@ void* Buffer::Map(size_t, size_t, int) glBindBuffer(Use, GLBuffer); void* v = glMapBuffer(Use, mode); - glBindBuffer(Use, 0); return v; } @@ -223,7 +249,6 @@ bool Buffer::Unmap(void*) { glBindBuffer(Use, GLBuffer); int r = glUnmapBuffer(Use); - glBindBuffer(Use, 0); return r != 0; } @@ -248,6 +273,7 @@ GLint ShaderSet::GetGLShader(Shader* s) ShaderImpl<Shader_Fragment, GL_FRAGMENT_SHADER>* gls = (ShaderImpl<Shader_Fragment, GL_FRAGMENT_SHADER>*)s; return gls->GLShader; } break; + default: break; } return -1; @@ -271,8 +297,6 @@ void ShaderSet::UnsetShader(int stage) glDetachShader(Prog, GLShader); Shaders[stage] = NULL; - - //Link(); } bool ShaderSet::SetUniform(const char* name, int n, const float* v) @@ -430,14 +454,6 @@ void ShaderBase::InitUniforms(const Uniform* refl, size_t reflSize) UniformData = (unsigned char*)OVR_ALLOC(UniformsSize); } -void ShaderBase::UpdateBuffer(Buffer* buf) -{ - if (UniformsSize) - { - buf->Data(Buffer_Uniform, UniformData, UniformsSize); - } -} - Texture::Texture(RenderParams* rp, int w, int h) : IsUserAllocated(true), pParams(rp), TexId(0), Width(w), Height(h) { if (w && h) @@ -454,7 +470,6 @@ void Texture::Set(int slot, ShaderStage) const { glActiveTexture(GL_TEXTURE0 + slot); glBindTexture(GL_TEXTURE_2D, TexId); - glActiveTexture(GL_TEXTURE0); } void Texture::SetSampleMode(int sm) @@ -498,7 +513,6 @@ void Texture::SetSampleMode(int sm) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); break; } - glBindTexture(GL_TEXTURE_2D, 0); } void Texture::UpdatePlaceholderTexture(GLuint texId, const Sizei& textureSize) diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_Util.h b/LibOVR/Src/CAPI/GL/CAPI_GL_Util.h index 5e694cc..a410f17 100644 --- a/LibOVR/Src/CAPI/GL/CAPI_GL_Util.h +++ b/LibOVR/Src/CAPI/GL/CAPI_GL_Util.h @@ -30,14 +30,15 @@ limitations under the License. #include "../../Kernel/OVR_RefCount.h" #include "../../Kernel/OVR_String.h" #include "../../Kernel/OVR_Types.h" +#include "../../Kernel/OVR_Log.h" #if defined(OVR_OS_WIN32) #include <Windows.h> #endif #if defined(OVR_OS_MAC) -#include <OpenGL/gl.h> -#include <OpenGL/glext.h> +#include <OpenGL/gl3.h> +#include <OpenGL/gl3ext.h> #else #ifndef GL_GLEXT_PROTOTYPES #define GL_GLEXT_PROTOTYPES @@ -46,19 +47,30 @@ limitations under the License. #include <GL/glext.h> #if defined(OVR_OS_WIN32) #include <GL/wglext.h> +#elif defined(OVR_OS_LINUX) +#include <GL/glx.h> #endif #endif namespace OVR { namespace CAPI { namespace GL { -// GL extension Hooks for PC. +// GL extension Hooks for Non-Mac. +#if !defined(OVR_OS_MAC) + +// Let Windows apps build without linking GL. #if defined(OVR_OS_WIN32) +typedef void (__stdcall *PFNGLENABLEPROC) (GLenum); +typedef void (__stdcall *PFNGLDISABLEPROC) (GLenum); +typedef void (__stdcall *PFNGLGETFLOATVPROC) (GLenum, GLfloat*); +typedef const GLubyte * (__stdcall *PFNGLGETSTRINGPROC) (GLenum); +typedef void (__stdcall *PFNGLGETINTEGERVPROC) (GLenum, GLint*); typedef PROC (__stdcall *PFNWGLGETPROCADDRESS) (LPCSTR); typedef void (__stdcall *PFNGLFLUSHPROC) (); typedef void (__stdcall *PFNGLFINISHPROC) (); typedef void (__stdcall *PFNGLDRAWARRAYSPROC) (GLenum mode, GLint first, GLsizei count); typedef void (__stdcall *PFNGLCLEARPROC) (GLbitfield); +typedef void (__stdcall *PFNGLCOLORMASKPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); typedef void (__stdcall *PFNGLDRAWELEMENTSPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices); typedef void (__stdcall *PFNGLGENTEXTURESPROC) (GLsizei n, GLuint *textures); typedef void (__stdcall *PFNGLDELETETEXTURESPROC) (GLsizei n, GLuint *textures); @@ -69,6 +81,15 @@ typedef void (__stdcall *PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, G typedef void (__stdcall *PFNGLVIEWPORTPROC) (GLint x, GLint y, GLsizei width, GLsizei height); extern PFNWGLGETPROCADDRESS wglGetProcAddress; +extern PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT; +extern PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT; + +extern PFNGLENABLEPROC glEnable; +extern PFNGLDISABLEPROC glDisable; +extern PFNGLCOLORMASKPROC glColorMask; +extern PFNGLGETFLOATVPROC glGetFloatv; +extern PFNGLGETSTRINGPROC glGetString; +extern PFNGLGETINTEGERVPROC glGetIntegerv; extern PFNGLCLEARPROC glClear; extern PFNGLCLEARCOLORPROC glClearColor; extern PFNGLCLEARDEPTHPROC glClearDepth; @@ -82,14 +103,14 @@ extern PFNGLTEXPARAMETERIPROC glTexParameteri; extern PFNGLFLUSHPROC glFlush; extern PFNGLFINISHPROC glFinish; -extern PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT; -extern PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT; -extern PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT; +#elif defined(OVR_OS_LINUX) + +extern PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT; + +#endif // defined(OVR_OS_WIN32) + extern PFNGLDELETESHADERPROC glDeleteShader; -extern PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT; -extern PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT; -extern PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT; -extern PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT; +extern PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer; extern PFNGLACTIVETEXTUREPROC glActiveTexture; extern PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray; extern PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; @@ -123,18 +144,13 @@ extern PFNGLUNIFORM4FVPROC glUniform4fv; extern PFNGLUNIFORM3FVPROC glUniform3fv; extern PFNGLUNIFORM2FVPROC glUniform2fv; extern PFNGLUNIFORM1FVPROC glUniform1fv; -extern PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D; -extern PFNGLRENDERBUFFERSTORAGEEXTPROC glRenderbufferStorageEXT; -extern PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT; -extern PFNGLGENRENDERBUFFERSEXTPROC glGenRenderbuffersEXT; -extern PFNGLDELETERENDERBUFFERSEXTPROC glDeleteRenderbuffersEXT; - -// For testing extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays; +extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays; +extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray; extern void InitGLExtensions(); -#endif +#endif // !defined(OVR_OS_MAC) // Rendering primitive type used to render Model. @@ -205,10 +221,11 @@ enum SampleMode // Rendering parameters/pointers describing GL rendering setup. struct RenderParams { -#ifdef OVR_OS_WIN32 +#if defined(OVR_OS_WIN32) HWND Window; - HGLRC WglContext; - HDC GdiDc; +#elif defined(OVR_OS_LINUX) + Display* Disp; + Window Win; #endif ovrSizei RTSize; @@ -301,7 +318,7 @@ protected: Array<Uniform> UniformInfo; public: - GLuint Prog; + GLuint Prog; GLint ProjLoc, ViewLoc; GLint TexLoc[8]; bool UsesLighting; @@ -455,8 +472,6 @@ public: void InitUniforms(const Uniform* refl, size_t reflSize); bool SetUniform(const char* name, int n, const float* v); bool SetUniformBool(const char* name, int n, const bool* v); - - void UpdateBuffer(Buffer* b); }; @@ -470,7 +485,7 @@ public: : ShaderBase(rp, SStage) , GLShader(0) { - BOOL success; + bool success; OVR_UNUSED(size); success = Compile((const char*) s); OVR_ASSERT(success); diff --git a/LibOVR/Src/CAPI/Shaders/DistortionChroma_ps.h b/LibOVR/Src/CAPI/Shaders/DistortionChroma_ps.h new file mode 100644 index 0000000..20d0f67 --- /dev/null +++ b/LibOVR/Src/CAPI/Shaders/DistortionChroma_ps.h @@ -0,0 +1,84 @@ +#ifndef DISTORTIONCHROMA_PS_H +#define DISTORTIONCHROMA_PS_H + +static const unsigned char DistortionChroma_ps[] = { + 0x44, 0x58, 0x42, 0x43, 0xf8, 0x80, 0xa6, 0xb4, 0xd3, 0xf2, 0xe4, 0x8b, + 0xd1, 0x64, 0x65, 0x3a, 0x55, 0xe3, 0xdf, 0xc9, 0x01, 0x00, 0x00, 0x00, + 0x90, 0x03, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, + 0xdc, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xb4, 0x01, 0x00, 0x00, + 0x14, 0x03, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0xa0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x00, 0x04, 0xff, 0xff, 0x00, 0x01, 0x00, 0x00, + 0x6b, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x63, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, + 0x61, 0x72, 0x00, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x00, 0x4d, + 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, + 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, + 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x36, 0x2e, + 0x33, 0x2e, 0x39, 0x36, 0x30, 0x30, 0x2e, 0x31, 0x36, 0x33, 0x38, 0x34, + 0x00, 0xab, 0xab, 0xab, 0x49, 0x53, 0x47, 0x4e, 0x9c, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0f, 0x07, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x07, 0x03, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x07, 0x03, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x07, 0x03, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, + 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, + 0x52, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0xab, + 0x4f, 0x53, 0x47, 0x4e, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x54, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x00, 0xab, 0xab, 0x53, 0x48, 0x44, 0x52, 0x58, 0x01, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x03, + 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x18, 0x00, 0x04, + 0x00, 0x70, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, + 0x62, 0x10, 0x00, 0x03, 0x72, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x62, 0x10, 0x00, 0x03, 0x32, 0x10, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x62, 0x10, 0x00, 0x03, 0x32, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x62, 0x10, 0x00, 0x03, 0x32, 0x10, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x65, 0x00, 0x00, 0x03, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x0b, + 0xf2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, 0x12, 0x20, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x0b, + 0xf2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, 0x22, 0x20, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x0b, + 0xf2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, 0x42, 0x20, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, + 0x82, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x3f, 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, + 0x74, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +}; + +#endif diff --git a/LibOVR/Src/CAPI/Shaders/DistortionChroma_ps.psh b/LibOVR/Src/CAPI/Shaders/DistortionChroma_ps.psh index 5c95ade..1102524 100644 --- a/LibOVR/Src/CAPI/Shaders/DistortionChroma_ps.psh +++ b/LibOVR/Src/CAPI/Shaders/DistortionChroma_ps.psh @@ -4,9 +4,9 @@ SamplerState Linear : register(s0); float4 main(in float4 oPosition : SV_Position, in float4 oColor : COLOR, in float3 oTexCoord0 : TEXCOORD0, in float3 oTexCoord1 : TEXCOORD1, in float3 oTexCoord2 : TEXCOORD2) : SV_Target { - float ResultR = Texture.Sample(Linear, oTexCoord0.xy).r; - float ResultG = Texture.Sample(Linear, oTexCoord1.xy).g; - float ResultB = Texture.Sample(Linear, oTexCoord2.xy).b; + float ResultR = Texture.SampleLevel(Linear, oTexCoord0.xy, 0.0).r; + float ResultG = Texture.SampleLevel(Linear, oTexCoord1.xy, 0.0).g; + float ResultB = Texture.SampleLevel(Linear, oTexCoord2.xy, 0.0).b; return float4(ResultR * oColor.r, ResultG * oColor.g, ResultB * oColor.b, 1.0); //" return oColor.rrrr; } diff --git a/LibOVR/Src/CAPI/Shaders/DistortionChroma_ps_refl.h b/LibOVR/Src/CAPI/Shaders/DistortionChroma_ps_refl.h new file mode 100644 index 0000000..a306aa5 --- /dev/null +++ b/LibOVR/Src/CAPI/Shaders/DistortionChroma_ps_refl.h @@ -0,0 +1 @@ +// No data available for shader reflection DistortionChroma_ps_refl
\ No newline at end of file diff --git a/LibOVR/Src/CAPI/Shaders/DistortionChroma_vs.h b/LibOVR/Src/CAPI/Shaders/DistortionChroma_vs.h new file mode 100644 index 0000000..5f2aedb --- /dev/null +++ b/LibOVR/Src/CAPI/Shaders/DistortionChroma_vs.h @@ -0,0 +1,106 @@ +#ifndef DISTORTIONCHROMA_VS_H +#define DISTORTIONCHROMA_VS_H + +static const unsigned char DistortionChroma_vs[] = { + 0x44, 0x58, 0x42, 0x43, 0xaf, 0x53, 0xeb, 0x12, 0x64, 0x0d, 0xd1, 0xaa, + 0x9c, 0x9d, 0x13, 0x42, 0x57, 0x7b, 0x4c, 0xb4, 0x01, 0x00, 0x00, 0x00, + 0xa0, 0x04, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, + 0x38, 0x01, 0x00, 0x00, 0xd8, 0x01, 0x00, 0x00, 0x7c, 0x02, 0x00, 0x00, + 0x24, 0x04, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0xfc, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x00, 0x04, 0xfe, 0xff, 0x00, 0x01, 0x00, 0x00, + 0xc8, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x24, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x00, 0xab, 0xab, 0xab, + 0x3c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xb4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x45, 0x79, 0x65, 0x54, 0x6f, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, + 0x56, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x00, 0xab, 0x01, 0x00, 0x03, 0x00, + 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x45, 0x79, 0x65, 0x54, 0x6f, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, + 0x56, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x00, 0x4d, 0x69, 0x63, 0x72, + 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, + 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, + 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x36, 0x2e, 0x33, 0x2e, 0x39, + 0x36, 0x30, 0x30, 0x2e, 0x31, 0x36, 0x33, 0x38, 0x34, 0x00, 0xab, 0xab, + 0x49, 0x53, 0x47, 0x4e, 0x98, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x03, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0f, 0x0f, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x03, 0x03, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x03, 0x03, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x03, 0x03, 0x00, 0x00, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, + 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, + 0x4f, 0x52, 0x44, 0x00, 0x4f, 0x53, 0x47, 0x4e, 0x9c, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, + 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, + 0x52, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0xab, + 0x53, 0x48, 0x44, 0x52, 0xa0, 0x01, 0x00, 0x00, 0x40, 0x00, 0x01, 0x00, + 0x68, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x04, 0x46, 0x8e, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, + 0x32, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, + 0xf2, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, + 0x32, 0x10, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, + 0x32, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, + 0x32, 0x10, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x04, + 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x65, 0x00, 0x00, 0x03, 0xf2, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x65, 0x00, 0x00, 0x03, 0x72, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x65, 0x00, 0x00, 0x03, 0x72, 0x20, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x65, 0x00, 0x00, 0x03, 0x72, 0x20, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x05, 0x32, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x46, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x08, + 0xc2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, + 0x00, 0x00, 0x80, 0x3f, 0x36, 0x00, 0x00, 0x05, 0xf2, 0x20, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x46, 0x1e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x32, 0x00, 0x00, 0x0b, 0x32, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x46, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x46, 0x10, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0xe6, 0x8a, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, + 0x42, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x3f, 0x32, 0x00, 0x00, 0x0b, 0x32, 0x20, 0x10, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x46, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, + 0xe6, 0x8a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x05, 0x42, 0x20, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x32, 0x00, 0x00, 0x0b, + 0x32, 0x20, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x46, 0x80, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, + 0x04, 0x00, 0x00, 0x00, 0xe6, 0x8a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0x42, 0x20, 0x10, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, + 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, 0x74, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +#endif diff --git a/LibOVR/Src/CAPI/Shaders/DistortionChroma_vs_refl.h b/LibOVR/Src/CAPI/Shaders/DistortionChroma_vs_refl.h new file mode 100644 index 0000000..cb9767d --- /dev/null +++ b/LibOVR/Src/CAPI/Shaders/DistortionChroma_vs_refl.h @@ -0,0 +1,9 @@ +#ifndef DistortionChroma_vs_refl + +const OVR::CAPI::D3D_NS::ShaderBase::Uniform DistortionChroma_vs_refl[] = +{ + { "EyeToSourceUVScale", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 0, 8 }, + { "EyeToSourceUVOffset", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 8, 8 }, +}; + +#endif diff --git a/LibOVR/Src/CAPI/Shaders/DistortionTimewarpChroma_vs.h b/LibOVR/Src/CAPI/Shaders/DistortionTimewarpChroma_vs.h new file mode 100644 index 0000000..6660f0c --- /dev/null +++ b/LibOVR/Src/CAPI/Shaders/DistortionTimewarpChroma_vs.h @@ -0,0 +1,219 @@ +#ifndef DISTORTIONTIMEWARPCHROMA_VS_H +#define DISTORTIONTIMEWARPCHROMA_VS_H + +static const unsigned char DistortionTimewarpChroma_vs[] = { + 0x44, 0x58, 0x42, 0x43, 0x03, 0x43, 0xb6, 0xcd, 0xb7, 0xe5, 0xeb, 0x34, + 0x11, 0x77, 0xf9, 0xfc, 0x49, 0xa0, 0x5a, 0x69, 0x01, 0x00, 0x00, 0x00, + 0xec, 0x09, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, + 0x9c, 0x01, 0x00, 0x00, 0x3c, 0x02, 0x00, 0x00, 0xe0, 0x02, 0x00, 0x00, + 0x70, 0x09, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0x60, 0x01, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x00, 0x04, 0xfe, 0xff, 0x00, 0x01, 0x00, 0x00, + 0x2b, 0x01, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x24, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x00, 0xab, 0xab, 0xab, + 0x3c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, + 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf8, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1c, 0x01, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x45, 0x79, 0x65, 0x54, 0x6f, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, + 0x56, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x00, 0xab, 0x01, 0x00, 0x03, 0x00, + 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x45, 0x79, 0x65, 0x54, 0x6f, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, + 0x56, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x00, 0x45, 0x79, 0x65, 0x52, + 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, + 0x00, 0xab, 0xab, 0xab, 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x79, 0x65, 0x52, + 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x64, 0x00, 0x4d, + 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, + 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, + 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x36, 0x2e, + 0x33, 0x2e, 0x39, 0x36, 0x30, 0x30, 0x2e, 0x31, 0x36, 0x33, 0x38, 0x34, + 0x00, 0xab, 0xab, 0xab, 0x49, 0x53, 0x47, 0x4e, 0x98, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0f, 0x09, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x50, 0x4f, 0x53, 0x49, + 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x54, + 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x4f, 0x53, 0x47, 0x4e, + 0x9c, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, + 0x92, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, + 0x92, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, + 0x53, 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, + 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, + 0x52, 0x44, 0x00, 0xab, 0x53, 0x48, 0x44, 0x52, 0x88, 0x06, 0x00, 0x00, + 0x40, 0x00, 0x01, 0x00, 0xa2, 0x01, 0x00, 0x00, 0x59, 0x00, 0x00, 0x04, + 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x5f, 0x00, 0x00, 0x03, 0x32, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5f, 0x00, 0x00, 0x03, 0x92, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x5f, 0x00, 0x00, 0x03, 0x32, 0x10, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x5f, 0x00, 0x00, 0x03, 0x32, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x5f, 0x00, 0x00, 0x03, 0x32, 0x10, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x67, 0x00, 0x00, 0x04, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0xf2, 0x20, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0x72, 0x20, 0x10, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0x72, 0x20, 0x10, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0x72, 0x20, 0x10, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x05, 0x32, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x46, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x08, + 0xc2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, + 0x00, 0x00, 0x80, 0x3f, 0x36, 0x00, 0x00, 0x05, 0xf2, 0x20, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x06, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x05, 0x42, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x36, 0x00, 0x00, 0x06, + 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, + 0x12, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x80, + 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, + 0x22, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, + 0x22, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x10, 0x80, + 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, + 0x42, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, + 0x42, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x80, + 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, + 0x82, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, + 0x82, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x10, 0x80, + 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x09, + 0xf2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x1f, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, + 0x32, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x08, 0xc2, 0x00, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, + 0x11, 0x00, 0x00, 0x07, 0x42, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x32, 0x00, 0x10, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x46, 0x80, 0x20, 0x80, 0x41, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x80, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, + 0x12, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3a, 0x10, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x1a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x32, 0x00, 0x00, 0x0a, 0x12, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x0a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x32, 0x00, 0x10, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x16, 0x85, 0x20, 0x80, 0x41, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x16, 0x85, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, + 0x22, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3a, 0x10, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x1a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x32, 0x00, 0x00, 0x0a, 0x22, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x10, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x0a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x52, 0x00, 0x10, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x56, 0x84, 0x20, 0x80, 0x41, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x56, 0x84, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, + 0x42, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3a, 0x10, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x1a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x32, 0x00, 0x00, 0x0a, 0x42, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x0a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x92, 0x00, 0x10, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x56, 0x81, 0x20, 0x80, 0x41, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x56, 0x81, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, + 0x82, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3a, 0x10, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x1a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x32, 0x00, 0x00, 0x0a, 0x82, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x10, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x0a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x07, 0x12, 0x00, 0x10, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x46, 0x0f, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x07, + 0x22, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x46, 0x0f, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x07, 0x32, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x46, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0xa6, 0x0a, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0b, 0x32, 0x20, 0x10, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x46, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe6, 0x8a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x05, 0x32, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x46, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x08, + 0xc2, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, + 0x00, 0x00, 0x80, 0x3f, 0x11, 0x00, 0x00, 0x07, 0x12, 0x00, 0x10, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x46, 0x0f, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x07, + 0x22, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x46, 0x0f, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x07, 0x12, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x07, 0x32, 0x00, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0b, + 0x32, 0x20, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x46, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe6, 0x8a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0x42, 0x20, 0x10, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, + 0x36, 0x00, 0x00, 0x05, 0x32, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x46, 0x10, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x08, + 0xc2, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, + 0x00, 0x00, 0x80, 0x3f, 0x11, 0x00, 0x00, 0x07, 0x12, 0x00, 0x10, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x46, 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x07, + 0x22, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x07, 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x07, 0x32, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0b, + 0x32, 0x20, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x46, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe6, 0x8a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0x42, 0x20, 0x10, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, + 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, 0x74, 0x00, 0x00, 0x00, + 0x31, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +#endif diff --git a/LibOVR/Src/CAPI/Shaders/DistortionTimewarpChroma_vs_refl.h b/LibOVR/Src/CAPI/Shaders/DistortionTimewarpChroma_vs_refl.h new file mode 100644 index 0000000..ef6847a --- /dev/null +++ b/LibOVR/Src/CAPI/Shaders/DistortionTimewarpChroma_vs_refl.h @@ -0,0 +1,11 @@ +#ifndef DistortionTimewarpChroma_vs_refl + +const OVR::CAPI::D3D_NS::ShaderBase::Uniform DistortionTimewarpChroma_vs_refl[] = +{ + { "EyeToSourceUVScale", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 0, 8 }, + { "EyeToSourceUVOffset", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 8, 8 }, + { "EyeRotationStart", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 16, 64 }, + { "EyeRotationEnd", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 80, 64 }, +}; + +#endif diff --git a/LibOVR/Src/CAPI/Shaders/DistortionTimewarp_vs.h b/LibOVR/Src/CAPI/Shaders/DistortionTimewarp_vs.h new file mode 100644 index 0000000..13b5a11 --- /dev/null +++ b/LibOVR/Src/CAPI/Shaders/DistortionTimewarp_vs.h @@ -0,0 +1,169 @@ +#ifndef DISTORTIONTIMEWARP_VS_H +#define DISTORTIONTIMEWARP_VS_H + +static const unsigned char DistortionTimewarp_vs[] = { + 0x44, 0x58, 0x42, 0x43, 0xef, 0x5d, 0x05, 0x24, 0x51, 0x13, 0x68, 0xcf, + 0x6d, 0x7a, 0xa5, 0x09, 0x84, 0xf9, 0x6c, 0xfc, 0x01, 0x00, 0x00, 0x00, + 0x94, 0x07, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, + 0x9c, 0x01, 0x00, 0x00, 0x0c, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, + 0x18, 0x07, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0x60, 0x01, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x00, 0x04, 0xfe, 0xff, 0x00, 0x01, 0x00, 0x00, + 0x2b, 0x01, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x24, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x00, 0xab, 0xab, 0xab, + 0x3c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, + 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf8, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1c, 0x01, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x45, 0x79, 0x65, 0x54, 0x6f, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, + 0x56, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x00, 0xab, 0x01, 0x00, 0x03, 0x00, + 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x45, 0x79, 0x65, 0x54, 0x6f, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, + 0x56, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x00, 0x45, 0x79, 0x65, 0x52, + 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, + 0x00, 0xab, 0xab, 0xab, 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x79, 0x65, 0x52, + 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x64, 0x00, 0x4d, + 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, + 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, + 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x36, 0x2e, + 0x33, 0x2e, 0x39, 0x36, 0x30, 0x30, 0x2e, 0x31, 0x36, 0x33, 0x38, 0x34, + 0x00, 0xab, 0xab, 0xab, 0x49, 0x53, 0x47, 0x4e, 0x68, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0f, 0x09, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x50, 0x4f, 0x53, 0x49, + 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x54, + 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x4f, 0x53, 0x47, 0x4e, + 0x6c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, + 0x53, 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, + 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, + 0x52, 0x44, 0x00, 0xab, 0x53, 0x48, 0x44, 0x52, 0x90, 0x04, 0x00, 0x00, + 0x40, 0x00, 0x01, 0x00, 0x24, 0x01, 0x00, 0x00, 0x59, 0x00, 0x00, 0x04, + 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x5f, 0x00, 0x00, 0x03, 0x32, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5f, 0x00, 0x00, 0x03, 0x92, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x5f, 0x00, 0x00, 0x03, 0x32, 0x10, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x67, 0x00, 0x00, 0x04, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0xf2, 0x20, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0x72, 0x20, 0x10, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x05, 0x32, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x46, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x08, + 0xc2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, + 0x00, 0x00, 0x80, 0x3f, 0x36, 0x00, 0x00, 0x05, 0xf2, 0x20, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x06, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x06, 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x09, 0x12, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x10, 0x80, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x06, 0x22, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x09, 0x22, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x1a, 0x00, 0x10, 0x80, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x06, 0x42, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x09, 0x42, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x2a, 0x00, 0x10, 0x80, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x06, 0x82, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x09, 0x82, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x3a, 0x00, 0x10, 0x80, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x32, 0x00, 0x00, 0x09, 0xf2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf6, 0x1f, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x05, 0x32, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x46, 0x10, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x08, + 0xc2, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, + 0x00, 0x00, 0x80, 0x3f, 0x11, 0x00, 0x00, 0x07, 0x12, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x46, 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, + 0x62, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x81, 0x20, 0x80, + 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x06, 0x81, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x32, 0x00, 0x00, 0x0a, 0x12, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0x12, 0x00, 0x10, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x1a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x80, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, + 0x62, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x84, 0x20, 0x80, + 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x56, 0x84, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x32, 0x00, 0x00, 0x0a, 0x22, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0x22, 0x00, 0x10, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x2a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x80, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, + 0x52, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x56, 0x84, 0x20, 0x80, + 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x56, 0x84, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x32, 0x00, 0x00, 0x0a, 0x42, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x1a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0x42, 0x00, 0x10, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x2a, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0a, 0x80, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, + 0x92, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x56, 0x81, 0x20, 0x80, + 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x56, 0x81, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x32, 0x00, 0x00, 0x0a, 0x82, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x1a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x07, 0x22, 0x00, 0x10, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x46, 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, + 0x82, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3a, 0x10, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x0a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x07, 0x12, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x46, 0x0e, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x07, 0x32, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0b, + 0x32, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x46, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe6, 0x8a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0x42, 0x20, 0x10, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, + 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, 0x74, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +#endif diff --git a/LibOVR/Src/CAPI/Shaders/DistortionTimewarp_vs_refl.h b/LibOVR/Src/CAPI/Shaders/DistortionTimewarp_vs_refl.h new file mode 100644 index 0000000..dd1569f --- /dev/null +++ b/LibOVR/Src/CAPI/Shaders/DistortionTimewarp_vs_refl.h @@ -0,0 +1,11 @@ +#ifndef DistortionTimewarp_vs_refl + +const OVR::CAPI::D3D_NS::ShaderBase::Uniform DistortionTimewarp_vs_refl[] = +{ + { "EyeToSourceUVScale", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 0, 8 }, + { "EyeToSourceUVOffset", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 8, 8 }, + { "EyeRotationStart", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 16, 64 }, + { "EyeRotationEnd", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 80, 64 }, +}; + +#endif diff --git a/LibOVR/Src/CAPI/Shaders/Distortion_ps.h b/LibOVR/Src/CAPI/Shaders/Distortion_ps.h new file mode 100644 index 0000000..2aa92f5 --- /dev/null +++ b/LibOVR/Src/CAPI/Shaders/Distortion_ps.h @@ -0,0 +1,66 @@ +#ifndef DISTORTION_PS_H +#define DISTORTION_PS_H + +static const unsigned char Distortion_ps[] = { + 0x44, 0x58, 0x42, 0x43, 0xc9, 0x40, 0x1a, 0xf6, 0x24, 0x65, 0x62, 0xf5, + 0x0a, 0x75, 0x65, 0xc3, 0x5e, 0x8d, 0xb8, 0x56, 0x01, 0x00, 0x00, 0x00, + 0xb8, 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, + 0xdc, 0x00, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00, 0x84, 0x01, 0x00, 0x00, + 0x3c, 0x02, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0xa0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x00, 0x04, 0xff, 0xff, 0x00, 0x01, 0x00, 0x00, + 0x6b, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x63, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, + 0x61, 0x72, 0x00, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x00, 0x4d, + 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, + 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, + 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x36, 0x2e, + 0x33, 0x2e, 0x39, 0x36, 0x30, 0x30, 0x2e, 0x31, 0x36, 0x33, 0x38, 0x34, + 0x00, 0xab, 0xab, 0xab, 0x49, 0x53, 0x47, 0x4e, 0x6c, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0f, 0x07, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x07, 0x03, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, + 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, + 0x52, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0xab, + 0x4f, 0x53, 0x47, 0x4e, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x54, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x00, 0xab, 0xab, 0x53, 0x48, 0x44, 0x52, 0xb0, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x03, + 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x18, 0x00, 0x04, + 0x00, 0x70, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, + 0x62, 0x10, 0x00, 0x03, 0x72, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x62, 0x10, 0x00, 0x03, 0x32, 0x10, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x65, 0x00, 0x00, 0x03, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x0b, + 0xf2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, 0x72, 0x20, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x46, 0x12, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, + 0x82, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x3f, 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, + 0x74, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +}; + +#endif diff --git a/LibOVR/Src/CAPI/Shaders/Distortion_ps.psh b/LibOVR/Src/CAPI/Shaders/Distortion_ps.psh index 4a33de5..36a7dc7 100644 --- a/LibOVR/Src/CAPI/Shaders/Distortion_ps.psh +++ b/LibOVR/Src/CAPI/Shaders/Distortion_ps.psh @@ -4,6 +4,6 @@ SamplerState Linear : register(s0); float4 main(in float4 oPosition : SV_Position, in float4 oColor : COLOR, in float3 oTexCoord0 : TEXCOORD0) : SV_Target { - float3 Result = Texture.Sample(Linear, oTexCoord0.xy).rgb; + float3 Result = Texture.SampleLevel(Linear, oTexCoord0.xy, 0.0).rgb; return float4(Result.r * oColor.r, Result.g * oColor.g, Result.b * oColor.b, 1.0); } diff --git a/LibOVR/Src/CAPI/Shaders/Distortion_ps_refl.h b/LibOVR/Src/CAPI/Shaders/Distortion_ps_refl.h new file mode 100644 index 0000000..8a613f5 --- /dev/null +++ b/LibOVR/Src/CAPI/Shaders/Distortion_ps_refl.h @@ -0,0 +1 @@ +// No data available for shader reflection Distortion_ps_refl
\ No newline at end of file diff --git a/LibOVR/Src/CAPI/Shaders/Distortion_vs.h b/LibOVR/Src/CAPI/Shaders/Distortion_vs.h new file mode 100644 index 0000000..91e2046 --- /dev/null +++ b/LibOVR/Src/CAPI/Shaders/Distortion_vs.h @@ -0,0 +1,84 @@ +#ifndef DISTORTION_VS_H +#define DISTORTION_VS_H + +static const unsigned char Distortion_vs[] = { + 0x44, 0x58, 0x42, 0x43, 0x69, 0x55, 0x09, 0xe1, 0x88, 0x43, 0xa7, 0xcb, + 0xe6, 0xdf, 0x06, 0x37, 0x5b, 0xc1, 0x8c, 0xa1, 0x01, 0x00, 0x00, 0x00, + 0x90, 0x03, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, + 0x38, 0x01, 0x00, 0x00, 0xa8, 0x01, 0x00, 0x00, 0x1c, 0x02, 0x00, 0x00, + 0x14, 0x03, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0xfc, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x00, 0x04, 0xfe, 0xff, 0x00, 0x01, 0x00, 0x00, + 0xc8, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x24, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x00, 0xab, 0xab, 0xab, + 0x3c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xb4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x45, 0x79, 0x65, 0x54, 0x6f, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, + 0x56, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x00, 0xab, 0x01, 0x00, 0x03, 0x00, + 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x45, 0x79, 0x65, 0x54, 0x6f, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, + 0x56, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x00, 0x4d, 0x69, 0x63, 0x72, + 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, + 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, + 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x36, 0x2e, 0x33, 0x2e, 0x39, + 0x36, 0x30, 0x30, 0x2e, 0x31, 0x36, 0x33, 0x38, 0x34, 0x00, 0xab, 0xab, + 0x49, 0x53, 0x47, 0x4e, 0x68, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x03, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0f, 0x0f, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x03, 0x03, 0x00, 0x00, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, + 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, + 0x4f, 0x52, 0x44, 0x00, 0x4f, 0x53, 0x47, 0x4e, 0x6c, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, + 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, + 0x52, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0xab, + 0x53, 0x48, 0x44, 0x52, 0xf0, 0x00, 0x00, 0x00, 0x40, 0x00, 0x01, 0x00, + 0x3c, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x04, 0x46, 0x8e, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, + 0x32, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, + 0xf2, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, + 0x32, 0x10, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x04, + 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x65, 0x00, 0x00, 0x03, 0xf2, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x65, 0x00, 0x00, 0x03, 0x72, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x05, 0x32, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x46, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x08, + 0xc2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, + 0x00, 0x00, 0x80, 0x3f, 0x36, 0x00, 0x00, 0x05, 0xf2, 0x20, 0x10, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x46, 0x1e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x32, 0x00, 0x00, 0x0b, 0x32, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x46, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x46, 0x10, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0xe6, 0x8a, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, + 0x42, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x3f, 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, + 0x74, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +}; + +#endif diff --git a/LibOVR/Src/CAPI/Shaders/Distortion_vs_refl.h b/LibOVR/Src/CAPI/Shaders/Distortion_vs_refl.h new file mode 100644 index 0000000..0e7d4fa --- /dev/null +++ b/LibOVR/Src/CAPI/Shaders/Distortion_vs_refl.h @@ -0,0 +1,9 @@ +#ifndef Distortion_vs_refl + +const OVR::CAPI::D3D_NS::ShaderBase::Uniform Distortion_vs_refl[] = +{ + { "EyeToSourceUVScale", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 0, 8 }, + { "EyeToSourceUVOffset", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 8, 8 }, +}; + +#endif diff --git a/LibOVR/Src/CAPI/Shaders/SimpleQuad_ps.h b/LibOVR/Src/CAPI/Shaders/SimpleQuad_ps.h new file mode 100644 index 0000000..2c01e6c --- /dev/null +++ b/LibOVR/Src/CAPI/Shaders/SimpleQuad_ps.h @@ -0,0 +1,51 @@ +#ifndef SIMPLEQUAD_PS_H +#define SIMPLEQUAD_PS_H + +static const unsigned char SimpleQuad_ps[] = { + 0x44, 0x58, 0x42, 0x43, 0xc5, 0x64, 0xa2, 0x55, 0x15, 0x24, 0x7d, 0xe6, + 0x27, 0xd2, 0xf4, 0x4e, 0x42, 0xb6, 0xba, 0x78, 0x01, 0x00, 0x00, 0x00, + 0x08, 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x44, 0x01, 0x00, 0x00, + 0x8c, 0x01, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0xc4, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x00, 0x04, 0xff, 0xff, 0x00, 0x01, 0x00, 0x00, + 0x90, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x24, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x00, 0xab, 0xab, 0xab, + 0x3c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0xab, 0xab, 0x01, 0x00, 0x03, 0x00, + 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, + 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, + 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x36, + 0x2e, 0x33, 0x2e, 0x39, 0x36, 0x30, 0x30, 0x2e, 0x31, 0x36, 0x33, 0x38, + 0x34, 0x00, 0xab, 0xab, 0x49, 0x53, 0x47, 0x4e, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x4f, 0x53, 0x47, 0x4e, + 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x53, 0x56, 0x5f, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x00, 0xab, 0xab, + 0x53, 0x48, 0x44, 0x52, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x04, 0x46, 0x8e, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, + 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, + 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, + 0x53, 0x54, 0x41, 0x54, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +#endif diff --git a/LibOVR/Src/CAPI/Shaders/SimpleQuad_ps_refl.h b/LibOVR/Src/CAPI/Shaders/SimpleQuad_ps_refl.h new file mode 100644 index 0000000..21595d1 --- /dev/null +++ b/LibOVR/Src/CAPI/Shaders/SimpleQuad_ps_refl.h @@ -0,0 +1,8 @@ +#ifndef SimpleQuad_ps_refl + +const OVR::CAPI::D3D_NS::ShaderBase::Uniform SimpleQuad_ps_refl[] = +{ + { "Color", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 0, 16 }, +}; + +#endif diff --git a/LibOVR/Src/CAPI/Shaders/SimpleQuad_vs.h b/LibOVR/Src/CAPI/Shaders/SimpleQuad_vs.h new file mode 100644 index 0000000..510c200 --- /dev/null +++ b/LibOVR/Src/CAPI/Shaders/SimpleQuad_vs.h @@ -0,0 +1,64 @@ +#ifndef SIMPLEQUAD_VS_H +#define SIMPLEQUAD_VS_H + +static const unsigned char SimpleQuad_vs[] = { + 0x44, 0x58, 0x42, 0x43, 0xb2, 0x87, 0xff, 0xa1, 0x41, 0xd7, 0x0e, 0x94, + 0x59, 0xd6, 0x1b, 0x8c, 0x94, 0x3d, 0xb9, 0x46, 0x01, 0x00, 0x00, 0x00, + 0xa8, 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, + 0x38, 0x01, 0x00, 0x00, 0x6c, 0x01, 0x00, 0x00, 0xa0, 0x01, 0x00, 0x00, + 0x2c, 0x02, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0xfc, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x00, 0x04, 0xfe, 0xff, 0x00, 0x01, 0x00, 0x00, + 0xc8, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x24, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x00, 0xab, 0xab, 0xab, + 0x3c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x00, + 0xb8, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, + 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x66, 0x66, 0x73, + 0x65, 0x74, 0x00, 0xab, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x00, 0xab, 0xab, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x4d, 0x69, 0x63, 0x72, + 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, + 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, + 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x36, 0x2e, 0x33, 0x2e, 0x39, + 0x36, 0x30, 0x30, 0x2e, 0x31, 0x36, 0x33, 0x38, 0x34, 0x00, 0xab, 0xab, + 0x49, 0x53, 0x47, 0x4e, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0x03, 0x00, 0x00, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, + 0x00, 0xab, 0xab, 0xab, 0x4f, 0x53, 0x47, 0x4e, 0x2c, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, + 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x53, 0x48, 0x44, 0x52, + 0x84, 0x00, 0x00, 0x00, 0x40, 0x00, 0x01, 0x00, 0x21, 0x00, 0x00, 0x00, + 0x59, 0x00, 0x00, 0x04, 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, 0x32, 0x10, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x04, 0xf2, 0x20, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0b, + 0x32, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe6, 0x8a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x46, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x08, 0xc2, 0x20, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x80, 0x3f, + 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, 0x74, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +#endif diff --git a/LibOVR/Src/CAPI/Shaders/SimpleQuad_vs_refl.h b/LibOVR/Src/CAPI/Shaders/SimpleQuad_vs_refl.h new file mode 100644 index 0000000..2e1fe09 --- /dev/null +++ b/LibOVR/Src/CAPI/Shaders/SimpleQuad_vs_refl.h @@ -0,0 +1,9 @@ +#ifndef SimpleQuad_vs_refl + +const OVR::CAPI::D3D_NS::ShaderBase::Uniform SimpleQuad_vs_refl[] = +{ + { "PositionOffset", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 0, 8 }, + { "Scale", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 8, 8 }, +}; + +#endif diff --git a/LibOVR/Src/Kernel/OVR_Alg.h b/LibOVR/Src/Kernel/OVR_Alg.h index 783af21..e03cea0 100644 --- a/LibOVR/Src/Kernel/OVR_Alg.h +++ b/LibOVR/Src/Kernel/OVR_Alg.h @@ -446,10 +446,10 @@ typename Array::ValueType& Median(Array& arr) UPInt mid = (count - 1) / 2; OVR_ASSERT(count > 0); - for (int j = 0; j <= mid; j++) + for (UPInt j = 0; j <= mid; j++) { - int min = j; - for (int k = j + 1; k < count; k++) + UPInt min = j; + for (UPInt k = j + 1; k < count; k++) if (arr[k] < arr[min]) min = k; Swap(arr[j], arr[min]); @@ -842,12 +842,12 @@ namespace ByteUtil { inline UInt64 SwapOrder(UInt64 v) { return (v>>56) | - ((v&UInt64(0x00FF000000000000))>>40) | - ((v&UInt64(0x0000FF0000000000))>>24) | - ((v&UInt64(0x000000FF00000000))>>8) | - ((v&UInt64(0x00000000FF000000))<<8) | - ((v&UInt64(0x0000000000FF0000))<<24) | - ((v&UInt64(0x000000000000FF00))<<40) | + ((v&UInt64(0x00FF000000000000ULL))>>40) | + ((v&UInt64(0x0000FF0000000000ULL))>>24) | + ((v&UInt64(0x000000FF00000000ULL))>>8) | + ((v&UInt64(0x00000000FF000000ULL))<<8) | + ((v&UInt64(0x0000000000FF0000ULL))<<24) | + ((v&UInt64(0x000000000000FF00ULL))<<40) | (v<<56); } inline SInt64 SwapOrder(SInt64 v) { return (SInt64)SwapOrder(UInt64(v)); } diff --git a/LibOVR/Src/Kernel/OVR_Deque.h b/LibOVR/Src/Kernel/OVR_Deque.h index 747810e..ca242ad 100644 --- a/LibOVR/Src/Kernel/OVR_Deque.h +++ b/LibOVR/Src/Kernel/OVR_Deque.h @@ -39,7 +39,6 @@ public: }; Deque(int capacity = DefaultCapacity); - Deque(const Deque<Elem> &OtherDeque); virtual ~Deque(void); virtual void PushBack (const Elem &Item); // Adds Item to the end @@ -67,6 +66,7 @@ protected: private: Deque& operator= (const Deque& q) { }; // forbidden + Deque(const Deque<Elem> &OtherDeque) { }; }; template <class Elem> @@ -76,19 +76,19 @@ public: InPlaceMutableDeque( int capacity = Deque<Elem>::DefaultCapacity ) : Deque<Elem>( capacity ) {} virtual ~InPlaceMutableDeque() {}; + using Deque<Elem>::PeekBack; + using Deque<Elem>::PeekFront; virtual Elem& PeekBack (int count = 0); // Returns count-th Item from the end virtual Elem& PeekFront (int count = 0); // Returns count-th Item from the beginning -private: - InPlaceMutableDeque& operator=(const InPlaceMutableDeque& q) {}; }; // Same as Deque, but allows to write more elements than maximum capacity // Old elements are lost as they are overwritten with the new ones template <class Elem> -class CircularBuffer : public Deque<Elem> +class CircularBuffer : public InPlaceMutableDeque<Elem> { public: - CircularBuffer(int MaxSize = Deque<Elem>::DefaultCapacity) : Deque<Elem>(MaxSize) { }; + CircularBuffer(int MaxSize = Deque<Elem>::DefaultCapacity) : InPlaceMutableDeque<Elem>(MaxSize) { }; // The following methods are inline as a workaround for a VS bug causing erroneous C4505 warnings // See: http://stackoverflow.com/questions/3051992/compiler-warning-at-c-template-base-class @@ -107,20 +107,6 @@ Capacity( capacity ), Beginning(0), End(0), ElemCount(0) ConstructArray<Elem>(Data, Capacity); } -// Deque Copy Constructor function -template <class Elem> -Deque<Elem>::Deque(const Deque &OtherDeque) : -Capacity( OtherDeque.Capacity ) // Initialize the constant -{ - Beginning = OtherDeque.Beginning; - End = OtherDeque.End; - ElemCount = OtherDeque.ElemCount; - - Data = (Elem*) OVR_ALLOC(Capacity * sizeof(Elem)); - for (int i = 0; i < Capacity; i++) - Data[i] = OtherDeque.Data[i]; -} - // Deque Destructor function template <class Elem> Deque<Elem>::~Deque(void) @@ -242,7 +228,7 @@ const Elem& Deque<Elem>::PeekBack(int count) const template <class Elem> Elem& InPlaceMutableDeque<Elem>::PeekFront(int count) { - // Error Check: Make sure we aren't reading from an empty Deque + // Error Check: Make sure we aren't reading from an empty Deque OVR_ASSERT( Deque<Elem>::ElemCount > count ); int idx = Deque<Elem>::Beginning + count; @@ -254,11 +240,11 @@ Elem& InPlaceMutableDeque<Elem>::PeekFront(int count) template <class Elem> Elem& InPlaceMutableDeque<Elem>::PeekBack(int count) { - // Error Check: Make sure we aren't reading from an empty Deque + // Error Check: Make sure we aren't reading from an empty Deque OVR_ASSERT( Deque<Elem>::ElemCount > count ); int idx = Deque<Elem>::End - count - 1; - if (idx < 0) + if (idx < 0) idx += Deque<Elem>::Capacity; return Deque<Elem>::Data[ idx ]; } diff --git a/LibOVR/Src/Kernel/OVR_FileFILE.cpp b/LibOVR/Src/Kernel/OVR_FileFILE.cpp index 4fe4cbe..8478086 100644 --- a/LibOVR/Src/Kernel/OVR_FileFILE.cpp +++ b/LibOVR/Src/Kernel/OVR_FileFILE.cpp @@ -89,7 +89,7 @@ public: class SysErrorModeDisabler { public: - SysErrorModeDisabler(const char* pfileName) { } + SysErrorModeDisabler(const char* pfileName) { OVR_UNUSED(pfileName); } }; #endif // OVR_OS_WIN32 diff --git a/LibOVR/Src/Kernel/OVR_Math.h b/LibOVR/Src/Kernel/OVR_Math.h index 9bd5bad..4aa42b0 100644 --- a/LibOVR/Src/Kernel/OVR_Math.h +++ b/LibOVR/Src/Kernel/OVR_Math.h @@ -125,7 +125,7 @@ template<class T> class Vector2; template<class T> class Vector3; template<class T> class Matrix3; template<class T> class Matrix4; -template<class T> class Pose; +template<class T> class Transform; template<class T> class PoseState; // CompatibleTypes::Type is used to lookup a compatible C-version of a C++ class. @@ -140,7 +140,7 @@ struct CompatibleTypes // Specializations providing CompatibleTypes::Type value. template<> struct CompatibleTypes<Quat<float> > { typedef ovrQuatf Type; }; template<> struct CompatibleTypes<Quat<double> > { typedef ovrQuatd Type; }; -template<> struct CompatibleTypes<Matrix3<double> > { typedef ovrMatrix3d Type; }; +template<> struct CompatibleTypes<Matrix3<double> > { typedef ovrMatrix3d Type; }; template<> struct CompatibleTypes<Matrix4<float> > { typedef ovrMatrix4f Type; }; template<> struct CompatibleTypes<Size<int> > { typedef ovrSizei Type; }; template<> struct CompatibleTypes<Size<float> > { typedef ovrSizef Type; }; @@ -150,11 +150,11 @@ template<> struct CompatibleTypes<Vector2<float> > { typedef ovrVector2f Type; template<> struct CompatibleTypes<Vector3<float> > { typedef ovrVector3f Type; }; template<> struct CompatibleTypes<Vector3<double> > { typedef ovrVector3d Type; }; -template<> struct CompatibleTypes<Pose<float> > { typedef ovrPosef Type; }; -template<> struct CompatibleTypes<PoseState<float> >{ typedef ovrPoseStatef Type; }; +template<> struct CompatibleTypes<Transform<float> > { typedef ovrPosef Type; }; +template<> struct CompatibleTypes<PoseState<float> > { typedef ovrPoseStatef Type; }; -template<> struct CompatibleTypes<Pose<double> > { typedef ovrPosed Type; }; -template<> struct CompatibleTypes<PoseState<double> >{ typedef ovrPoseStated Type; }; +template<> struct CompatibleTypes<Transform<double> > { typedef ovrPosed Type; }; +template<> struct CompatibleTypes<PoseState<double> > { typedef ovrPoseStated Type; }; //------------------------------------------------------------------------------------// // ***** Math @@ -509,7 +509,7 @@ public: T Length() const { return sqrt(LengthSq()); } // Returns squared distance between two points represented by vectors. - T DistanceSq(Vector3& b) const { return (*this - b).LengthSq(); } + T DistanceSq(Vector3 const& b) const { return (*this - b).LengthSq(); } // Returns distance between two points represented by vectors. T Distance(Vector3 const& b) const { return (*this - b).Length(); } @@ -705,7 +705,7 @@ public: // C-interop support. Quat(const typename CompatibleTypes<Quat<T> >::Type& s) : x(s.x), y(s.y), z(s.z), w(s.w) { } - operator const typename CompatibleTypes<Quat<T> >::Type () const + operator typename CompatibleTypes<Quat<T> >::Type () const { typename CompatibleTypes<Quat<T> >::Type result; result.x = x; @@ -1091,36 +1091,73 @@ typedef Quat<double> Quatd; // Position and orientation combined. template<class T> -class Pose +class Transform { public: - typedef typename CompatibleTypes<Pose<T> >::Type CompatibleType; + typedef typename CompatibleTypes<Transform<T> >::Type CompatibleType; - Pose() { } - Pose(const Quat<T>& orientation, const Vector3<T>& pos) - : Orientation(orientation), Position(pos) { } - Pose(const Pose& s) - : Orientation(s.Orientation), Position(s.Position) { } - Pose(const CompatibleType& s) - : Orientation(s.Orientation), Position(s.Position) { } - explicit Pose(const Pose<typename Math<T>::OtherFloatType> &s) - : Orientation(s.Orientation), Position(s.Position) { } + Transform() { } + Transform(const Quat<T>& orientation, const Vector3<T>& pos) + : Rotation(orientation), Translation(pos) { } + Transform(const Transform& s) + : Rotation(s.Rotation), Translation(s.Translation) { } + Transform(const CompatibleType& s) + : Rotation(s.Orientation), Translation(s.Position) { } + explicit Transform(const Transform<typename Math<T>::OtherFloatType> &s) + : Rotation(s.Rotation), Translation(s.Translation) { } - operator const typename CompatibleTypes<Pose<T> >::Type () const + operator typename CompatibleTypes<Transform<T> >::Type () const { - typename CompatibleTypes<Pose<T> >::Type result; - result.Orientation = Orientation; - result.Position = Position; + typename CompatibleTypes<Transform<T> >::Type result; + result.Orientation = Rotation; + result.Position = Translation; return result; } - Quat<T> Orientation; - Vector3<T> Position; + Quat<T> Rotation; + Vector3<T> Translation; + + Vector3<T> Rotate(const Vector3<T>& v) const + { + return Rotation.Rotate(v); + } + + Vector3<T> Translate(const Vector3<T>& v) const + { + return v + Translation; + } + + Vector3<T> Apply(const Vector3<T>& v) const + { + return Translate(Rotate(v)); + } + + Transform operator*(const Transform& other) const + { + return Transform(Rotation * other.Rotation, Apply(other.Translation)); + } + + PoseState<T> operator*(const PoseState<T>& poseState) const + { + PoseState<T> result; + result.Pose = (*this) * poseState.Pose; + result.LinearVelocity = this->Rotate(poseState.LinearVelocity); + result.LinearAcceleration = this->Rotate(poseState.LinearAcceleration); + result.AngularVelocity = this->Rotate(poseState.AngularVelocity); + result.AngularAcceleration = this->Rotate(poseState.AngularAcceleration); + return result; + } + + Transform Inverted() const + { + Quat<T> inv = Rotation.Inverted(); + return Transform(inv, inv.Rotate(-Translation)); + } }; -typedef Pose<float> Posef; -typedef Pose<double> Posed; +typedef Transform<float> Transformf; +typedef Transform<double> Transformd; //------------------------------------------------------------------------------------- @@ -1204,10 +1241,10 @@ public: M[3][0] = 0; M[3][1] = 0; M[3][2] = 0; M[3][3] = 1; } - explicit Matrix4(const Pose<T>& p) + explicit Matrix4(const Transform<T>& p) { - Matrix4 result(p.Orientation); - result.SetTranslation(p.Position); + Matrix4 result(p.Rotation); + result.SetTranslation(p.Translation); *this = result; } @@ -1226,7 +1263,7 @@ public: memcpy(M, s.M, sizeof(M)); } - operator const typename CompatibleTypes<Matrix4<T> >::Type () const + operator typename CompatibleTypes<Matrix4<T> >::Type () const { typename CompatibleTypes<Matrix4<T> >::Type result; OVR_COMPILER_ASSERT(sizeof(result) == sizeof(Matrix4)); @@ -1879,10 +1916,10 @@ public: M[0][1] = M[0][2] = M[1][0] = M[1][2] = M[2][0] = M[2][1] = 0; } - explicit Matrix3(const Pose<T>& p) + explicit Matrix3(const Transform<T>& p) { - Matrix3 result(p.Orientation); - result.SetTranslation(p.Position); + Matrix3 result(p.Rotation); + result.SetTranslation(p.Translation); *this = result; } @@ -1901,7 +1938,7 @@ public: memcpy(M, s.M, sizeof(M)); } - operator const typename CompatibleTypes<Matrix3<T> >::Type () const + operator typename CompatibleTypes<Matrix3<T> >::Type () const { typename CompatibleTypes<Matrix3<T> >::Type result; OVR_COMPILER_ASSERT(sizeof(result) == sizeof(Matrix3)); diff --git a/LibOVR/Src/Kernel/OVR_String.cpp b/LibOVR/Src/Kernel/OVR_String.cpp index 86aa126..75b7c0e 100644 --- a/LibOVR/Src/Kernel/OVR_String.cpp +++ b/LibOVR/Src/Kernel/OVR_String.cpp @@ -569,7 +569,7 @@ StringBuffer::StringBuffer(UPInt growSize) StringBuffer::StringBuffer(const char* data) : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false) { - *this = data; + AppendString(data); } StringBuffer::StringBuffer(const char* data, UPInt dataSize) @@ -585,10 +585,9 @@ StringBuffer::StringBuffer(const String& src) } StringBuffer::StringBuffer(const StringBuffer& src) - : pData(NULL), Size(0), BufferSize(src.GetGrowSize()), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false) + : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false) { AppendString(src.ToCStr(), src.GetSize()); - LengthIsSize = src.LengthIsSize; } StringBuffer::StringBuffer(const wchar_t* data) @@ -728,6 +727,12 @@ void StringBuffer::operator = (const String& src) memcpy(pData, src.ToCStr(), src.GetSize()); } +void StringBuffer::operator = (const StringBuffer& src) +{ + Clear(); + AppendString(src.ToCStr(), src.GetSize()); +} + // Inserts substr at posAt void StringBuffer::Insert(const char* substr, UPInt posAt, SPInt len) diff --git a/LibOVR/Src/Kernel/OVR_String.h b/LibOVR/Src/Kernel/OVR_String.h index f7151c7..0866968 100644 --- a/LibOVR/Src/Kernel/OVR_String.h +++ b/LibOVR/Src/Kernel/OVR_String.h @@ -474,6 +474,7 @@ public: void operator = (const char* str); void operator = (const wchar_t* str); void operator = (const String& src); + void operator = (const StringBuffer& src); // Addition void operator += (const String& src) { AppendString(src.ToCStr(),src.GetSize()); } diff --git a/LibOVR/Src/Kernel/OVR_SysFile.cpp b/LibOVR/Src/Kernel/OVR_SysFile.cpp index f487492..604527a 100644 --- a/LibOVR/Src/Kernel/OVR_SysFile.cpp +++ b/LibOVR/Src/Kernel/OVR_SysFile.cpp @@ -31,6 +31,7 @@ limitations under the License. #include <stdio.h> #include "OVR_SysFile.h" +#include "OVR_Log.h" namespace OVR { @@ -100,6 +101,7 @@ bool SysFile::Open(const String& path, int flags, int mode) if ((!pFile) || (!pFile->IsValid())) { pFile = *new UnopenedFile; + OVR_DEBUG_LOG(("Failed to open file: %s", path.ToCStr())); return 0; } //pFile = *OVR_NEW DelegatedFile(pFile); // MA Testing diff --git a/LibOVR/Src/Kernel/OVR_SysFile.h b/LibOVR/Src/Kernel/OVR_SysFile.h index d492377..61ad6e8 100644 --- a/LibOVR/Src/Kernel/OVR_SysFile.h +++ b/LibOVR/Src/Kernel/OVR_SysFile.h @@ -86,7 +86,7 @@ public: OVR_FORCE_INLINE bool Create(const String& path, int mode = Mode_ReadWrite) { return Open(path, Open_ReadWrite|Open_Create, mode); } - // Helper function: obtain file statistics information. In GFx, this is used to detect file changes. + // Helper function: obtain file statistics information. In OVR, this is used to detect file changes. // Return 0 if function failed, most likely because the file doesn't exist. static bool OVR_CDECL GetFileStat(FileStat* pfileStats, const String& path); diff --git a/LibOVR/Src/Kernel/OVR_Threads.h b/LibOVR/Src/Kernel/OVR_Threads.h index e1f5abe..307f107 100644 --- a/LibOVR/Src/Kernel/OVR_Threads.h +++ b/LibOVR/Src/Kernel/OVR_Threads.h @@ -392,7 +392,7 @@ protected: void Init(const CreateParams& params); // Protected copy constructor - Thread(const Thread &source) { OVR_UNUSED(source); } + Thread(const Thread &source) : RefCountBase<Thread>() { OVR_UNUSED(source); } }; diff --git a/LibOVR/Src/Kernel/OVR_Types.h b/LibOVR/Src/Kernel/OVR_Types.h index f45df59..8f2b3f3 100644 --- a/LibOVR/Src/Kernel/OVR_Types.h +++ b/LibOVR/Src/Kernel/OVR_Types.h @@ -262,7 +262,7 @@ typedef uint64_t UInt64; // BaseTypes namespace is explicitly declared to allow base types to be used // by customers directly without other contents of OVR namespace. // -// Its is expected that GFx samples will declare 'using namespace OVR::BaseTypes' +// Its is expected that OVR samples will declare 'using namespace OVR::BaseTypes' // to allow using these directly without polluting the target scope with other // OVR declarations, such as Ptr<>, String or Mutex. namespace BaseTypes diff --git a/LibOVR/Src/OVR_CAPI.cpp b/LibOVR/Src/OVR_CAPI.cpp index 253bb3b..a7f921f 100644 --- a/LibOVR/Src/OVR_CAPI.cpp +++ b/LibOVR/Src/OVR_CAPI.cpp @@ -51,7 +51,7 @@ FovPort::FovPort(const ovrFovPort &src) : UpTan(src.UpTan), DownTan(src.DownTan), LeftTan(src.LeftTan), RightTan(src.RightTan) { } -FovPort::operator const ovrFovPort () const +FovPort::operator ovrFovPort () const { ovrFovPort result; result.LeftTan = LeftTan; @@ -79,7 +79,7 @@ SensorState::SensorState(const ovrSensorState& s) StatusFlags = s.StatusFlags; } -SensorState::operator const ovrSensorState() const +SensorState::operator ovrSensorState() const { ovrSensorState result; result.Predicted = Predicted; @@ -206,23 +206,23 @@ OVR_EXPORT double ovr_WaitTillTime(double absTime) // 1. Init/shutdown. -static ovrBool CAPI_SystemInitCalled = FALSE; +static ovrBool CAPI_SystemInitCalled = 0; OVR_EXPORT ovrBool ovr_Initialize() { if (OVR::CAPI::GlobalState::pInstance) - return TRUE; + return 1; // We must set up the system for the plugin to work if (!OVR::System::IsInitialized()) { OVR::System::Init(OVR::Log::ConfigureDefaultLog(OVR::LogMask_All)); - CAPI_SystemInitCalled = TRUE; + CAPI_SystemInitCalled = 1; } // Constructor detects devices GlobalState::pInstance = new GlobalState; - return TRUE; + return 1; } OVR_EXPORT void ovr_Shutdown() @@ -237,7 +237,7 @@ OVR_EXPORT void ovr_Shutdown() if (CAPI_SystemInitCalled) { OVR::System::Destroy(); - CAPI_SystemInitCalled = FALSE; + CAPI_SystemInitCalled = 0; } return; } @@ -320,6 +320,27 @@ OVR_EXPORT const char* ovrHmd_GetLastError(ovrHmd hmd) //------------------------------------------------------------------------------------- + +// Returns capability bits that are enabled at this time; described by ovrHmdCapBits. +// Note that this value is different font ovrHmdDesc::Caps, which describes what +// capabilities are available. +OVR_EXPORT unsigned int ovrHmd_GetEnabledCaps(ovrHmd hmd) +{ + HMDState* p = (HMDState*)hmd; + return p ? p->EnabledHmdCaps : 0; +} + +// Modifies capability bits described by ovrHmdCapBits that can be modified, +// such as ovrHmd_LowPersistance. +OVR_EXPORT void ovrHmd_SetEnabledCaps(ovrHmd hmd, unsigned int capsBits) +{ + HMDState* p = (HMDState*)hmd; + if (p) + p->SetEnabledHmdCaps(capsBits); +} + + +//------------------------------------------------------------------------------------- // *** Sensor // Sensor APIs are separated from Create & Configure for several reasons: @@ -363,7 +384,7 @@ OVR_EXPORT ovrSensorState ovrHmd_GetSensorState(ovrHmd hmd, double absTime) OVR_EXPORT ovrBool ovrHmd_GetSensorDesc(ovrHmd hmd, ovrSensorDesc* descOut) { HMDState* p = (HMDState*)hmd; - return p->GetSensorDesc(descOut) ? TRUE : FALSE; + return p->GetSensorDesc(descOut) ? 1 : 0; } @@ -396,14 +417,13 @@ OVR_EXPORT ovrSizei ovrHmd_GetFovTextureSize(ovrHmd hmd, ovrEyeType eye, ovrFovP OVR_EXPORT ovrBool ovrHmd_ConfigureRendering( ovrHmd hmd, const ovrRenderAPIConfig* apiConfig, - unsigned int hmdCaps, unsigned int distortionCaps, - const ovrEyeDesc eyeDescIn[2], + const ovrFovPort eyeFovIn[2], ovrEyeRenderDesc eyeRenderDescOut[2] ) { - if (!hmd) return FALSE; - return ((HMDState*)hmd)->ConfigureRendering(eyeRenderDescOut, eyeDescIn, - apiConfig, hmdCaps, distortionCaps); + if (!hmd) return 0; + return ((HMDState*)hmd)->ConfigureRendering(eyeRenderDescOut, eyeFovIn, + apiConfig, distortionCaps); } @@ -451,7 +471,7 @@ OVR_EXPORT void ovrHmd_EndFrame(ovrHmd hmd) // TBD: Move directly into renderer bool dk2LatencyTest = (hmds->HMDInfo.HmdType == HmdType_DK2) && - (hmds->SensorCaps & ovrHmdCap_LatencyTest); + (hmds->EnabledHmdCaps & ovrHmdCap_LatencyTest); if (dk2LatencyTest) { hmds->LatencyTest2DrawColor[0] = hmds->TimeManager.GetFrameLatencyTestDrawColor(); @@ -460,14 +480,16 @@ OVR_EXPORT void ovrHmd_EndFrame(ovrHmd hmd) } if (hmds->pRenderer) - { + { + hmds->pRenderer->SaveGraphicsState(); hmds->pRenderer->EndFrame(true, hmds->LatencyTestActive ? hmds->LatencyTestDrawColor : NULL, // MA: Use this color since we are running DK2 test all the time. dk2LatencyTest ? hmds->LatencyTest2DrawColor : 0 //hmds->LatencyTest2Active ? hmds->LatencyTest2DrawColor : NULL - ); + ); + hmds->pRenderer->RestoreGraphicsState(); } // Call after present ovrHmd_EndFrameTiming(hmd); @@ -582,12 +604,13 @@ OVR_EXPORT void ovrHmd_EndFrameTiming(ovrHmd hmd) } -OVR_EXPORT void ovrHmd_ResetFrameTiming(ovrHmd hmd, unsigned int frameIndex, bool vsync) +OVR_EXPORT void ovrHmd_ResetFrameTiming(ovrHmd hmd, unsigned int frameIndex) { HMDState* hmds = (HMDState*)hmd; if (!hmds) return; - hmds->TimeManager.ResetFrameTiming(frameIndex, vsync, false, + hmds->TimeManager.ResetFrameTiming(frameIndex, + false, hmds->RenderingConfigured); hmds->LastFrameTimeSeconds = 0.0; hmds->LastGetFrameTimeSeconds = 0.0; @@ -630,7 +653,8 @@ OVR_EXPORT void ovrHmd_GetEyeTimewarpMatrices(ovrHmd hmd, ovrEyeType eye, -OVR_EXPORT ovrEyeRenderDesc ovrHmd_GetRenderDesc(ovrHmd hmd, const ovrEyeDesc eyeDesc) +OVR_EXPORT ovrEyeRenderDesc ovrHmd_GetRenderDesc(ovrHmd hmd, + ovrEyeType eyeType, ovrFovPort fov) { ovrEyeRenderDesc erd; @@ -641,7 +665,7 @@ OVR_EXPORT ovrEyeRenderDesc ovrHmd_GetRenderDesc(ovrHmd hmd, const ovrEyeDesc ey return erd; } - return hmds->RenderState.calcRenderDesc(eyeDesc); + return hmds->RenderState.calcRenderDesc(eyeType, fov); } @@ -652,18 +676,19 @@ OVR_EXPORT ovrEyeRenderDesc ovrHmd_GetRenderDesc(ovrHmd hmd, const ovrEyeDesc ey // Generate distortion mesh per eye. // scaleAndOffsetOut - this will be needed for shader -OVR_EXPORT ovrBool ovrHmd_CreateDistortionMesh( ovrHmd hmd, ovrEyeDesc eyeDesc, +OVR_EXPORT ovrBool ovrHmd_CreateDistortionMesh( ovrHmd hmd, + ovrEyeType eyeType, ovrFovPort fov, unsigned int distortionCaps, - ovrVector2f uvScaleOffsetOut[2], ovrDistortionMesh *meshData ) { if (!meshData) - return FALSE; + return 0; HMDState* hmds = (HMDState*)hmd; // Not used now, but Chromatic flag or others could possibly be checked for in the future. OVR_UNUSED1(distortionCaps); +#if defined (OVR_OS_WIN32) // TBD: We should probably be sharing some C API structures with C++ to avoid this mess... OVR_COMPILER_ASSERT(sizeof(DistortionMeshVertexData) == sizeof(ovrDistortionVertex)); OVR_COMPILER_ASSERT(OVR_OFFSET_OF(DistortionMeshVertexData, ScreenPosNDC) == OVR_OFFSET_OF(ovrDistortionVertex, Pos)); @@ -672,6 +697,7 @@ OVR_EXPORT ovrBool ovrHmd_CreateDistortionMesh( ovrHmd hmd, ovrEyeDesc eyeDesc, OVR_COMPILER_ASSERT(OVR_OFFSET_OF(DistortionMeshVertexData, TanEyeAnglesR) == OVR_OFFSET_OF(ovrDistortionVertex, TexR)); OVR_COMPILER_ASSERT(OVR_OFFSET_OF(DistortionMeshVertexData, TanEyeAnglesG) == OVR_OFFSET_OF(ovrDistortionVertex, TexG)); OVR_COMPILER_ASSERT(OVR_OFFSET_OF(DistortionMeshVertexData, TanEyeAnglesB) == OVR_OFFSET_OF(ovrDistortionVertex, TexB)); +#endif // *** Calculate a part of "StereoParams" needed for mesh generation @@ -681,21 +707,13 @@ OVR_EXPORT ovrBool ovrHmd_CreateDistortionMesh( ovrHmd hmd, ovrEyeDesc eyeDesc, // eyeToSourceUV is computed here for convenience, so that users don't need // to call ovrHmd_GetRenderScaleAndOffset unless changing RT dynamically. - const HmdRenderInfo& hmdri = hmds->RenderState.RenderInfo; - StereoEye stereoEye = (eyeDesc.Eye == ovrEye_Left) ? StereoEye_Left : StereoEye_Right; + StereoEye stereoEye = (eyeType == ovrEye_Left) ? StereoEye_Left : StereoEye_Right; - const DistortionRenderDesc& distortion = hmds->RenderState.Distortion[eyeDesc.Eye]; + const DistortionRenderDesc& distortion = hmds->RenderState.Distortion[eyeType]; // Find the mapping from TanAngle space to target NDC space. - ScaleAndOffset2D eyeToSourceNDC = CreateNDCScaleAndOffsetFromFov(eyeDesc.Fov); - // Find the mapping from TanAngle space to textureUV space. - ScaleAndOffset2D eyeToSourceUV = CreateUVScaleAndOffsetfromNDCScaleandOffset( - eyeToSourceNDC, - Recti(eyeDesc.RenderViewport), eyeDesc.TextureSize ); - - uvScaleOffsetOut[0] = eyeToSourceUV.Scale; - uvScaleOffsetOut[1] = eyeToSourceUV.Offset; + ScaleAndOffset2D eyeToSourceNDC = CreateNDCScaleAndOffsetFromFov(fov); int triangleCount = 0; int vertexCount = 0; @@ -710,10 +728,10 @@ OVR_EXPORT ovrBool ovrHmd_CreateDistortionMesh( ovrHmd hmd, ovrEyeDesc eyeDesc, // Convert to index meshData->IndexCount = triangleCount * 3; meshData->VertexCount = vertexCount; - return TRUE; + return 1; } - return FALSE; + return 0; } @@ -734,20 +752,16 @@ OVR_EXPORT void ovrHmd_DestroyDistortionMesh(ovrDistortionMesh* meshData) // Computes updated 'uvScaleOffsetOut' to be used with a distortion if render target size or // viewport changes after the fact. This can be used to adjust render size every frame, if desired. -OVR_EXPORT void ovrHmd_GetRenderScaleAndOffset( ovrHmd hmd, ovrEyeDesc eyeDesc, - unsigned int distortionCaps, +OVR_EXPORT void ovrHmd_GetRenderScaleAndOffset( ovrFovPort fov, + ovrSizei textureSize, ovrRecti renderViewport, ovrVector2f uvScaleOffsetOut[2] ) { - OVR_UNUSED2(hmd, distortionCaps); - // TBD: We could remove dependency on HMD here, but what if we need it in the future? - //HMDState* hmds = (HMDState*)hmd; - // Find the mapping from TanAngle space to target NDC space. - ScaleAndOffset2D eyeToSourceNDC = CreateNDCScaleAndOffsetFromFov(eyeDesc.Fov); + ScaleAndOffset2D eyeToSourceNDC = CreateNDCScaleAndOffsetFromFov(fov); // Find the mapping from TanAngle space to textureUV space. ScaleAndOffset2D eyeToSourceUV = CreateUVScaleAndOffsetfromNDCScaleandOffset( eyeToSourceNDC, - eyeDesc.RenderViewport, eyeDesc.TextureSize ); + renderViewport, textureSize ); uvScaleOffsetOut[0] = eyeToSourceUV.Scale; uvScaleOffsetOut[1] = eyeToSourceUV.Offset; diff --git a/LibOVR/Src/OVR_CAPI.h b/LibOVR/Src/OVR_CAPI.h index d5cce01..ec4708c 100644 --- a/LibOVR/Src/OVR_CAPI.h +++ b/LibOVR/Src/OVR_CAPI.h @@ -121,29 +121,53 @@ typedef enum } ovrHmdType; // HMD capability bits reported by device. +// typedef enum { + // Read-only flags. ovrHmdCap_Present = 0x0001, // This HMD exists (as opposed to being unplugged). ovrHmdCap_Available = 0x0002, // HMD and is sensor is available for use - // (if not owned by another app). - ovrHmdCap_Orientation = 0x0010, // Support orientation tracking (IMU). - ovrHmdCap_YawCorrection = 0x0020, // Supports yaw correction through magnetometer or other means. - ovrHmdCap_Position = 0x0040, // Supports positional tracking. + // (if not owned by another app). + + // These flags are intended for use with the new driver display mode. + /* + ovrHmdCap_ExtendDesktop = 0x0004, // Read only, means display driver is in compatibility mode. + + ovrHmdCap_DisplayOff = 0x0040, // Turns off Oculus HMD screen and output. + ovrHmdCap_NoMirrorToWindow = 0x2000, // Disables mirrowing of HMD output to the window; + // may improve rendering performance slightly. + */ + + // Modifiable flags (through ovrHmd_SetEnabledCaps). ovrHmdCap_LowPersistence = 0x0080, // Supports low persistence mode. - ovrHmdCap_LatencyTest = 0x0100, // Supports pixel reading for continous latency testing. + ovrHmdCap_LatencyTest = 0x0100, // Supports pixel reading for continuous latency testing. ovrHmdCap_DynamicPrediction = 0x0200, // Adjust prediction dynamically based on DK2 Latency. - // Support rendering without VSync for debugging - ovrHmdCap_NoVSync = 0x1000 -} ovrHmdCapBits; + ovrHmdCap_NoVSync = 0x1000, + ovrHmdCap_NoRestore = 0x4000, + + // These bits can be modified by ovrHmd_SetEnabledCaps. + ovrHmdCap_Writable_Mask = 0x1380 +} ovrHmdCaps; -// Describes distortion rendering parameters for ovrHmd_ConfigureRenderAPI or for -// ovrHmd_GenerateDistortionMesh. + +// Sensor capability bits reported by device. +// Used with ovrHmd_StartSensor. +typedef enum +{ + ovrSensorCap_Orientation = 0x0010, // Supports orientation tracking (IMU). + ovrSensorCap_YawCorrection = 0x0020, // Supports yaw correction through magnetometer or other means. + ovrSensorCap_Position = 0x0040, // Supports positional tracking. + +} ovrSensorCaps; + +// Distortion capability bits reported by device. +// Used with ovrHmd_ConfigureRendering and ovrHmd_CreateDistortionMesh. typedef enum { - ovrDistortion_Chromatic = 0x01, - ovrDistortion_TimeWarp = 0x02, - ovrDistortion_Vignette = 0x08 + ovrDistortionCap_Chromatic = 0x01, // Supports chromatic aberration correction. + ovrDistortionCap_TimeWarp = 0x02, // Supports timewarp. + ovrDistortionCap_Vignette = 0x08 // Supports vignetting around the edges of the view. } ovrDistortionCaps; @@ -171,8 +195,11 @@ typedef struct ovrHmdDesc_ const char* ProductName; const char* Manufacturer; - // Capability bits described by ovrHmdCapBits. - unsigned int Caps; + // Capability bits described by ovrHmdCaps. + unsigned int HmdCaps; + // Capability bits described by ovrSensorCaps. + unsigned int SensorCaps; + // Capability bits described by ovrDistortionCaps. unsigned int DistortionCaps; // Resolution of the entire HMD screen (for both eyes) in pixels. @@ -197,7 +224,7 @@ typedef struct ovrHmdDesc_ // Windows: "\\\\.\\DISPLAY3", etc. Can be used in EnumDisplaySettings/CreateDC. const char* DisplayDeviceName; // MacOS - long DisplayId; + int DisplayId; } ovrHmdDesc; // Describes the type of positional tracking being done. @@ -221,7 +248,7 @@ typedef enum } ovrStatusBits; -// State of the sensor at given a absolute time. +// State of the sensor at a given absolute time. typedef struct ovrSensorState_ { // Predicted pose configuration at requested absolute time. @@ -283,27 +310,16 @@ typedef struct ovrFrameTiming_ - -// Describes an eye for ovrHmd_Configure(). -// Configure will generate more complete ovrEyeRenderDesc based on this data. -// Users must fill in both render target TextureSize and a RenderViewport within it -// to specify the rectangle from which pre-distorted eye image will be taken. -// A different RenderViewport may be used during rendering by specifying either +// Rendering information for each eye, computed by either ovrHmd_ConfigureRendering(). +// or ovrHmd_GetRenderDesc() based on the specified Fov. +// Note that the rendering viewport is not included here as it can be +// specified separately and modified per frame though: // (a) calling ovrHmd_GetRenderScaleAndOffset with game-rendered api, // or (b) passing different values in ovrTexture in case of SDK-rendered distortion. -typedef struct ovrEyeDesc_ +typedef struct ovrEyeRenderDesc_ { ovrEyeType Eye; - ovrSizei TextureSize; // Absolute size of render texture. - ovrRecti RenderViewport; // Viewport within texture where eye rendering takes place. - // If specified as (0,0,0,0), it will be initialized to TextureSize. ovrFovPort Fov; -} ovrEyeDesc; - -// Rendering information for each eye, computed by ovrHmd_Configure(). -typedef struct ovrEyeRenderDesc_ -{ - ovrEyeDesc Desc; ovrRecti DistortedViewport; // Distortion viewport ovrVector2f PixelsPerTanAngleAtCenter; // How many display pixels will fit in tan(angle) = 1. ovrVector3f ViewAdjust; // Translation to be applied to view matrix. @@ -353,7 +369,7 @@ typedef struct ovrRenderAPIConfig_ // - If RenderViewport is all zeros, will be used. typedef struct ovrTextureHeader_ { - ovrRenderAPIType API; + ovrRenderAPIType API; ovrSizei TextureSize; ovrRecti RenderViewport; // Pixel viewport in texture that holds eye image. } ovrTextureHeader; @@ -425,20 +441,32 @@ OVR_EXPORT const char* ovrHmd_GetLastError(ovrHmd hmd); //------------------------------------------------------------------------------------- + +// Returns capability bits that are enabled at this time; described by ovrHmdCaps. +// Note that this value is different font ovrHmdDesc::HmdCaps, which describes what +// capabilities are available. +OVR_EXPORT unsigned int ovrHmd_GetEnabledCaps(ovrHmd hmd); + +// Modifies capability bits described by ovrHmdCaps that can be modified, +// such as ovrHmd_LowPersistance. +OVR_EXPORT void ovrHmd_SetEnabledCaps(ovrHmd hmd, unsigned int hmdCaps); + + +//------------------------------------------------------------------------------------- // ***** Sensor Interface // All sensor interface functions are thread-safe, allowing sensor state to be sampled // from different threads. - -// Starts sensor sampling, enabling specified capabilities, described by ovrHmdCapBits. -// - supportedCaps specifies support that is requested. The function will succeed even if, -// if these caps are not available (i.e. sensor or camera is unplugged). Support will -// automatically be enabled if such device is plugged in later. Software should check -// ovrSensorState.StatusFlags for real-time status. -// - requiredCaps specify sensor capabilities required at the time of the call. If they -// are not available, the function will fail. Pass 0 if only specifying SupportedCaps. -OVR_EXPORT ovrBool ovrHmd_StartSensor(ovrHmd hmd, unsigned int supportedCaps, - unsigned int requiredCaps); +// Starts sensor sampling, enabling specified capabilities, described by ovrSensorCaps. +// - supportedSensorCaps specifies support that is requested. The function will succeed +// even if these caps are not available (i.e. sensor or camera is unplugged). Support +// will automatically be enabled if such device is plugged in later. Software should +// check ovrSensorState.StatusFlags for real-time status. +// - requiredSensorCaps specify sensor capabilities required at the time of the call. +// If they are not available, the function will fail. Pass 0 if only specifying +// supportedSensorCaps. +OVR_EXPORT ovrBool ovrHmd_StartSensor(ovrHmd hmd, unsigned int supportedSensorCaps, + unsigned int requiredSensorCaps); // Stops sensor sampling, shutting down internal resources. OVR_EXPORT void ovrHmd_StopSensor(ovrHmd hmd); // Resets sensor orientation. @@ -510,10 +538,9 @@ OVR_EXPORT ovrSizei ovrHmd_GetFovTextureSize(ovrHmd hmd, ovrEyeType eye, ovrFovP // - distortionCaps describe distortion settings that will be applied. // OVR_EXPORT ovrBool ovrHmd_ConfigureRendering( ovrHmd hmd, - const ovrRenderAPIConfig* apiConfig, - unsigned int hmdCaps, + const ovrRenderAPIConfig* apiConfig, unsigned int distortionCaps, - const ovrEyeDesc eyeDescIn[2], + const ovrFovPort eyeFovIn[2], ovrEyeRenderDesc eyeRenderDescOut[2] ); @@ -539,12 +566,12 @@ OVR_EXPORT void ovrHmd_EndFrame(ovrHmd hmd); // HmdDesc.EyeRenderOrder[0] first. OVR_EXPORT ovrPosef ovrHmd_BeginEyeRender(ovrHmd hmd, ovrEyeType eye); -// Marks the end of eye rendering and submits eye texture for display after it is ready. +// Marks the end of eye rendering and submits the eye texture for display after it is ready. // Rendering viewport within the texture can change per frame if necessary. -// Specified texture may be presented immediately or wait till ovrHmd_EndFrame based -// on implementation. The API may performs distortion and scaling internally. +// Specified texture may be presented immediately or wait until ovrHmd_EndFrame based +// on the implementation. The API performs distortion and scaling internally. // 'renderPose' will typically be the value returned from ovrHmd_BeginEyeRender, but can -// be different if different pose was used for rendering. +// be different if a different pose was used for rendering. OVR_EXPORT void ovrHmd_EndEyeRender(ovrHmd hmd, ovrEyeType eye, ovrPosef renderPose, ovrTexture* eyeTexture); @@ -572,7 +599,8 @@ OVR_EXPORT void ovrHmd_EndEyeRender(ovrHmd hmd, ovrEyeType eye, // Computes distortion viewport, view adjust and other rendering for the specified // eye. This can be used instead of ovrHmd_ConfigureRendering to help setup rendering on // the game side. -OVR_EXPORT ovrEyeRenderDesc ovrHmd_GetRenderDesc(ovrHmd hmd, ovrEyeDesc eyeDesc); +OVR_EXPORT ovrEyeRenderDesc ovrHmd_GetRenderDesc(ovrHmd hmd, + ovrEyeType eyeType, ovrFovPort fov); // Describes a vertex used for distortion; this is intended to be converted into @@ -604,12 +632,12 @@ typedef struct ovrDistortionMesh_ // appropriate shaders based on their settings. // Distortion mesh data will be allocated and stored into the ovrDistortionMesh data structure, // which should be explicitly freed with ovrHmd_DestroyDistortionMesh. -// uvScaleOffsetOut[] are filled in based on render target settings of eyeDesc. +// Users should call ovrHmd_GetRenderScaleAndOffset to get uvScale and Offset values for rendering. // The function shouldn't fail unless theres is a configuration or memory error, in which case // ovrDistortionMesh values will be set to null. -OVR_EXPORT ovrBool ovrHmd_CreateDistortionMesh( ovrHmd hmd, ovrEyeDesc eyeDesc, +OVR_EXPORT ovrBool ovrHmd_CreateDistortionMesh( ovrHmd hmd, + ovrEyeType eyeType, ovrFovPort fov, unsigned int distortionCaps, - ovrVector2f uvScaleOffsetOut[2], ovrDistortionMesh *meshData ); // Frees distortion mesh allocated by ovrHmd_GenerateDistortionMesh. meshData elements @@ -618,8 +646,8 @@ OVR_EXPORT void ovrHmd_DestroyDistortionMesh( ovrDistortionMesh* meshData ); // Computes updated 'uvScaleOffsetOut' to be used with a distortion if render target size or // viewport changes after the fact. This can be used to adjust render size every frame, if desired. -OVR_EXPORT void ovrHmd_GetRenderScaleAndOffset( ovrHmd hmd, ovrEyeDesc eyeDesc, - unsigned int distortionCaps, +OVR_EXPORT void ovrHmd_GetRenderScaleAndOffset( ovrFovPort fov, + ovrSizei textureSize, ovrRecti renderViewport, ovrVector2f uvScaleOffsetOut[2] ); @@ -640,7 +668,7 @@ OVR_EXPORT void ovrHmd_EndFrameTiming(ovrHmd hmd); // Initializes and resets frame time tracking. This is typically not necessary, but // is helpful if game changes vsync state or video mode. vsync is assumed to be on if this // isn't called. Resets internal frame index to the specified number. -OVR_EXPORT void ovrHmd_ResetFrameTiming(ovrHmd hmd, unsigned int frameIndex, bool vsync); +OVR_EXPORT void ovrHmd_ResetFrameTiming(ovrHmd hmd, unsigned int frameIndex); // Predicts and returns Pose that should be used rendering the specified eye. diff --git a/LibOVR/Src/OVR_CAPI_D3D.h b/LibOVR/Src/OVR_CAPI_D3D.h index 75c383a..112525d 100644 --- a/LibOVR/Src/OVR_CAPI_D3D.h +++ b/LibOVR/Src/OVR_CAPI_D3D.h @@ -122,9 +122,8 @@ struct ovrD3D9ConfigData // General device settings. ovrRenderAPIConfigHeader Header; - IDirect3DDevice9 * pDevice; - ///ID3D10RenderTargetView* pBackBufferRT; - ///IDXGISwapChain* pSwapChain; + IDirect3DDevice9* pDevice; + IDirect3DSwapChain9* pSwapChain; }; union ovrD3D9Config @@ -138,8 +137,7 @@ struct ovrD3D9TextureData { // General device settings. ovrTextureHeader Header; - IDirect3DTexture9 * pTexture; - ///ID3D10ShaderResourceView* pSRView; + IDirect3DTexture9* pTexture; }; union ovrD3D9Texture @@ -148,9 +146,6 @@ union ovrD3D9Texture ovrD3D9TextureData D3D9; }; - - #endif - #endif // OVR_CAPI_h diff --git a/LibOVR/Src/OVR_CAPI_GL.h b/LibOVR/Src/OVR_CAPI_GL.h index c042b5d..ceabb74 100644 --- a/LibOVR/Src/OVR_CAPI_GL.h +++ b/LibOVR/Src/OVR_CAPI_GL.h @@ -21,8 +21,18 @@ otherwise accompanies this software in either electronic or hard copy form. // ***** GL Specific #if defined(OVR_OS_WIN32) -#include <GL/gl.h> -#include <GL/wglext.h> + #include <Windows.h> + #include <GL/gl.h> + #include <GL/glext.h> + #include <GL/wglext.h> +#elif defined(OVR_OS_MAC) + #include <OpenGL/gl3.h> + #include <OpenGL/gl3ext.h> + #include <OpenGL/OpenGL.h> +#else + #include <GL/gl.h> + #include <GL/glext.h> + #include <GL/glx.h> #endif @@ -31,9 +41,13 @@ typedef struct ovrGLConfigData_s { // General device settings. ovrRenderAPIConfigHeader Header; + +#if defined(OVR_OS_WIN32) HWND Window; - HGLRC WglContext; - HDC GdiDc; +#elif defined(OVR_OS_LINUX) + Display* Disp; + Window Win; +#endif } ovrGLConfigData; union ovrGLConfig diff --git a/LibOVR/Src/OVR_Common_HMDDevice.cpp b/LibOVR/Src/OVR_Common_HMDDevice.cpp index b4ef177..6bedcbe 100644 --- a/LibOVR/Src/OVR_Common_HMDDevice.cpp +++ b/LibOVR/Src/OVR_Common_HMDDevice.cpp @@ -143,6 +143,7 @@ bool HMDDeviceCreateDesc::GetDeviceInfo(DeviceInfo* info) const case HmdType_DKHDProto566Mi: deviceName = "Oculus Rift DKHD 566 Mi"; break; case HmdType_CrystalCoveProto: deviceName = "Oculus Rift Crystal Cove"; break; case HmdType_DK2: deviceName = "Oculus Rift DK2"; break; + default: deviceName = "Oculus HMD"; break; } info->ProductName = deviceName; diff --git a/LibOVR/Src/OVR_Device.h b/LibOVR/Src/OVR_Device.h index 4ddc7a2..52a41f9 100644 --- a/LibOVR/Src/OVR_Device.h +++ b/LibOVR/Src/OVR_Device.h @@ -347,7 +347,7 @@ public: char DisplayDeviceName[32]; // MacOS: - long DisplayId; + int DisplayId; // Constructor initializes all values to 0s. @@ -492,6 +492,76 @@ private: void operator = (const SensorInfo&) { OVR_ASSERT(0); } // Assignment not allowed. }; + + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Serial Number feature report. (DK1) +struct SerialReport +{ + static const int SERIAL_NUMBER_SIZE = 12; // Serial Number size = 12 bytes. (Refer 'Tracker Firmware Specification Section 4.9, Pg 18) + + SerialReport() + : CommandId(0) + { + memset(SerialNumberValue, 0, sizeof(SerialNumberValue)); + } + + SerialReport(UInt16 commandId, + UByte SNo[SERIAL_NUMBER_SIZE]) + : CommandId(commandId) + { + for (int i=0; i < SERIAL_NUMBER_SIZE; i++) + { + SerialNumberValue[i] = SNo[i]; + } + } + + UInt16 CommandId; + UByte SerialNumberValue[SERIAL_NUMBER_SIZE]; // See 'Tracker Firmware Specification' document for + // a description of Serial Report. +}; + + +//////////////////////////////////////////////////////////////////////////////////////////////// +//Added Serial Report Implementation. + +struct SerialImpl +{ + enum { PacketSize = 15 }; + UByte Buffer[PacketSize]; + + SerialReport Settings; + + SerialImpl() + { + memset(Buffer, 0, sizeof(Buffer)); + Buffer[0] = 10; + } + + SerialImpl(const SerialReport& settings) + :Settings(settings) + { + Pack(); + } + + void Pack() + { + Buffer[0] = 10; + Alg::EncodeUInt16(Buffer+1, Settings.CommandId); + for (int i = 0; i < Settings.SERIAL_NUMBER_SIZE; ++i) + Buffer[3 + i] = Settings.SerialNumberValue[i]; + } + + void Unpack() + { + Settings.CommandId = Alg::DecodeUInt16(Buffer+1); + for (int i = 0; i < Settings.SERIAL_NUMBER_SIZE; ++i) + Settings.SerialNumberValue[i] = Buffer[3 + i]; + } + +}; + + // Tracking settings (DK2). struct TrackingReport { @@ -631,20 +701,20 @@ struct PositionCalibrationReport PositionCalibrationReport() : CommandId(0), Version(0), - Position(0), Normal(0), Rotation(0), + Position(0), Normal(0), Angle(0), PositionIndex(0), NumPositions(0), PositionType(PositionType_LED) {} PositionCalibrationReport(UInt16 commandId, UByte version, - const Vector3f& position, - const Vector3f& normal, - float rotation, + const Vector3d& position, + const Vector3d& normal, + double rotation, UInt16 positionIndex, UInt16 numPositions, PositionTypeEnum positionType) : CommandId(commandId), Version(version), - Position(position), Normal(normal), Rotation(rotation), + Position(position), Normal(normal), Angle(rotation), PositionIndex(positionIndex), NumPositions(numPositions), PositionType(positionType) { } @@ -655,7 +725,7 @@ struct PositionCalibrationReport // center of the emitter plane of the display at nominal focus. Vector3d Normal; // Normal of the LED or inertial tracker. This is a signed integer in // meters. The normal is relative to the position. - double Rotation; // The rotation about the normal. This is in radians. + double Angle; // The rotation about the normal. This is in radians. UInt16 PositionIndex; // The current position being read or written to. Autoincrements on reads, gets set // to the written value on writes. UInt16 NumPositions; // The read-only number of items with positions stored. The last position is that of @@ -710,7 +780,7 @@ struct ManufacturingReport { ManufacturingReport() : CommandId(0), NumStages(0), Stage(0), - StageLocation(0), StageTime(0), Result(0), StageVersion(0) + StageVersion(0), StageLocation(0), StageTime(0), Result(0) {} ManufacturingReport( UInt16 commandId, @@ -721,7 +791,7 @@ struct ManufacturingReport UInt32 stageTime, UInt32 result) : CommandId(commandId), NumStages(numStages), Stage(stage), - StageLocation(stageLocation), StageTime(stageTime), Result(result), StageVersion(version) + StageVersion(version), StageLocation(stageLocation), StageTime(stageTime), Result(result) { } UInt16 CommandId; @@ -880,6 +950,8 @@ struct GyroOffsetReport double Temperature; }; + + //------------------------------------------------------------------------------------- // ***** SensorDevice @@ -946,6 +1018,12 @@ public: // Enable/disable onboard IMU calibration // If set to false, the device will return raw values virtual void SetOnboardCalibrationEnabled(bool enabled) = 0; + // Return true if the mag is calibrated + virtual bool IsMagCalibrated() { return false; } + + // Get/set feature reports from DK1 added to DK2. See 'Tracker Firmware Specification' document for details. + virtual bool SetSerialReport(const SerialReport&) { return false; } + virtual bool GetSerialReport(SerialReport*) { return false; } // Get/set feature reports added to DK2. See 'DK2 Firmware Specification' document for details. virtual bool SetTrackingReport(const TrackingReport&) { return false; } diff --git a/LibOVR/Src/OVR_DeviceImpl.h b/LibOVR/Src/OVR_DeviceImpl.h index 80b227b..8e737a5 100644 --- a/LibOVR/Src/OVR_DeviceImpl.h +++ b/LibOVR/Src/OVR_DeviceImpl.h @@ -84,7 +84,6 @@ private: }; - //------------------------------------------------------------------------------------- // DeviceManagerLock is a synchronization lock used by DeviceManager for Devices diff --git a/LibOVR/Src/OVR_DeviceMessages.h b/LibOVR/Src/OVR_DeviceMessages.h index 0fe0a3c..c182404 100644 --- a/LibOVR/Src/OVR_DeviceMessages.h +++ b/LibOVR/Src/OVR_DeviceMessages.h @@ -34,7 +34,7 @@ limitations under the License. #include "Kernel/OVR_Math.h" #include "Kernel/OVR_Array.h" #include "Kernel/OVR_Color.h" - +#include "Kernel/OVR_String.h" namespace OVR { @@ -103,7 +103,7 @@ class MessageBodyFrame : public Message { public: MessageBodyFrame(DeviceBase* dev) - : Message(Message_BodyFrame, dev), Temperature(0.0f), TimeDelta(0.0f), MagCalibrated(false) + : Message(Message_BodyFrame, dev), Temperature(0.0f), TimeDelta(0.0f) { } @@ -113,8 +113,6 @@ public: float Temperature; // Temperature reading on sensor surface, in degrees Celsius. float TimeDelta; // Time passed since last Body Frame, in seconds. - bool MagCalibrated; // True if MagneticField is calibrated, false if raw - // The absolute time from the host computers perspective that the message should be // interpreted as. This is based on incoming timestamp and processed by a filter // that syncs the clocks while attempting to keep the distance between messages @@ -226,7 +224,7 @@ class MessageCameraFrame : public Message { public: MessageCameraFrame(DeviceBase* dev) - : Message(Message_CameraFrame, dev) + : Message(Message_CameraFrame, dev), CameraHandle(NULL), pFrameData(NULL) { LostFrames = 0; } @@ -253,6 +251,8 @@ public: UInt32 Width, Height; // width & height in pixels. UInt32 Format; // format of pixel, see CameraDevice::PixelFormat enum UInt32 LostFrames; // number of lost frames before this frame + String DeviceIdentifier; // identifies the device sensing the message + UInt32* CameraHandle; // Identifies the camera object associated with this frame }; // Sent when a new camera is connected @@ -261,6 +261,11 @@ class MessageCameraAdded : public Message public: MessageCameraAdded(DeviceBase* dev) : Message(Message_CameraAdded, dev) { } + + MessageCameraAdded(UInt32* cam) + : Message(Message_CameraAdded, NULL), CameraHandle(cam) { } + + UInt32* CameraHandle; // Identifies the camera object associated with this frame }; } // namespace OVR diff --git a/LibOVR/Src/OVR_HIDDevice.h b/LibOVR/Src/OVR_HIDDevice.h index 657758b..24bfcfa 100644 --- a/LibOVR/Src/OVR_HIDDevice.h +++ b/LibOVR/Src/OVR_HIDDevice.h @@ -82,7 +82,7 @@ class HIDDeviceManager : public RefCountBase<HIDDeviceManager> public: // Creates a new HIDDeviceManager. Only one instance of HIDDeviceManager should be created at a time. - static HIDDeviceManager* Create(); + static HIDDeviceManager* Create(Ptr<OVR::DeviceManager>& deviceManager); // Enumerate HID devices using a HIDEnumerateVisitor derived visitor class. virtual bool Enumerate(HIDEnumerateVisitor* enumVisitor) = 0; diff --git a/LibOVR/Src/OVR_JSON.cpp b/LibOVR/Src/OVR_JSON.cpp index 209a41f..262a0d9 100644 --- a/LibOVR/Src/OVR_JSON.cpp +++ b/LibOVR/Src/OVR_JSON.cpp @@ -432,6 +432,23 @@ JSON* JSON::Parse(const char* buff, const char** perror) } //----------------------------------------------------------------------------- +// This version works for buffers that are not null terminated strings. +JSON* JSON::ParseBuffer(const char *buff, int len, const char** perror) +{ + // Our JSON parser does not support length-based parsing, + // so ensure it is null-terminated. + char *termStr = new char[len + 1]; + memcpy(termStr, buff, len); + termStr[len] = '\0'; + + JSON *objJson = Parse(termStr, perror); + + delete[]termStr; + + return objJson; +} + +//----------------------------------------------------------------------------- // Parser core - when encountering text, process appropriately. const char* JSON::parseValue(const char* buff, const char** perror) { @@ -973,6 +990,51 @@ JSON* JSON::createHelper(JSONItemType itemType, double dval, const char* strVal) return item; } +//----------------------------------------------------------------------------- +// Get elements by name +double JSON::GetNumberByName(const char *name, double defValue) +{ + JSON* item = GetItemByName(name); + if (!item || item->Type != JSON_Number) { + return defValue; + } + else { + return item->dValue; + } +} + +int JSON::GetIntByName(const char *name, int defValue) +{ + JSON* item = GetItemByName(name); + if (!item || item->Type != JSON_Number) { + return defValue; + } + else { + return (int)item->dValue; + } +} + +bool JSON::GetBoolByName(const char *name, bool defValue) +{ + JSON* item = GetItemByName(name); + if (!item || item->Type != JSON_Bool) { + return defValue; + } + else { + return (int)item->dValue != 0; + } +} + +String JSON::GetStringByName(const char *name, const String &defValue) +{ + JSON* item = GetItemByName(name); + if (!item || item->Type != JSON_String) { + return defValue; + } + else { + return item->Value; + } +} //----------------------------------------------------------------------------- // Adds an element to an array object type @@ -1077,7 +1139,7 @@ JSON* JSON::Load(const char* path, const char** perror) } int len = f.GetLength(); - UByte* buff = (UByte*)OVR_ALLOC(len); + UByte* buff = (UByte*)OVR_ALLOC(len + 1); int bytes = f.Read(buff, len); f.Close(); @@ -1087,6 +1149,9 @@ JSON* JSON::Load(const char* path, const char** perror) return NULL; } + // Ensure the result is null-terminated since Parse() expects null-terminated input. + buff[len] = '\0'; + JSON* json = JSON::Parse((char*)buff, perror); OVR_FREE(buff); return json; diff --git a/LibOVR/Src/OVR_JSON.h b/LibOVR/Src/OVR_JSON.h index 7a2e939..a2a603c 100644 --- a/LibOVR/Src/OVR_JSON.h +++ b/LibOVR/Src/OVR_JSON.h @@ -82,6 +82,9 @@ public: // Returns null pointer and fills in *perror in case of parse error. static JSON* Parse(const char* buff, const char** perror = 0); + // This version works for buffers that are not null terminated strings. + static JSON* ParseBuffer(const char *buff, int len, const char** perror = 0); + // Loads and parses a JSON object from a file. // Returns 0 and assigns perror with error message on fail. static JSON* Load(const char* path, const char** perror = 0); @@ -102,6 +105,12 @@ public: JSON* GetItemByIndex(unsigned i); JSON* GetItemByName(const char* name); + // Accessors by name + double GetNumberByName(const char *name, double defValue = 0.0); + int GetIntByName(const char *name, int defValue = 0); + bool GetBoolByName(const char *name, bool defValue = false); + String GetStringByName(const char *name, const String &defValue = ""); + // Returns next item in a list of children; 0 if no more items exist. JSON* GetNextItem(JSON* item) { return Children.IsNull(item->pNext) ? 0 : item->pNext; } JSON* GetPrevItem(JSON* item) { return Children.IsNull(item->pPrev) ? 0 : item->pPrev; } diff --git a/LibOVR/Src/OVR_LatencyTestImpl.cpp b/LibOVR/Src/OVR_LatencyTestImpl.cpp index 9385a37..015d9e4 100644 --- a/LibOVR/Src/OVR_LatencyTestImpl.cpp +++ b/LibOVR/Src/OVR_LatencyTestImpl.cpp @@ -391,7 +391,11 @@ struct LatencyTestDisplayImpl //------------------------------------------------------------------------------------- // ***** LatencyTestDeviceFactory -LatencyTestDeviceFactory LatencyTestDeviceFactory::Instance; +LatencyTestDeviceFactory &LatencyTestDeviceFactory::GetInstance() +{ + static LatencyTestDeviceFactory instance; + return instance; +} void LatencyTestDeviceFactory::EnumerateDevices(EnumerateVisitor& visitor) { diff --git a/LibOVR/Src/OVR_LatencyTestImpl.h b/LibOVR/Src/OVR_LatencyTestImpl.h index 21ef331..34faec2 100644 --- a/LibOVR/Src/OVR_LatencyTestImpl.h +++ b/LibOVR/Src/OVR_LatencyTestImpl.h @@ -41,9 +41,9 @@ struct LatencyTestColorDetectedMessage; class LatencyTestDeviceFactory : public DeviceFactory { public: - static LatencyTestDeviceFactory Instance; + static LatencyTestDeviceFactory &GetInstance(); - // Enumerates devices, creating and destroying relevant objects in manager. + // Enumerates devices, creating and destroying relevant objects in manager. virtual void EnumerateDevices(EnumerateVisitor& visitor); virtual bool MatchVendorProduct(UInt16 vendorId, UInt16 productId) const; diff --git a/LibOVR/Src/OVR_Profile.cpp b/LibOVR/Src/OVR_Profile.cpp index 1fa8eb4..4844c29 100644 --- a/LibOVR/Src/OVR_Profile.cpp +++ b/LibOVR/Src/OVR_Profile.cpp @@ -161,7 +161,7 @@ bool ProfileManager::GetDeviceTags(const DeviceBase* device, String& product, St // If the HMD is unrecognized then use the name stamped into the // sensor firmware - if (hmdinfo.HmdType == HmdType_None || hmdinfo.Type == HmdType_Unknown) + if (hmdinfo.HmdType == HmdType_None || hmdinfo.HmdType == HmdType_Unknown) product_name = sinfo.ProductName.ToCStr(); else product_name = hmdinfo.ProductName.ToCStr(); @@ -758,7 +758,7 @@ Profile* ProfileManager::GetTaggedProfile(const char** tag_names, const char** t JSON* tagged_data = ProfileCache->GetItemByName("TaggedData"); OVR_ASSERT(tagged_data); if (tagged_data == NULL) - return false; + return NULL; Profile* profile = new Profile(); @@ -1450,7 +1450,7 @@ void Profile::SetFloatValues(const char* key, const float* vals, int num_vals) ValMap.Set(key, value); } - for (val_count; val_count < num_vals; val_count++) + for (; val_count < num_vals; val_count++) value->AddArrayNumber(vals[val_count]); } @@ -1510,7 +1510,7 @@ void Profile::SetDoubleValues(const char* key, const double* vals, int num_vals) ValMap.Set(key, value); } - for (val_count; val_count < num_vals; val_count++) + for (; val_count < num_vals; val_count++) value->AddArrayNumber(vals[val_count]); } diff --git a/LibOVR/Src/OVR_Recording.cpp b/LibOVR/Src/OVR_Recording.cpp new file mode 100644 index 0000000..a2006c8 --- /dev/null +++ b/LibOVR/Src/OVR_Recording.cpp @@ -0,0 +1,38 @@ +/************************************************************************************ + +Filename : Recording.h +Content : Support for recording sensor + camera data +Created : May 12, 2014 +Notes : + +Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.1 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +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 "Kernel/OVR_Math.h" +#include "Kernel/OVR_Array.h" +#include "OVR_DeviceMessages.h" +#include "OVR_Recording.h" + +namespace OVR { namespace Recording { + +// global instance that doesn't do anything +Recorder r; + +}} // OVR::Recording + diff --git a/LibOVR/Src/OVR_Recording.h b/LibOVR/Src/OVR_Recording.h new file mode 100644 index 0000000..fc83270 --- /dev/null +++ b/LibOVR/Src/OVR_Recording.h @@ -0,0 +1,83 @@ +/************************************************************************************ + +Filename : Recording.h +Content : Support for recording sensor + camera data +Created : March 14, 2014 +Notes : + +Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.1 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +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 OVR_Recording_h +#define OVR_Recording_h + +namespace OVR { namespace Recording { + +enum RecordingMode +{ + RecordingOff = 0x0, + RecordForPlayback = 0x1, + RecordForLogging = 0x2 +}; + +}} // OVR::Recording + +#ifdef ENABLE_RECORDING + +#include "Recording/Recording_Recorder.h" + +#else +// If Recording is not enabled, then stub it out + +namespace OVR { + +struct PositionCalibrationReport; +namespace Vision { + class CameraIntrinsics; + class DistortionCoefficients; + class Blob; +}; + +namespace Recording { + +class Recorder +{ +public: + OVR_FORCE_INLINE void RecordCameraParams(const Vision::CameraIntrinsics&, + const Vision::DistortionCoefficients&) { } + OVR_FORCE_INLINE void RecordLedPositions(const Array<PositionCalibrationReport>&) { } + OVR_FORCE_INLINE void RecordUserParams(const Vector3f&, float) { } + OVR_FORCE_INLINE void RecordDeviceIfcVersion(UByte) { } + OVR_FORCE_INLINE void RecordMessage(const Message&) { } + OVR_FORCE_INLINE void RecordCameraFrameUsed(UInt32) { } + OVR_FORCE_INLINE void RecordVisionSuccess(UInt32) { } + template<typename T> OVR_FORCE_INLINE void LogData(const char*, const T&) { } + OVR_FORCE_INLINE void SetRecordingMode(RecordingMode) { } + OVR_FORCE_INLINE RecordingMode GetRecordingMode() { return RecordingOff; } +}; + +extern Recorder r; + +OVR_FORCE_INLINE Recorder& GetRecorder() { return r; } + +}} // namespace OVR::Recording + +#endif // ENABLE_RECORDING + +#endif // OVR_Recording_h
\ No newline at end of file diff --git a/LibOVR/Src/OVR_Sensor2Impl.cpp b/LibOVR/Src/OVR_Sensor2Impl.cpp index fa5d6e9..95d486c 100644 --- a/LibOVR/Src/OVR_Sensor2Impl.cpp +++ b/LibOVR/Src/OVR_Sensor2Impl.cpp @@ -386,9 +386,7 @@ bool Sensor2DeviceImpl::getMagCalibrationReport(MagCalibrationReport* data) bool Sensor2DeviceImpl::SetPositionCalibrationReport(const PositionCalibrationReport& data) { - Lock::Locker lock(&IndexedReportLock); - - bool result; + bool result; if (!GetManagerImpl()->GetThreadQueue()-> PushCallAndWaitResult(this, &Sensor2DeviceImpl::setPositionCalibrationReport, &result, data)) { @@ -411,20 +409,6 @@ bool Sensor2DeviceImpl::setPositionCalibrationReport(const PositionCalibrationRe return GetInternalDevice()->SetFeatureReport(pci.Buffer, PositionCalibrationImpl::PacketSize); } -bool Sensor2DeviceImpl::GetPositionCalibrationReport(PositionCalibrationReport* data) -{ - Lock::Locker lock(&IndexedReportLock); - - bool result; - if (!GetManagerImpl()->GetThreadQueue()-> - PushCallAndWaitResult(this, &Sensor2DeviceImpl::getPositionCalibrationReport, &result, data)) - { - return false; - } - - return result; -} - bool Sensor2DeviceImpl::getPositionCalibrationReport(PositionCalibrationReport* data) { UByte version = GetDeviceInterfaceVersion(); @@ -454,10 +438,20 @@ bool Sensor2DeviceImpl::getPositionCalibrationReport(PositionCalibrationReport* bool Sensor2DeviceImpl::GetAllPositionCalibrationReports(Array<PositionCalibrationReport>* data) { - Lock::Locker lock(&IndexedReportLock); + bool result; + if (!GetManagerImpl()->GetThreadQueue()-> + PushCallAndWaitResult(this, &Sensor2DeviceImpl::getAllPositionCalibrationReports, &result, data)) + { + return false; + } + + return result; +} +bool Sensor2DeviceImpl::getAllPositionCalibrationReports(Array<PositionCalibrationReport>* data) +{ PositionCalibrationReport pc; - bool result = GetPositionCalibrationReport(&pc); + bool result = getPositionCalibrationReport(&pc); if (!result) return false; @@ -467,7 +461,7 @@ bool Sensor2DeviceImpl::GetAllPositionCalibrationReports(Array<PositionCalibrati for (int i = 0; i < positions; i++) { - result = GetPositionCalibrationReport(&pc); + result = getPositionCalibrationReport(&pc); if (!result) return false; OVR_ASSERT(pc.NumPositions == positions); @@ -697,8 +691,6 @@ bool Sensor2DeviceImpl::getKeepAliveMuxReport(KeepAliveMuxReport* data) bool Sensor2DeviceImpl::SetTemperatureReport(const TemperatureReport& data) { - Lock::Locker lock(&IndexedReportLock); - // direct call if we are already on the device manager thread if (GetCurrentThreadId() == GetManagerImpl()->GetThreadId()) { @@ -721,32 +713,41 @@ bool Sensor2DeviceImpl::setTemperatureReport(const TemperatureReport& data) return GetInternalDevice()->SetFeatureReport(ti.Buffer, TemperatureImpl::PacketSize); } -bool Sensor2DeviceImpl::GetTemperatureReport(TemperatureReport* data) +bool Sensor2DeviceImpl::getTemperatureReport(TemperatureReport* data) { - Lock::Locker lock(&IndexedReportLock); + TemperatureImpl ti; + if (GetInternalDevice()->GetFeatureReport(ti.Buffer, TemperatureImpl::PacketSize)) + { + ti.Unpack(); + *data = ti.Settings; + return true; + } + return false; +} + +bool Sensor2DeviceImpl::GetAllTemperatureReports(Array<Array<TemperatureReport> >* data) +{ // direct call if we are already on the device manager thread if (GetCurrentThreadId() == GetManagerImpl()->GetThreadId()) { - return getTemperatureReport(data); + return getAllTemperatureReports(data); } - bool result; - if (!GetManagerImpl()->GetThreadQueue()-> - PushCallAndWaitResult(this, &Sensor2DeviceImpl::getTemperatureReport, &result, data)) - { - return false; - } + bool result; + if (!GetManagerImpl()->GetThreadQueue()-> + PushCallAndWaitResult(this, &Sensor2DeviceImpl::getAllTemperatureReports, &result, data)) + { + return false; + } - return result; + return result; } -bool Sensor2DeviceImpl::GetAllTemperatureReports(Array<Array<TemperatureReport> >* data) +bool Sensor2DeviceImpl::getAllTemperatureReports(Array<Array<TemperatureReport> >* data) { - Lock::Locker lock(&IndexedReportLock); - TemperatureReport t; - bool result = GetTemperatureReport(&t); + bool result = getTemperatureReport(&t); if (!result) return false; @@ -759,7 +760,7 @@ bool Sensor2DeviceImpl::GetAllTemperatureReports(Array<Array<TemperatureReport> for (int i = 0; i < bins; i++) for (int j = 0; j < samples; j++) { - result = GetTemperatureReport(&t); + result = getTemperatureReport(&t); if (!result) return false; OVR_ASSERT(t.NumBins == bins && t.NumSamples == samples); @@ -769,19 +770,6 @@ bool Sensor2DeviceImpl::GetAllTemperatureReports(Array<Array<TemperatureReport> return true; } -bool Sensor2DeviceImpl::getTemperatureReport(TemperatureReport* data) -{ - TemperatureImpl ti; - if (GetInternalDevice()->GetFeatureReport(ti.Buffer, TemperatureImpl::PacketSize)) - { - ti.Unpack(); - *data = ti.Settings; - return true; - } - - return false; -} - bool Sensor2DeviceImpl::GetGyroOffsetReport(GyroOffsetReport* data) { // direct call if we are already on the device manager thread @@ -1125,4 +1113,12 @@ double Sensor2DeviceImpl::OnTicks(double tickSeconds) return NextKeepAliveTickSeconds - tickSeconds; } +/* +// TBD: don't report calibration for now, until we figure out the logic between camera and mag yaw correction +bool Sensor2DeviceImpl::IsMagCalibrated() +{ + return pCalibration->IsMagCalibrated(); +} +*/ + } // namespace OVR diff --git a/LibOVR/Src/OVR_Sensor2Impl.h b/LibOVR/Src/OVR_Sensor2Impl.h index 12da869..4555eed 100644 --- a/LibOVR/Src/OVR_Sensor2Impl.h +++ b/LibOVR/Src/OVR_Sensor2Impl.h @@ -71,7 +71,6 @@ public: virtual bool GetMagCalibrationReport(MagCalibrationReport* data); virtual bool SetPositionCalibrationReport(const PositionCalibrationReport& data); - bool GetPositionCalibrationReport(PositionCalibrationReport* data); virtual bool GetAllPositionCalibrationReports(Array<PositionCalibrationReport>* data); virtual bool SetCustomPatternReport(const CustomPatternReport& data); @@ -87,7 +86,6 @@ public: virtual bool GetUUIDReport(UUIDReport* data); virtual bool SetTemperatureReport(const TemperatureReport& data); - bool GetTemperatureReport(TemperatureReport* data); virtual bool GetAllTemperatureReports(Array<Array<TemperatureReport> >*); virtual bool GetGyroOffsetReport(GyroOffsetReport* data); @@ -111,6 +109,7 @@ protected: bool setPositionCalibrationReport(const PositionCalibrationReport& data); bool getPositionCalibrationReport(PositionCalibrationReport* data); + bool getAllPositionCalibrationReports(Array<PositionCalibrationReport>* data); bool setCustomPatternReport(const CustomPatternReport& data); bool getCustomPatternReport(CustomPatternReport* data); @@ -126,6 +125,7 @@ protected: bool setTemperatureReport(const TemperatureReport& data); bool getTemperatureReport(TemperatureReport* data); + bool getAllTemperatureReports(Array<Array<TemperatureReport> >*); bool getGyroOffsetReport(GyroOffsetReport* data); @@ -146,10 +146,6 @@ protected: UInt32 LastFrameTimestamp; SensorCalibration *pCalibration; - - // This lock is used to protect operations with auto-incrementing indices - // (see TemperatureReport and PositionCalibrationReport) - Lock IndexedReportLock; }; } // namespace OVR diff --git a/LibOVR/Src/OVR_Sensor2ImplUtil.h b/LibOVR/Src/OVR_Sensor2ImplUtil.h index ffe9b6a..91b2195 100644 --- a/LibOVR/Src/OVR_Sensor2ImplUtil.h +++ b/LibOVR/Src/OVR_Sensor2ImplUtil.h @@ -251,7 +251,7 @@ struct PositionCalibrationImpl EncodeSInt16(Buffer+18, (SInt16) normal.y); EncodeSInt16(Buffer+20, (SInt16) normal.z); - double rotation = Settings.Rotation * 1e4; + double rotation = Settings.Angle * 1e4; EncodeSInt16(Buffer+22, (SInt16) rotation); EncodeUInt16(Buffer+24, Settings.PositionIndex); @@ -272,7 +272,7 @@ struct PositionCalibrationImpl Settings.Normal.y = DecodeSInt16(Buffer + 18) * 1e-6; Settings.Normal.z = DecodeSInt16(Buffer + 20) * 1e-6; - Settings.Rotation = DecodeSInt16(Buffer + 22) * 1e-4; + Settings.Angle = DecodeSInt16(Buffer + 22) * 1e-4; Settings.PositionIndex = DecodeUInt16(Buffer + 24); Settings.NumPositions = DecodeUInt16(Buffer + 26); diff --git a/LibOVR/Src/OVR_SensorCalibration.cpp b/LibOVR/Src/OVR_SensorCalibration.cpp index 665898b..94fbb27 100644 --- a/LibOVR/Src/OVR_SensorCalibration.cpp +++ b/LibOVR/Src/OVR_SensorCalibration.cpp @@ -26,6 +26,7 @@ limitations under the License. #include "OVR_SensorCalibration.h" #include "Kernel/OVR_Log.h" +#include "Kernel/OVR_Threads.h" #include <time.h> namespace OVR { @@ -36,7 +37,7 @@ const UByte VERSION = 2; const UByte MAX_COMPAT_VERSION = 15; SensorCalibration::SensorCalibration(SensorDevice* pSensor) - : MagCalibrated(false), GyroAutoTemperature(0), GyroFilter(6000) + : MagCalibrated(false), GyroFilter(6000), GyroAutoTemperature(0) { this->pSensor = pSensor; }; @@ -56,10 +57,10 @@ void SensorCalibration::Initialize() } // read the temperature tables and prepare the interpolation structures - result = pSensor->GetAllTemperatureReports(&temperatureReports); + result = pSensor->GetAllTemperatureReports(&TemperatureReports); OVR_ASSERT(result); for (int i = 0; i < 3; i++) - Interpolators[i].Initialize(temperatureReports, i); + Interpolators[i].Initialize(TemperatureReports, i); // read the mag calibration MagCalibrationReport report; @@ -73,6 +74,66 @@ void SensorCalibration::Initialize() } } +void SensorCalibration::DebugPrintLocalTemperatureTable() +{ + LogText("TemperatureReports:\n"); + for (int i = 0; i < (int)TemperatureReports.GetSize(); i++) + { + for (int j = 0; j < (int)TemperatureReports[i].GetSize(); j++) + { + TemperatureReport& tr = TemperatureReports[i][j]; + + LogText("[%d][%d]: Version=%3d, Bin=%d/%d, " + "Sample=%d/%d, TargetTemp=%3.1lf, " + "ActualTemp=%4.1lf, " + "Offset=(%7.2lf, %7.2lf, %7.2lf), " + "Time=%d\n", i, j, tr.Version, + tr.Bin, tr.NumBins, + tr.Sample, tr.NumSamples, + tr.TargetTemperature, + tr.ActualTemperature, + tr.Offset.x, tr.Offset.y, tr.Offset.z, + tr.Time); + } + } +} + +void SensorCalibration::DebugClearHeadsetTemperatureReports() +{ + OVR_ASSERT(pSensor != NULL); + + bool result; + + Array<Array<TemperatureReport> > temperatureReports; + pSensor->GetAllTemperatureReports(&temperatureReports); + + OVR_ASSERT(temperatureReports.GetSize() > 0); + OVR_ASSERT(temperatureReports[0].GetSize() > 0); + + TemperatureReport& tr = TemperatureReports[0][0]; + + tr.ActualTemperature = 0.0; + tr.Time = 0; + tr.Version = 0; + tr.Offset.x = tr.Offset.y = tr.Offset.z = 0.0; + + for (UByte i = 0; i < tr.NumBins; i++) + { + tr.Bin = i; + + for (UByte j = 0; j < tr.NumSamples; j++) + { + tr.Sample = j; + + result = pSensor->SetTemperatureReport(tr); + OVR_ASSERT(result); + + // Need to wait for the tracker board to finish writing to eeprom. + Thread::MSleep(50); + } + } +} + void SensorCalibration::Apply(MessageBodyFrame& msg) { AutocalibrateGyro(msg); @@ -87,8 +148,6 @@ void SensorCalibration::Apply(MessageBodyFrame& msg) msg.Acceleration = AccelMatrix.Transform(msg.Acceleration - AccelOffset); if (MagCalibrated) msg.MagneticField = MagMatrix.Transform(msg.MagneticField); - // TBD: don't report mag calibration for now, since it is used to enable the yaw correction - msg.MagCalibrated = false; } void SensorCalibration::AutocalibrateGyro(MessageBodyFrame const& msg) @@ -127,26 +186,26 @@ void SensorCalibration::StoreAutoOffset() // find the best bin UPInt binIdx = 0; - for (UPInt i = 1; i < temperatureReports.GetSize(); i++) - if (Abs(GyroAutoTemperature - temperatureReports[i][0].TargetTemperature) < - Abs(GyroAutoTemperature - temperatureReports[binIdx][0].TargetTemperature)) + for (UPInt i = 1; i < TemperatureReports.GetSize(); i++) + if (Abs(GyroAutoTemperature - TemperatureReports[i][0].TargetTemperature) < + Abs(GyroAutoTemperature - TemperatureReports[binIdx][0].TargetTemperature)) binIdx = i; // find the oldest and newest samples // NB: uninitialized samples have Time == 0, so they will get picked as the oldest UPInt newestIdx = 0, oldestIdx = 0; - for (UPInt i = 1; i < temperatureReports[binIdx].GetSize(); i++) + for (UPInt i = 1; i < TemperatureReports[binIdx].GetSize(); i++) { // if the version is newer - do nothing - if (temperatureReports[binIdx][i].Version > VERSION) + if (TemperatureReports[binIdx][i].Version > VERSION) return; - if (temperatureReports[binIdx][i].Time > temperatureReports[binIdx][newestIdx].Time) + if (TemperatureReports[binIdx][i].Time > TemperatureReports[binIdx][newestIdx].Time) newestIdx = i; - if (temperatureReports[binIdx][i].Time < temperatureReports[binIdx][oldestIdx].Time) + if (TemperatureReports[binIdx][i].Time < TemperatureReports[binIdx][oldestIdx].Time) oldestIdx = i; } - TemperatureReport& oldestReport = temperatureReports[binIdx][oldestIdx]; - TemperatureReport& newestReport = temperatureReports[binIdx][newestIdx]; + TemperatureReport& oldestReport = TemperatureReports[binIdx][oldestIdx]; + TemperatureReport& newestReport = TemperatureReports[binIdx][newestIdx]; OVR_ASSERT((oldestReport.Sample == 0 && newestReport.Sample == 0 && newestReport.Version == 0) || oldestReport.Sample == (newestReport.Sample + 1) % newestReport.NumSamples); @@ -185,7 +244,27 @@ void SensorCalibration::StoreAutoOffset() // but if performance is a problem, it's possible to only recompute the data that has changed if (writeSuccess) for (int i = 0; i < 3; i++) - Interpolators[i].Initialize(temperatureReports, i); + Interpolators[i].Initialize(TemperatureReports, i); +} + +const TemperatureReport& median(const Array<TemperatureReport>& temperatureReportsBin, int coord) +{ + Array<double> values; + values.Reserve(temperatureReportsBin.GetSize()); + for (unsigned i = 0; i < temperatureReportsBin.GetSize(); i++) + if (temperatureReportsBin[i].ActualTemperature != 0) + values.PushBack(temperatureReportsBin[i].Offset[coord]); + if (values.GetSize() > 0) + { + double med = Median(values); + // this is kind of a hack + for (unsigned i = 0; i < temperatureReportsBin.GetSize(); i++) + if (temperatureReportsBin[i].Offset[coord] == med) + return temperatureReportsBin[i]; + // if we haven't found the median in the original array, something is wrong + OVR_DEBUG_BREAK; + } + return temperatureReportsBin[0]; } void OffsetInterpolator::Initialize(Array<Array<TemperatureReport> > const& temperatureReports, int coord) @@ -199,8 +278,7 @@ void OffsetInterpolator::Initialize(Array<Array<TemperatureReport> > const& temp for (int bin = 0; bin < bins; bin++) { OVR_ASSERT(temperatureReports[bin].GetSize() == temperatureReports[0].GetSize()); - //const TemperatureReport& report = median(temperatureReports[bin], coord); - const TemperatureReport& report = temperatureReports[bin][0]; + const TemperatureReport& report = median(temperatureReports[bin], coord); if (report.Version > 0 && report.Version <= MAX_COMPAT_VERSION) { Temperatures.PushBack(report.ActualTemperature); diff --git a/LibOVR/Src/OVR_SensorCalibration.h b/LibOVR/Src/OVR_SensorCalibration.h index 2c437b4..62883d2 100644 --- a/LibOVR/Src/OVR_SensorCalibration.h +++ b/LibOVR/Src/OVR_SensorCalibration.h @@ -51,11 +51,16 @@ public: void Initialize(); // Apply the calibration void Apply(MessageBodyFrame& msg); + // Is mag calibration available? + bool IsMagCalibrated() { return MagCalibrated; } protected: void StoreAutoOffset(); void AutocalibrateGyro(MessageBodyFrame const& msg); + void DebugPrintLocalTemperatureTable(); + void DebugClearHeadsetTemperatureReports(); + SensorDevice* pSensor; // Factory calibration data @@ -64,7 +69,7 @@ protected: Vector3f AccelOffset; // Temperature based data - Array<Array<TemperatureReport> > temperatureReports; + Array<Array<TemperatureReport> > TemperatureReports; OffsetInterpolator Interpolators[3]; // Autocalibration data diff --git a/LibOVR/Src/OVR_SensorFilter.h b/LibOVR/Src/OVR_SensorFilter.h index edd4360..0805d57 100644 --- a/LibOVR/Src/OVR_SensorFilter.h +++ b/LibOVR/Src/OVR_SensorFilter.h @@ -253,7 +253,7 @@ private: public: SensorFilterBodyFrame(int capacity = SensorFilterBase<Vector3d>::DefaultCapacity) : SensorFilterBase<Vector3d>(capacity), gain(2.5), - output(), Q(), runningTotalLengthSq(0) { }; + runningTotalLengthSq(0), Q(), output() { }; // return the scalar variance of the filter values (rotated to be in the same frame) double Variance() const diff --git a/LibOVR/Src/OVR_SensorFusion.cpp b/LibOVR/Src/OVR_SensorFusion.cpp index 6cfe00c..5c21178 100644 --- a/LibOVR/Src/OVR_SensorFusion.cpp +++ b/LibOVR/Src/OVR_SensorFusion.cpp @@ -3,7 +3,7 @@ Filename : OVR_SensorFusion.cpp Content : Methods that determine head orientation from sensor data over time Created : October 9, 2012 -Authors : Michael Antonov, Steve LaValle, Dov Katz, Max Katsev +Authors : Michael Antonov, Steve LaValle, Dov Katz, Max Katsev, Dan Gierl Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. @@ -30,28 +30,33 @@ limitations under the License. #include "OVR_JSON.h" #include "OVR_Profile.h" #include "OVR_Stereo.h" -#include "Recording/Recorder.h" +#include "OVR_Recording.h" // Temporary for debugging bool Global_Flag_1 = true; -//Convenient global variable to temporarily extract this data. -float TPH_CameraPoseOrientationWxyz[4]; +//Convenient global variables to temporarily extract this data. +float TPH_CameraPoseOrientationWxyz[4]; +double TPH_CameraPoseConfidence; +double TPH_CameraPoseConfidenceThresholdOverrideIfNonZero = 0; +bool TPH_IsPositionTracked = false; namespace OVR { +const Transformd DefaultWorldFromCamera(Quatd(), Vector3d(0, 0, -1)); + //------------------------------------------------------------------------------------- // ***** Sensor Fusion SensorFusion::SensorFusion(SensorDevice* sensor) - : MotionTrackingEnabled(true), VisionPositionEnabled(true), - EnableGravity(true), EnableYawCorrection(true), MagCalibrated(true), EnableCameraTiltCorrection(true), - FAngV(20), FAccelHeadset(1000), FAccelCamera(1000), - ExposureRecordHistory(100), LastMessageExposureFrame(NULL), - VisionMaxIMUTrackTime(4.0/60.0), // Integrate IMU up to 4 frames - HeadModel(0, OVR_DEFAULT_NECK_TO_EYE_VERTICAL, -OVR_DEFAULT_NECK_TO_EYE_HORIZONTAL), - DefaultCameraPosition(0, 0, -1) + : ExposureRecordHistory(100), LastMessageExposureFrame(NULL), + FocusDirection(Vector3d(0, 0, 0)), FocusFOV(0.0), + FAccelInImuFrame(1000), FAccelInCameraFrame(1000), FAngV(20), + EnableGravity(true), EnableYawCorrection(true), MagCalibrated(false), + EnableCameraTiltCorrection(true), + MotionTrackingEnabled(true), VisionPositionEnabled(true), + CenterPupilDepth(0.0) { pHandler = new BodyFrameHandler(this); @@ -61,9 +66,6 @@ SensorFusion::SensorFusion(SensorDevice* sensor) if (sensor) AttachToSensor(sensor); - // MA: 1/25/2014 for DK2 - SetCenterPupilDepth(0.076f); - Reset(); } @@ -74,50 +76,47 @@ SensorFusion::~SensorFusion() bool SensorFusion::AttachToSensor(SensorDevice* sensor) { + pHandler->RemoveHandlerFromDevices(); + Reset(); + if (sensor != NULL) { + // cache mag calibration state + MagCalibrated = sensor->IsMagCalibrated(); + // Load IMU position Array<PositionCalibrationReport> reports; - bool result = sensor->GetAllPositionCalibrationReports(&reports); - if(result) + if (result) { - PositionCalibrationReport const& imu = reports[reports.GetSize() - 1]; + PositionCalibrationReport imu = reports[reports.GetSize() - 1]; OVR_ASSERT(imu.PositionType == PositionCalibrationReport::PositionType_IMU); - IMUPosition = imu.Position; + // convert from vision to the world frame + // TBD convert rotation as necessary? + imu.Position.x *= -1.0; + imu.Position.z *= -1.0; - Recorder::Buffer(imu); - Recorder::Buffer(reports); + ImuFromScreen = Transformd(Quatd(imu.Normal, imu.Angle), imu.Position).Inverted(); - // convert from vision to the world frame - IMUPosition.x *= -1.0; - IMUPosition.z *= -1.0; + Recording::GetRecorder().RecordLedPositions(reports); + Recording::GetRecorder().RecordDeviceIfcVersion(sensor->GetDeviceInterfaceVersion()); } - else - { - // TODO: set up IMUPosition for devices that don't have this report. - } + // Repopulate CPFOrigin SetCenterPupilDepth(CenterPupilDepth); - } - pHandler->RemoveHandlerFromDevices(); - - if (sensor != NULL) - { + // Subscribe to sensor updates sensor->AddMessageHandler(pHandler); - } - - Reset(); - // Initialize the sensor state - // TBD: This is a hack to avoid a race condition if sensor status is checked immediately - // after sensor creation but before any data has flowed through. We should probably - // not depend strictly on data flow to determine capabilites like orientation and position - // tracking, or else use some sort of synchronous method to wait for data - LocklessState init; - init.StatusFlags = Status_OrientationTracked; - UpdatedState.SetState(init); + // Initialize the sensor state + // TBD: This is a hack to avoid a race condition if sensor status is checked immediately + // after sensor creation but before any data has flowed through. We should probably + // not depend strictly on data flow to determine capabilities like orientation and position + // tracking, or else use some sort of synchronous method to wait for data + LocklessState init; + init.StatusFlags = Status_OrientationTracked; + UpdatedState.SetState(init); + } return true; } @@ -128,31 +127,29 @@ void SensorFusion::Reset() Lock::Locker lockScope(pHandler->GetHandlerLock()); UpdatedState.SetState(LocklessState()); - State = PoseState<double>(); - State.Transform.Position = -CPFPositionInIMUFrame; // place CPF at the origin, not the IMU - VisionState = PoseState<double>(); + WorldFromImu = PoseState<double>(); + WorldFromImu.Pose = ImuFromCpf.Inverted(); // place CPF at the origin, not the IMU + CameraFromImu = PoseState<double>(); VisionError = PoseState<double>(); - CurrentExposureIMUDelta = PoseState<double>(); - CameraPose = Pose<double>(Quatd(), DefaultCameraPosition); - CameraPoseConfidence = -1; + WorldFromCamera = DefaultWorldFromCamera; + WorldFromCameraConfidence = -1; ExposureRecordHistory.Clear(); + NextExposureRecord = ExposureRecord(); LastMessageExposureFrame = MessageExposureFrame(NULL); LastVisionAbsoluteTime = 0; - FullVisionCorrectionExposureCounter = 0; Stage = 0; - MagNumReferences = 0; + MagRefs.Clear(); MagRefIdx = -1; - MagRefScore = 0; MagCorrectionIntegralTerm = Quatd(); AccelOffset = Vector3d(); - FAccelCamera.Clear(); - FAccelHeadset.Clear(); + FAccelInCameraFrame.Clear(); + FAccelInImuFrame.Clear(); FAngV.Clear(); - setNeckPivotFromPose ( State.Transform ); + setNeckPivotFromPose ( WorldFromImu.Pose ); } //------------------------------------------------------------------------------------- @@ -161,20 +158,23 @@ void SensorFusion::Reset() void SensorFusion::OnVisionFailure() { // do nothing + Recording::GetRecorder().RecordVisionSuccess(false); } -void SensorFusion::OnVisionPreviousFrame(const Pose<double>& pose) +void SensorFusion::OnVisionPreviousFrame(const Transform<double>& cameraFromImu) { // simply save the observation for use in the next OnVisionSuccess call; // this should not have unintended side-effects for position filtering, // since the vision time is not updated and the system keeps thinking we don't have vision yet - VisionState.Transform = pose; + CameraFromImu.Pose = cameraFromImu; } -void SensorFusion::OnVisionSuccess(const Pose<double>& pose, UInt32 exposureCounter) +void SensorFusion::OnVisionSuccess(const Transform<double>& cameraFromImu, UInt32 exposureCounter) { Lock::Locker lockScope(pHandler->GetHandlerLock()); + Recording::GetRecorder().RecordVisionSuccess(true); + LastVisionAbsoluteTime = GetTime(); // ********* LastVisionExposureRecord ********* @@ -190,49 +190,54 @@ void SensorFusion::OnVisionSuccess(const Pose<double>& pose, UInt32 exposureCoun // Right now, this will happen if we get first frame after prediction failure, // and this exposure wasn't in the buffer. (TBD: Unlikely.. unless IMU message wasn't sent?) if (LastVisionExposureRecord.ExposureCounter != exposureCounter) - LastVisionExposureRecord = ExposureRecord(exposureCounter, GetTime(), State, PoseState<double>()); + LastVisionExposureRecord = ExposureRecord(exposureCounter, GetTime(), WorldFromImu, PoseState<double>()); - // ********* VisionState ********* + // ********* CameraFromImu ********* // This is stored in the camera frame, so need to be careful when combining with the IMU data, // which is in the world frame - // convert to the world frame - Vector3d positionChangeW = CameraPose.Orientation.Rotate(pose.Position - VisionState.Transform.Position); - - VisionState.TimeInSeconds = LastVisionExposureRecord.ExposureTime; - VisionState.Transform = pose; + Transformd cameraFromImuPrev = CameraFromImu.Pose; + CameraFromImu.Pose = cameraFromImu; + CameraFromImu.TimeInSeconds = LastVisionExposureRecord.ExposureTime; // Check LastVisionExposureRecord.Delta.TimeInSeconds to avoid divide by zero, which we could (rarely) // get if we didn't have exposures delta for history (skipped exposure counters // due to video mode change that stalls USB, etc). - if (LastVisionExposureRecord.Delta.TimeInSeconds > 0.001) + if (LastVisionExposureRecord.ImuOnlyDelta.TimeInSeconds > 0.001) { + Vector3d visionVelocityInImuFrame = (cameraFromImu.Translation - cameraFromImuPrev.Translation) / + LastVisionExposureRecord.ImuOnlyDelta.TimeInSeconds; // Use the accel data to estimate the velocity at the exposure time // (as opposed to the average velocity between exposures) - Vector3d velocityW = LastVisionExposureRecord.Delta.LinearVelocity + - (positionChangeW - LastVisionExposureRecord.Delta.Transform.Position) / - LastVisionExposureRecord.Delta.TimeInSeconds; - VisionState.LinearVelocity = CameraPose.Orientation.Inverted().Rotate(velocityW); + Vector3d imuVelocityInWorldFrame = LastVisionExposureRecord.ImuOnlyDelta.LinearVelocity - + LastVisionExposureRecord.ImuOnlyDelta.Pose.Translation / LastVisionExposureRecord.ImuOnlyDelta.TimeInSeconds; + CameraFromImu.LinearVelocity = visionVelocityInImuFrame + + WorldFromCamera.Inverted().Rotate(imuVelocityInWorldFrame); } else { - VisionState.LinearVelocity = Vector3d(0,0,0); - } - - // ********* VisionError ********* - - // This is in the world frame, so transform the vision data appropriately + CameraFromImu.LinearVelocity = Vector3d(0,0,0); + } +} - VisionError.Transform.Position = CameraPose.Orientation.Rotate(VisionState.Transform.Position) + CameraPose.Position - - LastVisionExposureRecord.State.Transform.Position; - VisionError.LinearVelocity = CameraPose.Orientation.Rotate(VisionState.LinearVelocity) - - LastVisionExposureRecord.State.LinearVelocity; - VisionError.Transform.Orientation = CameraPose.Orientation * VisionState.Transform.Orientation * - LastVisionExposureRecord.State.Transform.Orientation.Inverted(); +PoseStated SensorFusion::computeVisionError() +{ + PoseStated worldFromImuVision = WorldFromCamera * CameraFromImu; + // Here we need to compute the difference between worldFromImuVision and WorldFromImu. + // However this difference needs to be represented in the World frame, not IMU frame. + // Therefore the computation is different from simply worldFromImuVision.Pose * WorldFromImu.Pose.Inverted(). + PoseStated err; + err.Pose.Rotation = worldFromImuVision.Pose.Rotation * + LastVisionExposureRecord.WorldFromImu.Pose.Rotation.Inverted(); + err.Pose.Translation = worldFromImuVision.Pose.Translation - + LastVisionExposureRecord.WorldFromImu.Pose.Translation; + err.LinearVelocity = worldFromImuVision.LinearVelocity - + LastVisionExposureRecord.WorldFromImu.LinearVelocity; + return err; } -Pose<double> SensorFusion::GetVisionPrediction(UInt32 exposureCounter) +Transform<double> SensorFusion::GetVisionPrediction(UInt32 exposureCounter) { Lock::Locker lockScope(pHandler->GetHandlerLock()); @@ -240,23 +245,41 @@ Pose<double> SensorFusion::GetVisionPrediction(UInt32 exposureCounter) // Should only be one iteration, unless we are skipping camera frames ExposureRecord record; PoseState<double> delta = PoseState<double>(); + while (!ExposureRecordHistory.IsEmpty() && (ExposureRecordHistory.PeekFront().ExposureCounter <= exposureCounter)) { record = ExposureRecordHistory.PopFront(); - delta.AdvanceByDelta(record.Delta); + delta.AdvanceByDelta(record.ImuOnlyDelta); } // Put the combine exposure record back in the history, for use in HandleVisionSuccess(...) - record.Delta = delta; + record.ImuOnlyDelta = delta; ExposureRecordHistory.PushFront(record); - // Add the effect of initial pose and velocity from vision. - // Don't forget to transform IMU to the camera frame - Pose<double> c(VisionState.Transform.Orientation * delta.Transform.Orientation, - VisionState.Transform.Position + VisionState.LinearVelocity * delta.TimeInSeconds + - CameraPose.Orientation.Inverted().Rotate(delta.Transform.Position)); + Transformd result; + if (record.VisionTrackingAvailable) + { + // if the tracking is working normally, use the change in the main state (SFusion output) + // to compute the prediction + result = CameraFromImu.Pose * + LastVisionExposureRecord.WorldFromImu.Pose.Inverted() * record.WorldFromImu.Pose; + } + else + { + // if we just acquired vision, the main state probably doesn't have the correct position, + // so can't rely on it for prediction + + // solution: use the accelerometer and vision velocity to propagate the previous sample forward + // (don't forget to transform IMU to the camera frame) + result = Transform<double> + ( + CameraFromImu.Pose.Rotation * delta.Pose.Rotation, + CameraFromImu.Pose.Translation + CameraFromImu.LinearVelocity * delta.TimeInSeconds + + WorldFromCamera.Inverted().Rotate(delta.Pose.Translation) + ); + } - return c; + return result; } void SensorFusion::handleMessage(const MessageBodyFrame& msg) @@ -269,24 +292,26 @@ void SensorFusion::handleMessage(const MessageBodyFrame& msg) Vector3d accel(msg.Acceleration); Vector3d mag(msg.MagneticField); double DeltaT = msg.TimeDelta; - MagCalibrated = msg.MagCalibrated; // Keep track of time - State.TimeInSeconds = msg.AbsoluteTimeSeconds; + WorldFromImu.TimeInSeconds = msg.AbsoluteTimeSeconds; // We got an update in the last 60ms and the data is not very old - bool visionIsRecent = (GetTime() - LastVisionAbsoluteTime < VisionMaxIMUTrackTime) && (GetVisionLatency() < 0.25); + bool visionIsRecent = (GetTime() - LastVisionAbsoluteTime < 0.07) && (GetVisionLatency() < 0.25); Stage++; // Insert current sensor data into filter history FAngV.PushBack(gyro); - FAccelHeadset.Update(accel, DeltaT, Quatd(gyro, gyro.Length() * DeltaT)); + FAccelInImuFrame.Update(accel, DeltaT, Quatd(gyro, gyro.Length() * DeltaT)); // Process raw inputs // in the future the gravity offset can be calibrated using vision feedback - Vector3d accelW = State.Transform.Orientation.Rotate(accel) - Vector3d(0, 9.8, 0); + Vector3d accelInWorldFrame = WorldFromImu.Pose.Rotate(accel) - Vector3d(0, 9.8, 0); + + // Recompute the vision error to account for all the corrections and the new data + VisionError = computeVisionError(); // Update headset orientation - State.StoreAndIntegrateGyro(gyro, DeltaT); + WorldFromImu.StoreAndIntegrateGyro(gyro, DeltaT); // Tilt correction based on accelerometer if (EnableGravity) applyTiltCorrection(DeltaT); @@ -296,6 +321,9 @@ void SensorFusion::handleMessage(const MessageBodyFrame& msg) // Yaw correction based on magnetometer if (EnableYawCorrection && MagCalibrated) // MagCalibrated is always false for DK2 for now applyMagYawCorrection(mag, DeltaT); + // Focus Correction + if ((FocusDirection.x != 0.0f || FocusDirection.z != 0.0f) && FocusFOV < Mathf::Pi) + applyFocusCorrection(DeltaT); // Update camera orientation if (EnableCameraTiltCorrection && visionIsRecent) @@ -305,49 +333,50 @@ void SensorFusion::handleMessage(const MessageBodyFrame& msg) // so it is periodically normalized. if ((Stage & 0xFF) == 0) { - State.Transform.Orientation.Normalize(); - CameraPose.Orientation.Normalize(); + WorldFromImu.Pose.Rotation.Normalize(); + WorldFromCamera.Rotation.Normalize(); } // Update headset position if (VisionPositionEnabled && visionIsRecent) { // Integrate UMI and velocity here up to a fixed amount of time after vision. - State.StoreAndIntegrateAccelerometer(accelW + AccelOffset, DeltaT); + WorldFromImu.StoreAndIntegrateAccelerometer(accelInWorldFrame + AccelOffset, DeltaT); // Position correction based on camera applyPositionCorrection(DeltaT); // Compute where the neck pivot would be. - setNeckPivotFromPose(State.Transform); + setNeckPivotFromPose(WorldFromImu.Pose); } else { // Fall back onto internal head model // Use the last-known neck pivot position to figure out the expected IMU position. // (should be the opposite of SensorFusion::setNeckPivotFromPose) - Vector3d imuInNeckPivotFrame = HeadModel - CPFPositionInIMUFrame; - State.Transform.Position = NeckPivotPosition + State.Transform.Orientation.Rotate(imuInNeckPivotFrame); + WorldFromNeck.Rotation = WorldFromImu.Pose.Rotation; + WorldFromImu.Pose = WorldFromNeck * (ImuFromCpf * CpfFromNeck).Inverted(); // We can't trust velocity past this point. - State.LinearVelocity = Vector3d(0,0,0); - State.LinearAcceleration = accelW; + WorldFromImu.LinearVelocity = Vector3d(0,0,0); + WorldFromImu.LinearAcceleration = accelInWorldFrame; } // Compute the angular acceleration - State.AngularAcceleration = (FAngV.GetSize() >= 12 && DeltaT > 0) ? + WorldFromImu.AngularAcceleration = (FAngV.GetSize() >= 12 && DeltaT > 0) ? (FAngV.SavitzkyGolayDerivative12() / DeltaT) : Vector3d(); // Update the dead reckoning state used for incremental vision tracking - CurrentExposureIMUDelta.StoreAndIntegrateGyro(gyro, DeltaT); - CurrentExposureIMUDelta.StoreAndIntegrateAccelerometer(accelW, DeltaT); - - // If we only compiled the stub version of Recorder, then branch prediction shouldn't - // have any problem with this if statement. Actually, it should be optimized out, but need to verify. - if(Recorder::GetRecorder()) - { - Posed savePose = static_cast<Posed>(GetPoseAtTime(GetTime())); - Recorder::LogData("sfTimeSeconds", State.TimeInSeconds); - Recorder::LogData("sfPose", savePose); - } + NextExposureRecord.ImuOnlyDelta.StoreAndIntegrateGyro(gyro, DeltaT); + NextExposureRecord.ImuOnlyDelta.StoreAndIntegrateAccelerometer(accelInWorldFrame, DeltaT); + NextExposureRecord.ImuOnlyDelta.TimeInSeconds = WorldFromImu.TimeInSeconds - LastMessageExposureFrame.CameraTimeSeconds; + NextExposureRecord.VisionTrackingAvailable &= (VisionPositionEnabled && visionIsRecent); + + Recording::GetRecorder().LogData("sfTimeSeconds", WorldFromImu.TimeInSeconds); + Recording::GetRecorder().LogData("sfStage", (double)Stage); + Recording::GetRecorder().LogData("sfPose", WorldFromImu.Pose); + //Recorder::LogData("sfAngAcc", State.AngularAcceleration); + //Recorder::LogData("sfAngVel", State.AngularVelocity); + //Recorder::LogData("sfLinAcc", State.LinearAcceleration); + //Recorder::LogData("sfLinVel", State.LinearVelocity); // Store the lockless state. LocklessState lstate; @@ -356,7 +385,11 @@ void SensorFusion::handleMessage(const MessageBodyFrame& msg) lstate.StatusFlags |= Status_PositionConnected; if (VisionPositionEnabled && visionIsRecent) lstate.StatusFlags |= Status_PositionTracked; - lstate.State = State; + + //A convenient means to temporarily extract this flag + TPH_IsPositionTracked = visionIsRecent; + + lstate.State = WorldFromImu; lstate.Temperature = msg.Temperature; lstate.Magnetometer = mag; UpdatedState.SetState(lstate); @@ -364,44 +397,21 @@ void SensorFusion::handleMessage(const MessageBodyFrame& msg) void SensorFusion::handleExposure(const MessageExposureFrame& msg) { - if (msg.CameraFrameCount > LastMessageExposureFrame.CameraFrameCount + 1) - { - LogText("Skipped %d tracker exposure counters\n", - msg.CameraFrameCount - (LastMessageExposureFrame.CameraFrameCount + 1)); - } - else - { - // MA: Check timing deltas - // Is seems repetitive tracking loss occurs when timing gets out of sync - // Could be caused by some bug in HW timing + time filter? - if (fabs(State.TimeInSeconds - msg.CameraTimeSeconds) > 0.1f) - { - static int logLimiter = 0; - if ((logLimiter & 0x3F) == 0) - { - LogText("Timing out of sync: State.T=%f, ExposureT=%f, delta=%f, Time()=%f\n", - State.TimeInSeconds, msg.CameraTimeSeconds, - State.TimeInSeconds - msg.CameraTimeSeconds, GetTime()); - } - logLimiter++; - } - - } - - CurrentExposureIMUDelta.TimeInSeconds = msg.CameraTimeSeconds - LastMessageExposureFrame.CameraTimeSeconds; - ExposureRecordHistory.PushBack(ExposureRecord( - msg.CameraFrameCount, msg.CameraTimeSeconds, State, CurrentExposureIMUDelta)); + NextExposureRecord.ExposureCounter = msg.CameraFrameCount; + NextExposureRecord.ExposureTime = msg.CameraTimeSeconds; + NextExposureRecord.WorldFromImu = WorldFromImu; + NextExposureRecord.ImuOnlyDelta.TimeInSeconds = msg.CameraTimeSeconds - LastMessageExposureFrame.CameraTimeSeconds; + ExposureRecordHistory.PushBack(NextExposureRecord); // Every new exposure starts from zero - CurrentExposureIMUDelta = PoseState<double>(); + NextExposureRecord = ExposureRecord(); LastMessageExposureFrame = msg; } // If you have a known-good pose, this sets the neck pivot position. -void SensorFusion::setNeckPivotFromPose(Posed const &pose) +void SensorFusion::setNeckPivotFromPose(Transformd const &worldFromImu) { - Vector3d imuInNeckPivotFrame = HeadModel - CPFPositionInIMUFrame; - NeckPivotPosition = pose.Position - pose.Orientation.Rotate(imuInNeckPivotFrame); + WorldFromNeck = worldFromImu * ImuFromCpf * CpfFromNeck; } // These two functions need to be moved into Quat class @@ -430,27 +440,45 @@ void SensorFusion::applyPositionCorrection(double deltaT) { // Each component of gainPos is equivalent to a Kalman gain of (sigma_process / sigma_observation) const Vector3d gainPos = Vector3d(10, 10, 8); - const Vector3d gainVel = gainPos.EntrywiseMultiply(gainPos) * 0.5; + const Vector3d gainVel = gainPos.EntrywiseMultiply(gainPos) * 0.5; + const Vector3d gainAccel = gainVel * 0.5; const double snapThreshold = 0.1; // Large value (previously 0.01, which caused frequent jumping) - if (LastVisionExposureRecord.ExposureCounter <= FullVisionCorrectionExposureCounter) - return; - - if (VisionError.Transform.Position.LengthSq() > (snapThreshold * snapThreshold) || + Vector3d correctionPos, correctionVel; + if (VisionError.Pose.Translation.LengthSq() > (snapThreshold * snapThreshold) || !(UpdatedState.GetState().StatusFlags & Status_PositionTracked)) { // high error or just reacquired position from vision - apply full correction - State.Transform.Position += VisionError.Transform.Position; - State.LinearVelocity += VisionError.LinearVelocity; - // record the frame counter to avoid additional correction until we see the new data - FullVisionCorrectionExposureCounter = LastMessageExposureFrame.CameraFrameCount; + + // to know where we are right now, take the vision pose (which is slightly old) + // and update it using the imu data since then + PoseStated worldFromImuVision = WorldFromCamera * CameraFromImu; + for (unsigned int i = 0; i < ExposureRecordHistory.GetSize(); i++) + worldFromImuVision.AdvanceByDelta(ExposureRecordHistory.PeekFront(i).ImuOnlyDelta); + worldFromImuVision.AdvanceByDelta(NextExposureRecord.ImuOnlyDelta); + + correctionPos = worldFromImuVision.Pose.Translation - WorldFromImu.Pose.Translation; + correctionVel = worldFromImuVision.LinearVelocity - WorldFromImu.LinearVelocity; + AccelOffset = Vector3d(); } else { - State.Transform.Position += VisionError.Transform.Position.EntrywiseMultiply(gainPos) * deltaT; - State.LinearVelocity += VisionError.Transform.Position.EntrywiseMultiply(gainVel) * deltaT; - // Uncomment the line below to try acclerometer bias estimation in filter - //AccelOffset += VisionError.Pose.Position * gainAccel * deltaT; + correctionPos = VisionError.Pose.Translation.EntrywiseMultiply(gainPos) * deltaT; + correctionVel = VisionError.Pose.Translation.EntrywiseMultiply(gainVel) * deltaT; + AccelOffset += VisionError.Pose.Translation.EntrywiseMultiply(gainAccel) * deltaT; + } + + WorldFromImu.Pose.Translation += correctionPos; + WorldFromImu.LinearVelocity += correctionVel; + + // Update the exposure records so that we don't apply the same correction twice + LastVisionExposureRecord.WorldFromImu.Pose.Translation += correctionPos; + LastVisionExposureRecord.WorldFromImu.LinearVelocity += correctionVel; + for (unsigned int i = 0; i < ExposureRecordHistory.GetSize(); i++) + { + PoseStated& state = ExposureRecordHistory.PeekBack(i).WorldFromImu; + state.Pose.Translation += correctionPos; + state.LinearVelocity += correctionVel; } } @@ -459,23 +487,24 @@ void SensorFusion::applyVisionYawCorrection(double deltaT) const double gain = 0.25; const double snapThreshold = 0.1; - if (LastVisionExposureRecord.ExposureCounter <= FullVisionCorrectionExposureCounter) - return; - - Quatd yawError = extractYawRotation(VisionError.Transform.Orientation); + Quatd yawError = extractYawRotation(VisionError.Pose.Rotation); Quatd correction; if (Alg::Abs(yawError.w) < cos(snapThreshold / 2)) // angle(yawError) > snapThreshold - { // high error, jump to the vision position correction = yawError; - // record the frame counter to avoid additional correction until we see the new data - FullVisionCorrectionExposureCounter = LastMessageExposureFrame.CameraFrameCount; - } else correction = yawError.Nlerp(Quatd(), gain * deltaT); - State.Transform.Orientation = correction * State.Transform.Orientation; + WorldFromImu.Pose.Rotation = correction * WorldFromImu.Pose.Rotation; + + // Update the exposure records so that we don't apply the same correction twice + LastVisionExposureRecord.WorldFromImu.Pose.Rotation = correction * LastVisionExposureRecord.WorldFromImu.Pose.Rotation; + for (unsigned int i = 0; i < ExposureRecordHistory.GetSize(); i++) + { + PoseStated& state = ExposureRecordHistory.PeekBack(i).WorldFromImu; + state.Pose.Rotation = correction * state.Pose.Rotation; + } } void SensorFusion::applyMagYawCorrection(Vector3d mag, double deltaT) @@ -486,74 +515,69 @@ void SensorFusion::applyMagYawCorrection(Vector3d mag, double deltaT) const double proportionalGain = 0.01; const double integralGain = 0.0005; - Vector3d magW = State.Transform.Orientation.Rotate(mag); + Vector3d magInWorldFrame = WorldFromImu.Pose.Rotate(mag); // verify that the horizontal component is sufficient - if (magW.x * magW.x + magW.z * magW.z < minMagLengthSq) + if (magInWorldFrame.x * magInWorldFrame.x + magInWorldFrame.z * magInWorldFrame.z < minMagLengthSq) return; - magW.Normalize(); + magInWorldFrame.Normalize(); + + // Delete a bad point + if (MagRefIdx >= 0 && MagRefs[MagRefIdx].Score < 0) + { + MagRefs.RemoveAtUnordered(MagRefIdx); + MagRefIdx = -1; + } // Update the reference point if needed - if (MagRefScore < 0 || MagRefIdx < 0 || - mag.Distance(MagRefsInBodyFrame[MagRefIdx]) > maxMagRefDist) + if (MagRefIdx < 0 || mag.Distance(MagRefs[MagRefIdx].InImuFrame) > maxMagRefDist) { - // Delete a bad point - if (MagRefIdx >= 0 && MagRefScore < 0) - { - MagNumReferences--; - MagRefsInBodyFrame[MagRefIdx] = MagRefsInBodyFrame[MagNumReferences]; - MagRefsInWorldFrame[MagRefIdx] = MagRefsInWorldFrame[MagNumReferences]; - MagRefsPoses[MagRefIdx] = MagRefsPoses[MagRefIdx]; - } // Find a new one MagRefIdx = -1; - MagRefScore = 1000; double bestDist = maxMagRefDist; - for (int i = 0; i < MagNumReferences; i++) + for (unsigned int i = 0; i < MagRefs.GetSize(); i++) { - double dist = mag.Distance(MagRefsInBodyFrame[i]); + double dist = mag.Distance(MagRefs[i].InImuFrame); if (bestDist > dist) { bestDist = dist; MagRefIdx = i; } } + // Create one if needed - if (MagRefIdx < 0 && MagNumReferences < MagMaxReferences) - { - MagRefIdx = MagNumReferences; - MagRefsInBodyFrame[MagRefIdx] = mag; - MagRefsInWorldFrame[MagRefIdx] = magW; - MagRefsPoses[MagRefIdx] = State.Transform.Orientation; - MagNumReferences++; - } + if (MagRefIdx < 0 && MagRefs.GetSize() < MagMaxReferences) + { + MagRefs.PushBack(MagReferencePoint(mag, WorldFromImu.Pose, 1000)); + } } if (MagRefIdx >= 0) { - Vector3d magRefW = MagRefsInWorldFrame[MagRefIdx]; + Vector3d magRefInWorldFrame = MagRefs[MagRefIdx].WorldFromImu.Rotate(MagRefs[MagRefIdx].InImuFrame); + magRefInWorldFrame.Normalize(); // If the vertical angle is wrong, decrease the score and do nothing - if (Alg::Abs(magRefW.y - magW.y) > maxTiltError) + if (Alg::Abs(magRefInWorldFrame.y - magInWorldFrame.y) > maxTiltError) { - MagRefScore -= 1; + MagRefs[MagRefIdx].Score -= 1; return; } - MagRefScore += 2; + MagRefs[MagRefIdx].Score += 2; #if 0 // this doesn't seem to work properly, need to investigate Quatd error = vectorAlignmentRotation(magW, magRefW); Quatd yawError = extractYawRotation(error); #else // Correction is computed in the horizontal plane - magW.y = magRefW.y = 0; - Quatd yawError = vectorAlignmentRotation(magW, magRefW); + magInWorldFrame.y = magRefInWorldFrame.y = 0; + Quatd yawError = vectorAlignmentRotation(magInWorldFrame, magRefInWorldFrame); #endif Quatd correction = yawError.Nlerp(Quatd(), proportionalGain * deltaT) * MagCorrectionIntegralTerm.Nlerp(Quatd(), deltaT); MagCorrectionIntegralTerm = MagCorrectionIntegralTerm * yawError.Nlerp(Quatd(), integralGain * deltaT); - State.Transform.Orientation = correction * State.Transform.Orientation; + WorldFromImu.Pose.Rotation = correction * WorldFromImu.Pose.Rotation; } } @@ -563,22 +587,22 @@ void SensorFusion::applyTiltCorrection(double deltaT) const double snapThreshold = 0.1; const Vector3d up(0, 1, 0); - Vector3d accelW = State.Transform.Orientation.Rotate(FAccelHeadset.GetFilteredValue()); - Quatd error = vectorAlignmentRotation(accelW, up); + Vector3d accelInWorldFrame = WorldFromImu.Pose.Rotate(FAccelInImuFrame.GetFilteredValue()); + Quatd error = vectorAlignmentRotation(accelInWorldFrame, up); Quatd correction; - if (FAccelHeadset.GetSize() == 1 || - ((Alg::Abs(error.w) < cos(snapThreshold / 2) && FAccelHeadset.Confidence() > 0.75))) + if (FAccelInImuFrame.GetSize() == 1 || + ((Alg::Abs(error.w) < cos(snapThreshold / 2) && FAccelInImuFrame.Confidence() > 0.75))) // full correction for start-up // or large error with high confidence correction = error; - else if (FAccelHeadset.Confidence() > 0.5) + else if (FAccelInImuFrame.Confidence() > 0.5) correction = error.Nlerp(Quatd(), gain * deltaT); else // accelerometer is unreliable due to movement return; - State.Transform.Orientation = correction * State.Transform.Orientation; + WorldFromImu.Pose.Rotation = correction * WorldFromImu.Pose.Rotation; } void SensorFusion::applyCameraTiltCorrection(Vector3d accel, double deltaT) @@ -587,49 +611,50 @@ void SensorFusion::applyCameraTiltCorrection(Vector3d accel, double deltaT) const double maxCameraPositionOffset = 0.2; const Vector3d up(0, 1, 0), forward(0, 0, -1); - if (LastVisionExposureRecord.ExposureCounter <= FullVisionCorrectionExposureCounter) - return; - // for startup use filtered value instead of instantaneous for stability - if (FAccelCamera.IsEmpty()) - accel = FAccelHeadset.GetFilteredValue(); + if (FAccelInCameraFrame.IsEmpty()) + accel = FAccelInImuFrame.GetFilteredValue(); - Quatd headsetToCamera = CameraPose.Orientation.Inverted() * VisionError.Transform.Orientation * State.Transform.Orientation; + Transformd cameraFromImu = WorldFromCamera.Inverted() * VisionError.Pose * WorldFromImu.Pose; // this is what the hypothetical camera-mounted accelerometer would show - Vector3d accelCamera = headsetToCamera.Rotate(accel); - FAccelCamera.Update(accelCamera, deltaT); - Vector3d accelCameraW = CameraPose.Orientation.Rotate(FAccelCamera.GetFilteredValue()); + Vector3d accelInCameraFrame = cameraFromImu.Rotate(accel); + FAccelInCameraFrame.Update(accelInCameraFrame, deltaT); + Vector3d cameraAccelInWorldFrame = WorldFromCamera.Rotate(FAccelInCameraFrame.GetFilteredValue()); - Quatd error1 = vectorAlignmentRotation(accelCameraW, up); + Quatd error1 = vectorAlignmentRotation(cameraAccelInWorldFrame, up); // cancel out yaw rotation - Vector3d forwardCamera = (error1 * CameraPose.Orientation).Rotate(forward); + Vector3d forwardCamera = (error1 * WorldFromCamera.Rotation).Rotate(forward); forwardCamera.y = 0; Quatd error2 = vectorAlignmentRotation(forwardCamera, forward); // combined error Quatd error = error2 * error1; - double confidence = FAccelCamera.Confidence(); + double confidence = FAccelInCameraFrame.Confidence(); // penalize the confidence if looking away from the camera // TODO: smooth fall-off - if (VisionState.Transform.Orientation.Rotate(forward).Angle(forward) > 1) + if (CameraFromImu.Pose.Rotate(forward).Angle(forward) > 1) confidence *= 0.5; + //Convenient global variable to temporarily extract this data. + TPH_CameraPoseConfidence = confidence; + //Allow override of confidence threshold + double confidenceThreshold = 0.75f; + if (TPH_CameraPoseConfidenceThresholdOverrideIfNonZero) + { + confidenceThreshold = TPH_CameraPoseConfidenceThresholdOverrideIfNonZero; + } + Quatd correction; - if (FAccelCamera.GetSize() == 1 || - confidence > CameraPoseConfidence + 0.2 || + if (FAccelInCameraFrame.GetSize() == 1 || + confidence > WorldFromCameraConfidence + 0.2 || // disabled due to false positives when moving side to side // (Alg::Abs(error.w) < cos(5 * snapThreshold / 2) && confidence > 0.55) || - (Alg::Abs(error.w) < cos(snapThreshold / 2) && confidence > 0.75)) + (Alg::Abs(error.w) < cos(snapThreshold / 2) && confidence > confidenceThreshold)) { // large error with high confidence correction = error; // update the confidence level - CameraPoseConfidence = confidence; - // record the frame counter to avoid additional correction until we see the new data - FullVisionCorrectionExposureCounter = LastMessageExposureFrame.CameraFrameCount; - - LogText("adjust camera tilt confidence %f angle %f\n", - CameraPoseConfidence, RadToDegree(correction.Angle(Quatd()))); + WorldFromCameraConfidence = confidence; } else { @@ -637,49 +662,104 @@ void SensorFusion::applyCameraTiltCorrection(Vector3d accel, double deltaT) return; } - Quatd newOrientation = correction * CameraPose.Orientation; + Transformd newWorldFromCamera(correction * WorldFromCamera.Rotation, Vector3d()); + // compute a camera position change that together with the camera rotation would result in zero player movement - Vector3d newPosition = CameraPose.Orientation.Rotate(VisionState.Transform.Position) + CameraPose.Position - - newOrientation.Rotate(VisionState.Transform.Position); + newWorldFromCamera.Translation += (WorldFromCamera * CameraFromImu.Pose).Translation - + (newWorldFromCamera * CameraFromImu.Pose).Translation; // if the new position is too far, reset to default // (can't hide the rotation, might as well use it to reset the position) - if (newPosition.DistanceSq(DefaultCameraPosition) > maxCameraPositionOffset * maxCameraPositionOffset) - newPosition = DefaultCameraPosition; + if (newWorldFromCamera.Translation.DistanceSq(DefaultWorldFromCamera.Translation) > maxCameraPositionOffset * maxCameraPositionOffset) + newWorldFromCamera.Translation = DefaultWorldFromCamera.Translation; - CameraPose.Orientation = newOrientation; - CameraPose.Position = newPosition; + WorldFromCamera = newWorldFromCamera; //Convenient global variable to temporarily extract this data. - TPH_CameraPoseOrientationWxyz[0] = (float) newOrientation.w; - TPH_CameraPoseOrientationWxyz[1] = (float) newOrientation.x; - TPH_CameraPoseOrientationWxyz[2] = (float) newOrientation.y; - TPH_CameraPoseOrientationWxyz[3] = (float) newOrientation.z; + TPH_CameraPoseOrientationWxyz[0] = (float) WorldFromCamera.Rotation.w; + TPH_CameraPoseOrientationWxyz[1] = (float) WorldFromCamera.Rotation.x; + TPH_CameraPoseOrientationWxyz[2] = (float) WorldFromCamera.Rotation.y; + TPH_CameraPoseOrientationWxyz[3] = (float) WorldFromCamera.Rotation.z; +} + +void SensorFusion::applyFocusCorrection(double deltaT) +{ + Vector3d up = Vector3d(0, 1, 0); + double gain = 0.01; + Vector3d currentDir = WorldFromImu.Pose.Rotate(Vector3d(0, 0, 1)); + Vector3d focusYawComponent = FocusDirection.ProjectToPlane(up); + Vector3d currentYawComponent = currentDir.ProjectToPlane(up); - LogText("adjust camera position %f %f %f\n", newPosition.x, newPosition.y, newPosition.z); + double angle = focusYawComponent.Angle(currentYawComponent); + + if( angle > FocusFOV ) + { + Quatd yawError; + if ( FocusFOV != 0.0f) + { + Vector3d lFocus = Quatd(up, -FocusFOV).Rotate(focusYawComponent); + Vector3d rFocus = Quatd(up, FocusFOV).Rotate(focusYawComponent); + double lAngle = lFocus.Angle(currentYawComponent); + double rAngle = rFocus.Angle(currentYawComponent); + if(lAngle < rAngle) + { + yawError = vectorAlignmentRotation(currentDir, lFocus); + } + else + { + yawError = vectorAlignmentRotation(currentDir, rFocus); + } + } + else + { + yawError = vectorAlignmentRotation(currentYawComponent, focusYawComponent); + } + + Quatd correction = yawError.Nlerp(Quatd(), gain * deltaT); + WorldFromImu.Pose.Rotation = correction * WorldFromImu.Pose.Rotation; + } +} + +//------------------------------------------------------------------------------------ +// Focus filter setting functions + +void SensorFusion::SetFocusDirection() +{ + SetFocusDirection(WorldFromImu.Pose.Rotate(Vector3d(0.0, 0.0, 1.0))); +} + +void SensorFusion::SetFocusDirection(Vector3d direction) +{ + FocusDirection = direction; +} + +void SensorFusion::SetFocusFOV(double fov) +{ + OVR_ASSERT(fov >= 0.0); + FocusFOV = fov; +} + +void SensorFusion::ClearFocus() +{ + FocusDirection = Vector3d(0.0, 0.0, 0.0); + FocusFOV = 0.0f; } //------------------------------------------------------------------------------------- // Head model functions. // Sets up head-and-neck model and device-to-pupil dimensions from the user's profile. -void SensorFusion::SetUserHeadDimensions(Profile const *profile, HmdRenderInfo const &hmdRenderInfo) +void SensorFusion::SetUserHeadDimensions(Profile const &profile, HmdRenderInfo const &hmdRenderInfo) { - float neckEyeHori = OVR_DEFAULT_NECK_TO_EYE_HORIZONTAL; - float neckEyeVert = OVR_DEFAULT_NECK_TO_EYE_VERTICAL; - if ( profile != NULL ) + float neckeye[2]; + int count = profile.GetFloatValues(OVR_KEY_NECK_TO_EYE_DISTANCE, neckeye, 2); + // Make sure these are vaguely sensible values. + if (count == 2) { - float neckeye[2]; - if (profile->GetFloatValues(OVR_KEY_NECK_TO_EYE_DISTANCE, neckeye, 2) == 2) - { - neckEyeHori = neckeye[0]; - neckEyeVert = neckeye[1]; - } + OVR_ASSERT ( ( neckeye[0] > 0.05f ) && ( neckeye[0] < 0.5f ) ); + OVR_ASSERT ( ( neckeye[1] > 0.05f ) && ( neckeye[1] < 0.5f ) ); + SetHeadModel ( Vector3f ( 0.0, neckeye[1], -neckeye[0] ) ); } - // Make sure these are vaguely sensible values. - OVR_ASSERT ( ( neckEyeHori > 0.05f ) && ( neckEyeHori < 0.5f ) ); - OVR_ASSERT ( ( neckEyeVert > 0.05f ) && ( neckEyeVert < 0.5f ) ); - SetHeadModel ( Vector3f ( 0.0, neckEyeVert, -neckEyeHori ) ); // Find the distance from the center of the screen to the "center eye" // This center eye is used by systems like rendering & audio to represent the player, @@ -691,20 +771,16 @@ void SensorFusion::SetUserHeadDimensions(Profile const *profile, HmdRenderInfo c // Crystal Cove was measured to be roughly 0.025 screen->faceplate which agrees with this assumption. // TODO: do this properly! Update: Measured this at 0.02733 with a CC prototype, CES era (PT7), on 2/19/14 -Steve float screenCenterToMidplate = 0.02733f; - float centerEyeRelief = hmdRenderInfo.GetEyeCenter().ReliefInMeters; - if ( profile == NULL ) - { - // No valid profile, so the eye-relief won't be correct either, so fill in a default that feels good - centerEyeRelief = 0.020f; - } float centerPupilDepth = screenCenterToMidplate + hmdRenderInfo.LensSurfaceToMidplateInMeters + centerEyeRelief; SetCenterPupilDepth ( centerPupilDepth ); + + Recording::GetRecorder().RecordUserParams(GetHeadModel(), GetCenterPupilDepth()); } Vector3f SensorFusion::GetHeadModel() const { - return (Vector3f)HeadModel; + return (Vector3f)CpfFromNeck.Inverted().Translation; } void SensorFusion::SetHeadModel(const Vector3f &headModel, bool resetNeckPivot /*= true*/ ) @@ -715,10 +791,10 @@ void SensorFusion::SetHeadModel(const Vector3f &headModel, bool resetNeckPivot / // they can be subtle but nauseating! OVR_ASSERT ( headModel.y > 0.0f ); OVR_ASSERT ( headModel.z < 0.0f ); - HeadModel = (Vector3d)headModel; + CpfFromNeck = Transformd(Quatd(), (Vector3d)headModel).Inverted(); if ( resetNeckPivot ) { - setNeckPivotFromPose ( State.Transform ); + setNeckPivotFromPose ( WorldFromImu.Pose ); } } @@ -727,28 +803,27 @@ float SensorFusion::GetCenterPupilDepth() const return CenterPupilDepth; } - void SensorFusion::SetCenterPupilDepth(float centerPupilDepth) { CenterPupilDepth = centerPupilDepth; - CPFPositionInIMUFrame = -IMUPosition; - CPFPositionInIMUFrame.z += CenterPupilDepth; + Transformd screenFromCpf(Quatd(), Vector3d(0, 0, centerPupilDepth)); + ImuFromCpf = ImuFromScreen * screenFromCpf; - setNeckPivotFromPose ( State.Transform ); + setNeckPivotFromPose ( WorldFromImu.Pose ); } //------------------------------------------------------------------------------------- // This is a "perceptually tuned predictive filter", which means that it is optimized // for improvements in the VR experience, rather than pure error. In particular, -// jitter is more perceptible at lower speeds whereas latency is more perceptable +// jitter is more perceptible at lower speeds whereas latency is more perceptible // after a high-speed motion. Therefore, the prediction interval is dynamically // adjusted based on speed. Significant more research is needed to further improve // this family of filters. -static Pose<double> calcPredictedPose(const PoseState<double>& poseState, double predictionDt) +static Transform<double> calcPredictedPose(const PoseState<double>& poseState, double predictionDt) { - Pose<double> pose = poseState.Transform; + Transform<double> pose = poseState.Pose; const double linearCoef = 1.0; Vector3d angularVelocity = poseState.AngularVelocity; double angularSpeed = angularVelocity.Length(); @@ -766,42 +841,39 @@ static Pose<double> calcPredictedPose(const PoseState<double>& poseState, double dynamicDt = candidateDt; if (angularSpeed > 0.001) - pose.Orientation = pose.Orientation * Quatd(angularVelocity, angularSpeed * dynamicDt); + pose.Rotation = pose.Rotation * Quatd(angularVelocity, angularSpeed * dynamicDt); - pose.Position += poseState.LinearVelocity * dynamicDt; + pose.Translation += poseState.LinearVelocity * dynamicDt; return pose; } -Posef SensorFusion::GetPoseAtTime(double absoluteTime) const +Transformf SensorFusion::GetPoseAtTime(double absoluteTime) const { SensorState ss = GetSensorStateAtTime ( absoluteTime ); - return ss.Predicted.Transform; + return ss.Predicted.Pose; } SensorState SensorFusion::GetSensorStateAtTime(double absoluteTime) const { const LocklessState lstate = UpdatedState.GetState(); - // Delta time from the last processed message - const double pdt = absoluteTime - lstate.State.TimeInSeconds; + // Delta time from the last available data + const double pdt = absoluteTime - lstate.State.TimeInSeconds; SensorState ss; ss.Recorded = PoseStatef(lstate.State); ss.Temperature = lstate.Temperature; ss.Magnetometer = Vector3f(lstate.Magnetometer); - ss.StatusFlags = lstate.StatusFlags; + ss.StatusFlags = lstate.StatusFlags; - // Do prediction logic ss.Predicted = ss.Recorded; ss.Predicted.TimeInSeconds = absoluteTime; - ss.Predicted.Transform = Posef(calcPredictedPose(lstate.State, pdt)); - // CPFOriginInIMUFrame transformation - const Vector3f cpfOriginInIMUFrame(CPFPositionInIMUFrame); - ss.Recorded.Transform.Position += ss.Recorded.Transform.Orientation.Rotate(cpfOriginInIMUFrame); - ss.Predicted.Transform.Position += ss.Predicted.Transform.Orientation.Rotate(cpfOriginInIMUFrame); + // Do prediction logic and ImuFromCpf transformation + ss.Recorded.Pose = Transformf(lstate.State.Pose * ImuFromCpf); + ss.Predicted.Pose = Transformf(calcPredictedPose(lstate.State, pdt) * ImuFromCpf); return ss; } @@ -822,7 +894,7 @@ void SensorFusion::OnMessage(const MessageBodyFrame& msg) void SensorFusion::BodyFrameHandler::OnMessage(const Message& msg) { - Recorder::Buffer(msg); + Recording::GetRecorder().RecordMessage(msg); if (msg.Type == Message_BodyFrame) pFusion->handleMessage(static_cast<const MessageBodyFrame&>(msg)); if (msg.Type == Message_ExposureFrame) diff --git a/LibOVR/Src/OVR_SensorFusion.h b/LibOVR/Src/OVR_SensorFusion.h index 3d10c3d..2a17920 100644 --- a/LibOVR/Src/OVR_SensorFusion.h +++ b/LibOVR/Src/OVR_SensorFusion.h @@ -4,7 +4,7 @@ PublicHeader: OVR.h Filename : OVR_SensorFusion.h Content : Methods that determine head orientation from sensor data over time Created : October 9, 2012 -Authors : Michael Antonov, Steve LaValle, Dov Katz, Max Katsev +Authors : Michael Antonov, Steve LaValle, Dov Katz, Max Katsev, Dan Gierl Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. @@ -30,7 +30,6 @@ limitations under the License. #include "OVR_Device.h" #include "OVR_SensorFilter.h" -#include <time.h> #include "Kernel/OVR_Timer.h" #include "Kernel/OVR_Threads.h" #include "Kernel/OVR_Lockless.h" @@ -58,12 +57,12 @@ template<class T> class PoseState { public: - typedef typename CompatibleTypes<Pose<T> >::Type CompatibleType; + typedef typename CompatibleTypes<Transform<T> >::Type CompatibleType; PoseState() : TimeInSeconds(0.0) { } // float <-> double conversion constructor. explicit PoseState(const PoseState<typename Math<T>::OtherFloatType> &src) - : Transform(src.Transform), + : Pose(src.Pose), AngularVelocity(src.AngularVelocity), LinearVelocity(src.LinearVelocity), AngularAcceleration(src.AngularAcceleration), LinearAcceleration(src.LinearAcceleration), TimeInSeconds(src.TimeInSeconds) @@ -71,16 +70,16 @@ public: // C-interop support: PoseStatef <-> ovrPoseStatef PoseState(const typename CompatibleTypes<PoseState<T> >::Type& src) - : Transform(src.Pose), + : Pose(src.Pose), AngularVelocity(src.AngularVelocity), LinearVelocity(src.LinearVelocity), AngularAcceleration(src.AngularAcceleration), LinearAcceleration(src.LinearAcceleration), TimeInSeconds(src.TimeInSeconds) { } - operator const typename CompatibleTypes<PoseState<T> >::Type () const + operator typename CompatibleTypes<PoseState<T> >::Type () const { typename CompatibleTypes<PoseState<T> >::Type result; - result.Pose = Transform; + result.Pose = Pose; result.AngularVelocity = AngularVelocity; result.LinearVelocity = LinearVelocity; result.AngularAcceleration = AngularAcceleration; @@ -90,7 +89,7 @@ public: } - Pose<T> Transform; + Transform<T> Pose; Vector3<T> AngularVelocity; Vector3<T> LinearVelocity; Vector3<T> AngularAcceleration; @@ -140,7 +139,7 @@ public: // C-interop support SensorState(const ovrSensorState& s); - operator const ovrSensorState () const; + operator ovrSensorState () const; // Pose state at the time that SensorState was requested. PoseStatef Predicted; @@ -163,12 +162,12 @@ public: class VisionHandler { public: - virtual void OnVisionSuccess(const Pose<double>& pose, UInt32 exposureCounter) = 0; - virtual void OnVisionPreviousFrame(const Pose<double>& pose) = 0; + virtual void OnVisionSuccess(const Transform<double>& cameraFromImu, UInt32 exposureCounter) = 0; + virtual void OnVisionPreviousFrame(const Transform<double>& cameraFromImu) = 0; virtual void OnVisionFailure() = 0; // Get a configuration that represents the change over a short time interval - virtual Pose<double> GetVisionPrediction(UInt32 exposureCounter) = 0; + virtual Transform<double> GetVisionPrediction(UInt32 exposureCounter) = 0; }; //------------------------------------------------------------------------------------- @@ -189,6 +188,8 @@ public: class SensorFusion : public NewOverrideBase, public VisionHandler { + friend class SensorFusionDebug; + enum { MagMaxReferences = 1000 @@ -212,10 +213,10 @@ public: // Sets up head-and-neck model and device-to-pupil dimensions from the user's profile and the HMD stats. // This copes elegantly if profile is NULL. - void SetUserHeadDimensions(Profile const *profile, HmdRenderInfo const &hmdRenderInfo); + void SetUserHeadDimensions(Profile const &profile, HmdRenderInfo const &hmdRenderInfo); // Get the predicted pose (orientation, position) of the center pupil frame (CPF) at a specific point in time. - Posef GetPoseAtTime(double absoluteTime) const; + Transformf GetPoseAtTime(double absoluteTime) const; // Get the full dynamical system state of the CPF, which includes velocities and accelerations, // predicted at a specified absolute point in time. @@ -259,11 +260,12 @@ public: // Interaction with vision // ----------------------------------------------- // Handle observation from vision system (orientation, position, time) - virtual void OnVisionSuccess(const Pose<double>& pose, UInt32 exposureCounter); - virtual void OnVisionPreviousFrame(const Pose<double>& pose); + virtual void OnVisionSuccess(const Transform<double>& cameraFromImu, UInt32 exposureCounter); + + virtual void OnVisionPreviousFrame(const Transform<double>& cameraFromImu); virtual void OnVisionFailure(); // Get a configuration that represents the change over a short time interval - virtual Pose<double> GetVisionPrediction(UInt32 exposureCounter); + virtual Transform<double> GetVisionPrediction(UInt32 exposureCounter); double GetTime () const; double GetVisionLatency () const; @@ -287,12 +289,21 @@ public: // Determines if yaw correction is enabled. bool IsYawCorrectionEnabled () const; - // True if mag has calibration values stored - bool HasMagCalibration () const; // Clear the reference points associating // mag readings with orientations void ClearMagReferences (); + // Sets the focus filter direction to the current HMD direction + void SetFocusDirection(); + // Sets the focus filter to a direction in the body frame. Once set, a complementary filter + // will very slowly drag the world to keep the direction of the HMD within the FOV of the focus + void SetFocusDirection(Vector3d direction); + // Sets the FOV (in radians) of the focus. When the yaw difference between the HMD's current pose + // and the focus is smaller than the FOV, the complementary filter does not act. + void SetFocusFOV(double rads); + // Turns off the focus filter (equivalent to setting the focus to 0 + void ClearFocus(); + private: // ----------------------------------------------- @@ -335,94 +346,107 @@ private: { UInt32 ExposureCounter; double ExposureTime; - PoseState<double> State; // State of the headset at the time of exposure. - PoseState<double> Delta; // IMU Delta between previous exposure (or a vision frame) and this one. - - ExposureRecord() : ExposureCounter(0), ExposureTime(0.0) { } - ExposureRecord(UInt32 exposureCounter, double exposureTime, - const PoseState<double>& state, - const PoseState<double>& stateDelta) + // State of the headset at the time of exposure + PoseState<double> WorldFromImu; + // Change in state since the last exposure based on IMU data only + PoseState<double> ImuOnlyDelta; + // Did we have tracking for the entire interval between exposures + bool VisionTrackingAvailable; + + ExposureRecord() : ExposureCounter(0), ExposureTime(0.0), VisionTrackingAvailable(true) { } + ExposureRecord(UInt32 exposureCounter, double exposureTime, + const PoseState<double>& worldFromImu, const PoseState<double>& imuOnlyDelta) : ExposureCounter(exposureCounter), ExposureTime(exposureTime), - State(state), Delta(stateDelta) { } + WorldFromImu(worldFromImu), ImuOnlyDelta(imuOnlyDelta), VisionTrackingAvailable(true) { } + }; + + // ----------------------------------------------- + + // Entry describing the magnetometer reference point + // Used for mag yaw correction + struct MagReferencePoint + { + Vector3d InImuFrame; + Transformd WorldFromImu; + int Score; + + MagReferencePoint() { } + MagReferencePoint(const Vector3d& inImuFrame, const Transformd& worldFromImu, int score) + : InImuFrame(inImuFrame), WorldFromImu(worldFromImu), Score(score) { } }; // ----------------------------------------------- // The phase of the head as estimated by sensor fusion - PoseState<double> State; + PoseState<double> WorldFromImu; // State that can be read without any locks, so that high priority rendering thread // doesn't have to worry about being blocked by a sensor/vision threads that got preempted. LocklessUpdater<LocklessState> UpdatedState; // The pose we got from Vision, augmented with velocity information from numerical derivatives - // This is the only state that is stored in the camera reference frame; the rest are in the world frame - PoseState<double> VisionState; - // Difference between the state from vision and the main State at the time of exposure - PoseState<double> VisionError; - // ExposureRecord that corresponds to the same exposure/frame as VisionState - ExposureRecord LastVisionExposureRecord; - // Change in state since the last exposure based on IMU data only - // (used for incremental tracking predictions) - PoseState<double> CurrentExposureIMUDelta; + PoseState<double> CameraFromImu; + // Difference between the vision and sensor fusion poses at the time of last exposure adjusted + // by all the corrections applied since then + // NB: this one is unlike all the other poses/transforms we use, since it's a difference + // between 2 WorldFromImu transforms, but is stored in the world frame, not the IMU frame + // (see computeVisionError() for details) + // For composition purposes it should be considered a WorldFromWorld transform, where the left + // side comes from vision and the right - from sensor fusion + PoseState<double> VisionError; // Past exposure records between the last update from vision and now // (should only be one record unless vision latency is high) CircularBuffer<ExposureRecord> ExposureRecordHistory; + // ExposureRecord that corresponds to the last pose we got from vision + ExposureRecord LastVisionExposureRecord; + // Incomplete ExposureRecord that will go into the history buffer when + // the new MessageExposureFrame is received + ExposureRecord NextExposureRecord; // Timings of the previous exposure, used to populate ExposureRecordHistory - MessageExposureFrame LastMessageExposureFrame; + MessageExposureFrame LastMessageExposureFrame; // Time of the last vision update - double LastVisionAbsoluteTime; - // Used by the head model. - Vector3d NeckPivotPosition; - - bool EnableCameraTiltCorrection; - // Pose of the camera in the world coordinate system - Pose<double> CameraPose; - double CameraPoseConfidence; - Vector3d DefaultCameraPosition; + double LastVisionAbsoluteTime; - UInt32 FullVisionCorrectionExposureCounter; - - // This is a signed distance, but positive because Z increases looking inward. - // This is expressed relative to the IMU in the HMD and corresponds to the location - // of the cyclopean virtual camera focal point if both the physical and virtual - // worlds are isometrically mapped onto each other. -Steve - float CenterPupilDepth; - Vector3d CPFPositionInIMUFrame; - // Position of the IMU relative to the center of the screen (loaded from the headset firmware) - Vector3d IMUPosition; - // Origin of the positional coordinate system in the real world relative to the camera. - Vector3d PositionOrigin; - - double VisionMaxIMUTrackTime; - unsigned int Stage; - BodyFrameHandler *pHandler; - volatile bool EnableGravity; + BodyFrameHandler *pHandler; + + Vector3d FocusDirection; + double FocusFOV; - SensorFilterBodyFrame FAccelHeadset, FAccelCamera; + SensorFilterBodyFrame FAccelInImuFrame, FAccelInCameraFrame; SensorFilterd FAngV; Vector3d AccelOffset; - bool EnableYawCorrection; - bool MagCalibrated; -public: // The below made public for access during rendering for debugging - int MagNumReferences; - Vector3d MagRefsInBodyFrame[MagMaxReferences]; - Vector3d MagRefsInWorldFrame[MagMaxReferences]; - Quatd MagRefsPoses[MagMaxReferences]; - int MagRefIdx; -private: - int MagRefScore; - Quatd MagCorrectionIntegralTerm; + bool EnableGravity; + + bool EnableYawCorrection; + bool MagCalibrated; + Array<MagReferencePoint> MagRefs; + int MagRefIdx; + Quatd MagCorrectionIntegralTerm; - bool MotionTrackingEnabled; - bool VisionPositionEnabled; + bool EnableCameraTiltCorrection; + // Describes the pose of the camera in the world coordinate system + Transformd WorldFromCamera; + double WorldFromCameraConfidence; - // Built-in head model for faking - // position using orientation only - Vector3d HeadModel; + bool MotionTrackingEnabled; + bool VisionPositionEnabled; + + // This is a signed distance, but positive because Z increases looking inward. + // This is expressed relative to the IMU in the HMD and corresponds to the location + // of the cyclopean virtual camera focal point if both the physical and virtual + // worlds are isometrically mapped onto each other. -Steve + float CenterPupilDepth; + // Describes the position of the user eyes relative to the IMU + Transformd ImuFromCpf; + // Position of the center of the screen relative to the IMU (loaded from the headset firmware) + Transformd ImuFromScreen; + // Built-in head model for faking position using orientation only + Transformd CpfFromNeck; + // Last known base of the neck pose used for head model computations + Transformd WorldFromNeck; //--------------------------------------------- @@ -431,13 +455,11 @@ private: void handleMessage(const MessageBodyFrame& msg); void handleExposure(const MessageExposureFrame& msg); - // Returns new gyroCorrection - Vector3d calcMagYawCorrectionForMessage(Vector3d gyroCorrection, - Quatd q, Quatd qInv, - Vector3d calMag, Vector3d up, double deltaT); - // Apply headset yaw correction from magnetometer + // Compute the difference between vision and sensor fusion data + PoseStated computeVisionError(); + // Apply headset yaw correction from magnetometer // for models without camera or when camera isn't available - void applyMagYawCorrection(Vector3d mag, double deltaT); + void applyMagYawCorrection(Vector3d mag, double deltaT); // Apply headset tilt correction from the accelerometer void applyTiltCorrection(double deltaT); // Apply headset yaw correction from the camera @@ -446,9 +468,11 @@ private: void applyPositionCorrection(double deltaT); // Apply camera tilt correction from the accelerometer void applyCameraTiltCorrection(Vector3d accel, double deltaT); + // Apply camera focus correction + void applyFocusCorrection(double deltaT); // If you have a known-good pose, this sets the neck pivot position. - void setNeckPivotFromPose ( Posed const &pose ); + void setNeckPivotFromPose ( Transformd const &pose ); }; @@ -481,16 +505,6 @@ inline bool SensorFusion::IsYawCorrectionEnabled() const return EnableYawCorrection; } -inline bool SensorFusion::HasMagCalibration() const -{ - return MagCalibrated; -} - -inline void SensorFusion::ClearMagReferences() -{ - MagNumReferences = 0; -} - inline bool SensorFusion::IsVisionPositionEnabled() const { return VisionPositionEnabled; @@ -513,7 +527,7 @@ inline bool SensorFusion::IsCameraTiltCorrectionEnabled() const inline double SensorFusion::GetVisionLatency() const { - return LastVisionAbsoluteTime - VisionState.TimeInSeconds; + return LastVisionAbsoluteTime - CameraFromImu.TimeInSeconds; } inline double SensorFusion::GetTime() const @@ -542,14 +556,14 @@ void PoseState<T>::StoreAndIntegrateGyro(Vector3d angVel, double dt) AngularVelocity = angVel; double angle = angVel.Length() * dt; if (angle > 0) - Transform.Orientation = Transform.Orientation * Quatd(angVel, angle); + Pose.Rotation = Pose.Rotation * Quatd(angVel, angle); } template<class T> void PoseState<T>::StoreAndIntegrateAccelerometer(Vector3d linearAccel, double dt) { LinearAcceleration = linearAccel; - Transform.Position += LinearVelocity * dt + LinearAcceleration * (dt * dt * 0.5); + Pose.Translation += LinearVelocity * dt + LinearAcceleration * (dt * dt * 0.5); LinearVelocity += LinearAcceleration * dt; } @@ -558,8 +572,8 @@ void PoseState<T>::StoreAndIntegrateAccelerometer(Vector3d linearAccel, double d template<class T> void PoseState<T>::AdvanceByDelta(const PoseState<T>& delta) { - Transform.Orientation = Transform.Orientation * delta.Transform.Orientation; - Transform.Position += delta.Transform.Position + LinearVelocity * delta.TimeInSeconds; + Pose.Rotation = Pose.Rotation * delta.Pose.Rotation; + Pose.Translation += delta.Pose.Translation + LinearVelocity * delta.TimeInSeconds; LinearVelocity += delta.LinearVelocity; TimeInSeconds += delta.TimeInSeconds; } diff --git a/LibOVR/Src/OVR_SensorFusionDebug.h b/LibOVR/Src/OVR_SensorFusionDebug.h new file mode 100644 index 0000000..0fc7eb5 --- /dev/null +++ b/LibOVR/Src/OVR_SensorFusionDebug.h @@ -0,0 +1,82 @@ +/************************************************************************************ + +PublicHeader: OVR.h +Filename : OVR_SensorFusionDebug.h +Content : Friend proxy to allow debugging access to SensorFusion +Created : April 16, 2014 +Authors : Dan Gierl + +Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.1 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +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 OVR_SensorFusionDebug_h +#define OVR_SensorFusionDebug_h + +#include "OVR_SensorFusion.h" + +namespace OVR { + +class SensorFusionDebug +{ +private: + + SensorFusion * sf; + +public: + + SensorFusionDebug (SensorFusion * const sf) : + sf(sf) + { + } + + // Returns the number of magnetometer reference points currently gathered + int GetNumMagRefPoints () const; + // Returns the index of the magnetometer reference point being currently used + int GetCurMagRefPointIdx () const; + // Returns a copy of all the data associated with a magnetometer reference point + // This includes it's score, the magnetometer reading as a vector, + // and the HMD's pose at the time it was gathered + void GetMagRefData (int idx, int * score, Vector3d * magBF, Quatd * magPose) const; + +}; + +//------------------------------------------------------------------------------------ +// Magnetometer reference point access functions + +int SensorFusionDebug::GetNumMagRefPoints() const +{ + return (int)sf->MagRefs.GetSize(); +} + +int SensorFusionDebug::GetCurMagRefPointIdx() const +{ + return sf->MagRefIdx; +} + +void SensorFusionDebug::GetMagRefData(int idx, int * score, Vector3d * magBF, Quatd * magPose) const +{ + OVR_ASSERT(idx >= 0 && idx < GetNumMagRefPoints()); + *score = sf->MagRefs[idx].Score; + *magBF = sf->MagRefs[idx].InImuFrame; + *magPose = sf->MagRefs[idx].WorldFromImu.Rotation; +} + +} // OVR + +#endif
\ No newline at end of file diff --git a/LibOVR/Src/OVR_SensorImpl.cpp b/LibOVR/Src/OVR_SensorImpl.cpp index 43f3b67..91ae7e0 100644 --- a/LibOVR/Src/OVR_SensorImpl.cpp +++ b/LibOVR/Src/OVR_SensorImpl.cpp @@ -166,7 +166,11 @@ void SensorDisplayInfoImpl::Unpack() //------------------------------------------------------------------------------------- // ***** SensorDeviceFactory -SensorDeviceFactory SensorDeviceFactory::Instance; +SensorDeviceFactory &SensorDeviceFactory::GetInstance() +{ + static SensorDeviceFactory instance; + return instance; +} void SensorDeviceFactory::EnumerateDevices(EnumerateVisitor& visitor) { @@ -572,6 +576,11 @@ void SensorDeviceImpl::GetFactoryCalibration(Vector3f* AccelOffset, Vector3f* Gy *Temperature = CalibrationTemperature; } +bool SensorDeviceImpl::IsMagCalibrated() +{ + return magCalibrated; +} + void SensorDeviceImpl::SetOnboardCalibrationEnabled(bool enabled) { // Push call with wait. @@ -731,7 +740,6 @@ void SensorDeviceImpl::onTrackerMessage(TrackerMessage* message) sensors.RotationRate = LastRotationRate; sensors.MagneticField = LastMagneticField; sensors.Temperature = LastTemperature; - sensors.MagCalibrated = magCalibrated; HandlerRef.Call(sensors); } @@ -769,7 +777,6 @@ void SensorDeviceImpl::onTrackerMessage(TrackerMessage* message) if (HandlerRef.HasHandlers()) { MessageBodyFrame sensors(this); - sensors.MagCalibrated = magCalibrated; UByte iterations = s.SampleCount; if (s.SampleCount > 3) @@ -1058,7 +1065,7 @@ bool SensorDeviceImpl::GetMagCalibrationReport(MagCalibrationReport* data) time(&now); // parse the calibration time - time_t calibration_time = now; + //time_t calibration_time = now; JSON* caltime = calibration->GetItemByName("Time"); if (caltime) { @@ -1083,7 +1090,7 @@ bool SensorDeviceImpl::GetMagCalibrationReport(MagCalibrationReport* data) #endif ct.tm_year -= 1900; ct.tm_mon--; - calibration_time = mktime(&ct); + //calibration_time = mktime(&ct); } // parse the calibration matrix @@ -1111,6 +1118,48 @@ bool SensorDeviceImpl::GetMagCalibrationReport(MagCalibrationReport* data) return true; } -} // namespace OVR +bool SensorDeviceImpl::SetSerialReport(const SerialReport& data) +{ + bool result; + if (!GetManagerImpl()->GetThreadQueue()-> + PushCallAndWaitResult(this, &Sensor2DeviceImpl::setSerialReport, &result, data)) + { + return false; + } + + return result; +} + +bool SensorDeviceImpl::setSerialReport(const SerialReport& data) +{ + SerialImpl di(data); + return GetInternalDevice()->SetFeatureReport(di.Buffer, SerialImpl::PacketSize); +} +bool SensorDeviceImpl::GetSerialReport(SerialReport* data) +{ + bool result; + if (!GetManagerImpl()->GetThreadQueue()-> + PushCallAndWaitResult(this, &Sensor2DeviceImpl::getSerialReport, &result, data)) + { + return false; + } + + return result; +} + +bool SensorDeviceImpl::getSerialReport(SerialReport* data) +{ + SerialImpl di; + if (GetInternalDevice()->GetFeatureReport(di.Buffer, SerialImpl::PacketSize)) + { + di.Unpack(); + *data = di.Settings; + return true; + } + + return false; +} + +} // namespace OVR diff --git a/LibOVR/Src/OVR_SensorImpl.h b/LibOVR/Src/OVR_SensorImpl.h index 70e05f8..f53b831 100644 --- a/LibOVR/Src/OVR_SensorImpl.h +++ b/LibOVR/Src/OVR_SensorImpl.h @@ -29,6 +29,7 @@ limitations under the License. #include "OVR_HIDDeviceImpl.h" #include "OVR_SensorTimeFilter.h" +#include "OVR_Device.h" #ifdef OVR_OS_ANDROID #include "OVR_PhoneSensors.h" @@ -44,7 +45,7 @@ class ExternalVisitor; class SensorDeviceFactory : public DeviceFactory { public: - static SensorDeviceFactory Instance; + static SensorDeviceFactory &GetInstance(); // Enumerates devices, creating and destroying relevant objects in manager. virtual void EnumerateDevices(EnumerateVisitor& visitor); @@ -213,6 +214,7 @@ public: Matrix4f* AccelMatrix, Matrix4f* GyroMatrix, float* Temperature); virtual void SetOnboardCalibrationEnabled(bool enabled); + virtual bool IsMagCalibrated(); // Sets report rate (in Hz) of MessageBodyFrame messages (delivered through MessageHandler::OnMessage call). // Currently supported maximum rate is 1000Hz. If the rate is set to 500 or 333 Hz then OnMessage will be @@ -226,6 +228,9 @@ public: // value will contain the actual rate. virtual unsigned GetReportRate() const; + bool SetSerialReport(const SerialReport& data); + bool GetSerialReport(SerialReport* data); + // Hack to create HMD device from sensor display info. static void EnumerateHMDFromSensorDisplayInfo(const SensorDisplayInfoImpl& displayInfo, DeviceFactory::EnumerateVisitor& visitor); @@ -246,6 +251,9 @@ protected: Void setOnboardCalibrationEnabled(bool enabled); + bool setSerialReport(const SerialReport& data); + bool getSerialReport(SerialReport* data); + // Called for decoded messages void onTrackerMessage(TrackerMessage* message); bool decodeTrackerMessage(TrackerMessage* message, UByte* buffer, int size); @@ -295,7 +303,6 @@ protected: #ifdef OVR_OS_ANDROID void replaceWithPhoneMag(Vector3f* val); - PhoneSensors* pPhoneSensors; #endif diff --git a/LibOVR/Src/OVR_SensorImpl_Common.cpp b/LibOVR/Src/OVR_SensorImpl_Common.cpp index a84d50a..99febe8 100644 --- a/LibOVR/Src/OVR_SensorImpl_Common.cpp +++ b/LibOVR/Src/OVR_SensorImpl_Common.cpp @@ -124,7 +124,7 @@ void SensorRangeImpl::Unpack() } SensorConfigImpl::SensorConfigImpl() - : CommandId(0), Flags(0), PacketInterval(0), KeepAliveIntervalMs(0) + : CommandId(0), Flags(0), PacketInterval(0), SampleRate(0) { memset(Buffer, 0, PacketSize); Buffer[0] = 2; @@ -147,16 +147,16 @@ void SensorConfigImpl::Pack() Buffer[2] = UByte(CommandId >> 8); Buffer[3] = Flags; Buffer[4] = UByte(PacketInterval); - Buffer[5] = UByte(KeepAliveIntervalMs & 0xFF); - Buffer[6] = UByte(KeepAliveIntervalMs >> 8); + Buffer[5] = UByte(SampleRate & 0xFF); + Buffer[6] = UByte(SampleRate >> 8); } void SensorConfigImpl::Unpack() { - CommandId = Buffer[1] | (UInt16(Buffer[2]) << 8); - Flags = Buffer[3]; - PacketInterval = Buffer[4]; - KeepAliveIntervalMs= Buffer[5] | (UInt16(Buffer[6]) << 8); + CommandId = Buffer[1] | (UInt16(Buffer[2]) << 8); + Flags = Buffer[3]; + PacketInterval = Buffer[4]; + SampleRate = Buffer[5] | (UInt16(Buffer[6]) << 8); } SensorFactoryCalibrationImpl::SensorFactoryCalibrationImpl() diff --git a/LibOVR/Src/OVR_SensorImpl_Common.h b/LibOVR/Src/OVR_SensorImpl_Common.h index 293330c..a7091ba 100644 --- a/LibOVR/Src/OVR_SensorImpl_Common.h +++ b/LibOVR/Src/OVR_SensorImpl_Common.h @@ -87,8 +87,8 @@ struct SensorConfigImpl UInt16 CommandId; UByte Flags; - UInt16 PacketInterval; - UInt16 KeepAliveIntervalMs; + UInt16 PacketInterval; // LDC - This should be a UByte. Fix when you have time to test it. + UInt16 SampleRate; SensorConfigImpl(); diff --git a/LibOVR/Src/OVR_Stereo.cpp b/LibOVR/Src/OVR_Stereo.cpp index 7e78b82..936a02a 100644 --- a/LibOVR/Src/OVR_Stereo.cpp +++ b/LibOVR/Src/OVR_Stereo.cpp @@ -364,6 +364,9 @@ void LensConfig::SetUpInverseApprox() #endif }break; + + default: + break; } } @@ -440,7 +443,7 @@ bool LoadLensConfig ( LensConfig *presult, UByte const *pbuffer, int bufferSizeI { case LCSV_CatmullRom10Version1: { - if ( bufferSizeInBytes < sizeof(LensConfigStored_CatmullRom10Version1) ) + if ( bufferSizeInBytes < (int)sizeof(LensConfigStored_CatmullRom10Version1) ) { return false; } @@ -503,7 +506,7 @@ int SaveLensConfigSizeInBytes ( LensConfig const &config ) // Returns true on success. bool SaveLensConfig ( UByte *pbuffer, int bufferSizeInBytes, LensConfig const &config ) { - if ( bufferSizeInBytes < sizeof ( LensConfigStored_CatmullRom10Version1 ) ) + if ( bufferSizeInBytes < (int)sizeof ( LensConfigStored_CatmullRom10Version1 ) ) { return false; } @@ -645,6 +648,9 @@ HMDInfo CreateDebugHMDInfo(HmdTypeEnum hmdType) info.Shutter.PixelSettleTime = 0.0f; info.Shutter.PixelPersistence = 0.18f * info.Shutter.VsyncToNextVsync; break; + + default: + break; } return info; @@ -868,7 +874,7 @@ LensConfig GenerateLensConfigFromEyeRelief ( float eyeReliefInMeters, HmdRenderI }; DistortionDescriptor distortions[10]; - for ( int i = 0; i < sizeof(distortions)/sizeof(distortions[0]); i++ ) + for ( unsigned int i = 0; i < sizeof(distortions)/sizeof(distortions[0]); i++ ) { distortions[i].Config.SetToIdentity(); distortions[i].EyeRelief = 0.0f; @@ -1374,6 +1380,11 @@ FovPort CalculateFovFromHmdInfo ( StereoEye eyeType, offsetToRightInMeters = -(hmd.EyeLeft.NoseToPupilInMeters - 0.5f * hmd.LensSeparationInMeters); } + // Limit the eye-relief to 6 mm for FOV calculations since this just tends to spread off-screen + // and get clamped anyways on DK1 (but in Unity it continues to spreads and causes + // unnecessarily large render targets) + eyeReliefInMeters = Alg::Max(eyeReliefInMeters, 0.006f); + // Central view. fovPort = CalculateFovFromEyePosition ( eyeReliefInMeters, offsetToRightInMeters, diff --git a/LibOVR/Src/OVR_Stereo.h b/LibOVR/Src/OVR_Stereo.h index bd5438d..dd5499c 100644 --- a/LibOVR/Src/OVR_Stereo.h +++ b/LibOVR/Src/OVR_Stereo.h @@ -75,8 +75,8 @@ struct FovPort UpTan(u), DownTan(d), LeftTan(l), RightTan(r) { } // C-interop support: FovPort <-> ovrFovPort (implementation in OVR_CAPI.cpp). - FovPort (const ovrFovPort &src); - operator const ovrFovPort () const; + FovPort(const ovrFovPort& src); + operator ovrFovPort () const; static FovPort CreateFromRadians(float horizontalFov, float verticalFov) diff --git a/LibOVR/Src/OVR_ThreadCommandQueue.cpp b/LibOVR/Src/OVR_ThreadCommandQueue.cpp index 427a539..bc0d7dc 100644 --- a/LibOVR/Src/OVR_ThreadCommandQueue.cpp +++ b/LibOVR/Src/OVR_ThreadCommandQueue.cpp @@ -179,8 +179,7 @@ class ThreadCommandQueueImpl : public NewOverrideBase public: ThreadCommandQueueImpl(ThreadCommandQueue* queue) - : pQueue(queue), CommandBuffer(2048), - ExitEnqueued(false), ExitProcessed(false) + : pQueue(queue), ExitEnqueued(false), ExitProcessed(false), CommandBuffer(2048) { } ~ThreadCommandQueueImpl(); diff --git a/LibOVR/Src/OVR_Win32_DeviceManager.cpp b/LibOVR/Src/OVR_Win32_DeviceManager.cpp index 6327d58..3fd25b2 100644 --- a/LibOVR/Src/OVR_Win32_DeviceManager.cpp +++ b/LibOVR/Src/OVR_Win32_DeviceManager.cpp @@ -413,9 +413,9 @@ DeviceManager* DeviceManager::Create() { if (manager->Initialize(0)) { - manager->AddFactory(&SensorDeviceFactory::Instance); - manager->AddFactory(&LatencyTestDeviceFactory::Instance); - manager->AddFactory(&Win32::HMDDeviceFactory::Instance); + manager->AddFactory(&SensorDeviceFactory::GetInstance()); + manager->AddFactory(&LatencyTestDeviceFactory::GetInstance()); + manager->AddFactory(&Win32::HMDDeviceFactory::GetInstance()); manager->AddRef(); } diff --git a/LibOVR/Src/OVR_Win32_HIDDevice.cpp b/LibOVR/Src/OVR_Win32_HIDDevice.cpp index 6d33f7a..e94c2ab 100644 --- a/LibOVR/Src/OVR_Win32_HIDDevice.cpp +++ b/LibOVR/Src/OVR_Win32_HIDDevice.cpp @@ -619,10 +619,8 @@ HIDDeviceManager* HIDDeviceManager::CreateInternal(Win32::DeviceManager* devMana // ***** Creation // Creates a new HIDDeviceManager and initializes OVR. -HIDDeviceManager* HIDDeviceManager::Create() +HIDDeviceManager* HIDDeviceManager::Create(Ptr<OVR::DeviceManager>& deviceManager) { - OVR_ASSERT_LOG(false, ("Standalone mode not implemented yet.")); - if (!System::IsInitialized()) { // Use custom message, since Log is not yet installed. @@ -631,21 +629,21 @@ HIDDeviceManager* HIDDeviceManager::Create() return 0; } - Ptr<Win32::HIDDeviceManager> manager = *new Win32::HIDDeviceManager(NULL); + Ptr<Win32::DeviceManager> deviceManagerWin32 = *new Win32::DeviceManager; - if (manager) + if (!deviceManagerWin32) { - if (manager->Initialize()) - { - manager->AddRef(); - } - else - { - manager.Clear(); - } + return NULL; + } + + if (!deviceManagerWin32->Initialize(0)) + { + return NULL; } - return manager.GetPtr(); + deviceManager = deviceManagerWin32; + + return deviceManagerWin32->GetHIDDeviceManager(); } } // namespace OVR diff --git a/LibOVR/Src/OVR_Win32_HMDDevice.cpp b/LibOVR/Src/OVR_Win32_HMDDevice.cpp index 08c98f2..b7dcd1a 100644 --- a/LibOVR/Src/OVR_Win32_HMDDevice.cpp +++ b/LibOVR/Src/OVR_Win32_HMDDevice.cpp @@ -227,7 +227,11 @@ BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData) //------------------------------------------------------------------------------------- // ***** HMDDeviceFactory -HMDDeviceFactory HMDDeviceFactory::Instance; +HMDDeviceFactory &HMDDeviceFactory::GetInstance() +{ + static HMDDeviceFactory instance; + return instance; +} void HMDDeviceFactory::EnumerateDevices(EnumerateVisitor& visitor) { diff --git a/LibOVR/Src/OVR_Win32_HMDDevice.h b/LibOVR/Src/OVR_Win32_HMDDevice.h index d1e481c..81178bb 100644 --- a/LibOVR/Src/OVR_Win32_HMDDevice.h +++ b/LibOVR/Src/OVR_Win32_HMDDevice.h @@ -44,7 +44,7 @@ class HMDDevice; class HMDDeviceFactory : public DeviceFactory { public: - static HMDDeviceFactory Instance; + static HMDDeviceFactory &GetInstance(); // Enumerates devices, creating and destroying relevant objects in manager. virtual void EnumerateDevices(EnumerateVisitor& visitor); diff --git a/LibOVR/Src/OVR_Win32_SensorDevice.cpp b/LibOVR/Src/OVR_Win32_SensorDevice.cpp index e8beb31..734766c 100644 --- a/LibOVR/Src/OVR_Win32_SensorDevice.cpp +++ b/LibOVR/Src/OVR_Win32_SensorDevice.cpp @@ -39,9 +39,9 @@ void SensorDeviceImpl::EnumerateHMDFromSensorDisplayInfo (const SensorDisplayInfoImpl& displayInfo, DeviceFactory::EnumerateVisitor& visitor) { - - Win32::HMDDeviceCreateDesc hmdCreateDesc(&Win32::HMDDeviceFactory::Instance, String(), String()); - hmdCreateDesc.SetScreenParameters( 0, 0, + Win32::HMDDeviceCreateDesc hmdCreateDesc(&Win32::HMDDeviceFactory::GetInstance(), String(), String()); + + hmdCreateDesc.SetScreenParameters( 0, 0, displayInfo.HResolution, displayInfo.VResolution, displayInfo.HScreenSize, displayInfo.VScreenSize, displayInfo.VCenter, displayInfo.LensSeparation); diff --git a/LibOVR/Src/Recording/Recorder.h b/LibOVR/Src/Recording/Recorder.h deleted file mode 100644 index 460c3e6..0000000 --- a/LibOVR/Src/Recording/Recorder.h +++ /dev/null @@ -1,273 +0,0 @@ -/************************************************************************************ - -Filename : Recorder.h -Content : Support for recording sensor + camera data -Created : March 14, 2014 -Notes : - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.1 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -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 OVR_Recorder_h -#define OVR_Recorder_h - -#define ENABLE_RECORDING 0 - -#include "../../Include/OVR.h" - -#if ENABLE_RECORDING - -#include "../Vision/Vision_CameraCalibration.h" -#include "../Vision/Vision_Blob.h" -#include "../Vision/Vision_Image.h" -#include "../Vision/Vision_ModulatedLEDModel.h" -#include "LogDataTypes.h" -#include "matfile.h" - -#define RECORDING_LOCATION "%Y%m%d_%H%M%S" - -#endif -namespace OVR{ - - typedef UByte RecordingMode; - enum RecordingMode_t - { - RecordingOff = 0x0, - RecordForPlayback = 0x1, - RecordForLogging = 0x2 - }; -}; - -#if ENABLE_RECORDING - -namespace OVR{ - - class Recorder - { - public: - - static void SetPrefix(const char* prefix); - static String GetPrefix(); - - struct StartupParams - { - StartupParams() - : intrinsics(), - distortion(), - ledPositions(), - imuPosition(), - devIfcVersion(1) - {} - - ~StartupParams() - { - } - - Vision::CameraIntrinsics intrinsics; - Vision::DistortionCoefficients distortion; - Array<PositionCalibrationReport> ledPositions; - PositionCalibrationReport imuPosition; - UByte devIfcVersion; - }; - - // Global Interface - static void Buffer(const Message& msg); - - static void Buffer(const Vision::CameraIntrinsics& intrinsics, - const Vision::DistortionCoefficients& distortion); - - static void Buffer(const Array<PositionCalibrationReport>& ledPositions); - - static void Buffer(const PositionCalibrationReport& imuPosition); - - static void BufferDevIfcVersion(const UByte devIfcVersion); - - template<typename T> - static void LogData(const char* label, const T& data) - { - Recorder* myRecorder = GetRecorder(); - if(myRecorder && (myRecorder->recordingMode & RecordForLogging)) - myRecorder->DoLogData(label, data); - } - - static void LogData(const char* label, const Vision::Blob blobs[], const int numElements); - - static void LogData(const char* label, const Vector3d& vect3); - - static void LogData(const char* label, const Quatd& quat); - - static void LogData(const char* label, const Posed& pose); - - static Recorder* GetRecorder(); - // Instantiates Recorder if it does not already exist. - static Recorder* BuildRecorder(); - // Activates or deactivates recording. Returns resultant state (true = recording, false = not recording). - static bool ToggleRecording(const RecordingMode mode); - - Recorder(); - - ~Recorder(); - - void SaveCameraParams(const Vision::CameraIntrinsics& intrinsics, - const Vision::DistortionCoefficients& distortion); - - void SaveLedPositions(const Array<PositionCalibrationReport>& ledPositions); - - void SaveImuPosition(const PositionCalibrationReport& imuPosition); - - void SaveDevIfcVersion(const UByte devIfcVersion); - - void WriteToRec(const Array<UByte>& buffer); - - template<class T> - void DoLogData(const char* label, const T& data) - { - if(!(recordingMode & RecordForLogging)) - return; - Ptr<LogDataEntryBase> entry; - StringHash<Ptr<LogDataEntryBase> >::Iterator iter = logDataBuffer.Find(label); - if(!iter.IsEnd()) - entry = logDataBuffer.Find(label)->Second; - if(!entry) - { - // Add new entry - entry = getNewEntry(label, data); - logDataBuffer.Add(label, entry); - } - - OVR_ASSERT(entry != NULL); - - // Add new sample to the entry that we found - - Array<T>& myBuffer = dynamic_cast<LogDataEntry<T>*>(entry.GetPtr())->buffer; - myBuffer.PushBack(data); - } - - void DoLogData(const char* label, const Vision::Blob blobs[]); - - void DoLogData(const char* label, const Posed& pose); - - void DoLogData(const char* label, const Vector3d& vect3); - - void DoLogData(const char* label, const Quatd& quat); - - // Activates or deactivates recording. Returns resultant state (true = recording, false = not recording). - bool DoToggleRecording(const RecordingMode mode); - - // Keep this up-to-date when the recording format changes - static const UInt16 RECORDING_FORMAT_VERSION = 1; - - private: - Ptr<LogDataEntryBase> getNewEntry(const char* label, const float&); - Ptr<LogDataEntryBase> getNewEntry(const char* label, const double&); - Ptr<LogDataEntryBase> getNewEntry(const char* label, const int&); - Ptr<LogDataEntryBase> getNewEntry(const char* label, const Vision::Blob[]); - Ptr<LogDataEntryBase> getNewEntry(const char* label, const Posed&); - Ptr<LogDataEntryBase> getNewEntry(const char* label, const Vector3d&); - Ptr<LogDataEntryBase> getNewEntry(const char* label, const Quatd&); - - void start(); - - // Serialize the startup params that we have saved and write them to file. Then set readyForMessages flag. - void writeStartupParams(); - - int bufferPositionReport(const PositionCalibrationReport& report, UByte* buffer); - - void finalize(); - - void writeBlobStats(const char* label, LogDataEntryBase* entry); - - void writeVector3d(const char* label, const Array<Vector3d>& data); - - void writePosed(const char* label, const Array<Posed>& data); - - void writeQuatd(const char* label, const Array<Quatd>& data); - - void reset(); - - String getFilePrefix(); - - // File that will contain simulation/playback data - FILE* recFile; - vortex::CMatFile matFile; - - // Logging data to be written to .mat file - StringHash<Ptr<LogDataEntryBase> > logDataBuffer; - - StartupParams startup; // Startup params. Must be written before general messages - bool readyForMessages; // Indicates that the startup params have been written, and we can safely write messages to the .rec file - - // To preserve ordering of incoming messages - Lock recorderLock; - // How/are we currently recording? - UByte recordingMode; - }; - -}; - -#else // If Recording is not enabled, then no-op all the functions so they can be inlined/optimized away by the compiler. - -namespace OVR{ - - namespace Vision{ - class CameraIntrinsics; - class DistortionCoefficients; - class Blob; - }; - struct PositionCalibrationReport; - - class Recorder - { - public: - static void Buffer(const Message&) { } - - static void Buffer(const Vision::CameraIntrinsics&, - const Vision::DistortionCoefficients&) - { } - - static void Buffer(const Array<PositionCalibrationReport>&) { } - - static void Buffer(const PositionCalibrationReport&) { } - - static void BufferDevIfcVersion(const UByte) { }; - - static Recorder* GetRecorder() { return NULL; } - - static Recorder* BuildRecorder() { return NULL; } - - static bool ToggleRecording(const int) { return false; } - - template<typename T> - static void LogData(const char*, const T&) { }; - - static void LogData(const char*, const Vision::Blob[], const int) { }; - - Recorder() { } - - ~Recorder() { } - - bool DoToggleRecording(const int) { return false; } - - void AddToBuffer(const Message&) { } - }; -} // namespace OVR - -#endif // ENABLE_RECORDING - -#endif // OVR_Recorder_h diff --git a/LibOVR/Src/Util/Util_ImageWindow.cpp b/LibOVR/Src/Util/Util_ImageWindow.cpp index e038d1f..cb091c7 100644 --- a/LibOVR/Src/Util/Util_ImageWindow.cpp +++ b/LibOVR/Src/Util/Util_ImageWindow.cpp @@ -27,8 +27,12 @@ limitations under the License. #include "Util_ImageWindow.h" +#if defined(OVR_OS_WIN32) + #include <Windows.h> +#include "DWrite.h" + typedef HRESULT (WINAPI *D2D1CreateFactoryFn)( _In_ D2D1_FACTORY_TYPE, _In_ REFIID, @@ -36,11 +40,19 @@ typedef HRESULT (WINAPI *D2D1CreateFactoryFn)( _Out_ ID2D1Factory ** ); +typedef HRESULT (WINAPI *DWriteCreateFactoryFn)( + _In_ DWRITE_FACTORY_TYPE factoryType, + _In_ REFIID iid, + _Out_ IUnknown **factory + ); + namespace OVR { namespace Util { ID2D1Factory* ImageWindow::pD2DFactory = NULL; -ImageWindow* ImageWindow::globalWindow = NULL; +IDWriteFactory* ImageWindow::pDWriteFactory = NULL; +ImageWindow* ImageWindow::globalWindow[4]; +int ImageWindow::windowCount = 0; LRESULT CALLBACK MainWndProc( HWND hwnd, @@ -83,25 +95,31 @@ LRESULT CALLBACK MainWndProc( //return 0; } -ImageWindow::ImageWindow() : +ImageWindow::ImageWindow( uint32_t width, uint32_t height ) : frontBufferMutex( new Mutex() ) { HINSTANCE hInst = LoadLibrary( L"d2d1.dll" ); + HINSTANCE hInstWrite = LoadLibrary( L"Dwrite.dll" ); D2D1CreateFactoryFn createFactory = NULL; + DWriteCreateFactoryFn writeFactory = NULL; if( hInst ) { createFactory = (D2D1CreateFactoryFn)GetProcAddress( hInst, "D2D1CreateFactory" ); } - globalWindow = this; + if( hInstWrite ) + { + writeFactory = (DWriteCreateFactoryFn)GetProcAddress( hInstWrite, "DWriteCreateFactory" ); + } + + globalWindow[windowCount] = this; - int width = 752; - int height = 480; + ++windowCount; - if( pD2DFactory == NULL && createFactory ) + if( pD2DFactory == NULL && createFactory && writeFactory ) { createFactory( D2D1_FACTORY_TYPE_MULTI_THREADED, @@ -109,6 +127,14 @@ ImageWindow::ImageWindow() : NULL, &pD2DFactory ); + + // Create a DirectWrite factory. + writeFactory( + DWRITE_FACTORY_TYPE_SHARED, + __uuidof(pDWriteFactory), + reinterpret_cast<IUnknown **>(&pDWriteFactory) + ); + } resolution = D2D1::SizeU( width, height ); @@ -120,84 +146,17 @@ ImageWindow::ImageWindow() : colorBitmap = NULL; } -ImageWindow::ImageWindow( UINT width, UINT height ) : - frontBufferMutex( new Mutex() ) +ImageWindow::~ImageWindow() { - - - HINSTANCE hInstance = GetModuleHandle( NULL ); - - WNDCLASS wc; - wc.lpszClassName = L"ImageWindowClass"; - wc.lpfnWndProc = MainWndProc; - wc.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW; - wc.hInstance = hInstance; - wc.hIcon = LoadIcon( NULL, IDI_APPLICATION ); - wc.hCursor = LoadCursor( NULL, IDC_ARROW ); - wc.hbrBackground = (HBRUSH)( COLOR_WINDOW+1 ); - wc.lpszMenuName = L""; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - - RegisterClass(&wc); - - hWindow = CreateWindow( - L"ImageWindowClass", - L"ImageWindow", - WS_OVERLAPPEDWINDOW & ~WS_SYSMENU, - CW_USEDEFAULT, - CW_USEDEFAULT, - width, - height, - NULL, - NULL, - hInstance, - NULL); - - resolution = D2D1::SizeU( width, height ); - - SetWindowLongPtr( hWindow, GWLP_USERDATA, (LONG_PTR)this ); - - ShowWindow( hWindow, SW_SHOW ); - - RECT rc = {0}; - GetClientRect( hWindow, &rc ); - - D2D1_RENDER_TARGET_PROPERTIES props = D2D1::RenderTargetProperties(); - D2D1_HWND_RENDER_TARGET_PROPERTIES hwndProps = D2D1::HwndRenderTargetProperties( - hWindow, - resolution - ); - - ID2D1HwndRenderTarget* hwndTarget = NULL; - // Create a Direct2D render target - pRT = NULL; - pD2DFactory->CreateHwndRenderTarget( - &props, - &hwndProps, - &hwndTarget - ); - - pRT = hwndTarget; - - D2D1_SIZE_U size = D2D1::SizeU( width, height ); - - D2D1_PIXEL_FORMAT pixelFormat = D2D1::PixelFormat( - DXGI_FORMAT_A8_UNORM, - D2D1_ALPHA_MODE_PREMULTIPLIED - ); - - D2D1_BITMAP_PROPERTIES bitmapProps; - bitmapProps.dpiX = 72; - bitmapProps.dpiY = 72; - bitmapProps.pixelFormat = pixelFormat; - - HRESULT result = pRT->CreateBitmap( size, bitmapProps, &greyBitmap ); - result = pRT->CreateBitmap( size, bitmapProps, &colorBitmap ); + for( int i = 0; i < MaxWindows; ++i ) + { + if( globalWindow[i] == this ) + { + globalWindow[i] = NULL; + break; + } } -ImageWindow::~ImageWindow() -{ if( greyBitmap ) greyBitmap->Release(); @@ -207,6 +166,15 @@ ImageWindow::~ImageWindow() if( pRT ) pRT->Release(); + { + Mutex::Locker locker( frontBufferMutex ); + + while( frames.GetSize() ) + { + Ptr<Frame> aFrame = frames.PopBack(); + } + } + delete frontBufferMutex; ShowWindow( hWindow, SW_HIDE ); @@ -291,6 +259,8 @@ void ImageWindow::Process() if( pRT && greyBitmap ) { OnPaint(); + + pRT->Flush(); } } @@ -301,55 +271,48 @@ void ImageWindow::Complete() if( frames.IsEmpty() ) return; - if( frames.PeekBack(0).ready ) + if( frames.PeekBack(0)->ready ) return; - Frame& frame = frames.PeekBack(0); + Ptr<Frame> frame = frames.PeekBack(0); - frame.ready = true; + frame->ready = true; } void ImageWindow::OnPaint() { - static float mover = -752.0f; - Mutex::Locker locker( frontBufferMutex ); // Nothing to do if( frames.IsEmpty() ) return; - if( !frames.PeekFront(0).ready ) + if( !frames.PeekFront(0)->ready ) return; - Frame currentFrame = frames.PopFront(); - Frame dummyFrame = {0}; + Ptr<Frame> currentFrame = frames.PopFront(); - Frame& nextFrame = dummyFrame; + Ptr<Frame> nextFrame = NULL; if( !frames.IsEmpty() ) nextFrame = frames.PeekFront(0); - while( nextFrame.ready ) + while( nextFrame && nextFrame->ready ) { // Free up the current frame since it's been removed from the deque - free( currentFrame.imageData ); - if( currentFrame.colorImageData ) - free( currentFrame.colorImageData ); - currentFrame = frames.PopFront(); if( frames.IsEmpty() ) - return; + break; nextFrame = frames.PeekFront(0); } - if( currentFrame.imageData ) - greyBitmap->CopyFromMemory( NULL, currentFrame.imageData, currentFrame.width ); + if( currentFrame->imageData ) + greyBitmap->CopyFromMemory( NULL, currentFrame->imageData, currentFrame->width ); - if( currentFrame.colorImageData ) - colorBitmap->CopyFromMemory( NULL, currentFrame.colorImageData, currentFrame.colorPitch ); + if( currentFrame->colorImageData ) + colorBitmap->CopyFromMemory( NULL, currentFrame->colorImageData, currentFrame->colorPitch ); pRT->BeginDraw(); @@ -368,14 +331,15 @@ void ImageWindow::OnPaint() pRT->CreateSolidColorBrush( D2D1::ColorF(D2D1::ColorF::White, 1.0f), &whiteBrush ); - if( currentFrame.imageData ) + if( currentFrame->imageData ) { pRT->FillOpacityMask( greyBitmap, whiteBrush, D2D1_OPACITY_MASK_CONTENT_TEXT_NATURAL, D2D1::RectF( -(FLOAT)resolution.width, 0.0f, (FLOAT)0.0f, (FLOAT)resolution.height ), + //D2D1::RectF( 0.0f, 0.0f, (FLOAT)0.0f, (FLOAT)resolution.height ), D2D1::RectF( 0.0f, 0.0f, (FLOAT)resolution.width, (FLOAT)resolution.height ) ); } - else if( currentFrame.colorImageData ) + else if( currentFrame->colorImageData ) { pRT->DrawBitmap( colorBitmap, D2D1::RectF( -(FLOAT)resolution.width, 0.0f, (FLOAT)0.0f, (FLOAT)resolution.height ) ); @@ -388,7 +352,7 @@ void ImageWindow::OnPaint() Array<CirclePlot>::Iterator it; - for( it = currentFrame.plots.Begin(); it != currentFrame.plots.End(); ++it ) + for( it = currentFrame->plots.Begin(); it != currentFrame->plots.End(); ++it ) { ID2D1SolidColorBrush* aBrush; @@ -408,44 +372,96 @@ void ImageWindow::OnPaint() aBrush->Release(); } + static const WCHAR msc_fontName[] = L"Verdana"; + static const FLOAT msc_fontSize = 20; + + IDWriteTextFormat* textFormat = NULL; + + // Create a DirectWrite text format object. + pDWriteFactory->CreateTextFormat( + msc_fontName, + NULL, + DWRITE_FONT_WEIGHT_NORMAL, + DWRITE_FONT_STYLE_NORMAL, + DWRITE_FONT_STRETCH_NORMAL, + msc_fontSize, + L"", //locale + &textFormat + ); + + D2D1_SIZE_F renderTargetSize = pRT->GetSize(); + + Array<TextPlot>::Iterator textIt; + for( textIt = currentFrame->textLines.Begin(); textIt != currentFrame->textLines.End(); ++textIt ) + { + ID2D1SolidColorBrush* aBrush; + + pRT->CreateSolidColorBrush( D2D1::ColorF( textIt->r, textIt->g, textIt->b), &aBrush ); + + WCHAR* tmpString = (WCHAR*)calloc( textIt->text.GetLength(), sizeof( WCHAR ) ); + for( unsigned i = 0; i < textIt->text.GetLength(); ++i ) + { + tmpString[i] = (WCHAR)textIt->text.GetCharAt( i ); + } + + pRT->DrawTextW( tmpString, (UINT32)textIt->text.GetLength(), textFormat, + D2D1::RectF(textIt->x, textIt->y, renderTargetSize.width, renderTargetSize.height), aBrush ); + + free( tmpString ); + + aBrush->Release(); + } + + if( textFormat ) + textFormat->Release(); + pRT->EndDraw(); - if( currentFrame.imageData ) - free( currentFrame.imageData ); - if( currentFrame.colorImageData ) - free( currentFrame.colorImageData ); + pRT->Flush(); } -void ImageWindow::UpdateImageBW( const UINT8* imageData, UINT width, UINT height ) +Ptr<Frame> ImageWindow::lastUnreadyFrame() +{ + static int framenumber = 0; + + if( frames.GetSize() && !frames.PeekBack( 0 )->ready ) + return frames.PeekBack( 0 ); + + // Create a new frame if an unready one doesn't already exist + Ptr<Frame> tmpFrame = *new Frame( framenumber ); + frames.PushBack( tmpFrame ); + + ++framenumber; + + return tmpFrame; +} + +void ImageWindow::UpdateImageBW( const uint8_t* imageData, uint32_t width, uint32_t height ) { if( pRT && greyBitmap ) { Mutex::Locker locker( frontBufferMutex ); - Frame frame = {0}; - frame.imageData = malloc( width * height ); - frame.width = width; - frame.height = height; - memcpy( frame.imageData, imageData, width * height ); - - frames.PushBack( frame ); + Ptr<Frame> frame = lastUnreadyFrame(); + frame->imageData = malloc( width * height ); + frame->width = width; + frame->height = height; + memcpy( frame->imageData, imageData, width * height ); } } -void ImageWindow::UpdateImageRGBA( const UINT8* imageData, UINT width, UINT height, UINT pitch ) +void ImageWindow::UpdateImageRGBA( const uint8_t* imageData, uint32_t width, uint32_t height, uint32_t pitch ) { if( pRT && colorBitmap ) { Mutex::Locker locker( frontBufferMutex ); - Frame frame = {0}; - frame.colorImageData = malloc( pitch * height ); - frame.width = width; - frame.height = height; - frame.colorPitch = pitch; - memcpy( frame.colorImageData, imageData, pitch * height ); - - frames.PushBack( frame ); + Ptr<Frame> frame = lastUnreadyFrame(); + frame->colorImageData = malloc( pitch * height ); + frame->width = width; + frame->height = height; + frame->colorPitch = pitch; + memcpy( frame->colorImageData, imageData, pitch * height ); } } @@ -464,10 +480,32 @@ void ImageWindow::addCircle( float x, float y, float radius, float r, float g, f cp.fill = fill; Mutex::Locker locker( frontBufferMutex ); - Frame& frame = frames.PeekBack( 0 ); - frame.plots.PushBack( cp ); + + Ptr<Frame> frame = lastUnreadyFrame(); + frame->plots.PushBack( cp ); } } +void ImageWindow::addText( float x, float y, float r, float g, float b, OVR::String text ) +{ + if( pRT ) + { + TextPlot tp; + + tp.x = x; + tp.y = y; + tp.r = r; + tp.g = g; + tp.b = b; + tp.text = text; + + Mutex::Locker locker( frontBufferMutex ); + Ptr<Frame> frame = lastUnreadyFrame(); + frame->textLines.PushBack( tp ); + } +} + }} + +#endif //defined(OVR_OS_WIN32)
\ No newline at end of file diff --git a/LibOVR/Src/Util/Util_ImageWindow.h b/LibOVR/Src/Util/Util_ImageWindow.h index 418598c..4b88959 100644 --- a/LibOVR/Src/Util/Util_ImageWindow.h +++ b/LibOVR/Src/Util/Util_ImageWindow.h @@ -5,7 +5,7 @@ Content : An output object for windows that can display raw images for tes Created : March 13, 2014 Authors : Dean Beeler -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. +Copyright : Copyright 2014 Oculus, Inc. All Rights reserved. Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, @@ -27,9 +27,12 @@ limitations under the License. #ifndef UTIL_IMAGEWINDOW_H #define UTIL_IMAGEWINDOW_H +#if defined(OVR_OS_WIN32) #define WIN32_LEAN_AND_MEAN 1 #include <windows.h> #include <d2d1.h> +#include <dwrite.h> +#endif #include "../../Include/OVR.h" #include "../Kernel/OVR_Hash.h" @@ -41,8 +44,6 @@ limitations under the License. namespace OVR { namespace Util { -class ImageWindow -{ typedef struct { float x; @@ -61,44 +62,77 @@ class ImageWindow float r; float g; float b; - WCHAR* text; + OVR::String text; } TextPlot; - typedef struct +class Frame : virtual public RefCountBaseV<Frame> + { +public: + + Frame( int frame ) : + frameNumber( frame ), + imageData( NULL ), + colorImageData( NULL ), + plots(), + textLines(), + width( 0 ), + height( 0 ), + colorPitch( 0 ), + ready( false ) { + + } + + ~Frame() + { + if( imageData ) + free( imageData ); + if( colorImageData ) + free( colorImageData ); + + plots.ClearAndRelease(); + textLines.ClearAndRelease(); + } + + int frameNumber; + Array<CirclePlot> plots; + Array<TextPlot> textLines; void* imageData; void* colorImageData; int width; int height; int colorPitch; bool ready; - } Frame; - - static ID2D1Factory* pD2DFactory; +}; +#if defined(OVR_OS_WIN32) +class ImageWindow +{ HWND hWindow; ID2D1RenderTarget* pRT; D2D1_SIZE_U resolution; Mutex* frontBufferMutex; - InPlaceMutableDeque<Frame> frames; + InPlaceMutableDeque< Ptr<Frame> > frames; ID2D1Bitmap* greyBitmap; ID2D1Bitmap* colorBitmap; - + public: // constructors ImageWindow(); - ImageWindow( UINT width, UINT height ); + ImageWindow( uint32_t width, uint32_t height ); virtual ~ImageWindow(); + void GetResolution( size_t& width, size_t& height ) { width = resolution.width; height = resolution.height; } + void OnPaint(); // Called by Windows when it receives a WM_PAINT message - void UpdateImage( const UINT8* imageData, UINT width, UINT height ) { UpdateImageBW( imageData, width, height ); } - void UpdateImageBW( const UINT8* imageData, UINT width, UINT height ); - void UpdateImageRGBA( const UINT8* imageData, UINT width, UINT height, UINT pitch ); + void UpdateImage( const uint8_t* imageData, uint32_t width, uint32_t height ) { UpdateImageBW( imageData, width, height ); } + void UpdateImageBW( const uint8_t* imageData, uint32_t width, uint32_t height ); + void UpdateImageRGBA( const uint8_t* imageData, uint32_t width, uint32_t height, uint32_t pitch ); void Complete(); // Called by drawing thread to submit a frame void Process(); // Called by rendering thread to do window processing @@ -106,17 +140,61 @@ public: void AssociateSurface( void* surface ); void addCircle( float x , float y, float radius, float r, float g, float b, bool fill ); + void addText( float x, float y, float r, float g, float b, OVR::String text ); - static ImageWindow* GlobalWindow() { return globalWindow; } + static ImageWindow* GlobalWindow( int window ) { return globalWindow[window]; } + static int WindowCount() { return windowCount; } private: + Ptr<Frame> lastUnreadyFrame(); - static ImageWindow* globalWindow; + static const int MaxWindows = 4; + static ImageWindow* globalWindow[MaxWindows]; + static int windowCount; + static ID2D1Factory* pD2DFactory; + static IDWriteFactory* pDWriteFactory; +}; - static bool running; +#else + +class ImageWindow +{ +public: + // constructors + ImageWindow() {} + ImageWindow( uint32_t width, uint32_t height ) { OVR_UNUSED( width ); OVR_UNUSED( height ); } + virtual ~ImageWindow() { } + + void GetResolution( size_t& width, size_t& height ) { width = 0; height = 0; } + + void OnPaint() { } + + void UpdateImage( const uint8_t* imageData, uint32_t width, uint32_t height ) { UpdateImageBW( imageData, width, height ); } + void UpdateImageBW( const uint8_t* imageData, uint32_t width, uint32_t height ) { } + void UpdateImageRGBA( const uint8_t* imageData, uint32_t width, uint32_t height, uint32_t pitch ) { } + void Complete() { } + + void Process() { } + + void AssociateSurface( void* surface ) { } + + void addCircle( float x , float y, float radius, float r, float g, float b, bool fill ) { } + void addText( float x, float y, float r, float g, float b, OVR::String text ) { } + + static ImageWindow* GlobalWindow( int window ) { return globalWindow[window]; } + static int WindowCount() { return windowCount; } + +private: + + static const int MaxWindows = 4; + static ImageWindow* globalWindow[4]; + static int windowCount; }; +#endif + }} // namespace OVR::Util + #endif
\ No newline at end of file diff --git a/LibOVR/Src/Util/Util_LatencyTest2.cpp b/LibOVR/Src/Util/Util_LatencyTest2.cpp index f4baf29..6fc8b1f 100644 --- a/LibOVR/Src/Util/Util_LatencyTest2.cpp +++ b/LibOVR/Src/Util/Util_LatencyTest2.cpp @@ -33,9 +33,6 @@ limitations under the License. namespace OVR { namespace Util { -//static const float BIG_FLOAT = 1000000.0f; -//static const float SMALL_FLOAT = -1000000.0f; - //------------------------------------------------------------------------------------- // ***** LatencyTest2 diff --git a/LibOVR/Src/Util/Util_LatencyTest2.h b/LibOVR/Src/Util/Util_LatencyTest2.h index ae11a52..61e8477 100644 --- a/LibOVR/Src/Util/Util_LatencyTest2.h +++ b/LibOVR/Src/Util/Util_LatencyTest2.h @@ -118,7 +118,7 @@ struct FrameTimeRecordSet // Advances I to absolute color index bool FindReadbackIndex(int* i, int readbackIndex) const { - for (; *i < RecordCount; *i++) + for (; *i < RecordCount; (*i)++) { if ((*this)[*i].ReadbackIndex == readbackIndex) return true; diff --git a/LibOVR/Src/Util/Util_Render_Stereo.cpp b/LibOVR/Src/Util/Util_Render_Stereo.cpp index 87fed3c..e84381e 100644 --- a/LibOVR/Src/Util/Util_Render_Stereo.cpp +++ b/LibOVR/Src/Util/Util_Render_Stereo.cpp @@ -836,8 +836,8 @@ void DistortionMeshCreate( DistortionMeshVertexData **ppVertices, UInt16 **ppTri } *ppVertices = NULL; *ppTriangleListIndices = NULL; - *pNumTriangles = NULL; - *pNumVertices = NULL; + *pNumTriangles = 0; + *pNumVertices = 0; return; } @@ -848,6 +848,7 @@ void DistortionMeshCreate( DistortionMeshVertexData **ppVertices, UInt16 **ppTri // Populate vertex buffer info float xOffset = 0.0f; float uOffset = 0.0f; + OVR_UNUSED(uOffset); if (rightEye) { @@ -1002,8 +1003,204 @@ void DistortionMeshCreate( DistortionMeshVertexData **ppVertices, UInt16 **ppTri } } +//----------------------------------------------------------------------------------- +// ***** Heightmap Mesh Rendering + + +static const int HMA_GridSizeLog2 = 7; +static const int HMA_GridSize = 1<<HMA_GridSizeLog2; +static const int HMA_NumVertsPerEye = (HMA_GridSize+1)*(HMA_GridSize+1); +static const int HMA_NumTrisPerEye = (HMA_GridSize)*(HMA_GridSize)*2; + + +void HeightmapMeshDestroy ( HeightmapMeshVertexData *pVertices, UInt16 *pTriangleMeshIndices ) +{ + OVR_FREE ( pVertices ); + OVR_FREE ( pTriangleMeshIndices ); +} + +void HeightmapMeshCreate ( HeightmapMeshVertexData **ppVertices, UInt16 **ppTriangleListIndices, + int *pNumVertices, int *pNumTriangles, + const StereoEyeParams &stereoParams, const HmdRenderInfo &hmdRenderInfo ) +{ + bool rightEye = ( stereoParams.Eye == StereoEye_Right ); + int vertexCount = 0; + int triangleCount = 0; + + // Generate mesh into allocated data and return result. + HeightmapMeshCreate(ppVertices, ppTriangleListIndices, &vertexCount, &triangleCount, + rightEye, hmdRenderInfo, stereoParams.EyeToSourceNDC); + + *pNumVertices = vertexCount; + *pNumTriangles = triangleCount; +} +// Generate heightmap mesh for one eye. +void HeightmapMeshCreate( HeightmapMeshVertexData **ppVertices, UInt16 **ppTriangleListIndices, + int *pNumVertices, int *pNumTriangles, bool rightEye, + const HmdRenderInfo &hmdRenderInfo, + const ScaleAndOffset2D &eyeToSourceNDC ) +{ + *pNumVertices = HMA_NumVertsPerEye; + *pNumTriangles = HMA_NumTrisPerEye; + + *ppVertices = (HeightmapMeshVertexData*) OVR_ALLOC( sizeof(HeightmapMeshVertexData) * (*pNumVertices) ); + *ppTriangleListIndices = (UInt16*) OVR_ALLOC( sizeof(UInt16) * (*pNumTriangles) * 3 ); + + if (!*ppVertices || !*ppTriangleListIndices) + { + if (*ppVertices) + { + OVR_FREE(*ppVertices); + } + if (*ppTriangleListIndices) + { + OVR_FREE(*ppTriangleListIndices); + } + *ppVertices = NULL; + *ppTriangleListIndices = NULL; + *pNumTriangles = 0; + *pNumVertices = 0; + return; + } + + // Populate vertex buffer info + float xOffset = 0.0f; + float uOffset = 0.0f; + + if (rightEye) + { + xOffset = 1.0f; + uOffset = 0.5f; + } + + // First pass - build up raw vertex data. + HeightmapMeshVertexData* pcurVert = *ppVertices; + + for ( int y = 0; y <= HMA_GridSize; y++ ) + { + for ( int x = 0; x <= HMA_GridSize; x++ ) + { + Vector2f sourceCoordNDC; + // NDC texture coords [-1,+1] + sourceCoordNDC.x = 2.0f * ( (float)x / (float)HMA_GridSize ) - 1.0f; + sourceCoordNDC.y = 2.0f * ( (float)y / (float)HMA_GridSize ) - 1.0f; + Vector2f tanEyeAngle = TransformRendertargetNDCToTanFovSpace ( eyeToSourceNDC, sourceCoordNDC ); + + pcurVert->TanEyeAngles = tanEyeAngle; + + HmdShutterTypeEnum shutterType = hmdRenderInfo.Shutter.Type; + switch ( shutterType ) + { + case HmdShutter_Global: + pcurVert->TimewarpLerp = 0.0f; + break; + case HmdShutter_RollingLeftToRight: + // Retrace is left to right - left eye goes 0.0 -> 0.5, then right goes 0.5 -> 1.0 + pcurVert->TimewarpLerp = sourceCoordNDC.x * 0.25f + 0.25f; + if (rightEye) + { + pcurVert->TimewarpLerp += 0.5f; + } + break; + case HmdShutter_RollingRightToLeft: + // Retrace is right to left - right eye goes 0.0 -> 0.5, then left goes 0.5 -> 1.0 + pcurVert->TimewarpLerp = 0.75f - sourceCoordNDC.x * 0.25f; + if (rightEye) + { + pcurVert->TimewarpLerp -= 0.5f; + } + break; + case HmdShutter_RollingTopToBottom: + // Retrace is top to bottom on both eyes at the same time. + pcurVert->TimewarpLerp = sourceCoordNDC.y * 0.5f + 0.5f; + break; + default: OVR_ASSERT ( false ); break; + } + + // Don't let verts overlap to the other eye. + //sourceCoordNDC.x = Alg::Max ( -1.0f, Alg::Min ( sourceCoordNDC.x, 1.0f ) ); + //sourceCoordNDC.y = Alg::Max ( -1.0f, Alg::Min ( sourceCoordNDC.y, 1.0f ) ); + + //pcurVert->ScreenPosNDC.x = 0.5f * sourceCoordNDC.x - 0.5f + xOffset; + pcurVert->ScreenPosNDC.x = sourceCoordNDC.x; + pcurVert->ScreenPosNDC.y = -sourceCoordNDC.y; + + pcurVert++; + } + } + + + // Populate index buffer info + UInt16 *pcurIndex = *ppTriangleListIndices; + + for ( int triNum = 0; triNum < HMA_GridSize * HMA_GridSize; triNum++ ) + { + // Use a Morton order to help locality of FB, texture and vertex cache. + // (0.325ms raster order -> 0.257ms Morton order) + OVR_ASSERT ( HMA_GridSize < 256 ); + int x = ( ( triNum & 0x0001 ) >> 0 ) | + ( ( triNum & 0x0004 ) >> 1 ) | + ( ( triNum & 0x0010 ) >> 2 ) | + ( ( triNum & 0x0040 ) >> 3 ) | + ( ( triNum & 0x0100 ) >> 4 ) | + ( ( triNum & 0x0400 ) >> 5 ) | + ( ( triNum & 0x1000 ) >> 6 ) | + ( ( triNum & 0x4000 ) >> 7 ); + int y = ( ( triNum & 0x0002 ) >> 1 ) | + ( ( triNum & 0x0008 ) >> 2 ) | + ( ( triNum & 0x0020 ) >> 3 ) | + ( ( triNum & 0x0080 ) >> 4 ) | + ( ( triNum & 0x0200 ) >> 5 ) | + ( ( triNum & 0x0800 ) >> 6 ) | + ( ( triNum & 0x2000 ) >> 7 ) | + ( ( triNum & 0x8000 ) >> 8 ); + int FirstVertex = x * (HMA_GridSize+1) + y; + // Another twist - we want the top-left and bottom-right quadrants to + // have the triangles split one way, the other two split the other. + // +---+---+---+---+ + // | /| /|\ |\ | + // | / | / | \ | \ | + // |/ |/ | \| \| + // +---+---+---+---+ + // | /| /|\ |\ | + // | / | / | \ | \ | + // |/ |/ | \| \| + // +---+---+---+---+ + // |\ |\ | /| /| + // | \ | \ | / | / | + // | \| \|/ |/ | + // +---+---+---+---+ + // |\ |\ | /| /| + // | \ | \ | / | / | + // | \| \|/ |/ | + // +---+---+---+---+ + // This way triangle edges don't span long distances over the distortion function, + // so linear interpolation works better & we can use fewer tris. + if ( ( x < HMA_GridSize/2 ) != ( y < HMA_GridSize/2 ) ) // != is logical XOR + { + *pcurIndex++ = (UInt16)FirstVertex; + *pcurIndex++ = (UInt16)FirstVertex+1; + *pcurIndex++ = (UInt16)FirstVertex+(HMA_GridSize+1)+1; + + *pcurIndex++ = (UInt16)FirstVertex+(HMA_GridSize+1)+1; + *pcurIndex++ = (UInt16)FirstVertex+(HMA_GridSize+1); + *pcurIndex++ = (UInt16)FirstVertex; + } + else + { + *pcurIndex++ = (UInt16)FirstVertex; + *pcurIndex++ = (UInt16)FirstVertex+1; + *pcurIndex++ = (UInt16)FirstVertex+(HMA_GridSize+1); + + *pcurIndex++ = (UInt16)FirstVertex+1; + *pcurIndex++ = (UInt16)FirstVertex+(HMA_GridSize+1)+1; + *pcurIndex++ = (UInt16)FirstVertex+(HMA_GridSize+1); + } + } +} + //----------------------------------------------------------------------------------- // ***** Prediction and timewarp. // @@ -1075,10 +1272,10 @@ PredictionValues PredictionGetDeviceValues ( const HmdRenderInfo &hmdRenderInfo, return result; } -Matrix4f TimewarpComputePoseDelta ( Matrix4f const &renderedViewFromWorld, Matrix4f const &predictedViewFromWorld ) +Matrix4f TimewarpComputePoseDelta ( Matrix4f const &renderedViewFromWorld, Matrix4f const &predictedViewFromWorld, Matrix4f const&eyeViewAdjust ) { - Matrix4f worldFromPredictedView = predictedViewFromWorld.InvertedHomogeneousTransform(); - Matrix4f matRenderFromNowStart = renderedViewFromWorld * worldFromPredictedView; + Matrix4f worldFromPredictedView = (eyeViewAdjust * predictedViewFromWorld).InvertedHomogeneousTransform(); + Matrix4f matRenderFromNowStart = (eyeViewAdjust * renderedViewFromWorld) * worldFromPredictedView; // The sensor-predicted orientations have: X=right, Y=up, Z=backwards. // The vectors inside the mesh are in NDC to keep the shader simple: X=right, Y=down, Z=forwards. @@ -1109,12 +1306,19 @@ Matrix4f TimewarpComputePoseDelta ( Matrix4f const &renderedViewFromWorld, Matri return matRenderFromNowStart; } +Matrix4f TimewarpComputePoseDeltaPosition ( Matrix4f const &renderedViewFromWorld, Matrix4f const &predictedViewFromWorld, Matrix4f const&eyeViewAdjust ) +{ + Matrix4f worldFromPredictedView = (eyeViewAdjust * predictedViewFromWorld).InvertedHomogeneousTransform(); + Matrix4f matRenderXform = (eyeViewAdjust * renderedViewFromWorld) * worldFromPredictedView; + + return matRenderXform.Inverted(); +} TimewarpMachine::TimewarpMachine() { for ( int i = 0; i < 2; i++ ) { - EyeRenderPoses[i] = Posef(); + EyeRenderPoses[i] = Transformf(); } DistortionTimeCount = 0; VsyncEnabled = false; @@ -1145,7 +1349,7 @@ double TimewarpMachine::GetViewRenderPredictionTime() return NextFramePresentFlushTime + CurrentPredictionValues.PresentFlushToRenderedScene; } -Posef TimewarpMachine::GetViewRenderPredictionPose(SensorFusion &sfusion) +Transformf TimewarpMachine::GetViewRenderPredictionPose(SensorFusion &sfusion) { double predictionTime = GetViewRenderPredictionTime(); return sfusion.GetPoseAtTime(predictionTime); @@ -1161,29 +1365,31 @@ double TimewarpMachine::GetVisiblePixelTimeEnd() // Note that PredictionGetDeviceValues() did all the vsync-dependent thinking for us. return NextFramePresentFlushTime + CurrentPredictionValues.PresentFlushToTimewarpEnd; } -Posef TimewarpMachine::GetPredictedVisiblePixelPoseStart(SensorFusion &sfusion) +Transformf TimewarpMachine::GetPredictedVisiblePixelPoseStart(SensorFusion &sfusion) { double predictionTime = GetVisiblePixelTimeStart(); return sfusion.GetPoseAtTime(predictionTime); } -Posef TimewarpMachine::GetPredictedVisiblePixelPoseEnd (SensorFusion &sfusion) +Transformf TimewarpMachine::GetPredictedVisiblePixelPoseEnd (SensorFusion &sfusion) { double predictionTime = GetVisiblePixelTimeEnd(); return sfusion.GetPoseAtTime(predictionTime); } -Matrix4f TimewarpMachine::GetTimewarpDeltaStart(SensorFusion &sfusion, Posef const &renderedPose) +Matrix4f TimewarpMachine::GetTimewarpDeltaStart(SensorFusion &sfusion, Transformf const &renderedPose) { - Posef visiblePose = GetPredictedVisiblePixelPoseStart ( sfusion ); + Transformf visiblePose = GetPredictedVisiblePixelPoseStart ( sfusion ); Matrix4f visibleMatrix(visiblePose); Matrix4f renderedMatrix(renderedPose); - return TimewarpComputePoseDelta ( renderedMatrix, visibleMatrix ); + Matrix4f identity; // doesn't matter for orientation-only timewarp + return TimewarpComputePoseDelta ( renderedMatrix, visibleMatrix, identity ); } -Matrix4f TimewarpMachine::GetTimewarpDeltaEnd (SensorFusion &sfusion, Posef const &renderedPose) +Matrix4f TimewarpMachine::GetTimewarpDeltaEnd (SensorFusion &sfusion, Transformf const &renderedPose) { - Posef visiblePose = GetPredictedVisiblePixelPoseEnd ( sfusion ); + Transformf visiblePose = GetPredictedVisiblePixelPoseEnd ( sfusion ); Matrix4f visibleMatrix(visiblePose); Matrix4f renderedMatrix(renderedPose); - return TimewarpComputePoseDelta ( renderedMatrix, visibleMatrix ); + Matrix4f identity; // doesn't matter for orientation-only timewarp + return TimewarpComputePoseDelta ( renderedMatrix, visibleMatrix, identity ); } diff --git a/LibOVR/Src/Util/Util_Render_Stereo.h b/LibOVR/Src/Util/Util_Render_Stereo.h index 2ad9103..326059e 100644 --- a/LibOVR/Src/Util/Util_Render_Stereo.h +++ b/LibOVR/Src/Util/Util_Render_Stereo.h @@ -349,6 +349,37 @@ void DistortionMeshCreate( DistortionMeshVertexData **ppVertices, UInt16 **ppTri void DistortionMeshDestroy ( DistortionMeshVertexData *pVertices, UInt16 *pTriangleMeshIndices ); +//----------------------------------------------------------------------------------- +// ***** Heightmap Mesh Rendering +// + +// Stores both texture UV coords, or tan(angle) values. +// This struct *must* be binary compatible with CAPI ovrHeightmapVertex. +struct HeightmapMeshVertexData +{ + // [-1,+1],[-1,+1] over the entire framebuffer. + Vector2f ScreenPosNDC; + // [0.0-1.0] interpolation value for timewarping - see documentation for details. + float TimewarpLerp; + // The vectors in tan(angle) space. + // Scale and offset by the values in StereoEyeParams.EyeToSourceUV.Scale + // and StereoParams.EyeToSourceUV.Offset to get to real texture UV coords. + Vector2f TanEyeAngles; +}; + + +void HeightmapMeshCreate ( HeightmapMeshVertexData **ppVertices, UInt16 **ppTriangleListIndices, + int *pNumVertices, int *pNumTriangles, + const StereoEyeParams &stereoParams, const HmdRenderInfo &hmdRenderInfo ); + +// Generate heightmap mesh for a eye. This version requires less data then stereoParms, supporting +// dynamic change in render target viewport. +void HeightmapMeshCreate( HeightmapMeshVertexData **ppVertices, UInt16 **ppTriangleListIndices, + int *pNumVertices, int *pNumTriangles, bool rightEye, + const HmdRenderInfo &hmdRenderInfo, const ScaleAndOffset2D &eyeToSourceNDC ); + +void HeightmapMeshDestroy ( HeightmapMeshVertexData *pVertices, UInt16 *pTriangleMeshIndices ); + //----------------------------------------------------------------------------------- @@ -380,7 +411,8 @@ PredictionValues PredictionGetDeviceValues ( const HmdRenderInfo &hmdRenderInfo, // (which may have been computed later on, and thus is more accurate), and this // will return the matrix to pass to the timewarp distortion shader. // TODO: deal with different handedness? -Matrix4f TimewarpComputePoseDelta ( Matrix4f const &renderedViewFromWorld, Matrix4f const &predictedViewFromWorld ); +Matrix4f TimewarpComputePoseDelta ( Matrix4f const &renderedViewFromWorld, Matrix4f const &predictedViewFromWorld, Matrix4f const&eyeViewAdjust ); +Matrix4f TimewarpComputePoseDeltaPosition ( Matrix4f const &renderedViewFromWorld, Matrix4f const &predictedViewFromWorld, Matrix4f const&eyeViewAdjust ); @@ -402,7 +434,7 @@ public: // and the predicted pose of the HMD at that time. // You usually only need to call one of these functions. double GetViewRenderPredictionTime(); - Posef GetViewRenderPredictionPose(SensorFusion &sfusion); + Transformf GetViewRenderPredictionPose(SensorFusion &sfusion); // Timewarp prediction functions. You usually only need to call one of these three sets of functions. @@ -411,13 +443,13 @@ public: double GetVisiblePixelTimeStart(); double GetVisiblePixelTimeEnd(); // Predicted poses of the HMD at those first and last pixels. - Posef GetPredictedVisiblePixelPoseStart(SensorFusion &sfusion); - Posef GetPredictedVisiblePixelPoseEnd (SensorFusion &sfusion); + Transformf GetPredictedVisiblePixelPoseStart(SensorFusion &sfusion); + Transformf GetPredictedVisiblePixelPoseEnd (SensorFusion &sfusion); // The delta matrices to feed to the timewarp distortion code, // given the pose that was used for rendering. // (usually the one returned by GetViewRenderPredictionPose() earlier) - Matrix4f GetTimewarpDeltaStart(SensorFusion &sfusion, Posef const &renderedPose); - Matrix4f GetTimewarpDeltaEnd (SensorFusion &sfusion, Posef const &renderedPose); + Matrix4f GetTimewarpDeltaStart(SensorFusion &sfusion, Transformf const &renderedPose); + Matrix4f GetTimewarpDeltaEnd (SensorFusion &sfusion, Transformf const &renderedPose); // Just-In-Time distortion aims to delay the second sensor reading & distortion @@ -448,7 +480,7 @@ private: float DistortionTimeAverage; // Pose at which last time the eye was rendered. - Posef EyeRenderPoses[2]; + Transformf EyeRenderPoses[2]; // Absolute time of the last present+flush double LastFramePresentFlushTime; diff --git a/Samples/CommonSrc/Platform/Win32_Platform.h b/Samples/CommonSrc/Platform/Win32_Platform.h index 23f0b70..a450cb4 100644 --- a/Samples/CommonSrc/Platform/Win32_Platform.h +++ b/Samples/CommonSrc/Platform/Win32_Platform.h @@ -61,7 +61,12 @@ public: bool SetupWindow(int w, int h); void DestroyWindow(); void ShowWindow(bool visible); - void Exit(int exitcode) { Quit = 1; ExitCode = exitcode; } + void Exit(int exitcode) + { + for (MSG msg; PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); ) + ; + Quit = 1; ExitCode = exitcode; + } RenderDevice* SetupGraphics(const SetupGraphicsDeviceSet& setupGraphicsDesc, const char* type, diff --git a/Samples/CommonSrc/Render/Render_D3D1X_Device.cpp b/Samples/CommonSrc/Render/Render_D3D1X_Device.cpp index d7c606f..5476a6f 100644 --- a/Samples/CommonSrc/Render/Render_D3D1X_Device.cpp +++ b/Samples/CommonSrc/Render/Render_D3D1X_Device.cpp @@ -50,6 +50,7 @@ static D3D1x_(INPUT_ELEMENT_DESC) ModelVertexDesc[] = {"Normal", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, offsetof(Vertex, Norm), D3D1x_(INPUT_PER_VERTEX_DATA), 0}, }; +#pragma region Geometry shaders static const char* StdVertexShaderSrc = "float4x4 Proj;\n" "float4x4 View;\n" @@ -95,7 +96,10 @@ static const char* SolidPixelShaderSrc = "};\n" "float4 main(in Varyings ov) : SV_Target\n" "{\n" - " return Color;\n" + " float4 finalColor = ov.Color;" + // blend state expects premultiplied alpha + " finalColor.rgb *= finalColor.a;\n" + " return finalColor;\n" "}\n"; static const char* GouraudPixelShaderSrc = @@ -107,7 +111,10 @@ static const char* GouraudPixelShaderSrc = "};\n" "float4 main(in Varyings ov) : SV_Target\n" "{\n" - " return ov.Color;\n" + " float4 finalColor = ov.Color;" + // blend state expects premultiplied alpha + " finalColor.rgb *= finalColor.a;\n" + " return finalColor;\n" "}\n"; static const char* TexturePixelShaderSrc = @@ -213,11 +220,14 @@ static const char* AlphaTexturePixelShaderSrc = "float4 main(in Varyings ov) : SV_Target\n" "{\n" " float4 finalColor = ov.Color;\n" - " finalColor.a *= Texture.Sample(Linear, ov.TexCoord).r;\n" + " finalColor.a *= Texture.Sample(Linear, ov.TexCoord).r;\n" + // blend state expects premultiplied alpha + " finalColor.rgb *= finalColor.a;\n" " return finalColor;\n" "}\n"; +#pragma endregion - +#pragma region Distortion shaders // ***** PostProcess Shader static const char* PostProcessVertexShaderSrc = @@ -280,11 +290,12 @@ static const char* PostProcessPixelShaderWithChromAbSrc = " EdgeFadeIn = saturate ( EdgeFadeIn );\n" // Actually do the lookups. - " float ResultR = Texture.Sample(Linear, SourceCoordR).r;\n" - " float ResultG = Texture.Sample(Linear, SourceCoordG).g;\n" - " float ResultB = Texture.Sample(Linear, SourceCoordB).b;\n" - - " return float4(ResultR * EdgeFadeIn, ResultG * EdgeFadeIn, ResultB * EdgeFadeIn, 1.0);\n" + " float4 Result = float4(0,0,0,1);\n" + " Result.r = Texture.Sample(Linear, SourceCoordR).r;\n" + " Result.g = Texture.Sample(Linear, SourceCoordG).g;\n" + " Result.b = Texture.Sample(Linear, SourceCoordB).b;\n" + " Result.rgb *= EdgeFadeIn;\n" + " return Result;\n" "}\n"; //---------------------------------------------------------------------------- @@ -310,7 +321,6 @@ static D3D1x_(INPUT_ELEMENT_DESC) DistortionVertexDesc[] = {"Color", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 8+8+8+8, D3D1x_(INPUT_PER_VERTEX_DATA), 0}, }; - //---------------------------------------------------------------------------- // Simple distortion shader that does three texture reads. // Used for mesh-based distortion without timewarp. @@ -334,16 +344,33 @@ static const char* PostProcessMeshVertexShaderSrc = "}\n"; static const char* PostProcessMeshPixelShaderSrc = - "Texture2D Texture : register(t0);\n" + "Texture2D HmdSpcTexture : register(t0);\n" + "Texture2D OverlayTexture : register(t1);\n" "SamplerState Linear : register(s0);\n" + "float UseOverlay = 1;\n" "\n" "float4 main(in float4 oPosition : SV_Position, in float4 oColor : COLOR,\n" " in float2 oTexCoord0 : TEXCOORD0, in float2 oTexCoord1 : TEXCOORD1, in float2 oTexCoord2 : TEXCOORD2) : SV_Target\n" "{\n" - " float ResultR = Texture.Sample(Linear, oTexCoord0).r;\n" - " float ResultG = Texture.Sample(Linear, oTexCoord1).g;\n" - " float ResultB = Texture.Sample(Linear, oTexCoord2).b;\n" - " return float4(ResultR * oColor.r, ResultG * oColor.g, ResultB * oColor.b, 1.0);\n" + " float4 finalColor = float4(0,0,0,1);\n" + " finalColor.r = HmdSpcTexture.Sample(Linear, oTexCoord0).r;\n" + " finalColor.g = HmdSpcTexture.Sample(Linear, oTexCoord1).g;\n" + " finalColor.b = HmdSpcTexture.Sample(Linear, oTexCoord2).b;\n" + + " if(UseOverlay > 0)\n" + " {\n" + " float2 overlayColorR = OverlayTexture.Sample(Linear, oTexCoord0).ra;\n" + " float2 overlayColorG = OverlayTexture.Sample(Linear, oTexCoord1).ga;\n" + " float2 overlayColorB = OverlayTexture.Sample(Linear, oTexCoord2).ba;\n" + + // do premultiplied alpha blending - overlayColorX.x is color, overlayColorX.y is alpha + " finalColor.r = finalColor.r * saturate(1-overlayColorR.y) + overlayColorR.x;\n" + " finalColor.g = finalColor.g * saturate(1-overlayColorG.y) + overlayColorG.x;\n" + " finalColor.b = finalColor.b * saturate(1-overlayColorB.y) + overlayColorB.x;\n" + " }\n" + + " finalColor.rgb = saturate(finalColor.rgb * oColor.rgb);\n" + " return finalColor;\n" "}\n"; @@ -357,8 +384,11 @@ static const char* PostProcessMeshTimewarpVertexShaderSrc = "float2 EyeToSourceUVOffset;\n" "float3x3 EyeRotationStart;\n" "float3x3 EyeRotationEnd;\n" - "void main(in float2 Position : POSITION, in float4 Color : COLOR0, in float2 TexCoord0 : TEXCOORD0, in float2 TexCoord1 : TEXCOORD1, in float2 TexCoord2 : TEXCOORD2,\n" - " out float4 oPosition : SV_Position, out float4 oColor : COLOR, out float2 oTexCoord0 : TEXCOORD0, out float2 oTexCoord1 : TEXCOORD1, out float2 oTexCoord2 : TEXCOORD2)\n" + "void main(in float2 Position : POSITION, in float4 Color : COLOR0,\n" + " in float2 TexCoord0 : TEXCOORD0, in float2 TexCoord1 : TEXCOORD1, in float2 TexCoord2 : TEXCOORD2,\n" + " out float4 oPosition : SV_Position, out float4 oColor : COLOR,\n" + " out float2 oHmdSpcTexCoordR : TEXCOORD0, out float2 oHmdSpcTexCoordG : TEXCOORD1, out float2 oHmdSpcTexCoordB : TEXCOORD2," + " out float2 oOverlayTexCoordR : TEXCOORD3, out float2 oOverlayTexCoordG : TEXCOORD4, out float2 oOverlayTexCoordB : TEXCOORD5)\n" "{\n" " oPosition.x = Position.x;\n" " oPosition.y = Position.y;\n" @@ -401,51 +431,73 @@ static const char* PostProcessMeshTimewarpVertexShaderSrc = // These are now still in TanEyeAngle space. // Scale them into the correct [0-1],[0-1] UV lookup space (depending on eye) - " float2 SrcCoordR = FlattenedR * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - " float2 SrcCoordG = FlattenedG * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - " float2 SrcCoordB = FlattenedB * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - " oTexCoord0 = SrcCoordR;\n" - " oTexCoord1 = SrcCoordG;\n" - " oTexCoord2 = SrcCoordB;\n" + " oHmdSpcTexCoordR = FlattenedR * EyeToSourceUVScale + EyeToSourceUVOffset;\n" + " oHmdSpcTexCoordG = FlattenedG * EyeToSourceUVScale + EyeToSourceUVOffset;\n" + " oHmdSpcTexCoordB = FlattenedB * EyeToSourceUVScale + EyeToSourceUVOffset;\n" + + // Static layer texcoords don't get any time warp offset + " oOverlayTexCoordR = TexCoord0 * EyeToSourceUVScale + EyeToSourceUVOffset;\n" + " oOverlayTexCoordG = TexCoord1 * EyeToSourceUVScale + EyeToSourceUVOffset;\n" + " oOverlayTexCoordB = TexCoord2 * EyeToSourceUVScale + EyeToSourceUVOffset;\n" + " oColor = Color.r;\n" // Used for vignette fade. "}\n"; static const char* PostProcessMeshTimewarpPixelShaderSrc = - "Texture2D Texture : register(t0);\n" + "Texture2D HmdSpcTexture : register(t0);\n" + "Texture2D OverlayTexture : register(t1);\n" "SamplerState Linear : register(s0);\n" + "float UseOverlay = 1;\n" "\n" "float4 main(in float4 oPosition : SV_Position, in float4 oColor : COLOR,\n" - " in float2 oTexCoord0 : TEXCOORD0, in float2 oTexCoord1 : TEXCOORD1, in float2 oTexCoord2 : TEXCOORD2) : SV_Target\n" + " in float2 oHmdSpcTexCoordR : TEXCOORD0, in float2 oHmdSpcTexCoordG : TEXCOORD1, in float2 oHmdSpcTexCoordB : TEXCOORD2," + " in float2 oOverlayTexCoordR : TEXCOORD3, in float2 oOverlayTexCoordG : TEXCOORD4, in float2 oOverlayTexCoordB : TEXCOORD5) : SV_Target\n" "{\n" - " float ResultR = Texture.Sample(Linear, oTexCoord0).r;\n" - " float ResultG = Texture.Sample(Linear, oTexCoord1).g;\n" - " float ResultB = Texture.Sample(Linear, oTexCoord2).b;\n" - " return float4(ResultR * oColor.r, ResultG * oColor.g, ResultB * oColor.b, 1.0);\n" + " float4 finalColor = float4(0,0,0,1);\n" + " finalColor.r = HmdSpcTexture.Sample(Linear, oHmdSpcTexCoordR).r;\n" + " finalColor.g = HmdSpcTexture.Sample(Linear, oHmdSpcTexCoordG).g;\n" + " finalColor.b = HmdSpcTexture.Sample(Linear, oHmdSpcTexCoordB).b;\n" + + " if(UseOverlay > 0)\n" + " {\n" + " float2 overlayColorR = OverlayTexture.Sample(Linear, oOverlayTexCoordR).ra;\n" + " float2 overlayColorG = OverlayTexture.Sample(Linear, oOverlayTexCoordG).ga;\n" + " float2 overlayColorB = OverlayTexture.Sample(Linear, oOverlayTexCoordB).ba;\n" + + // do premultiplied alpha blending - overlayColorX.x is color, overlayColorX.y is alpha + " finalColor.r = finalColor.r * saturate(1-overlayColorR.y) + overlayColorR.x;\n" + " finalColor.g = finalColor.g * saturate(1-overlayColorG.y) + overlayColorG.x;\n" + " finalColor.b = finalColor.b * saturate(1-overlayColorB.y) + overlayColorB.x;\n" + " }\n" + + " finalColor.rgb = saturate(finalColor.rgb * oColor.rgb);\n" + " return finalColor;\n" "}\n"; + //---------------------------------------------------------------------------- // Pixel shader is very simple - does three texture reads. // Vertex shader does all the hard work. // Used for mesh-based distortion with positional timewarp. static const char* PostProcessMeshPositionalTimewarpVertexShaderSrc = - "Texture2DMS<float,4> DepthTexture : register(t0);\n" + "Texture2DMS<float,4> DepthTexture : register(t0);\n" // Padding because we are uploading "standard uniform buffer" constants "float4x4 Padding1;\n" "float4x4 Padding2;\n" "float2 EyeToSourceUVScale;\n" "float2 EyeToSourceUVOffset;\n" - "float2 DepthProjector;\n" - "float2 DepthDimSize;\n" - "float4x4 EyeRotationStart;\n" + "float2 DepthProjector;\n" + "float2 DepthDimSize;\n" + "float4x4 EyeRotationStart;\n" "float4x4 EyeRotationEnd;\n" "float4 PositionFromDepth(float2 inTexCoord)\n" "{\n" " float2 eyeToSourceTexCoord = inTexCoord * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - " float depth = DepthTexture.Load(int2(eyeToSourceTexCoord * DepthDimSize), 0).x;\n" - " float linearDepth = DepthProjector.y / (depth - DepthProjector.x);\n" - " float4 retVal = float4(inTexCoord, 1, 1);\n" + " float depth = DepthTexture.Load(int2(eyeToSourceTexCoord * DepthDimSize), 0).x;\n" + " float linearDepth = DepthProjector.y / (depth - DepthProjector.x);\n" + " float4 retVal = float4(inTexCoord, 1, 1);\n" " retVal.xyz *= linearDepth;\n" " return retVal;\n" "}\n" @@ -465,10 +517,11 @@ static const char* PostProcessMeshPositionalTimewarpVertexShaderSrc = " return noDepthUV.xy;\n" "}\n" - "void main( in float2 Position : POSITION, in float4 Color : COLOR0, in float2 TexCoord0 : TEXCOORD0,\n" - " in float2 TexCoord1 : TEXCOORD1, in float2 TexCoord2 : TEXCOORD2,\n" - " out float4 oPosition : SV_Position, out float4 oColor : COLOR,\n" - " out float2 oTexCoord0 : TEXCOORD0, out float2 oTexCoord1 : TEXCOORD1, out float2 oTexCoord2 : TEXCOORD2)\n" + "void main(in float2 Position : POSITION, in float4 Color : COLOR0, in float2 TexCoord0 : TEXCOORD0,\n" + " in float2 TexCoord1 : TEXCOORD1, in float2 TexCoord2 : TEXCOORD2,\n" + " out float4 oPosition : SV_Position, out float4 oColor : COLOR,\n" + " out float2 oHmdSpcTexCoordR : TEXCOORD0, out float2 oHmdSpcTexCoordG : TEXCOORD1, out float2 oHmdSpcTexCoordB : TEXCOORD2," + " out float2 oOverlayTexCoordR : TEXCOORD3, out float2 oOverlayTexCoordG : TEXCOORD4, out float2 oOverlayTexCoordB : TEXCOORD5)\n" "{\n" " oPosition.x = Position.x;\n" " oPosition.y = Position.y;\n" @@ -480,28 +533,118 @@ static const char* PostProcessMeshPositionalTimewarpVertexShaderSrc = //" float4x4 lerpedEyeRot = EyeRotationStart;\n" // warped positions are a bit more involved, hence a separate function - " oTexCoord0 = TimewarpTexCoordToWarpedPos(TexCoord0, lerpedEyeRot);\n" - " oTexCoord1 = TimewarpTexCoordToWarpedPos(TexCoord1, lerpedEyeRot);\n" - " oTexCoord2 = TimewarpTexCoordToWarpedPos(TexCoord2, lerpedEyeRot);\n" + " oHmdSpcTexCoordR = TimewarpTexCoordToWarpedPos(TexCoord0, lerpedEyeRot);\n" + " oHmdSpcTexCoordG = TimewarpTexCoordToWarpedPos(TexCoord1, lerpedEyeRot);\n" + " oHmdSpcTexCoordB = TimewarpTexCoordToWarpedPos(TexCoord2, lerpedEyeRot);\n" + + " oOverlayTexCoordR = TexCoord0 * EyeToSourceUVScale + EyeToSourceUVOffset;\n" + " oOverlayTexCoordG = TexCoord1 * EyeToSourceUVScale + EyeToSourceUVOffset;\n" + " oOverlayTexCoordB = TexCoord2 * EyeToSourceUVScale + EyeToSourceUVOffset;\n" " oColor = Color.r; // Used for vignette fade.\n" "}\n"; static const char* PostProcessMeshPositionalTimewarpPixelShaderSrc = - "Texture2D Texture : register(t0);\n" + "Texture2D HmdSpcTexture : register(t0);\n" + "Texture2D OverlayTexture : register(t1);\n" "SamplerState Linear : register(s0);\n" + "float2 DepthDimSize;\n" + "float UseOverlay = 1;\n" + "\n" + "float4 main(in float4 oPosition : SV_Position, in float4 oColor : COLOR,\n" + " in float2 oHmdSpcTexCoordR : TEXCOORD0, in float2 oHmdSpcTexCoordG : TEXCOORD1, in float2 oHmdSpcTexCoordB : TEXCOORD2," + " in float2 oOverlayTexCoordR : TEXCOORD3, in float2 oOverlayTexCoordG : TEXCOORD4, in float2 oOverlayTexCoordB : TEXCOORD5) : SV_Target\n" + "{\n" + " float4 finalColor = float4(0,0,0,1);\n" + " finalColor.r = HmdSpcTexture.Sample(Linear, oHmdSpcTexCoordR).r;\n" + " finalColor.g = HmdSpcTexture.Sample(Linear, oHmdSpcTexCoordG).g;\n" + " finalColor.b = HmdSpcTexture.Sample(Linear, oHmdSpcTexCoordB).b;\n" + + " if(UseOverlay > 0)\n" + " {\n" + " float2 overlayColorR = OverlayTexture.Sample(Linear, oOverlayTexCoordR).ra;\n" + " float2 overlayColorG = OverlayTexture.Sample(Linear, oOverlayTexCoordG).ga;\n" + " float2 overlayColorB = OverlayTexture.Sample(Linear, oOverlayTexCoordB).ba;\n" + + // do premultiplied alpha blending - overlayColorX.x is color, overlayColorX.y is alpha + " finalColor.r = finalColor.r * saturate(1-overlayColorR.y) + overlayColorR.x;\n" + " finalColor.g = finalColor.g * saturate(1-overlayColorG.y) + overlayColorG.x;\n" + " finalColor.b = finalColor.b * saturate(1-overlayColorB.y) + overlayColorB.x;\n" + " }\n" + + " finalColor.rgb = saturate(finalColor.rgb * oColor.rgb);\n" + " return finalColor;\n" + "}\n"; + +//---------------------------------------------------------------------------- +// Pixel shader is very simple - does three texture reads. +// Vertex shader does all the hard work. +// Used for mesh-based heightmap reprojection for positional timewarp. + +static D3D1x_(INPUT_ELEMENT_DESC) HeightmapVertexDesc[] = +{ + {"Position", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D1x_(INPUT_PER_VERTEX_DATA), 0}, + {"TexCoord", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D1x_(INPUT_PER_VERTEX_DATA), 0}, +}; + +static const char* PostProcessHeightmapTimewarpVertexShaderSrc = + "Texture2DMS<float,4> DepthTexture : register(t0);\n" + // Padding because we are uploading "standard uniform buffer" constants + "float4x4 Padding1;\n" + "float4x4 Padding2;\n" + "float2 EyeToSourceUVScale;\n" + "float2 EyeToSourceUVOffset;\n" "float2 DepthDimSize;\n" + "float4x4 EyeXformStart;\n" + "float4x4 EyeXformEnd;\n" + //"float4x4 Projection;\n" + "float4x4 InvProjection;\n" + + "float4 PositionFromDepth(float2 position, float2 inTexCoord)\n" + "{\n" + " float depth = DepthTexture.Load(int2(inTexCoord * DepthDimSize), 0).x;\n" + " float4 retVal = float4(position, depth, 1);\n" + " return retVal;\n" + "}\n" + + "float4 TimewarpPos(float2 position, float2 inTexCoord, float4x4 rotMat)\n" + "{\n" + // Apply the 4x4 timewarp rotation to these vectors. + " float4 transformed = PositionFromDepth(position, inTexCoord);\n" + // TODO: Precombining InvProjection in rotMat causes loss of precision flickering + " transformed = mul ( InvProjection, transformed );\n" + " transformed = mul ( rotMat, transformed );\n" + // Commented out as Projection is currently contained in rotMat + //" transformed = mul ( Projection, transformed );\n" + " return transformed;\n" + "}\n" + + "void main( in float2 Position : POSITION, in float3 TexCoord0 : TEXCOORD0,\n" + " out float4 oPosition : SV_Position, out float2 oTexCoord0 : TEXCOORD0)\n" + "{\n" + " float2 eyeToSrcTexCoord = TexCoord0.xy * EyeToSourceUVScale + EyeToSourceUVOffset;\n" + " oTexCoord0 = eyeToSrcTexCoord;\n" + + " float timewarpLerpFactor = TexCoord0.z;\n" + " float4x4 lerpedEyeRot = lerp(EyeXformStart, EyeXformEnd, timewarpLerpFactor);\n" + //" float4x4 lerpedEyeRot = EyeXformStart;\n" + + " oPosition = TimewarpPos(Position.xy, oTexCoord0, lerpedEyeRot);\n" + "}\n"; + +static const char* PostProcessHeightmapTimewarpPixelShaderSrc = + "Texture2D Texture : register(t0);\n" + "SamplerState Linear : register(s0);\n" "\n" - "float4 main(in float4 oPosition : SV_Position, in float4 oColor : COLOR,\n" - " in float2 oTexCoord0 : TEXCOORD0, in float2 oTexCoord1 : TEXCOORD1, in float2 oTexCoord2 : TEXCOORD2) : SV_Target\n" + "float4 main(in float4 oPosition : SV_Position, in float2 oTexCoord0 : TEXCOORD0) : SV_Target\n" "{\n" " float3 result;\n" - " result.r = Texture.Sample(Linear, oTexCoord0).r;\n" - " result.g = Texture.Sample(Linear, oTexCoord1).g;\n" - " result.b = Texture.Sample(Linear, oTexCoord2).b;\n" - " return float4(result * oColor, 1.0);\n" + " result = Texture.Sample(Linear, oTexCoord0);\n" + " return float4(result, 1.0);\n" "}\n"; +#pragma endregion + //---------------------------------------------------------------------------- static const char* VShaderSrcs[VShader_Count] = @@ -511,7 +654,8 @@ static const char* VShaderSrcs[VShader_Count] = PostProcessVertexShaderSrc, PostProcessMeshVertexShaderSrc, PostProcessMeshTimewarpVertexShaderSrc, - PostProcessMeshPositionalTimewarpVertexShaderSrc + PostProcessMeshPositionalTimewarpVertexShaderSrc, + PostProcessHeightmapTimewarpVertexShaderSrc }; static const char* FShaderSrcs[FShader_Count] = { @@ -525,7 +669,8 @@ static const char* FShaderSrcs[FShader_Count] = MultiTexturePixelShaderSrc, PostProcessMeshPixelShaderSrc, PostProcessMeshTimewarpPixelShaderSrc, - PostProcessMeshPositionalTimewarpPixelShaderSrc + PostProcessMeshPositionalTimewarpPixelShaderSrc, + PostProcessHeightmapTimewarpPixelShaderSrc }; RenderDevice::RenderDevice(const RendererParams& p, HWND window) @@ -630,12 +775,23 @@ RenderDevice::RenderDevice(const RendererParams& p, HWND window) HRESULT validate = Device->CreateInputLayout(ModelVertexDesc, sizeof(ModelVertexDesc)/sizeof(ModelVertexDesc[0]), buffer, bufferSize, objRef); OVR_UNUSED(validate); - ID3D10Blob* vsData2 = CompileShader("vs_4_1", PostProcessMeshVertexShaderSrc); - SPInt bufferSize2 = vsData2->GetBufferSize(); - const void* buffer2 = vsData2->GetBufferPointer(); - ID3D1xInputLayout** objRef2 = &DistortionVertexIL.GetRawRef(); - HRESULT validate2 = Device->CreateInputLayout(DistortionVertexDesc, sizeof(DistortionVertexDesc)/sizeof(DistortionVertexDesc[0]), buffer2, bufferSize2, objRef2); - OVR_UNUSED(validate2); + { + ID3D10Blob* vsData2 = CompileShader("vs_4_1", PostProcessMeshVertexShaderSrc); + SPInt bufferSize2 = vsData2->GetBufferSize(); + const void* buffer2 = vsData2->GetBufferPointer(); + ID3D1xInputLayout** objRef2 = &DistortionVertexIL.GetRawRef(); + HRESULT validate2 = Device->CreateInputLayout(DistortionVertexDesc, sizeof(DistortionVertexDesc)/sizeof(DistortionVertexDesc[0]), buffer2, bufferSize2, objRef2); + OVR_UNUSED(validate2); + } + + { + ID3D10Blob* vsData2 = CompileShader("vs_4_1", PostProcessHeightmapTimewarpVertexShaderSrc); + SPInt bufferSize2 = vsData2->GetBufferSize(); + const void* buffer2 = vsData2->GetBufferPointer(); + ID3D1xInputLayout** objRef2 = &HeightmapVertexIL.GetRawRef(); + HRESULT validate2 = Device->CreateInputLayout(HeightmapVertexDesc, sizeof(HeightmapVertexDesc)/sizeof(HeightmapVertexDesc[0]), buffer2, bufferSize2, objRef2); + OVR_UNUSED(validate2); + } Ptr<ShaderSet> gouraudShaders = *new ShaderSet(); gouraudShaders->SetShader(VertexShaders[VShader_MVP]); @@ -647,7 +803,7 @@ RenderDevice::RenderDevice(const RendererParams& p, HWND window) memset(&bm, 0, sizeof(bm)); bm.BlendEnable[0] = true; bm.BlendOp = bm.BlendOpAlpha = D3D1x_(BLEND_OP_ADD); - bm.SrcBlend = bm.SrcBlendAlpha = D3D1x_(BLEND_SRC_ALPHA); + bm.SrcBlend = bm.SrcBlendAlpha = D3D1x_(BLEND_ONE); //premultiplied alpha bm.DestBlend = bm.DestBlendAlpha = D3D1x_(BLEND_INV_SRC_ALPHA); bm.RenderTargetWriteMask[0] = D3D1x_(COLOR_WRITE_ENABLE_ALL); Device->CreateBlendState(&bm, &BlendState.GetRawRef()); @@ -656,7 +812,7 @@ RenderDevice::RenderDevice(const RendererParams& p, HWND window) memset(&bm, 0, sizeof(bm)); bm.RenderTarget[0].BlendEnable = true; bm.RenderTarget[0].BlendOp = bm.RenderTarget[0].BlendOpAlpha = D3D1x_(BLEND_OP_ADD); - bm.RenderTarget[0].SrcBlend = bm.RenderTarget[0].SrcBlendAlpha = D3D1x_(BLEND_SRC_ALPHA); + bm.RenderTarget[0].SrcBlend = bm.RenderTarget[0].SrcBlendAlpha = D3D1x_(BLEND_ONE); //premultiplied alpha bm.RenderTarget[0].DestBlend = bm.RenderTarget[0].DestBlendAlpha = D3D1x_(BLEND_INV_SRC_ALPHA); bm.RenderTarget[0].RenderTargetWriteMask = D3D1x_(COLOR_WRITE_ENABLE_ALL); Device->CreateBlendState(&bm, &BlendState.GetRawRef()); @@ -675,7 +831,7 @@ RenderDevice::RenderDevice(const RendererParams& p, HWND window) const Render::Vertex QuadVertices[] = { Vertex(Vector3f(0, 1, 0)), Vertex(Vector3f(1, 1, 0)), Vertex(Vector3f(0, 0, 0)), Vertex(Vector3f(1, 0, 0)) }; - QuadVertexBuffer->Data(Buffer_Vertex, QuadVertices, sizeof(QuadVertices)); + QuadVertexBuffer->Data(Buffer_Vertex | Buffer_ReadOnly, QuadVertices, sizeof(QuadVertices)); SetDepthMode(0, 0); } @@ -802,6 +958,7 @@ bool RenderDevice::RecreateSwapChain() scDesc.BufferDesc.Width = WindowWidth; scDesc.BufferDesc.Height = WindowHeight; scDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + //scDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; // Use default refresh rate; switching rate on CC prototype can cause screen lockup. scDesc.BufferDesc.RefreshRate.Numerator = 0; scDesc.BufferDesc.RefreshRate.Denominator = 1; @@ -1486,7 +1643,7 @@ ID3D1xSamplerState* RenderDevice::GetSamplerState(int sm) else if (sm & Sample_Anisotropic) { ss.Filter = D3D1x_(FILTER_ANISOTROPIC); - ss.MaxAnisotropy = 8; + ss.MaxAnisotropy = 4; } else { @@ -1573,10 +1730,14 @@ void RenderDevice::GenerateSubresourceData( { bytesPerBlock = 8; } - else if (format == DXGI_FORMAT_BC3_UNORM) - { - bytesPerBlock = 16; - } + else if (format == DXGI_FORMAT_BC2_UNORM) + { + bytesPerBlock = 16; + } + else if (format == DXGI_FORMAT_BC3_UNORM) + { + bytesPerBlock = 16; + } unsigned blockWidth = 0; blockWidth = (subresWidth + 3) / 4; @@ -1659,9 +1820,21 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo imageDimUpperLimit = 1024; } - if (format == Texture_DXT1 || format == Texture_DXT5) + if (format == Texture_DXT1 || format == Texture_DXT3 || format == Texture_DXT5) { - int convertedFormat = (format == Texture_DXT1) ? DXGI_FORMAT_BC1_UNORM : DXGI_FORMAT_BC3_UNORM; + int convertedFormat; + switch (format) { + case Texture_DXT1: + convertedFormat = DXGI_FORMAT_BC1_UNORM; + break; + case Texture_DXT3: + convertedFormat = DXGI_FORMAT_BC2_UNORM; + break; + case Texture_DXT5: + default: + convertedFormat = DXGI_FORMAT_BC3_UNORM; + break; + } unsigned largestMipWidth = 0; unsigned largestMipHeight = 0; unsigned effectiveMipCount = mipcount; @@ -1670,7 +1843,7 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo #ifdef OVR_DEFINE_NEW #undef new #endif - + D3D1x_(SUBRESOURCE_DATA)* subresData = (D3D1x_(SUBRESOURCE_DATA)*) OVR_ALLOC(sizeof(D3D1x_(SUBRESOURCE_DATA)) * mipcount); GenerateSubresourceData(width, height, convertedFormat, imageDimUpperLimit, data, subresData, largestMipWidth, @@ -1923,7 +2096,6 @@ void RenderDevice::SetRenderTarget(Render::Texture* color, Render::Texture* dept Context->OMSetRenderTargets(1, &((Texture*)color)->TexRtv.GetRawRef(), ((Texture*)depth)->TexDsv); } - void RenderDevice::SetWorldUniforms(const Matrix4f& proj) { StdUniforms.Proj = proj.Transposed(); @@ -1937,13 +2109,13 @@ void RenderDevice::Render(const Matrix4f& matrix, Model* model) if (!model->VertexBuffer) { Ptr<Buffer> vb = *CreateBuffer(); - vb->Data(Buffer_Vertex, &model->Vertices[0], model->Vertices.GetSize() * sizeof(Vertex)); + vb->Data(Buffer_Vertex | Buffer_ReadOnly, &model->Vertices[0], model->Vertices.GetSize() * sizeof(Vertex)); model->VertexBuffer = vb; } if (!model->IndexBuffer) { Ptr<Buffer> ib = *CreateBuffer(); - ib->Data(Buffer_Index, &model->Indices[0], model->Indices.GetSize() * 2); + ib->Data(Buffer_Index | Buffer_ReadOnly, &model->Indices[0], model->Indices.GetSize() * 2); model->IndexBuffer = ib; } @@ -1961,21 +2133,28 @@ void RenderDevice::RenderWithAlpha( const Fill* fill, Render::Buffer* vertices, } void RenderDevice::Render(const Fill* fill, Render::Buffer* vertices, Render::Buffer* indices, - const Matrix4f& matrix, int offset, int count, PrimitiveType rprim, bool useDistortionVertex/* = false*/) + const Matrix4f& matrix, int offset, int count, PrimitiveType rprim, MeshType meshType/* = Mesh_Scene*/) { ID3D1xBuffer* vertexBuffer = ((Buffer*)vertices)->GetBuffer(); UINT vertexOffset = offset; UINT vertexStride = sizeof(Vertex); - if ( useDistortionVertex ) - { - Context->IASetInputLayout(DistortionVertexIL); - vertexStride = sizeof(DistortionVertex); - } - else + switch(meshType) { + case Mesh_Scene: Context->IASetInputLayout(ModelVertexIL); vertexStride = sizeof(Vertex); + break; + case Mesh_Distortion: + Context->IASetInputLayout(DistortionVertexIL); + vertexStride = sizeof(DistortionVertex); + break; + case Mesh_Heightmap: + Context->IASetInputLayout(HeightmapVertexIL); + vertexStride = sizeof(HeightmapVertex); + break; + default: OVR_ASSERT(false); } + Context->IASetVertexBuffers(0, 1, &vertexBuffer, &vertexStride, &vertexOffset); if (indices) @@ -2058,9 +2237,12 @@ UPInt RenderDevice::QueryGPUMemorySize() void RenderDevice::Present ( bool withVsync ) { - if( OVR::Util::ImageWindow::GlobalWindow() ) + for( int i = 0; i < 4; ++i ) { - OVR::Util::ImageWindow::GlobalWindow()->Process(); + if( OVR::Util::ImageWindow::GlobalWindow( i ) ) + { + OVR::Util::ImageWindow::GlobalWindow( i )->Process(); + } } if ( withVsync ) diff --git a/Samples/CommonSrc/Render/Render_D3D1X_Device.h b/Samples/CommonSrc/Render/Render_D3D1X_Device.h index e06bcda..bd733cc 100644 --- a/Samples/CommonSrc/Render/Render_D3D1X_Device.h +++ b/Samples/CommonSrc/Render/Render_D3D1X_Device.h @@ -265,6 +265,7 @@ public: Ptr<ID3D1xDepthStencilState> CurDepthState; Ptr<ID3D1xInputLayout> ModelVertexIL; Ptr<ID3D1xInputLayout> DistortionVertexIL; + Ptr<ID3D1xInputLayout> HeightmapVertexIL; Ptr<ID3D1xSamplerState> SamplerStates[Sample_Count]; @@ -351,7 +352,7 @@ public: virtual void Render(const Matrix4f& matrix, Model* model); virtual void Render(const Fill* fill, Render::Buffer* vertices, Render::Buffer* indices, - const Matrix4f& matrix, int offset, int count, PrimitiveType prim = Prim_Triangles, bool useDistortionVertex = false); + const Matrix4f& matrix, int offset, int count, PrimitiveType prim = Prim_Triangles, MeshType meshType = Mesh_Scene); virtual void RenderWithAlpha( const Fill* fill, Render::Buffer* vertices, Render::Buffer* indices, const Matrix4f& matrix, int offset, int count, PrimitiveType prim = Prim_Triangles); diff --git a/Samples/CommonSrc/Render/Render_Device.cpp b/Samples/CommonSrc/Render/Render_Device.cpp index e917fb0..88e611a 100644 --- a/Samples/CommonSrc/Render/Render_Device.cpp +++ b/Samples/CommonSrc/Render/Render_Device.cpp @@ -206,35 +206,35 @@ namespace OVR { namespace Render { // Cube vertices and their normals. Vector3f CubeVertices[][3] = { - Vector3f(x1, y2, z1), Vector3f(z1, x1), Vector3f(0.0f, 1.0f, 0.0f), - Vector3f(x2, y2, z1), Vector3f(z1, x2), Vector3f(0.0f, 1.0f, 0.0f), - Vector3f(x2, y2, z2), Vector3f(z2, x2), Vector3f(0.0f, 1.0f, 0.0f), - Vector3f(x1, y2, z2), Vector3f(z2, x1), Vector3f(0.0f, 1.0f, 0.0f), - - Vector3f(x1, y1, z1), Vector3f(z1, x1), Vector3f(0.0f, -1.0f, 0.0f), - Vector3f(x2, y1, z1), Vector3f(z1, x2), Vector3f(0.0f, -1.0f, 0.0f), - Vector3f(x2, y1, z2), Vector3f(z2, x2), Vector3f(0.0f, -1.0f, 0.0f), - Vector3f(x1, y1, z2), Vector3f(z2, x1), Vector3f(0.0f, -1.0f, 0.0f), - - Vector3f(x1, y1, z2), Vector3f(z2, y1), Vector3f(-1.0f, 0.0f, 0.0f), - Vector3f(x1, y1, z1), Vector3f(z1, y1), Vector3f(-1.0f, 0.0f, 0.0f), - Vector3f(x1, y2, z1), Vector3f(z1, y2), Vector3f(-1.0f, 0.0f, 0.0f), - Vector3f(x1, y2, z2), Vector3f(z2, y2), Vector3f(-1.0f, 0.0f, 0.0f), - - Vector3f(x2, y1, z2), Vector3f(z2, y1), Vector3f(1.0f, 0.0f, 0.0f), - Vector3f(x2, y1, z1), Vector3f(z1, y1), Vector3f(1.0f, 0.0f, 0.0f), - Vector3f(x2, y2, z1), Vector3f(z1, y2), Vector3f(1.0f, 0.0f, 0.0f), - Vector3f(x2, y2, z2), Vector3f(z2, y2), Vector3f(1.0f, 0.0f, 0.0f), - - Vector3f(x1, y1, z1), Vector3f(x1, y1), Vector3f(0.0f, 0.0f, -1.0f), - Vector3f(x2, y1, z1), Vector3f(x2, y1), Vector3f(0.0f, 0.0f, -1.0f), - Vector3f(x2, y2, z1), Vector3f(x2, y2), Vector3f(0.0f, 0.0f, -1.0f), - Vector3f(x1, y2, z1), Vector3f(x1, y2), Vector3f(0.0f, 0.0f, -1.0f), - - Vector3f(x1, y1, z2), Vector3f(x1, y1), Vector3f(0.0f, 0.0f, 1.0f), - Vector3f(x2, y1, z2), Vector3f(x2, y1), Vector3f(0.0f, 0.0f, 1.0f), - Vector3f(x2, y2, z2), Vector3f(x2, y2), Vector3f(0.0f, 0.0f, 1.0f), - Vector3f(x1, y2, z2), Vector3f(x1, y2), Vector3f(0.0f, 0.0f, 1.0f) + { Vector3f(x1, y2, z1), Vector3f(z1, x1), Vector3f(0.0f, 1.0f, 0.0f) }, + { Vector3f(x2, y2, z1), Vector3f(z1, x2), Vector3f(0.0f, 1.0f, 0.0f) }, + { Vector3f(x2, y2, z2), Vector3f(z2, x2), Vector3f(0.0f, 1.0f, 0.0f) }, + { Vector3f(x1, y2, z2), Vector3f(z2, x1), Vector3f(0.0f, 1.0f, 0.0f) }, + + { Vector3f(x1, y1, z1), Vector3f(z1, x1), Vector3f(0.0f, -1.0f, 0.0f) }, + { Vector3f(x2, y1, z1), Vector3f(z1, x2), Vector3f(0.0f, -1.0f, 0.0f) }, + { Vector3f(x2, y1, z2), Vector3f(z2, x2), Vector3f(0.0f, -1.0f, 0.0f) }, + { Vector3f(x1, y1, z2), Vector3f(z2, x1), Vector3f(0.0f, -1.0f, 0.0f) }, + + { Vector3f(x1, y1, z2), Vector3f(z2, y1), Vector3f(-1.0f, 0.0f, 0.0f) }, + { Vector3f(x1, y1, z1), Vector3f(z1, y1), Vector3f(-1.0f, 0.0f, 0.0f) }, + { Vector3f(x1, y2, z1), Vector3f(z1, y2), Vector3f(-1.0f, 0.0f, 0.0f) }, + { Vector3f(x1, y2, z2), Vector3f(z2, y2), Vector3f(-1.0f, 0.0f, 0.0f) }, + + { Vector3f(x2, y1, z2), Vector3f(z2, y1), Vector3f(1.0f, 0.0f, 0.0f) }, + { Vector3f(x2, y1, z1), Vector3f(z1, y1), Vector3f(1.0f, 0.0f, 0.0f) }, + { Vector3f(x2, y2, z1), Vector3f(z1, y2), Vector3f(1.0f, 0.0f, 0.0f) }, + { Vector3f(x2, y2, z2), Vector3f(z2, y2), Vector3f(1.0f, 0.0f, 0.0f) }, + + { Vector3f(x1, y1, z1), Vector3f(x1, y1), Vector3f(0.0f, 0.0f, -1.0f) }, + { Vector3f(x2, y1, z1), Vector3f(x2, y1), Vector3f(0.0f, 0.0f, -1.0f) }, + { Vector3f(x2, y2, z1), Vector3f(x2, y2), Vector3f(0.0f, 0.0f, -1.0f) }, + { Vector3f(x1, y2, z1), Vector3f(x1, y2), Vector3f(0.0f, 0.0f, -1.0f) }, + + { Vector3f(x1, y1, z2), Vector3f(x1, y1), Vector3f(0.0f, 0.0f, 1.0f) }, + { Vector3f(x2, y1, z2), Vector3f(x2, y1), Vector3f(0.0f, 0.0f, 1.0f) }, + { Vector3f(x2, y2, z2), Vector3f(x2, y2), Vector3f(0.0f, 0.0f, 1.0f) }, + { Vector3f(x1, y2, z2), Vector3f(x1, y2), Vector3f(0.0f, 0.0f, 1.0f) } }; @@ -899,7 +899,8 @@ namespace OVR { namespace Render { ppfs = LoadBuiltinShader(Shader_Fragment, FShader_PostProcessWithChromAb); vs = LoadBuiltinShader(Shader_Vertex, VShader_PostProcess); } - else if (PostProcessShaderActive == PostProcessShader_MeshDistortionAndChromAb) + else if (PostProcessShaderActive == PostProcessShader_MeshDistortionAndChromAb || + PostProcessShaderActive == PostProcessShader_MeshDistortionAndChromAbHeightmapTimewarp) { ppfs = LoadBuiltinShader(Shader_Fragment, FShader_PostProcessMeshWithChromAb); vs = LoadBuiltinShader(Shader_Vertex, VShader_PostProcessMesh); @@ -909,11 +910,11 @@ namespace OVR { namespace Render { ppfs = LoadBuiltinShader(Shader_Fragment, FShader_PostProcessMeshWithChromAbTimewarp); vs = LoadBuiltinShader(Shader_Vertex, VShader_PostProcessMeshTimewarp); } - else if (PostProcessShaderActive == PostProcessShader_MeshDistortionAndChromAbPositionalTimewarp) - { - ppfs = LoadBuiltinShader(Shader_Fragment, FShader_PostProcessMeshWithChromAbPositionalTimewarp); - vs = LoadBuiltinShader(Shader_Vertex, VShader_PostProcessMeshPositionalTimewarp); - } + else if (PostProcessShaderActive == PostProcessShader_MeshDistortionAndChromAbPositionalTimewarp) + { + ppfs = LoadBuiltinShader(Shader_Fragment, FShader_PostProcessMeshWithChromAbPositionalTimewarp); + vs = LoadBuiltinShader(Shader_Vertex, VShader_PostProcessMeshPositionalTimewarp); + } else { OVR_ASSERT(false); @@ -926,6 +927,23 @@ namespace OVR { namespace Render { pPostProcessShader->SetShader(ppfs); } + // Heightmap method does the timewarp on the first pass + if (!pPostProcessHeightmapShader && + PostProcessShaderActive == PostProcessShader_MeshDistortionAndChromAbHeightmapTimewarp) + { + Shader *vs = NULL; + Shader *ppfs = NULL; + + ppfs = LoadBuiltinShader(Shader_Fragment, FShader_PostProcessHeightmapTimewarp); + vs = LoadBuiltinShader(Shader_Vertex, VShader_PostProcessHeightmapTimewarp); + + OVR_ASSERT(ppfs); // Means the shader failed to compile - look in the debug spew. + OVR_ASSERT(vs); + + pPostProcessHeightmapShader = *CreateShaderSet(); + pPostProcessHeightmapShader->SetShader(vs); + pPostProcessHeightmapShader->SetShader(ppfs); + } if(!pFullScreenVertexBuffer) { @@ -937,7 +955,7 @@ namespace OVR { namespace Render { Vertex(Vector3f(0, 0, 0), Color(1, 1, 1, 1), 0, 1), Vertex(Vector3f(1, 0, 0), Color(1, 1, 1, 1), 1, 1) }; - pFullScreenVertexBuffer->Data(Buffer_Vertex, QuadVertices, sizeof(QuadVertices)); + pFullScreenVertexBuffer->Data(Buffer_Vertex | Buffer_ReadOnly, QuadVertices, sizeof(QuadVertices)); } return true; } @@ -960,7 +978,7 @@ namespace OVR { namespace Render { void RenderDevice::FinishScene() { SetExtraShaders(0); - SetRenderTarget(0); + SetDefaultRenderTarget(); } @@ -971,9 +989,10 @@ namespace OVR { namespace Render { { PostProcessingType = pptype; - if ( ( pptype == PostProcess_MeshDistortion ) || + if (( pptype == PostProcess_MeshDistortion ) || ( pptype == PostProcess_MeshDistortionTimewarp ) || - ( pptype == PostProcess_MeshDistortionPositionalTimewarp ) ) + ( pptype == PostProcess_MeshDistortionPositionalTimewarp ) || + ( pptype == PostProcess_MeshDistortionHeightmapTimewarp)) { for ( int eyeNum = 0; eyeNum < 2; eyeNum++ ) { @@ -1009,13 +1028,55 @@ namespace OVR { namespace Render { DistortionMeshNumTris[eyeNum] = numTris; pDistortionMeshVertexBuffer[eyeNum] = *CreateBuffer(); - pDistortionMeshVertexBuffer[eyeNum]->Data ( Buffer_Vertex, pVerts, sizeof(DistortionVertex) * numVerts ); + pDistortionMeshVertexBuffer[eyeNum]->Data ( Buffer_Vertex | Buffer_ReadOnly, pVerts, sizeof(DistortionVertex) * numVerts ); pDistortionMeshIndexBuffer[eyeNum] = *CreateBuffer(); - pDistortionMeshIndexBuffer[eyeNum]->Data ( Buffer_Index, pIndices, ( sizeof(UInt16) * numIndices ) ); + pDistortionMeshIndexBuffer[eyeNum]->Data ( Buffer_Index | Buffer_ReadOnly, pIndices, ( sizeof(UInt16) * numIndices ) ); DistortionMeshDestroy ( pRawVerts, pIndices ); OVR_FREE ( pVerts ); } + + if(pptype == PostProcess_MeshDistortionHeightmapTimewarp) + { + // Create the positional timewarp rectangular heightmap mesh + for ( int eyeNum = 0; eyeNum < 2; eyeNum++ ) + { + const StereoEyeParams &stereoParams = ( eyeNum == 0 ) ? stereoParamsLeft : stereoParamsRight; + + // Get the mesh data. + int numVerts = 0; + int numTris = 0; + HeightmapMeshVertexData *pRawVerts = NULL; + UInt16 *pIndices = NULL; + HeightmapMeshCreate ( &pRawVerts, &pIndices, &numVerts, &numTris, stereoParams, hmdRenderInfo ); + int numIndices = numTris * 3; + + // Convert to final vertex data. + HeightmapVertex *pVerts = (HeightmapVertex*)OVR_ALLOC ( sizeof(HeightmapVertex) * numVerts ); + HeightmapVertex *pCurVert = pVerts; + HeightmapMeshVertexData *pCurRawVert = pRawVerts; + for ( int vertNum = 0; vertNum < numVerts; vertNum++ ) + { + pCurVert->Pos.x = pCurRawVert->ScreenPosNDC.x; + pCurVert->Pos.y = pCurRawVert->ScreenPosNDC.y; + Vector2f texCoord = pCurRawVert->TanEyeAngles; + pCurVert->Tex.x = texCoord.x; + pCurVert->Tex.y = texCoord.y; + pCurVert->Tex.z = (OVR::UByte)( floorf ( pCurRawVert->TimewarpLerp * 255.999f ) ); + pCurRawVert++; + pCurVert++; + } + + HeightmapMeshNumTris[eyeNum] = numTris; + pHeightmapMeshVertexBuffer[eyeNum] = *CreateBuffer(); + pHeightmapMeshVertexBuffer[eyeNum]->Data ( Buffer_Vertex, pVerts, sizeof(HeightmapVertex) * numVerts ); + pHeightmapMeshIndexBuffer[eyeNum] = *CreateBuffer(); + pHeightmapMeshIndexBuffer[eyeNum]->Data ( Buffer_Index, pIndices, ( sizeof(UInt16) * numIndices ) ); + + HeightmapMeshDestroy ( pRawVerts, pIndices ); + OVR_FREE ( pVerts ); + } + } } else { @@ -1025,117 +1086,265 @@ namespace OVR { namespace Render { void RenderDevice::ApplyPostProcess(Matrix4f const &matNowFromWorldStart, Matrix4f const &matNowFromWorldEnd, - Matrix4f const &matRenderFromWorldLeft, Matrix4f const &matRenderFromWorldRight, - StereoEyeParams const &stereoParamsLeft, StereoEyeParams const &stereoParamsRight, - Ptr<Texture> pSourceTextureLeftOrOnly, - Ptr<Texture> pSourceTextureRight, - Ptr<Texture> pSourceTextureLeftOrOnlyDepth, - Ptr<Texture> pSourceTextureRightDepth) + Matrix4f const &matRenderFromWorldLeft, Matrix4f const &matRenderFromWorldRight, + StereoEyeParams const &stereoParamsLeft, StereoEyeParams const &stereoParamsRight, + RenderTarget* pHmdSpaceLayerRenderTargetLeftOrBothEyes, + RenderTarget* pHmdSpaceLayerRenderTargetRight, + RenderTarget* pOverlayLayerRenderTargetLeftOrBothEyes, + RenderTarget* pOverlayLayerRenderTargetRight) { SetExtraShaders(0); - if ( PostProcessingType == PostProcess_MeshDistortion ) - { - Recti vp ( 0, 0, WindowWidth, WindowHeight ); - SetViewport(vp); - float r, g, b, a; - DistortionClearColor.GetRGBA(&r, &g, &b, &a); - Clear(r, g, b, a); - - Matrix4f dummy; - ShaderFill fill(pPostProcessShader); - - fill.SetTexture ( 0, pSourceTextureLeftOrOnly ); - pPostProcessShader->SetUniform2f("EyeToSourceUVScale", stereoParamsLeft.EyeToSourceUV.Scale.x, stereoParamsLeft.EyeToSourceUV.Scale.y ); - pPostProcessShader->SetUniform2f("EyeToSourceUVOffset", stereoParamsLeft.EyeToSourceUV.Offset.x, stereoParamsLeft.EyeToSourceUV.Offset.y ); - Render(&fill, pDistortionMeshVertexBuffer[0], pDistortionMeshIndexBuffer[0], dummy, 0, DistortionMeshNumTris[0] * 3, Prim_Triangles, true); - - if ( pSourceTextureRight != NULL ) - { - fill.SetTexture ( 0, pSourceTextureRight ); - } - pPostProcessShader->SetUniform2f("EyeToSourceUVScale", stereoParamsRight.EyeToSourceUV.Scale.x, stereoParamsRight.EyeToSourceUV.Scale.y ); - pPostProcessShader->SetUniform2f("EyeToSourceUVOffset", stereoParamsRight.EyeToSourceUV.Offset.x, stereoParamsRight.EyeToSourceUV.Offset.y ); - Render(&fill, pDistortionMeshVertexBuffer[1], pDistortionMeshIndexBuffer[1], dummy, 0, DistortionMeshNumTris[1] * 3, Prim_Triangles, true); - } - else if ( PostProcessingType == PostProcess_MeshDistortionTimewarp ) - { - Recti vp ( 0, 0, WindowWidth, WindowHeight ); - SetViewport(vp); - float r, g, b, a; - DistortionClearColor.GetRGBA(&r, &g, &b, &a); - Clear(r, g, b, a); - - ShaderFill fill(pPostProcessShader); - fill.SetTexture ( 0, pSourceTextureLeftOrOnly ); - - for ( int eyeNum = 0; eyeNum < 2; eyeNum++ ) - { - Matrix4f const &matRenderFromWorld = ( eyeNum == 0 ) ? matRenderFromWorldLeft : matRenderFromWorldRight; - const StereoEyeParams &stereoParams = ( eyeNum == 0 ) ? stereoParamsLeft : stereoParamsRight; - - Matrix4f matRenderFromNowStart = TimewarpComputePoseDelta ( matRenderFromWorld, matNowFromWorldStart ); - Matrix4f matRenderFromNowEnd = TimewarpComputePoseDelta ( matRenderFromWorld, matNowFromWorldEnd ); - - pPostProcessShader->SetUniform2f("EyeToSourceUVScale", stereoParams.EyeToSourceUV.Scale.x, stereoParams.EyeToSourceUV.Scale.y ); - pPostProcessShader->SetUniform2f("EyeToSourceUVOffset", stereoParams.EyeToSourceUV.Offset.x, stereoParams.EyeToSourceUV.Offset.y ); - pPostProcessShader->SetUniform3x3f("EyeRotationStart", matRenderFromNowStart); - pPostProcessShader->SetUniform3x3f("EyeRotationEnd", matRenderFromNowEnd); - - Matrix4f dummy; - if ( ( pSourceTextureRight != NULL ) && ( eyeNum == 1 ) ) - { - fill.SetTexture ( 0, pSourceTextureRight ); - } - Render(&fill, pDistortionMeshVertexBuffer[eyeNum], pDistortionMeshIndexBuffer[eyeNum], dummy, 0, DistortionMeshNumTris[eyeNum] * 3, Prim_Triangles, true); - } - } - else if ( PostProcessingType == PostProcess_MeshDistortionPositionalTimewarp ) - { - Recti vp( 0, 0, WindowWidth, WindowHeight ); - SetViewport(vp); - float r, g, b, a; - DistortionClearColor.GetRGBA(&r, &g, &b, &a); - Clear(r, g, b, a); - - ShaderFill fill(pPostProcessShader); - fill.SetTexture ( 0, pSourceTextureLeftOrOnly ); - fill.SetTexture ( 0, pSourceTextureLeftOrOnlyDepth, Shader_Vertex ); - - for ( int eyeNum = 0; eyeNum < 2; eyeNum++ ) - { - Matrix4f const &matRenderFromWorld = ( eyeNum == 0 ) ? matRenderFromWorldLeft : matRenderFromWorldRight; - const StereoEyeParams &stereoParams = ( eyeNum == 0 ) ? stereoParamsLeft : stereoParamsRight; - - Matrix4f matRenderFromNowStart = TimewarpComputePoseDelta ( matRenderFromWorld, matNowFromWorldStart ); - Matrix4f matRenderFromNowEnd = TimewarpComputePoseDelta ( matRenderFromWorld, matNowFromWorldEnd ); - - pPostProcessShader->SetUniform2f("EyeToSourceUVScale", stereoParams.EyeToSourceUV.Scale.x, stereoParams.EyeToSourceUV.Scale.y ); - pPostProcessShader->SetUniform2f("EyeToSourceUVOffset", stereoParams.EyeToSourceUV.Offset.x, stereoParams.EyeToSourceUV.Offset.y ); - - // DepthProjector values can also be calculated as: - // float DepthProjectorX = FarClip / (FarClip - NearClip); - // float DepthProjectorY = (-FarClip * NearClip) / (FarClip - NearClip); - pPostProcessShader->SetUniform2f("DepthProjector", -stereoParams.RenderedProjection.M[2][2], stereoParams.RenderedProjection.M[2][3]); - pPostProcessShader->SetUniform2f("DepthDimSize", (float)pSourceTextureLeftOrOnlyDepth->GetWidth(), (float)pSourceTextureLeftOrOnlyDepth->GetHeight()); - pPostProcessShader->SetUniform4x4f("EyeRotationStart", matRenderFromNowStart); - pPostProcessShader->SetUniform4x4f("EyeRotationEnd", matRenderFromNowEnd); - - - Matrix4f dummy; - if ( ( pSourceTextureRight != NULL ) && ( eyeNum == 1 ) ) - { - OVR_ASSERT(pSourceTextureRightDepth != NULL); - fill.SetTexture ( 0, pSourceTextureRight ); - fill.SetTexture ( 0, pSourceTextureRightDepth, Shader_Vertex ); - } - - Render(&fill, pDistortionMeshVertexBuffer[eyeNum], pDistortionMeshIndexBuffer[eyeNum], dummy, 0, DistortionMeshNumTris[eyeNum] * 3, Prim_Triangles, true); - } - } - else - { - if ( PostProcessingType == PostProcess_PixelDistortion ) + bool usingOverlay = pOverlayLayerRenderTargetLeftOrBothEyes != NULL; + + switch( PostProcessingType ) + { + case PostProcess_MeshDistortion: + { + Recti vp ( 0, 0, WindowWidth, WindowHeight ); + SetViewport(vp); + float r, g, b, a; + DistortionClearColor.GetRGBA(&r, &g, &b, &a); + Clear(r, g, b, a); + + Matrix4f dummy; + ShaderFill fill(pPostProcessShader); + + fill.SetTexture ( 0, pHmdSpaceLayerRenderTargetLeftOrBothEyes->pColorTex ); + fill.SetTexture ( 1, (usingOverlay ? pOverlayLayerRenderTargetLeftOrBothEyes->pColorTex : NULL)); + pPostProcessShader->SetUniform1f("UseOverlay", usingOverlay ? 1.0f : 0.0f); + pPostProcessShader->SetUniform2f("EyeToSourceUVScale", stereoParamsLeft.EyeToSourceUV.Scale.x, stereoParamsLeft.EyeToSourceUV.Scale.y ); + pPostProcessShader->SetUniform2f("EyeToSourceUVOffset", stereoParamsLeft.EyeToSourceUV.Offset.x, stereoParamsLeft.EyeToSourceUV.Offset.y ); + Render(&fill, pDistortionMeshVertexBuffer[0], pDistortionMeshIndexBuffer[0], dummy, 0, DistortionMeshNumTris[0] * 3, Prim_Triangles, Mesh_Distortion); + + if ( pHmdSpaceLayerRenderTargetRight != NULL ) + { + fill.SetTexture ( 0, pHmdSpaceLayerRenderTargetRight->pColorTex ); + fill.SetTexture ( 1, (usingOverlay ? pOverlayLayerRenderTargetRight->pColorTex : NULL)); + } + pPostProcessShader->SetUniform2f("EyeToSourceUVScale", stereoParamsRight.EyeToSourceUV.Scale.x, stereoParamsRight.EyeToSourceUV.Scale.y ); + pPostProcessShader->SetUniform2f("EyeToSourceUVOffset", stereoParamsRight.EyeToSourceUV.Offset.x, stereoParamsRight.EyeToSourceUV.Offset.y ); + Render(&fill, pDistortionMeshVertexBuffer[1], pDistortionMeshIndexBuffer[1], dummy, 0, DistortionMeshNumTris[1] * 3, Prim_Triangles, Mesh_Distortion); + } + break; + + case PostProcess_MeshDistortionTimewarp: + { + Recti vp ( 0, 0, WindowWidth, WindowHeight ); + SetViewport(vp); + float r, g, b, a; + DistortionClearColor.GetRGBA(&r, &g, &b, &a); + Clear(r, g, b, a); + + ShaderFill fill(pPostProcessShader); + fill.SetTexture ( 0, pHmdSpaceLayerRenderTargetLeftOrBothEyes->pColorTex ); + fill.SetTexture ( 1, (usingOverlay ? pOverlayLayerRenderTargetLeftOrBothEyes->pColorTex : NULL)); + pPostProcessShader->SetUniform1f("UseOverlay", usingOverlay ? 1.0f : 0.0f); + + for ( int eyeNum = 0; eyeNum < 2; eyeNum++ ) + { + Matrix4f const &matRenderFromWorld = ( eyeNum == 0 ) ? matRenderFromWorldLeft : matRenderFromWorldRight; + const StereoEyeParams &stereoParams = ( eyeNum == 0 ) ? stereoParamsLeft : stereoParamsRight; + + Matrix4f matRenderFromNowStart = TimewarpComputePoseDelta ( matRenderFromWorld, matNowFromWorldStart, stereoParams.ViewAdjust ); + Matrix4f matRenderFromNowEnd = TimewarpComputePoseDelta ( matRenderFromWorld, matNowFromWorldEnd, stereoParams.ViewAdjust ); + + pPostProcessShader->SetUniform2f("EyeToSourceUVScale", stereoParams.EyeToSourceUV.Scale.x, stereoParams.EyeToSourceUV.Scale.y ); + pPostProcessShader->SetUniform2f("EyeToSourceUVOffset", stereoParams.EyeToSourceUV.Offset.x, stereoParams.EyeToSourceUV.Offset.y ); + pPostProcessShader->SetUniform3x3f("EyeRotationStart", matRenderFromNowStart); + pPostProcessShader->SetUniform3x3f("EyeRotationEnd", matRenderFromNowEnd); + + Matrix4f dummy; + if ( ( pHmdSpaceLayerRenderTargetRight != NULL ) && ( eyeNum == 1 ) ) + { + fill.SetTexture ( 0, pHmdSpaceLayerRenderTargetRight->pColorTex ); + fill.SetTexture ( 1, (usingOverlay ? pOverlayLayerRenderTargetRight->pColorTex : NULL)); + } + Render(&fill, pDistortionMeshVertexBuffer[eyeNum], pDistortionMeshIndexBuffer[eyeNum], dummy, 0, DistortionMeshNumTris[eyeNum] * 3, Prim_Triangles, Mesh_Distortion); + } + } + break; + + case PostProcess_MeshDistortionPositionalTimewarp: + { + Recti vp( 0, 0, WindowWidth, WindowHeight ); + SetViewport(vp); + float r, g, b, a; + DistortionClearColor.GetRGBA(&r, &g, &b, &a); + Clear(r, g, b, a); + + ShaderFill fill(pPostProcessShader); + fill.SetTexture ( 0, pHmdSpaceLayerRenderTargetLeftOrBothEyes->pColorTex ); + fill.SetTexture ( 0, pHmdSpaceLayerRenderTargetLeftOrBothEyes->pDepthTex, Shader_Vertex ); + fill.SetTexture ( 1, (usingOverlay ? pOverlayLayerRenderTargetLeftOrBothEyes->pColorTex : NULL)); + pPostProcessShader->SetUniform1f("UseOverlay", usingOverlay ? 1.0f : 0.0f); + + for ( int eyeNum = 0; eyeNum < 2; eyeNum++ ) + { + Matrix4f const &matRenderFromWorld = ( eyeNum == 0 ) ? matRenderFromWorldLeft : matRenderFromWorldRight; + const StereoEyeParams &stereoParams = ( eyeNum == 0 ) ? stereoParamsLeft : stereoParamsRight; + + Matrix4f matRenderFromNowStart = TimewarpComputePoseDelta ( matRenderFromWorld, matNowFromWorldStart, stereoParams.ViewAdjust ); + Matrix4f matRenderFromNowEnd = TimewarpComputePoseDelta ( matRenderFromWorld, matNowFromWorldEnd, stereoParams.ViewAdjust ); + + pPostProcessShader->SetUniform2f("EyeToSourceUVScale", stereoParams.EyeToSourceUV.Scale.x, stereoParams.EyeToSourceUV.Scale.y ); + pPostProcessShader->SetUniform2f("EyeToSourceUVOffset", stereoParams.EyeToSourceUV.Offset.x, stereoParams.EyeToSourceUV.Offset.y ); + + // DepthProjector values can also be calculated as: + // float DepthProjectorX = FarClip / (FarClip - NearClip); + // float DepthProjectorY = (-FarClip * NearClip) / (FarClip - NearClip); + pPostProcessShader->SetUniform2f("DepthProjector", -stereoParams.RenderedProjection.M[2][2], stereoParams.RenderedProjection.M[2][3]); + pPostProcessShader->SetUniform2f("DepthDimSize", (float)pHmdSpaceLayerRenderTargetLeftOrBothEyes->Size.w, (float)pHmdSpaceLayerRenderTargetLeftOrBothEyes->Size.h); + pPostProcessShader->SetUniform4x4f("EyeRotationStart", matRenderFromNowStart); + pPostProcessShader->SetUniform4x4f("EyeRotationEnd", matRenderFromNowEnd); + + + Matrix4f dummy; + if ( ( pHmdSpaceLayerRenderTargetRight != NULL ) && ( eyeNum == 1 ) ) + { + OVR_ASSERT(pHmdSpaceLayerRenderTargetRight->pDepthTex != NULL); + fill.SetTexture ( 0, pHmdSpaceLayerRenderTargetRight->pColorTex ); + fill.SetTexture ( 0, pHmdSpaceLayerRenderTargetRight->pDepthTex, Shader_Vertex ); + fill.SetTexture ( 1, (usingOverlay ? pOverlayLayerRenderTargetRight->pColorTex : NULL)); + } + + Render(&fill, pDistortionMeshVertexBuffer[eyeNum], pDistortionMeshIndexBuffer[eyeNum], dummy, 0, DistortionMeshNumTris[eyeNum] * 3, Prim_Triangles, Mesh_Distortion); + } + } + break; + + case PostProcess_MeshDistortionHeightmapTimewarp: + { + // Create pass1 textures if not already done + for ( int eyeNum = 0; eyeNum < 2; eyeNum++ ) + { + Texture* templateTexture = NULL; + switch(eyeNum) + { + case 0: templateTexture = pHmdSpaceLayerRenderTargetLeftOrBothEyes->pColorTex; break; + case 1: templateTexture = pHmdSpaceLayerRenderTargetRight->pColorTex; break; + default: OVR_ASSERT(false); + } + + if( templateTexture == NULL) + { + if(HeightmapTimewarpRTs[eyeNum].pColorTex != NULL) + { + HeightmapTimewarpRTs[eyeNum].pColorTex = NULL; + HeightmapTimewarpRTs[eyeNum].pDepthTex = NULL; + } + } + else if( HeightmapTimewarpRTs[eyeNum].pColorTex == NULL || + HeightmapTimewarpRTs[eyeNum].Size.w != templateTexture->GetWidth() || + HeightmapTimewarpRTs[eyeNum].Size.h != templateTexture->GetHeight()) + { + HeightmapTimewarpRTs[eyeNum].Size.w = templateTexture->GetWidth(); + HeightmapTimewarpRTs[eyeNum].Size.h = templateTexture->GetHeight(); + + HeightmapTimewarpRTs[eyeNum].pColorTex = *CreateTexture(Texture_RGBA | Texture_RenderTarget | templateTexture->GetSamples(), + HeightmapTimewarpRTs[eyeNum].Size.w, HeightmapTimewarpRTs[eyeNum].Size.h, NULL); + + HeightmapTimewarpRTs[eyeNum].pColorTex->SetSampleMode ( Sample_ClampBorder | Sample_Linear); + + HeightmapTimewarpRTs[eyeNum].pDepthTex = *CreateTexture(Texture_Depth | Texture_RenderTarget | Texture_SampleDepth | templateTexture->GetSamples(), + HeightmapTimewarpRTs[eyeNum].Size.w, HeightmapTimewarpRTs[eyeNum].Size.h, NULL); + } + } + + Matrix4f identity; + + // Pass 1 - do heightmap-based positional time warp + { + SetDepthMode(true, true); + + ShaderFill heightmapFill(pPostProcessHeightmapShader); + + for ( int eyeNum = 0; eyeNum < 2; eyeNum++ ) + { + const StereoEyeParams &stereoParams = ( eyeNum == 0 ) ? stereoParamsLeft : stereoParamsRight; + + switch(eyeNum) + { + case 0: + { + heightmapFill.SetTexture ( 0, pHmdSpaceLayerRenderTargetLeftOrBothEyes->pColorTex ); + heightmapFill.SetTexture ( 0, pHmdSpaceLayerRenderTargetLeftOrBothEyes->pDepthTex, Shader_Vertex ); + SetRenderTarget(HeightmapTimewarpRTs[eyeNum]); // output to temp buffers + } + break; + case 1: + if ( ( pHmdSpaceLayerRenderTargetRight != NULL ) ) + { + heightmapFill.SetTexture ( 0, pHmdSpaceLayerRenderTargetRight->pColorTex ); + heightmapFill.SetTexture ( 0, pHmdSpaceLayerRenderTargetRight->pDepthTex, Shader_Vertex ); + SetRenderTarget(HeightmapTimewarpRTs[eyeNum]); // output to temp buffers + } + break; + default: OVR_ASSERT(false); + } + + SetViewport(stereoParams.RenderedViewport); + Clear(); + + Matrix4f const &matRenderFromWorld = ( eyeNum == 0 ) ? matRenderFromWorldLeft : matRenderFromWorldRight; + + Matrix4f matRenderFromNowStart = TimewarpComputePoseDeltaPosition ( matRenderFromWorld, matNowFromWorldStart, stereoParams.ViewAdjust ); + Matrix4f matRenderFromNowEnd = TimewarpComputePoseDeltaPosition ( matRenderFromWorld, matNowFromWorldEnd, stereoParams.ViewAdjust ); + + pPostProcessHeightmapShader->SetUniform2f("EyeToSourceUVScale", stereoParams.EyeToSourceUV.Scale.x, stereoParams.EyeToSourceUV.Scale.y ); + pPostProcessHeightmapShader->SetUniform2f("EyeToSourceUVOffset", stereoParams.EyeToSourceUV.Offset.x, stereoParams.EyeToSourceUV.Offset.y ); + + pPostProcessHeightmapShader->SetUniform2f("DepthDimSize", (float)pHmdSpaceLayerRenderTargetLeftOrBothEyes->Size.w, (float)pHmdSpaceLayerRenderTargetLeftOrBothEyes->Size.h); + + // TODO: Combining "proj * xform * invProj" leads to artifacts due to precision loss with the inversion + pPostProcessHeightmapShader->SetUniform4x4f("EyeXformStart", stereoParams.RenderedProjection * matRenderFromNowStart); + pPostProcessHeightmapShader->SetUniform4x4f("EyeXformEnd", stereoParams.RenderedProjection * matRenderFromNowEnd); + //pPostProcessHeightmapShader->SetUniform4x4f("EyeXformStart", stereoParams.RenderedProjection * matRenderFromNowStart * stereoParams.RenderedProjection.Inverted()); + //pPostProcessHeightmapShader->SetUniform4x4f("EyeXformEnd", stereoParams.RenderedProjection * matRenderFromNowEnd * stereoParams.RenderedProjection.Inverted()); + //pPostProcessHeightmapShader->SetUniform4x4f("Projection", stereoParams.RenderedProjection); + pPostProcessHeightmapShader->SetUniform4x4f("InvProjection", stereoParams.RenderedProjection.Inverted()); + + Render(&heightmapFill, pHeightmapMeshVertexBuffer[eyeNum], pHeightmapMeshIndexBuffer[eyeNum], identity, 0, HeightmapMeshNumTris[eyeNum] * 3, Prim_Triangles, Mesh_Heightmap); + } + } + + // Pass 2 - do distortion + { + SetDefaultRenderTarget(); + SetDepthMode(false, false); + + Recti vp( 0, 0, WindowWidth, WindowHeight ); + SetViewport(vp); + float r, g, b, a; + DistortionClearColor.GetRGBA(&r, &g, &b, &a); + Clear(r, g, b, a); + + ShaderFill fill(pPostProcessShader); + fill.SetTexture ( 0, HeightmapTimewarpRTs[0].pColorTex ); + fill.SetTexture ( 1, (usingOverlay ? pOverlayLayerRenderTargetLeftOrBothEyes->pColorTex : NULL)); + pPostProcessShader->SetUniform1f("UseOverlay", usingOverlay ? 1.0f : 0.0f); + + for ( int eyeNum = 0; eyeNum < 2; eyeNum++ ) + { + const StereoEyeParams &stereoParams = ( eyeNum == 0 ) ? stereoParamsLeft : stereoParamsRight; + + // TODO: Could avoid the need for these vars since the mesh doesn't actually to time warping + pPostProcessShader->SetUniform2f("EyeToSourceUVScale", stereoParams.EyeToSourceUV.Scale.x, stereoParams.EyeToSourceUV.Scale.y ); + pPostProcessShader->SetUniform2f("EyeToSourceUVOffset", stereoParams.EyeToSourceUV.Offset.x, stereoParams.EyeToSourceUV.Offset.y ); + + if ( ( HeightmapTimewarpRTs[1].pColorTex != NULL ) && ( eyeNum == 1 ) ) + { + fill.SetTexture ( 0, HeightmapTimewarpRTs[1].pColorTex ); + fill.SetTexture ( 1, (usingOverlay ? pOverlayLayerRenderTargetRight->pColorTex : NULL)); + } + + Render(&fill, pDistortionMeshVertexBuffer[eyeNum], pDistortionMeshIndexBuffer[eyeNum], identity, 0, DistortionMeshNumTris[eyeNum] * 3, Prim_Triangles, Mesh_Distortion); + } + } + } + break; + + case PostProcess_PixelDistortion: { float r, g, b, a; DistortionClearColor.GetRGBA(&r, &g, &b, &a); @@ -1201,18 +1410,20 @@ namespace OVR { namespace Render { 0, 0, 0, 1); ShaderFill fill(pPostProcessShader); - if ( ( pSourceTextureRight != NULL ) && ( eyeNum == 1 ) ) + if ( ( pHmdSpaceLayerRenderTargetRight != NULL ) && ( eyeNum == 1 ) ) { - fill.SetTexture ( 0, pSourceTextureRight ); + fill.SetTexture ( 0, pHmdSpaceLayerRenderTargetRight->pColorTex ); } else { - fill.SetTexture ( 0, pSourceTextureLeftOrOnly ); + fill.SetTexture ( 0, pHmdSpaceLayerRenderTargetLeftOrBothEyes->pColorTex ); } Render(&fill, pFullScreenVertexBuffer, NULL, view, 0, 4, Prim_TriangleStrip); } } - else if ( PostProcessingType == PostProcess_NoDistortion ) + break; + + case PostProcess_NoDistortion: { // Just splat the thing on the framebuffer with no distortion. Clear ( 0.0f, 0.4f, 0.0f, 1.0f, 1.0f ); @@ -1225,8 +1436,8 @@ namespace OVR { namespace Render { ortho.M[1][3] = 0.0f; ortho.M[2][2] = 0; SetProjection(ortho); - int rtWidth = pSourceTextureLeftOrOnly->GetWidth(); - int rtHeight = pSourceTextureLeftOrOnly->GetHeight(); + int rtWidth = pHmdSpaceLayerRenderTargetLeftOrBothEyes->pColorTex->GetWidth(); + int rtHeight = pHmdSpaceLayerRenderTargetLeftOrBothEyes->pColorTex->GetHeight(); for ( int eyeNum = 0; eyeNum < 2; eyeNum++ ) { @@ -1234,13 +1445,13 @@ namespace OVR { namespace Render { SetViewport ( stereoParams.DistortionViewport ); Ptr<Texture> pTex; - if ( ( pSourceTextureRight != NULL ) && ( eyeNum == 1 ) ) + if ( ( pHmdSpaceLayerRenderTargetRight != NULL ) && ( eyeNum == 1 ) ) { - pTex = pSourceTextureRight; + pTex = pHmdSpaceLayerRenderTargetRight->pColorTex; } else { - pTex = pSourceTextureLeftOrOnly; + pTex = pHmdSpaceLayerRenderTargetLeftOrBothEyes->pColorTex; } float ul = (float)( stereoParams.RenderedViewport.x ) / (float)rtWidth; @@ -1253,10 +1464,10 @@ namespace OVR { namespace Render { Color(255,255,255,255), pTex ); } } - else - { - OVR_ASSERT ( !"Unknown distortion type" ); - } + break; + + default: + OVR_ASSERT ( !"Unknown distortion type" ); } } diff --git a/Samples/CommonSrc/Render/Render_Device.h b/Samples/CommonSrc/Render/Render_Device.h index f8a6dff..eea352e 100644 --- a/Samples/CommonSrc/Render/Render_Device.h +++ b/Samples/CommonSrc/Render/Render_Device.h @@ -83,6 +83,7 @@ enum BuiltinShaders VShader_PostProcessMesh , VShader_PostProcessMeshTimewarp , VShader_PostProcessMeshPositionalTimewarp , + VShader_PostProcessHeightmapTimewarp , VShader_Count , FShader_Solid = 0, @@ -96,6 +97,7 @@ enum BuiltinShaders FShader_PostProcessMeshWithChromAb , FShader_PostProcessMeshWithChromAbTimewarp , FShader_PostProcessMeshWithChromAbPositionalTimewarp , + FShader_PostProcessHeightmapTimewarp , FShader_Count , }; @@ -151,6 +153,12 @@ enum SampleMode Sample_Count =13, }; +enum MeshType +{ + Mesh_Scene, + Mesh_Distortion, + Mesh_Heightmap, +}; struct Color4f { @@ -354,7 +362,12 @@ public: virtual void* GetInternalImplementation() { return NULL; }; }; - +struct RenderTarget +{ + Ptr<Texture> pColorTex; + Ptr<Texture> pDepthTex; + Sizei Size; +}; //----------------------------------------------------------------------------------- @@ -438,7 +451,7 @@ struct Vertex Vertex (const Vector3f& p, const Color& c = Color(64,0,0,255), float u = 0, float v = 0, Vector3f n = Vector3f(1,0,0)) - : Pos(p), C(c), U(u), V(v), Norm(n), U2(u), V2(v) {} + : Pos(p), C(c), U(u), V(v), U2(u), V2(v), Norm(n) {} Vertex(float x, float y, float z, const Color& c = Color(64,0,0,255), float u = 0, float v = 0) : Pos(x,y,z), C(c), U(u), V(v), U2(u), V2(v) { } @@ -461,6 +474,12 @@ struct DistortionVertex Color Col; }; +struct HeightmapVertex +{ + Vector2f Pos; + Vector3f Tex; +}; + // this is stored in a uniform buffer, don't change it without fixing all renderers struct LightingParams { @@ -685,6 +704,7 @@ enum PostProcessType PostProcess_MeshDistortion, PostProcess_MeshDistortionTimewarp, PostProcess_MeshDistortionPositionalTimewarp, + PostProcess_MeshDistortionHeightmapTimewarp, PostProcess_NoDistortion, }; @@ -701,11 +721,11 @@ struct DisplayId String MonitorName; // Monitor name for fullscreen mode // MacOS - long CgDisplayId; // CGDirectDisplayID + int CgDisplayId; // CGDirectDisplayID DisplayId() : CgDisplayId(0) {} - DisplayId(long id) : CgDisplayId(id) {} - DisplayId(String m, long id=0) : MonitorName(m), CgDisplayId(id) {} + DisplayId(int id) : CgDisplayId(id) {} + DisplayId(String m, int id=0) : MonitorName(m), CgDisplayId(id) {} operator bool () const { @@ -754,6 +774,7 @@ protected: PostProcessType PostProcessingType; Ptr<ShaderSet> pPostProcessShader; + Ptr<ShaderSet> pPostProcessHeightmapShader; Ptr<Buffer> pFullScreenVertexBuffer; Color DistortionClearColor; UPInt TotalTextureMemoryUsage; @@ -763,9 +784,15 @@ protected: Ptr<Buffer> pDistortionMeshVertexBuffer[2]; Ptr<Buffer> pDistortionMeshIndexBuffer[2]; + int HeightmapMeshNumTris[2]; + Ptr<Buffer> pHeightmapMeshVertexBuffer[2]; + Ptr<Buffer> pHeightmapMeshIndexBuffer[2]; + // For lighting on platforms with uniform buffers Ptr<Buffer> LightingBuffer; + RenderTarget HeightmapTimewarpRTs[2]; // one for each eye + public: enum CompareFunc { @@ -784,7 +811,11 @@ public: virtual void Init() {} virtual void Shutdown(); - virtual bool SetParams(const RendererParams&) { return 0; } + virtual bool SetParams(const RendererParams& rp) + { + Params = rp; + return true; + } const RendererParams& GetParams() const { return Params; } @@ -859,10 +890,11 @@ public: virtual void ApplyPostProcess(Matrix4f const &matNowFromWorldStart, Matrix4f const &matNowFromWorldEnd, Matrix4f const &matRenderFromWorldLeft, Matrix4f const &matRenderFromWorldRight, StereoEyeParams const &stereoParamsLeft, StereoEyeParams const &stereoParamsRight, - Ptr<Texture> pSourceTextureLeftOrOnly, - Ptr<Texture> pSourceTextureRight, - Ptr<Texture> pSourceTextureLeftOrOnlyDepth, - Ptr<Texture> pSourceTextureRightDepth); + RenderTarget* pHmdSpaceLayerRenderTargetLeftOrBothEyes, + RenderTarget* pHmdSpaceLayerRenderTargetRight, + RenderTarget* pStaticLayerRenderTargetLeftOrBothEyes, + RenderTarget* pStaticLayerRenderTargetRight); + // Finish scene. virtual void FinishScene(); @@ -870,6 +902,12 @@ public: // NULL depth buffer means use an internal, temporary one. virtual void SetRenderTarget(Texture* color, Texture* depth = NULL, Texture* stencil = NULL) { OVR_UNUSED3(color, depth, stencil); } + void SetRenderTarget(const RenderTarget& renderTarget) + { + SetRenderTarget(renderTarget.pColorTex, renderTarget.pDepthTex); + } + // go to back buffer + void SetDefaultRenderTarget() { SetRenderTarget(NULL, NULL); } virtual void SetDepthMode(bool enable, bool write, CompareFunc func = Compare_Less) = 0; virtual void SetProjection(const Matrix4f& proj); virtual void SetWorldUniforms(const Matrix4f& proj) = 0; @@ -887,7 +925,7 @@ public: virtual void Render(const Matrix4f& matrix, Model* model) = 0; // offset is in bytes; indices can be null. virtual void Render(const Fill* fill, Buffer* vertices, Buffer* indices, - const Matrix4f& matrix, int offset, int count, PrimitiveType prim = Prim_Triangles, bool useDistortionVertex = false) = 0; + const Matrix4f& matrix, int offset, int count, PrimitiveType prim = Prim_Triangles, MeshType meshType = Mesh_Scene) = 0; virtual void RenderWithAlpha(const Fill* fill, Render::Buffer* vertices, Render::Buffer* indices, const Matrix4f& matrix, int offset, int count, PrimitiveType prim = Prim_Triangles) = 0; @@ -913,7 +951,11 @@ public: } // Don't call these directly, use App/Platform instead - virtual bool SetFullscreen(DisplayMode fullscreen) { OVR_UNUSED(fullscreen); return false; } + virtual bool SetFullscreen(DisplayMode fullscreen) + { + Params.Fullscreen = fullscreen; + return true; + } virtual void SetWindowSize(int w, int h) { WindowWidth = w; @@ -932,6 +974,7 @@ public: PostProcessShader_MeshDistortionAndChromAb, PostProcessShader_MeshDistortionAndChromAbTimewarp, PostProcessShader_MeshDistortionAndChromAbPositionalTimewarp, + PostProcessShader_MeshDistortionAndChromAbHeightmapTimewarp, PostProcessShader_Count }; diff --git a/Samples/CommonSrc/Render/Render_FontEmbed_DejaVu48.h b/Samples/CommonSrc/Render/Render_FontEmbed_DejaVu48.h index 2428ddd..2683244 100644 --- a/Samples/CommonSrc/Render/Render_FontEmbed_DejaVu48.h +++ b/Samples/CommonSrc/Render/Render_FontEmbed_DejaVu48.h @@ -9457,7 +9457,7 @@ const unsigned char DejaVu_tex[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -Font DejaVu = {56, 45, -11, DejaVu_chars, DejaVu_kern, 1016, 141, DejaVu_tex}; +Font DejaVu = {56, 45, -11, DejaVu_chars, DejaVu_kern, 1016, 141, DejaVu_tex, 0}; }} diff --git a/Samples/CommonSrc/Render/Render_GL_Device.cpp b/Samples/CommonSrc/Render/Render_GL_Device.cpp index 4b3ddec..774af07 100644 --- a/Samples/CommonSrc/Render/Render_GL_Device.cpp +++ b/Samples/CommonSrc/Render/Render_GL_Device.cpp @@ -26,19 +26,40 @@ limitations under the License. #include "OVR_CAPI_GL.h" namespace OVR { namespace Render { namespace GL { + +#if !defined(OVR_OS_MAC) // GL Hooks for PC. #if defined(OVR_OS_WIN32) +PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB; +PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB; PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT; PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT; -PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT; -PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT; + +void* GetFunction(const char* functionName) +{ + return wglGetProcAddress(functionName); +} + +#else + +PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT; + +void (*GetFunction(const char *functionName))( void ) +{ + return glXGetProcAddress((GLubyte*)functionName); +} + +#endif + +PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers; +PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers; PFNGLDELETESHADERPROC glDeleteShader; -PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT; -PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT; -PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT; -PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT; +PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus; +PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer; +PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D; +PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer; PFNGLACTIVETEXTUREPROC glActiveTexture; PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray; PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; @@ -73,87 +94,96 @@ PFNGLUNIFORM3FVPROC glUniform3fv; PFNGLUNIFORM2FVPROC glUniform2fv; PFNGLUNIFORM1FVPROC glUniform1fv; PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D; -PFNGLRENDERBUFFERSTORAGEEXTPROC glRenderbufferStorageEXT; -PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT; -PFNGLGENRENDERBUFFERSEXTPROC glGenRenderbuffersEXT; -PFNGLDELETERENDERBUFFERSEXTPROC glDeleteRenderbuffersEXT; - +PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage; +PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer; +PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers; +PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers; PFNGLGENVERTEXARRAYSPROC glGenVertexArrays; +PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays; +PFNGLBINDVERTEXARRAYPROC glBindVertexArray; void InitGLExtensions() { - if (glGenFramebuffersEXT) + if (glGenFramebuffers) return; - - - wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC) wglGetProcAddress("wglGetSwapIntervalEXT"); - wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC) wglGetProcAddress("wglSwapIntervalEXT"); - glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC) wglGetProcAddress("glGenFramebuffersEXT"); - glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC) wglGetProcAddress("glDeleteFramebuffersEXT"); - glDeleteShader = (PFNGLDELETESHADERPROC) wglGetProcAddress("glDeleteShader"); - glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) wglGetProcAddress("glCheckFramebufferStatusEXT"); - glFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) wglGetProcAddress("glFramebufferRenderbufferEXT"); - glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) wglGetProcAddress("glFramebufferTexture2DEXT"); - glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC) wglGetProcAddress("glBindFramebufferEXT"); - glActiveTexture = (PFNGLACTIVETEXTUREPROC) wglGetProcAddress("glActiveTexture"); - glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) wglGetProcAddress("glDisableVertexAttribArray"); - glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) wglGetProcAddress("glVertexAttribPointer"); - glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) wglGetProcAddress("glEnableVertexAttribArray"); - glBindBuffer = (PFNGLBINDBUFFERPROC) wglGetProcAddress("glBindBuffer"); - glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC) wglGetProcAddress("glUniformMatrix3fv"); - glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) wglGetProcAddress("glUniformMatrix4fv"); - glDeleteBuffers = (PFNGLDELETEBUFFERSPROC) wglGetProcAddress("glDeleteBuffers"); - glBufferData = (PFNGLBUFFERDATAPROC) wglGetProcAddress("glBufferData"); - glGenBuffers = (PFNGLGENBUFFERSPROC) wglGetProcAddress("glGenBuffers"); - glMapBuffer = (PFNGLMAPBUFFERPROC) wglGetProcAddress("glMapBuffer"); - glUnmapBuffer = (PFNGLUNMAPBUFFERPROC) wglGetProcAddress("glUnmapBuffer"); - glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) wglGetProcAddress("glGetShaderInfoLog"); - glGetShaderiv = (PFNGLGETSHADERIVPROC) wglGetProcAddress("glGetShaderiv"); - glCompileShader = (PFNGLCOMPILESHADERPROC) wglGetProcAddress("glCompileShader"); - glShaderSource = (PFNGLSHADERSOURCEPROC) wglGetProcAddress("glShaderSource"); - glCreateShader = (PFNGLCREATESHADERPROC) wglGetProcAddress("glCreateShader"); - glCreateProgram = (PFNGLCREATEPROGRAMPROC) wglGetProcAddress("glCreateProgram"); - glAttachShader = (PFNGLATTACHSHADERPROC) wglGetProcAddress("glAttachShader"); - glDetachShader = (PFNGLDETACHSHADERPROC) wglGetProcAddress("glDetachShader"); - glDeleteProgram = (PFNGLDELETEPROGRAMPROC) wglGetProcAddress("glDeleteProgram"); - glUniform1i = (PFNGLUNIFORM1IPROC) wglGetProcAddress("glUniform1i"); - glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) wglGetProcAddress("glGetUniformLocation"); - glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC) wglGetProcAddress("glGetActiveUniform"); - glUseProgram = (PFNGLUSEPROGRAMPROC) wglGetProcAddress("glUseProgram"); - glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) wglGetProcAddress("glGetProgramInfoLog"); - glGetProgramiv = (PFNGLGETPROGRAMIVPROC) wglGetProcAddress("glGetProgramiv"); - glLinkProgram = (PFNGLLINKPROGRAMPROC) wglGetProcAddress("glLinkProgram"); - glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC) wglGetProcAddress("glBindAttribLocation"); - glUniform4fv = (PFNGLUNIFORM4FVPROC) wglGetProcAddress("glUniform4fv"); - glUniform3fv = (PFNGLUNIFORM3FVPROC) wglGetProcAddress("glUniform3fv"); - glUniform2fv = (PFNGLUNIFORM2FVPROC) wglGetProcAddress("glUniform2fv"); - glUniform1fv = (PFNGLUNIFORM1FVPROC) wglGetProcAddress("glUniform1fv"); - glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC) wglGetProcAddress("glCompressedTexImage2D"); - glRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC) wglGetProcAddress("glRenderbufferStorageEXT"); - glBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC) wglGetProcAddress("glBindRenderbufferEXT"); - glGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC) wglGetProcAddress("glGenRenderbuffersEXT"); - glDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC) wglGetProcAddress("glDeleteRenderbuffersEXT"); - - - glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC) wglGetProcAddress("glGenVertexArrays"); -} +#if defined(OVR_OS_WIN32) + wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC) GetFunction("wglGetSwapIntervalEXT"); + wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC) GetFunction("wglSwapIntervalEXT"); +#else + glXSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC) GetFunction("glXSwapIntervalEXT"); #endif + glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) GetFunction("glGenFramebuffersEXT"); + glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) GetFunction("glDeleteFramebuffersEXT"); + glDeleteShader = (PFNGLDELETESHADERPROC) GetFunction("glDeleteShader"); + glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) GetFunction("glCheckFramebufferStatusEXT"); + glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) GetFunction("glFramebufferRenderbufferEXT"); + glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) GetFunction("glFramebufferTexture2DEXT"); + glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) GetFunction("glBindFramebufferEXT"); + glActiveTexture = (PFNGLACTIVETEXTUREPROC) GetFunction("glActiveTexture"); + glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) GetFunction("glDisableVertexAttribArray"); + glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) GetFunction("glVertexAttribPointer"); + glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) GetFunction("glEnableVertexAttribArray"); + glBindBuffer = (PFNGLBINDBUFFERPROC) GetFunction("glBindBuffer"); + glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC) GetFunction("glUniformMatrix3fv"); + glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) GetFunction("glUniformMatrix4fv"); + glDeleteBuffers = (PFNGLDELETEBUFFERSPROC) GetFunction("glDeleteBuffers"); + glBufferData = (PFNGLBUFFERDATAPROC) GetFunction("glBufferData"); + glGenBuffers = (PFNGLGENBUFFERSPROC) GetFunction("glGenBuffers"); + glMapBuffer = (PFNGLMAPBUFFERPROC) GetFunction("glMapBuffer"); + glUnmapBuffer = (PFNGLUNMAPBUFFERPROC) GetFunction("glUnmapBuffer"); + glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) GetFunction("glGetShaderInfoLog"); + glGetShaderiv = (PFNGLGETSHADERIVPROC) GetFunction("glGetShaderiv"); + glCompileShader = (PFNGLCOMPILESHADERPROC) GetFunction("glCompileShader"); + glShaderSource = (PFNGLSHADERSOURCEPROC) GetFunction("glShaderSource"); + glCreateShader = (PFNGLCREATESHADERPROC) GetFunction("glCreateShader"); + glCreateProgram = (PFNGLCREATEPROGRAMPROC) GetFunction("glCreateProgram"); + glAttachShader = (PFNGLATTACHSHADERPROC) GetFunction("glAttachShader"); + glDetachShader = (PFNGLDETACHSHADERPROC) GetFunction("glDetachShader"); + glDeleteProgram = (PFNGLDELETEPROGRAMPROC) GetFunction("glDeleteProgram"); + glUniform1i = (PFNGLUNIFORM1IPROC) GetFunction("glUniform1i"); + glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) GetFunction("glGetUniformLocation"); + glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC) GetFunction("glGetActiveUniform"); + glUseProgram = (PFNGLUSEPROGRAMPROC) GetFunction("glUseProgram"); + glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) GetFunction("glGetProgramInfoLog"); + glGetProgramiv = (PFNGLGETPROGRAMIVPROC) GetFunction("glGetProgramiv"); + glLinkProgram = (PFNGLLINKPROGRAMPROC) GetFunction("glLinkProgram"); + glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC) GetFunction("glBindAttribLocation"); + glUniform4fv = (PFNGLUNIFORM4FVPROC) GetFunction("glUniform4fv"); + glUniform3fv = (PFNGLUNIFORM3FVPROC) GetFunction("glUniform3fv"); + glUniform2fv = (PFNGLUNIFORM2FVPROC) GetFunction("glUniform2fv"); + glUniform1fv = (PFNGLUNIFORM1FVPROC) GetFunction("glUniform1fv"); + glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC) GetFunction("glCompressedTexImage2D"); + glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) GetFunction("glRenderbufferStorageEXT"); + glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC) GetFunction("glBindRenderbufferEXT"); + glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC) GetFunction("glGenRenderbuffersEXT"); + glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC) GetFunction("glDeleteRenderbuffersEXT"); + glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC) GetFunction("glGenVertexArrays"); + glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC) GetFunction("glDeleteVertexArrays"); + glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC) GetFunction("glBindVertexArray"); +} + +#endif static const char* StdVertexShaderSrc = + "#version 110\n" + "uniform mat4 Proj;\n" "uniform mat4 View;\n" + "attribute vec4 Position;\n" "attribute vec4 Color;\n" "attribute vec2 TexCoord;\n" "attribute vec2 TexCoord1;\n" "attribute vec3 Normal;\n" - "varying vec4 oColor;\n" - "varying vec2 oTexCoord;\n" - "varying vec2 oTexCoord1;\n" - "varying vec3 oNormal;\n" - "varying vec3 oVPos;\n" + + "varying vec4 oColor;\n" + "varying vec2 oTexCoord;\n" + "varying vec2 oTexCoord1;\n" + "varying vec3 oNormal;\n" + "varying vec3 oVPos;\n" + "void main()\n" "{\n" " gl_Position = Proj * (View * Position);\n" @@ -165,14 +195,19 @@ static const char* StdVertexShaderSrc = "}\n"; static const char* DirectVertexShaderSrc = + "#version 110\n" + "uniform mat4 View;\n" + "attribute vec4 Position;\n" "attribute vec4 Color;\n" "attribute vec2 TexCoord;\n" "attribute vec3 Normal;\n" - "varying vec4 oColor;\n" - "varying vec2 oTexCoord;\n" - "varying vec3 oNormal;\n" + + "varying vec4 oColor;\n" + "varying vec2 oTexCoord;\n" + "varying vec3 oNormal;\n" + "void main()\n" "{\n" " gl_Position = View * Position;\n" @@ -182,23 +217,33 @@ static const char* DirectVertexShaderSrc = "}\n"; static const char* SolidFragShaderSrc = + "#version 110\n" + "uniform vec4 Color;\n" + "void main()\n" "{\n" " gl_FragColor = Color;\n" "}\n"; static const char* GouraudFragShaderSrc = + "#version 110\n" + "varying vec4 oColor;\n" + "void main()\n" "{\n" " gl_FragColor = oColor;\n" "}\n"; static const char* TextureFragShaderSrc = + "#version 110\n" + "uniform sampler2D Texture0;\n" + "varying vec4 oColor;\n" "varying vec2 oTexCoord;\n" + "void main()\n" "{\n" " gl_FragColor = oColor * texture2D(Texture0, oTexCoord);\n" @@ -207,6 +252,7 @@ static const char* TextureFragShaderSrc = "}\n"; #define LIGHTING_COMMON \ + "#version 110\n" \ "uniform vec3 Ambient;\n" \ "uniform vec4 LightPos[8];\n" \ "uniform vec4 LightColor[8];\n" \ @@ -231,98 +277,91 @@ static const char* TextureFragShaderSrc = static const char* LitSolidFragShaderSrc = LIGHTING_COMMON + "void main()\n" "{\n" " gl_FragColor = DoLight() * oColor;\n" "}\n"; static const char* LitTextureFragShaderSrc = - "uniform sampler2D Texture0;\n" LIGHTING_COMMON + + "uniform sampler2D Texture0;\n" + "void main()\n" "{\n" " gl_FragColor = DoLight() * texture2D(Texture0, oTexCoord);\n" "}\n"; static const char* AlphaTextureFragShaderSrc = + "#version 110\n" + "uniform sampler2D Texture0;\n" + "varying vec4 oColor;\n" "varying vec2 oTexCoord;\n" + "void main()\n" "{\n" - " gl_FragColor = oColor * vec4(1,1,1,texture2D(Texture0, oTexCoord).a);\n" + " gl_FragColor = oColor * vec4(1,1,1,texture2D(Texture0, oTexCoord).r);\n" "}\n"; static const char* MultiTextureFragShaderSrc = + "#version 110\n" + "uniform sampler2D Texture0;\n" "uniform sampler2D Texture1;\n" + "varying vec4 oColor;\n" "varying vec2 oTexCoord;\n" "varying vec2 oTexCoord1;\n" + "void main()\n" "{\n" - " vec4 color1 = texture2D(Texture0, oTexCoord);\n" - " vec4 color2 = texture2D(Texture1, oTexCoord1);\n" - " color2.rgb = color2.rgb * mix(1.9, 1.2, clamp(length(color2.rgb),0.0,1.0));\n" - " color2 = color1 * color2;\n" - " if (color2.a <= 0.6)\n" + " vec4 color = texture2D(Texture0, oTexCoord);\n" + + " gl_FragColor = texture2D(Texture1, oTexCoord1);\n" + " gl_FragColor.rgb = gl_FragColor.rgb * mix(1.9, 1.2, clamp(length(gl_FragColor.rgb),0.0,1.0));\n" + + " gl_FragColor = color * gl_FragColor;\n" + + " if (gl_FragColor.a <= 0.6)\n" " discard;\n" - " gl_FragColor = color2;\n" "}\n"; static const char* PostProcessMeshFragShaderSrc = + "#version 110\n" + "uniform sampler2D Texture;\n" + "varying vec4 oColor;\n" "varying vec2 oTexCoord0;\n" "varying vec2 oTexCoord1;\n" "varying vec2 oTexCoord2;\n" - "\n" - "void main()\n" - "{\n" - " float ResultR = texture2D(Texture, oTexCoord0).r;\n" - " float ResultG = texture2D(Texture, oTexCoord1).g;\n" - " float ResultB = texture2D(Texture, oTexCoord2).b;\n" - " gl_FragColor = vec4(ResultR * oColor.r, ResultG * oColor.g, ResultB * oColor.b, 1.0);\n" - "}\n"; - -static const char* PostProcessMeshTimewarpFragShaderSrc = - "uniform sampler2D Texture;\n" - "varying vec4 oColor;\n" - "varying vec2 oTexCoord0;\n" - "varying vec2 oTexCoord1;\n" - "varying vec2 oTexCoord2;\n" - "\n" - "void main()\n" - "{\n" - " float ResultR = texture2D(Texture, oTexCoord0).r;\n" - " float ResultG = texture2D(Texture, oTexCoord1).g;\n" - " float ResultB = texture2D(Texture, oTexCoord2).b;\n" - " gl_FragColor = vec4(ResultR * oColor.r, ResultG * oColor.g, ResultB * oColor.b, 1.0);\n" - "}\n"; - -static const char* PostProcessMeshPositionalTimewarpFragShaderSrc = - "uniform sampler2D Texture0;\n" - "uniform sampler2D Texture1;\n" - "varying vec4 oColor;\n" - "varying vec2 oTexCoord0;\n" - "varying vec2 oTexCoord1;\n" - "varying vec2 oTexCoord2;\n" - "\n" + "void main()\n" "{\n" - " gl_FragColor.r = oColor.r * texture2D(Texture1, oTexCoord0).r;\n" - " gl_FragColor.g = oColor.g * texture2D(Texture1, oTexCoord1).g;\n" - " gl_FragColor.b = oColor.b * texture2D(Texture1, oTexCoord2).b;\n" + " gl_FragColor.r = oColor.r * texture2D(Texture, oTexCoord0).r;\n" + " gl_FragColor.g = oColor.g * texture2D(Texture, oTexCoord1).g;\n" + " gl_FragColor.b = oColor.b * texture2D(Texture, oTexCoord2).b;\n" " gl_FragColor.a = 1.0;\n" "}\n"; +static const char* PostProcessMeshTimewarpFragShaderSrc = PostProcessMeshFragShaderSrc; +static const char* PostProcessMeshPositionalTimewarpFragShaderSrc = PostProcessMeshFragShaderSrc; +static const char* PostProcessHeightmapTimewarpFragShaderSrc = PostProcessMeshFragShaderSrc; static const char* PostProcessVertexShaderSrc = + "#version 110\n" + "uniform mat4 View;\n" "uniform mat4 Texm;\n" + "attribute vec4 Position;\n" "attribute vec2 TexCoord;\n" - "varying vec2 oTexCoord;\n" + + "varying vec2 oTexCoord;\n" + "void main()\n" "{\n" " gl_Position = View * Position;\n" @@ -330,6 +369,8 @@ static const char* PostProcessVertexShaderSrc = "}\n"; static const char* PostProcessMeshVertexShaderSrc = + "#version 110\n" + "uniform vec2 EyeToSourceUVScale;\n" "uniform vec2 EyeToSourceUVOffset;\n" @@ -353,15 +394,17 @@ static const char* PostProcessMeshVertexShaderSrc = // Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion). // Scale them into the correct [0-1],[0-1] UV lookup space (depending on eye) " oTexCoord0 = TexCoord0 * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - " oTexCoord0.y = 1-oTexCoord0.y;\n" + " oTexCoord0.y = 1.0-oTexCoord0.y;\n" " oTexCoord1 = TexCoord1 * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - " oTexCoord1.y = 1-oTexCoord1.y;\n" + " oTexCoord1.y = 1.0-oTexCoord1.y;\n" " oTexCoord2 = TexCoord2 * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - " oTexCoord2.y = 1-oTexCoord2.y;\n" + " oTexCoord2.y = 1.0-oTexCoord2.y;\n" " oColor = Color;\n" // Used for vignette fade. "}\n"; static const char* PostProcessMeshTimewarpVertexShaderSrc = + "#version 110\n" + "uniform vec2 EyeToSourceUVScale;\n" "uniform vec2 EyeToSourceUVOffset;\n" "uniform mat4 EyeRotationStart;\n" @@ -392,7 +435,7 @@ static const char* PostProcessMeshTimewarpVertexShaderSrc = " vec3 TanEyeAngleB = vec3 ( TexCoord2.x, TexCoord2.y, 1.0 );\n" // Accurate time warp lerp vs. faster -#if 1 +#if 0 // Apply the two 3x3 timewarp rotations to these vectors. " vec3 TransformedRStart = (EyeRotationStart * vec4(TanEyeAngleR, 0)).xyz;\n" " vec3 TransformedGStart = (EyeRotationStart * vec4(TanEyeAngleG, 0)).xyz;\n" @@ -405,7 +448,10 @@ static const char* PostProcessMeshTimewarpVertexShaderSrc = " vec3 TransformedG = mix ( TransformedGStart, TransformedGEnd, Color.a );\n" " vec3 TransformedB = mix ( TransformedBStart, TransformedBEnd, Color.a );\n" #else - " mat3 EyeRotation = mix ( EyeRotationStart, EyeRotationEnd, Color.a );\n" + " mat3 EyeRotation;\n" + " EyeRotation[0] = mix ( EyeRotationStart[0], EyeRotationEnd[0], Color.a ).xyz;\n" + " EyeRotation[1] = mix ( EyeRotationStart[1], EyeRotationEnd[1], Color.a ).xyz;\n" + " EyeRotation[2] = mix ( EyeRotationStart[2], EyeRotationEnd[2], Color.a ).xyz;\n" " vec3 TransformedR = EyeRotation * TanEyeAngleR;\n" " vec3 TransformedG = EyeRotation * TanEyeAngleG;\n" " vec3 TransformedB = EyeRotation * TanEyeAngleB;\n" @@ -425,42 +471,46 @@ static const char* PostProcessMeshTimewarpVertexShaderSrc = " vec2 SrcCoordG = FlattenedG * EyeToSourceUVScale + EyeToSourceUVOffset;\n" " vec2 SrcCoordB = FlattenedB * EyeToSourceUVScale + EyeToSourceUVOffset;\n" " oTexCoord0 = SrcCoordR;\n" - " oTexCoord0.y = 1-oTexCoord0.y;\n" + " oTexCoord0.y = 1.0-oTexCoord0.y;\n" " oTexCoord1 = SrcCoordG;\n" - " oTexCoord1.y = 1-oTexCoord1.y;\n" + " oTexCoord1.y = 1.0-oTexCoord1.y;\n" " oTexCoord2 = SrcCoordB;\n" - " oTexCoord2.y = 1-oTexCoord2.y;\n" - " oColor = Color.r;\n" // Used for vignette fade. + " oTexCoord2.y = 1.0-oTexCoord2.y;\n" + " oColor = vec4(Color.r, Color.r, Color.r, Color.r);\n" // Used for vignette fade. "}\n"; static const char* PostProcessMeshPositionalTimewarpVertexShaderSrc = +#if 1 //TODO: Disabled until we fix positional timewarp and layering on GL. +PostProcessMeshTimewarpVertexShaderSrc; +#else "#version 150\n" - "uniform sampler2D Texture0;\n" + + "uniform sampler2D Texture0;\n" "uniform vec2 EyeToSourceUVScale;\n" "uniform vec2 EyeToSourceUVOffset;\n" - "uniform vec2 DepthProjector;\n" - "uniform vec2 DepthDimSize;\n" - "uniform mat4 EyeRotationStart;\n" + "uniform vec2 DepthProjector;\n" + "uniform vec2 DepthDimSize;\n" + "uniform mat4 EyeRotationStart;\n" "uniform mat4 EyeRotationEnd;\n" - "in vec2 Position;\n" - "in vec4 Color;\n" - "in vec2 TexCoord0;\n" - "in vec2 TexCoord1;\n" - "in vec2 TexCoord2;\n" + "attribute vec2 Position;\n" + "attribute vec4 Color;\n" + "attribute vec2 TexCoord0;\n" + "attribute vec2 TexCoord1;\n" + "attribute vec2 TexCoord2;\n" - "out vec4 oColor;\n" - "out vec2 oTexCoord0;\n" - "out vec2 oTexCoord1;\n" - "out vec2 oTexCoord2;\n" + "varying vec4 oColor;\n" + "varying vec2 oTexCoord0;\n" + "varying vec2 oTexCoord1;\n" + "varying vec2 oTexCoord2;\n" "vec4 PositionFromDepth(vec2 inTexCoord)\n" "{\n" " vec2 eyeToSourceTexCoord = inTexCoord * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - " eyeToSourceTexCoord.y = 1 - eyeToSourceTexCoord.y;\n" - " float depth = texelFetch(Texture0, ivec2(eyeToSourceTexCoord * DepthDimSize), 0).x;\n" - " float linearDepth = DepthProjector.y / (depth - DepthProjector.x);\n" - " vec4 retVal = vec4(inTexCoord, 1, 1);\n" + " eyeToSourceTexCoord.y = 1.0 - eyeToSourceTexCoord.y;\n" + " float depth = texelFetch(Texture0, ivec2(eyeToSourceTexCoord * DepthDimSize), 0).x;\n" //FIXME: Use Texture2DLod for #version 110 support. + " float linearDepth = DepthProjector.y / (depth - DepthProjector.x);\n" + " vec4 retVal = vec4(inTexCoord, 1, 1);\n" " retVal.xyz *= linearDepth;\n" " return retVal;\n" "}\n" @@ -468,7 +518,7 @@ static const char* PostProcessMeshPositionalTimewarpVertexShaderSrc = "vec2 TimewarpTexCoordToWarpedPos(vec2 inTexCoord, float a)\n" "{\n" // Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion). - // These are now "real world" vectors in direction (x,y,1) relative to the eye of the HMD. + // These are now "real world" vectors in direction (x,y,1) relative to the eye of the HMD. // Apply the 4x4 timewarp rotation to these vectors. " vec4 inputPos = PositionFromDepth(inTexCoord);\n" " vec3 transformed = mix ( EyeRotationStart * inputPos, EyeRotationEnd * inputPos, a ).xyz;\n" @@ -476,7 +526,7 @@ static const char* PostProcessMeshPositionalTimewarpVertexShaderSrc = " vec2 flattened = transformed.xy / transformed.z;\n" // Scale them into ([0,0.5],[0,1]) or ([0.5,0],[0,1]) UV lookup space (depending on eye) " vec2 noDepthUV = flattened * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - //" float depth = texture2DLod(Texture0, noDepthUV, 0).r;\n" + //" float depth = texture2D(Texture0, noDepthUV).r;\n" " return noDepthUV.xy;\n" "}\n" @@ -489,45 +539,76 @@ static const char* PostProcessMeshPositionalTimewarpVertexShaderSrc = // warped positions are a bit more involved, hence a separate function " oTexCoord0 = TimewarpTexCoordToWarpedPos(TexCoord0, Color.a);\n" - " oTexCoord0.y = 1-oTexCoord0.y;\n" + " oTexCoord0.y = 1.0 - oTexCoord0.y;\n" " oTexCoord1 = TimewarpTexCoordToWarpedPos(TexCoord1, Color.a);\n" - " oTexCoord1.y = 1-oTexCoord1.y;\n" + " oTexCoord1.y = 1.0 - oTexCoord1.y;\n" " oTexCoord2 = TimewarpTexCoordToWarpedPos(TexCoord2, Color.a);\n" - " oTexCoord2.y = 1-oTexCoord2.y;\n" + " oTexCoord2.y = 1.0 - oTexCoord2.y;\n" - " oColor = vec4(Color.r); // Used for vignette fade.\n" + " oColor = vec4(Color.r, Color.r, Color.r, Color.r); // Used for vignette fade.\n" "}\n"; +#endif -static const char* PostProcessFragShaderSrc = - "uniform vec2 LensCenter;\n" - "uniform vec2 ScreenCenter;\n" + +static const char* PostProcessHeightmapTimewarpVertexShaderSrc = +#if 1 //TODO: Disabled until we fix positional timewarp and layering on GL. +PostProcessMeshTimewarpVertexShaderSrc; +#else + "#version 150\n" + + "uniform sampler2D Texture0;\n" "uniform vec2 EyeToSourceUVScale;\n" - "uniform vec2 EyeToSourceNDCScale;\n" - "uniform vec4 HmdWarpParam;\n" - "uniform sampler2D Texture1;\n" + "uniform vec2 EyeToSourceUVOffset;\n" + "uniform vec2 DepthDimSize;\n" + "uniform mat4 EyeXformStart;\n" + "uniform mat4 EyeXformEnd;\n" + //"uniform mat4 Projection;\n" + "uniform mat4 InvProjection;\n" - "varying vec2 oTexCoord;\n" + "attribute vec2 Position;\n" + "attribute vec3 TexCoord0;\n" + + "varying vec2 oTexCoord0;\n" + + "vec4 PositionFromDepth(vec2 position, vec2 inTexCoord)\n" + "{\n" + " float depth = texelFetch(Texture0, ivec2(inTexCoord * DepthDimSize), 0).x;\n" //FIXME: Use Texture2DLod for #version 110 support. + " vec4 retVal = vec4(position, depth, 1);\n" + " return retVal;\n" + "}\n" - "vec2 HmdWarp(vec2 in01)\n" + "vec4 TimewarpPos(vec2 position, vec2 inTexCoord, mat4 rotMat)\n" "{\n" - " vec2 theta = (in01 - LensCenter) * EyeToSourceNDCScale;\n" // Scales to [-1, 1] - " float rSq = theta.x * theta.x + theta.y * theta.y;\n" - " vec2 theta1 = theta * (HmdWarpParam.x + HmdWarpParam.y * rSq + " - " HmdWarpParam.z * rSq * rSq + HmdWarpParam.w * rSq * rSq * rSq);\n" - " return LensCenter + EyeToSourceUVScale * theta1;\n" + // Apply the 4x4 timewarp rotation to these vectors. + " vec4 transformed = PositionFromDepth(position, inTexCoord);\n" + " transformed = InvProjection * transformed;\n" + " transformed = rotMat * transformed;\n" + //" transformed = mul ( Projection, transformed );\n" + " return transformed;\n" "}\n" "void main()\n" "{\n" - " vec2 tc = HmdWarp(oTexCoord);\n" - " if (!all(equal(clamp(tc, ScreenCenter-vec2(0.25,0.5), ScreenCenter+vec2(0.25,0.5)), tc)))\n" - " gl_FragColor = vec4(0);\n" - " else\n" - " gl_FragColor = texture2D(Texture1, tc);\n" - "}\n"; + " vec2 eyeToSrcTexCoord = TexCoord0.xy * EyeToSourceUVScale + EyeToSourceUVOffset;\n" + " oTexCoord0 = eyeToSrcTexCoord;\n" + + " float timewarpLerpFactor = TexCoord0.z;\n" + " mat4 lerpedEyeRot; // GL cannot mix() matrices :-( \n" + " lerpedEyeRot[0] = mix(EyeXformStart[0], EyeXformEnd[0], timewarpLerpFactor);\n" + " lerpedEyeRot[1] = mix(EyeXformStart[1], EyeXformEnd[1], timewarpLerpFactor);\n" + " lerpedEyeRot[2] = mix(EyeXformStart[2], EyeXformEnd[2], timewarpLerpFactor);\n" + " lerpedEyeRot[3] = mix(EyeXformStart[3], EyeXformEnd[3], timewarpLerpFactor);\n" + //" float4x4 lerpedEyeRot = EyeXformStart;\n" + // warped positions are a bit more involved, hence a separate function + " gl_Position = TimewarpPos(Position.xy, oTexCoord0, lerpedEyeRot);\n" + "}\n"; +#endif + // Shader with lens distortion and chromatic aberration correction. static const char* PostProcessFragShaderWithChromAbSrc = + "#version 110\n" + "uniform sampler2D Texture;\n" "uniform vec3 DistortionClearColor;\n" "uniform float EdgeFadeScale;\n" @@ -562,19 +643,19 @@ static const char* PostProcessFragShaderWithChromAbSrc = // Scale them into ([0,0.5],[0,1]) or ([0.5,0],[0,1]) UV lookup space (depending on eye) " vec2 SourceCoordR = TanEyeAngleR * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - " SourceCoordR.y = 1 - SourceCoordR.y;\n" + " SourceCoordR.y = 1.0 - SourceCoordR.y;\n" " vec2 SourceCoordG = TanEyeAngleG * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - " SourceCoordG.y = 1 - SourceCoordG.y;\n" + " SourceCoordG.y = 1.0 - SourceCoordG.y;\n" " vec2 SourceCoordB = TanEyeAngleB * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - " SourceCoordB.y = 1 - SourceCoordB.y;\n" + " SourceCoordB.y = 1.0 - SourceCoordB.y;\n" // Find the distance to the nearest edge. " vec2 NDCCoord = TanEyeAngleG * EyeToSourceNDCScale + EyeToSourceNDCOffset;\n" - " float EdgeFadeIn = clamp ( EdgeFadeScale, 0, 1e5 ) * ( 1.0 - max ( abs ( NDCCoord.x ), abs ( NDCCoord.y ) ) );\n" + " float EdgeFadeIn = clamp ( EdgeFadeScale, 0.0, 1e5 ) * ( 1.0 - max ( abs ( NDCCoord.x ), abs ( NDCCoord.y ) ) );\n" " if ( EdgeFadeIn < 0.0 )\n" " {\n" " gl_FragColor = vec4(DistortionClearColor.r, DistortionClearColor.g, DistortionClearColor.b, 1.0);\n" - " return;\n" + " return;\n" " }\n" " EdgeFadeIn = clamp ( EdgeFadeIn, 0.0, 1.0 );\n" @@ -583,7 +664,7 @@ static const char* PostProcessFragShaderWithChromAbSrc = " float ResultG = texture2D(Texture, SourceCoordG).g;\n" " float ResultB = texture2D(Texture, SourceCoordB).b;\n" - " gl_FragColor = vec4(ResultR * EdgeFadeIn, ResultG * EdgeFadeIn, ResultB * EdgeFadeIn, 1.0);\n" + " gl_FragColor = vec4(ResultR * EdgeFadeIn, ResultG * EdgeFadeIn, ResultB * EdgeFadeIn, 1.0);\n" "}\n"; @@ -595,7 +676,8 @@ static const char* VShaderSrcs[VShader_Count] = PostProcessVertexShaderSrc, PostProcessMeshVertexShaderSrc, PostProcessMeshTimewarpVertexShaderSrc, - PostProcessMeshPositionalTimewarpVertexShaderSrc + PostProcessMeshPositionalTimewarpVertexShaderSrc, + PostProcessHeightmapTimewarpVertexShaderSrc, }; static const char* FShaderSrcs[FShader_Count] = { @@ -609,24 +691,71 @@ static const char* FShaderSrcs[FShader_Count] = MultiTextureFragShaderSrc, PostProcessMeshFragShaderSrc, PostProcessMeshTimewarpFragShaderSrc, - PostProcessMeshPositionalTimewarpFragShaderSrc + PostProcessMeshPositionalTimewarpFragShaderSrc, + PostProcessHeightmapTimewarpFragShaderSrc }; RenderDevice::RenderDevice(const RendererParams&) { + int GlMajorVersion = 0; + int GlMinorVersion = 0; + + const char* glVersionString = (const char*)glGetString(GL_VERSION); + char prefix[64]; + bool foundVersion = false; + + for (int i = 10; i < 30; ++i) + { + int major = i / 10; + int minor = i % 10; + OVR_sprintf(prefix, 64, "%d.%d", major, minor); + if (strstr(glVersionString, prefix) == glVersionString) + { + GlMajorVersion = major; + GlMinorVersion = minor; + foundVersion = true; + break; + } + } + + if (!foundVersion) + { + glGetIntegerv(GL_MAJOR_VERSION, &GlMajorVersion); + glGetIntegerv(GL_MAJOR_VERSION, &GlMinorVersion); + } + + if (GlMajorVersion >= 3) + { + SupportsVao = true; + } + else + { + const char* extensions = (const char*)glGetString(GL_EXTENSIONS); + SupportsVao = (strstr("GL_ARB_vertex_array_object", extensions) != NULL); + } + for (int i = 0; i < VShader_Count; i++) + { + OVR_ASSERT ( VShaderSrcs[i] != NULL ); // You forgot a shader! VertexShaders[i] = *new Shader(this, Shader_Vertex, VShaderSrcs[i]); + } for (int i = 0; i < FShader_Count; i++) + { + OVR_ASSERT ( FShaderSrcs[i] != NULL ); // You forgot a shader! FragShaders[i] = *new Shader(this, Shader_Fragment, FShaderSrcs[i]); + } Ptr<ShaderSet> gouraudShaders = *new ShaderSet(); gouraudShaders->SetShader(VertexShaders[VShader_MVP]); gouraudShaders->SetShader(FragShaders[FShader_Gouraud]); DefaultFill = *new ShaderFill(gouraudShaders); - glGenFramebuffersEXT(1, &CurrentFbo); + glGenFramebuffers(1, &CurrentFbo); + + if (SupportsVao) + glGenVertexArrays(1, &Vao); } RenderDevice::~RenderDevice() @@ -641,7 +770,10 @@ void RenderDevice::Shutdown() // This runs before the subclass's Shutdown(), where the context, etc, may be deleted. - glDeleteFramebuffersEXT(1, &CurrentFbo); + glDeleteFramebuffers(1, &CurrentFbo); + + if (SupportsVao) + glDeleteVertexArrays(1, &Vao); for (int i = 0; i < VShader_Count; ++i) VertexShaders[i].Clear(); @@ -674,17 +806,14 @@ Shader *RenderDevice::LoadBuiltinShader(ShaderStage stage, int shader) void RenderDevice::BeginRendering() { + //glEnable(GL_FRAMEBUFFER_SRGB); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glFrontFace(GL_CW); - glLineWidth(3.0f); glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); } void RenderDevice::SetDepthMode(bool enable, bool write, CompareFunc func) @@ -707,15 +836,12 @@ void RenderDevice::SetDepthMode(bool enable, bool write, CompareFunc func) void RenderDevice::SetViewport(const Recti& vp) { - int wh; - if (CurRenderTarget) - wh = CurRenderTarget->Height; - else - wh = WindowHeight; - glViewport(vp.x, wh-vp.y-vp.h, vp.w, vp.h); - - //glEnable(GL_SCISSOR_TEST); - //glScissor(vp.x, wh-vp.y-vp.h, vp.w, vp.h); + int wh; + if (CurRenderTarget) + wh = CurRenderTarget->Height; + else + wh = WindowHeight; + glViewport(vp.x, wh - vp.y - vp.h, vp.w, vp.h); } void RenderDevice::WaitUntilGpuIdle() @@ -752,22 +878,22 @@ void RenderDevice::SetRenderTarget(Render::Texture* color, Render::Texture* dept CurRenderTarget = (Texture*)color; if (color == NULL) { - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); return; } if (depth == NULL) depth = GetDepthBuffer(color->GetWidth(), color->GetHeight(), CurRenderTarget->GetSamples()); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, CurrentFbo); - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, ((Texture*)color)->TexId, 0); + glBindFramebuffer(GL_FRAMEBUFFER, CurrentFbo); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ((Texture*)color)->TexId, 0); if (depth) - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, ((Texture*)depth)->TexId, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, ((Texture*)depth)->TexId, 0); else - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); - GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); - if (status != GL_FRAMEBUFFER_COMPLETE_EXT) + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) OVR_DEBUG_LOG(("framebuffer not complete: %x", status)); } @@ -781,7 +907,6 @@ void RenderDevice::SetTexture(Render::ShaderStage, int slot, const Texture* t) { glActiveTexture(GL_TEXTURE0 + slot); glBindTexture(GL_TEXTURE_2D, ((Texture*)t)->TexId); - glActiveTexture(GL_TEXTURE0); } Buffer* RenderDevice::CreateBuffer() @@ -797,17 +922,20 @@ Fill* RenderDevice::CreateSimpleFill(int flags) void RenderDevice::Render(const Matrix4f& matrix, Model* model) { + if (SupportsVao) + glBindVertexArray(Vao); + // Store data in buffers if not already if (!model->VertexBuffer) { Ptr<Render::Buffer> vb = *CreateBuffer(); - vb->Data(Buffer_Vertex, &model->Vertices[0], model->Vertices.GetSize() * sizeof(Vertex)); + vb->Data(Buffer_Vertex | Buffer_ReadOnly, &model->Vertices[0], model->Vertices.GetSize() * sizeof(Vertex)); model->VertexBuffer = vb; } if (!model->IndexBuffer) { Ptr<Render::Buffer> ib = *CreateBuffer(); - ib->Data(Buffer_Index, &model->Indices[0], model->Indices.GetSize() * 2); + ib->Data(Buffer_Index | Buffer_ReadOnly, &model->Indices[0], model->Indices.GetSize() * 2); model->IndexBuffer = ib; } @@ -817,7 +945,7 @@ void RenderDevice::Render(const Matrix4f& matrix, Model* model) } void RenderDevice::Render(const Fill* fill, Render::Buffer* vertices, Render::Buffer* indices, - const Matrix4f& matrix, int offset, int count, PrimitiveType rprim, bool useDistortionVertex/* = false*/) + const Matrix4f& matrix, int offset, int count, PrimitiveType rprim, MeshType meshType /*= Mesh_Scene*/) { ShaderSet* shaders = (ShaderSet*) ((ShaderFill*)fill)->GetShaders(); @@ -854,28 +982,33 @@ void RenderDevice::Render(const Fill* fill, Render::Buffer* vertices, Render::Bu for (int i = 0; i < 5; i++) glEnableVertexAttribArray(i); - if (useDistortionVertex) - { - glVertexAttribPointer(0, 2, GL_FLOAT, false, sizeof(DistortionVertex), (char*)offset + offsetof(DistortionVertex, Pos)); - glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, true, sizeof(DistortionVertex), (char*)offset + offsetof(DistortionVertex, Col)); - glVertexAttribPointer(2, 2, GL_FLOAT, false, sizeof(DistortionVertex), (char*)offset + offsetof(DistortionVertex, TexR)); - glVertexAttribPointer(3, 2, GL_FLOAT, false, sizeof(DistortionVertex), (char*)offset + offsetof(DistortionVertex, TexG)); - glVertexAttribPointer(4, 2, GL_FLOAT, false, sizeof(DistortionVertex), (char*)offset + offsetof(DistortionVertex, TexB)); - } - else - { - glVertexAttribPointer(0, 3, GL_FLOAT, false, sizeof(Vertex), (char*)offset + offsetof(Vertex, Pos)); - glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, true, sizeof(Vertex), (char*)offset + offsetof(Vertex, C)); - glVertexAttribPointer(2, 2, GL_FLOAT, false, sizeof(Vertex), (char*)offset + offsetof(Vertex, U)); - glVertexAttribPointer(3, 2, GL_FLOAT, false, sizeof(Vertex), (char*)offset + offsetof(Vertex, U2)); - glVertexAttribPointer(4, 3, GL_FLOAT, false, sizeof(Vertex), (char*)offset + offsetof(Vertex, Norm)); - } + switch (meshType) + { + case Mesh_Distortion: + glVertexAttribPointer(0, 2, GL_FLOAT, false, sizeof(DistortionVertex), reinterpret_cast<char*>(offset) + offsetof(DistortionVertex, Pos)); + glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, true, sizeof(DistortionVertex), reinterpret_cast<char*>(offset) + offsetof(DistortionVertex, Col)); + glVertexAttribPointer(2, 2, GL_FLOAT, false, sizeof(DistortionVertex), reinterpret_cast<char*>(offset) + offsetof(DistortionVertex, TexR)); + glVertexAttribPointer(3, 2, GL_FLOAT, false, sizeof(DistortionVertex), reinterpret_cast<char*>(offset) + offsetof(DistortionVertex, TexG)); + glVertexAttribPointer(4, 2, GL_FLOAT, false, sizeof(DistortionVertex), reinterpret_cast<char*>(offset) + offsetof(DistortionVertex, TexB)); + break; + + case Mesh_Heightmap: + glVertexAttribPointer(0, 2, GL_FLOAT, false, sizeof(HeightmapVertex), reinterpret_cast<char*>(offset) + offsetof(HeightmapVertex, Pos)); + glVertexAttribPointer(1, 2, GL_FLOAT, false, sizeof(HeightmapVertex), reinterpret_cast<char*>(offset) + offsetof(HeightmapVertex, Tex)); + break; + + default: + glVertexAttribPointer(0, 3, GL_FLOAT, false, sizeof(Vertex), reinterpret_cast<char*>(offset) + offsetof(Vertex, Pos)); + glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, true, sizeof(Vertex), reinterpret_cast<char*>(offset) + offsetof(Vertex, C)); + glVertexAttribPointer(2, 2, GL_FLOAT, false, sizeof(Vertex), reinterpret_cast<char*>(offset) + offsetof(Vertex, U)); + glVertexAttribPointer(3, 2, GL_FLOAT, false, sizeof(Vertex), reinterpret_cast<char*>(offset) + offsetof(Vertex, U2)); + glVertexAttribPointer(4, 3, GL_FLOAT, false, sizeof(Vertex), reinterpret_cast<char*>(offset) + offsetof(Vertex, Norm)); + } if (indices) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ((Buffer*)indices)->GLBuffer); glDrawElements(prim, count, GL_UNSIGNED_SHORT, NULL); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } else { @@ -922,7 +1055,6 @@ bool Buffer::Data(int use, const void* buffer, size_t size) glBindBuffer(Use, GLBuffer); glBufferData(Use, size, buffer, mode); - glBindBuffer(Use, 0); return 1; } @@ -934,7 +1066,6 @@ void* Buffer::Map(size_t, size_t, int) glBindBuffer(Use, GLBuffer); void* v = glMapBuffer(Use, mode); - glBindBuffer(Use, 0); return v; } @@ -942,7 +1073,6 @@ bool Buffer::Unmap(void*) { glBindBuffer(Use, GLBuffer); int r = glUnmapBuffer(Use); - glBindBuffer(Use, 0); return r != 0; } @@ -997,7 +1127,6 @@ void ShaderSet::UnsetShader(int stage) if (gls) glDetachShader(Prog, gls->GLShader); Shaders[stage] = NULL; - Link(); } bool ShaderSet::Link() @@ -1160,7 +1289,7 @@ void Texture::SetSampleMode(int sm) case Sample_Anisotropic: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 8); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 4); break; case Sample_Nearest: @@ -1187,7 +1316,6 @@ void Texture::SetSampleMode(int sm) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); break; } - glBindTexture(GL_TEXTURE_2D, 0); } ovrTexture Texture::Get_ovrTexture() @@ -1210,7 +1338,7 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo switch(format & Texture_TypeMask) { case Texture_RGBA: glformat = GL_RGBA; break; - case Texture_R: glformat = GL_ALPHA; break; + case Texture_R: glformat = GL_RED; break; case Texture_Depth: glformat = GL_DEPTH_COMPONENT32F; gltype = GL_FLOAT; break; case Texture_DXT1: glformat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break; case Texture_DXT3: glformat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break; @@ -1220,7 +1348,7 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo } Texture* NewTex = new Texture(this, width, height); glBindTexture(GL_TEXTURE_2D, NewTex->TexId); - OVR_ASSERT(!glGetError()); + OVR_ASSERT(!glGetError()); if (format & Texture_Compressed) { @@ -1275,7 +1403,6 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo } OVR_ASSERT(!glGetError()); - glBindTexture(GL_TEXTURE_2D, 0); return NewTex; } @@ -1283,16 +1410,16 @@ RBuffer::RBuffer(GLenum format, GLint w, GLint h) { Width = w; Height = h; - glGenRenderbuffersEXT(1, &BufId); - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, BufId); - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, format, w, h); - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); + glGenRenderbuffers(1, &BufId); + glBindRenderbuffer(GL_RENDERBUFFER, BufId); + glRenderbufferStorage(GL_RENDERBUFFER, format, w, h); + glBindRenderbuffer(GL_RENDERBUFFER, 0); } RBuffer::~RBuffer() { if (BufId) - glDeleteRenderbuffersEXT(1, &BufId); + glDeleteRenderbuffers(1, &BufId); } }}} diff --git a/Samples/CommonSrc/Render/Render_GL_Device.h b/Samples/CommonSrc/Render/Render_GL_Device.h index 5d97eef..563c87b 100644 --- a/Samples/CommonSrc/Render/Render_GL_Device.h +++ b/Samples/CommonSrc/Render/Render_GL_Device.h @@ -3,7 +3,7 @@ Filename : Render_GL_Device.h Content : RenderDevice implementation header for OpenGL Created : September 10, 2012 -Authors : Andrew Reisse +Authors : Andrew Reisse, David Borel Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. @@ -27,37 +27,45 @@ limitations under the License. #include "../Render/Render_Device.h" #if defined(OVR_OS_WIN32) -#include <Windows.h> -#endif - -#if defined(OVR_OS_MAC) -#include <OpenGL/gl.h> -#include <OpenGL/glext.h> + #include <Windows.h> + #include <GL/gl.h> + #include <GL/glext.h> + #include <GL/wglext.h> +#elif defined(OVR_OS_MAC) + #include <OpenGL/gl3.h> + #include <OpenGL/gl3ext.h> #else -#ifndef GL_GLEXT_PROTOTYPES -#define GL_GLEXT_PROTOTYPES -#endif -#include <GL/gl.h> -#include <GL/glext.h> -#if defined(OVR_OS_WIN32) -#include <GL/wglext.h> -#endif + #include <GL/gl.h> + #include <GL/glext.h> + #include <GL/glx.h> #endif + namespace OVR { namespace Render { namespace GL { + +#if !defined(OVR_OS_MAC) // GL extension Hooks for PC. #if defined(OVR_OS_WIN32) - + extern PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT; extern PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT; -extern PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT; -extern PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT; +extern PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB; +extern PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB; + +#elif defined(OVR_OS_LINUX) + +extern PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT; + +#endif + +extern PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers; +extern PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers; extern PFNGLDELETESHADERPROC glDeleteShader; -extern PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT; -extern PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT; -extern PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT; -extern PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT; +extern PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus; +extern PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer; +extern PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D; +extern PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebuffer; extern PFNGLACTIVETEXTUREPROC glActiveTexture; extern PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray; extern PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; @@ -91,19 +99,18 @@ extern PFNGLUNIFORM3FVPROC glUniform3fv; extern PFNGLUNIFORM2FVPROC glUniform2fv; extern PFNGLUNIFORM1FVPROC glUniform1fv; extern PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D; -extern PFNGLRENDERBUFFERSTORAGEEXTPROC glRenderbufferStorageEXT; -extern PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT; -extern PFNGLGENRENDERBUFFERSEXTPROC glGenRenderbuffersEXT; -extern PFNGLDELETERENDERBUFFERSEXTPROC glDeleteRenderbuffersEXT; - -// For testing +extern PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage; +extern PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer; +extern PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers; +extern PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers; extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays; +extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays; +extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray; extern void InitGLExtensions(); #endif - class RenderDevice; class Buffer : public Render::Buffer @@ -227,12 +234,15 @@ class RenderDevice : public Render::RenderDevice Matrix4f Proj; + GLuint Vao; + protected: Ptr<Texture> CurRenderTarget; Array<Ptr<Texture> > DepthBuffers; GLuint CurrentFbo; const LightingParams* Lighting; + bool SupportsVao; public: RenderDevice(const RendererParams& p); @@ -243,8 +253,6 @@ public: virtual void FillTexturedRect(float left, float top, float right, float bottom, float ul, float vt, float ur, float vb, Color c, Ptr<OVR::Render::Texture> tex); virtual void SetViewport(const Recti& vp); - - //virtual void SetScissor(int x, int y, int w, int h); virtual void WaitUntilGpuIdle(); @@ -266,7 +274,7 @@ public: virtual void Render(const Matrix4f& matrix, Model* model); virtual void Render(const Fill* fill, Render::Buffer* vertices, Render::Buffer* indices, - const Matrix4f& matrix, int offset, int count, PrimitiveType prim = Prim_Triangles, bool useDistortionVertex = false); + const Matrix4f& matrix, int offset, int count, PrimitiveType prim = Prim_Triangles, MeshType meshType = Mesh_Scene); virtual void RenderWithAlpha(const Fill* fill, Render::Buffer* vertices, Render::Buffer* indices, const Matrix4f& matrix, int offset, int count, PrimitiveType prim = Prim_Triangles); diff --git a/Samples/CommonSrc/Render/Render_GL_Win32_Device.cpp b/Samples/CommonSrc/Render/Render_GL_Win32_Device.cpp index 1065c98..9bfcec9 100644 --- a/Samples/CommonSrc/Render/Render_GL_Win32_Device.cpp +++ b/Samples/CommonSrc/Render/Render_GL_Win32_Device.cpp @@ -36,11 +36,10 @@ PFNDWMENABLECOMPOSITIONPROC DwmEnableComposition; // ***** GL::Win32::RenderDevice -RenderDevice::RenderDevice(const Render::RendererParams& p, HWND win, HDC dc, HGLRC gl) +RenderDevice::RenderDevice(const Render::RendererParams& p, HWND win, HGLRC gl) : GL::RenderDevice(p) , Window(win) , WglContext(gl) - , GdiDc(dc) , PreFullscreen(0, 0, 0, 0) , HMonitor(0) , FSDesktop(0, 0, 0, 0) @@ -52,6 +51,7 @@ RenderDevice::RenderDevice(const Render::RendererParams& p, HWND win, HDC dc, HG Render::RenderDevice* RenderDevice::CreateDevice(const RendererParams& rp, void* oswnd) { HWND hwnd = (HWND)oswnd; + HDC dc = GetDC(hwnd); if (!DwmEnableComposition) { @@ -62,40 +62,93 @@ Render::RenderDevice* RenderDevice::CreateDevice(const RendererParams& rp, void* } DwmEnableComposition(DWM_EC_DISABLECOMPOSITION); + { + PIXELFORMATDESCRIPTOR pfd; + memset(&pfd, 0, sizeof(pfd)); + + pfd.nSize = sizeof(pfd); + pfd.nVersion = 1; + pfd.iPixelType = PFD_TYPE_RGBA; + pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER; + pfd.cColorBits = 32; + pfd.cDepthBits = 16; + + int pf = ChoosePixelFormat(dc, &pfd); + if (!pf) + { + ReleaseDC(hwnd, dc); + return NULL; + } + + if (!SetPixelFormat(dc, pf, &pfd)) + { + ReleaseDC(hwnd, dc); + return NULL; + } + + HGLRC context = wglCreateContext(dc); + if (!wglMakeCurrent(dc, context)) + { + wglDeleteContext(context); + ReleaseDC(hwnd, dc); + return NULL; + } + + wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB"); + wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB"); + + wglDeleteContext(context); + } - PIXELFORMATDESCRIPTOR pfd; - memset(&pfd, 0, sizeof(pfd)); - pfd.nSize = sizeof(pfd); - pfd.nVersion = 1; - pfd.iPixelType = PFD_TYPE_RGBA; - pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER; - pfd.cColorBits = 32; - pfd.cDepthBits = 16; + int iAttributes[] = { + //WGL_DRAW_TO_WINDOW_ARB, GL_TRUE, + WGL_SUPPORT_OPENGL_ARB, GL_TRUE, + WGL_COLOR_BITS_ARB, 32, + WGL_DEPTH_BITS_ARB, 16, + WGL_DOUBLE_BUFFER_ARB, GL_TRUE, + WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB, GL_TRUE, + 0, 0}; + + float fAttributes[] = {0,0}; + + int pf = 0; + UINT numFormats = 0; - HDC dc = GetDC(hwnd); - int pf = ChoosePixelFormat(dc, &pfd); - if (!pf) + if (!wglChoosePixelFormatARB(dc, iAttributes, fAttributes, 1, &pf, &numFormats)) { ReleaseDC(hwnd, dc); return NULL; } + + PIXELFORMATDESCRIPTOR pfd; + memset(&pfd, 0, sizeof(pfd)); + if (!SetPixelFormat(dc, pf, &pfd)) { ReleaseDC(hwnd, dc); return NULL; } - HGLRC context = wglCreateContext(dc); - if (!wglMakeCurrent(dc, context)) - { - wglDeleteContext(context); - ReleaseDC(hwnd, dc); - return NULL; - } + + GLint attribs[] = + { + WGL_CONTEXT_MAJOR_VERSION_ARB, 2, + WGL_CONTEXT_MINOR_VERSION_ARB, 1, + WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, + 0 + }; + + HGLRC context = wglCreateContextAttribsARB(dc, 0, attribs); + if (!wglMakeCurrent(dc, context)) + { + wglDeleteContext(context); + ReleaseDC(hwnd, dc); + return NULL; + } InitGLExtensions(); - return new RenderDevice(rp, hwnd, dc, context); + return new RenderDevice(rp, hwnd, context); } ovrRenderAPIConfig RenderDevice::Get_ovrRenderAPIConfig() const @@ -104,9 +157,7 @@ ovrRenderAPIConfig RenderDevice::Get_ovrRenderAPIConfig() const cfg.OGL.Header.API = ovrRenderAPI_OpenGL; cfg.OGL.Header.RTSize = Sizei(WindowWidth, WindowHeight); cfg.OGL.Header.Multisample = Params.Multisample; - cfg.OGL.WglContext = WglContext; cfg.OGL.Window = Window; - cfg.OGL.GdiDc = GdiDc; return cfg.Config; } @@ -118,7 +169,10 @@ void RenderDevice::Present(bool useVsync) if (wglGetSwapIntervalEXT() != swapInterval) wglSwapIntervalEXT(swapInterval); - success = SwapBuffers(GdiDc); + HDC dc = GetDC(Window); + success = SwapBuffers(dc); + ReleaseDC(Window, dc); + OVR_ASSERT(success); } @@ -131,9 +185,7 @@ void RenderDevice::Shutdown() { wglMakeCurrent(NULL,NULL); wglDeleteContext(WglContext); - ReleaseDC(Window, GdiDc); WglContext = NULL; - GdiDc = NULL; Window = NULL; } } @@ -263,25 +315,6 @@ bool RenderDevice::SetFullscreen(DisplayMode fullscreen) monInfo.cbSize = sizeof(MONITORINFOEX); GetMonitorInfo(HMonitor, &monInfo); - // Find the requested device mode - DEVMODE dmode; - bool foundMode = false; - memset(&dmode, 0, sizeof(DEVMODE)); - dmode.dmSize = sizeof(DEVMODE); - Recti vp = VP; - for(int i=0 ; EnumDisplaySettings(monInfo.szDevice, i, &dmode); ++i) - { - foundMode = (dmode.dmPelsWidth==(DWORD)vp.w) && - (dmode.dmPelsHeight==(DWORD)vp.h) && - (dmode.dmBitsPerPel==(DWORD)32); - if (foundMode) - break; - } - if(!foundMode) - return false; - - dmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; - // Save the current window position/size RECT rect; GetWindowRect(Window, &rect); @@ -296,26 +329,20 @@ bool RenderDevice::SetFullscreen(DisplayMode fullscreen) SetWindowLongPtr(Window, GWL_STYLE, style & (~WS_OVERLAPPEDWINDOW)); SetWindowLongPtr(Window, GWL_EXSTYLE, exstyle | WS_EX_APPWINDOW | WS_EX_TOPMOST); - // Attempt to change the resolution - LONG ret = ChangeDisplaySettingsEx(monInfo.szDevice, &dmode, NULL, CDS_FULLSCREEN, NULL); - //LONG ret = ChangeDisplaySettings(&dmode, CDS_FULLSCREEN); - - // If it failed, clean up and return. - if (ret != DISP_CHANGE_SUCCESSFUL) - { - SetWindowLongPtr(Window, GWL_STYLE, style); - SetWindowLongPtr(Window, GWL_EXSTYLE, exstyle); - return false; - } + ChangeDisplaySettingsEx(monInfo.szDevice, NULL, NULL, CDS_FULLSCREEN, NULL); // We need to call GetMonitorInfo() again becase // details may have changed with the resolution GetMonitorInfo(HMonitor, &monInfo); + int x = monInfo.rcMonitor.left; + int y = monInfo.rcMonitor.top; + int w = monInfo.rcMonitor.right - monInfo.rcMonitor.left; + int h = monInfo.rcMonitor.bottom - monInfo.rcMonitor.top; + // Set the window's size and position so // that it covers the entire screen - SetWindowPos(Window, HWND_TOPMOST, monInfo.rcMonitor.left, monInfo.rcMonitor.top, vp.w, vp.h, - SWP_SHOWWINDOW | SWP_NOZORDER | SWP_FRAMECHANGED); + SetWindowPos(Window, HWND_TOPMOST, x, y, w, h, SWP_SHOWWINDOW | SWP_NOZORDER | SWP_FRAMECHANGED); } Params.Fullscreen = fullscreen; diff --git a/Samples/CommonSrc/Render/Render_GL_Win32_Device.h b/Samples/CommonSrc/Render/Render_GL_Win32_Device.h index de81a80..273e997 100644 --- a/Samples/CommonSrc/Render/Render_GL_Win32_Device.h +++ b/Samples/CommonSrc/Render/Render_GL_Win32_Device.h @@ -42,13 +42,12 @@ class RenderDevice : public GL::RenderDevice HWND Window; HGLRC WglContext; - HDC GdiDc; Recti PreFullscreen; Recti FSDesktop; HMONITOR HMonitor; public: - RenderDevice(const Render::RendererParams& p, HWND win, HDC dc, HGLRC gl); + RenderDevice(const Render::RendererParams& p, HWND win, HGLRC gl); virtual ~RenderDevice() { Shutdown(); } // Implement static initializer function to create this class. diff --git a/Samples/CommonSrc/Render/Render_LoadTextureDDS.cpp b/Samples/CommonSrc/Render/Render_LoadTextureDDS.cpp index 5bbdb21..cf20cdd 100644 --- a/Samples/CommonSrc/Render/Render_LoadTextureDDS.cpp +++ b/Samples/CommonSrc/Render/Render_LoadTextureDDS.cpp @@ -29,8 +29,11 @@ limitations under the License. namespace OVR { namespace Render { static const UPInt OVR_DDS_PF_FOURCC = 0x4; -static const UInt32 OVR_DTX1_MAGIC_NUMBER = 827611204; -static const UInt32 OVR_DTX5_MAGIC_NUMBER = 894720068; +static const UInt32 OVR_DXT1_MAGIC_NUMBER = 0x31545844; // "DXT1" +static const UInt32 OVR_DXT2_MAGIC_NUMBER = 0x32545844; // "DXT2" +static const UInt32 OVR_DXT3_MAGIC_NUMBER = 0x33545844; // "DXT3" +static const UInt32 OVR_DXT4_MAGIC_NUMBER = 0x34545844; // "DXT4" +static const UInt32 OVR_DXT5_MAGIC_NUMBER = 0x35545844; // "DXT5" struct OVR_DDS_PIXELFORMAT { @@ -62,6 +65,20 @@ struct OVR_DDS_HEADER UInt32 Reserved2; }; +// Returns -1 on failure, or a valid TextureFormat value on success +static inline int InterpretPixelFormatFourCC(UInt32 fourCC) { + switch (fourCC) { + case OVR_DXT1_MAGIC_NUMBER: return Texture_DXT1; + case OVR_DXT2_MAGIC_NUMBER: return Texture_DXT3; + case OVR_DXT3_MAGIC_NUMBER: return Texture_DXT3; + case OVR_DXT4_MAGIC_NUMBER: return Texture_DXT5; + case OVR_DXT5_MAGIC_NUMBER: return Texture_DXT5; + } + + // Unrecognized FourCC + return -1; +} + Texture* LoadTextureDDS(RenderDevice* ren, File* f) { OVR_DDS_HEADER header; @@ -87,24 +104,20 @@ Texture* LoadTextureDDS(RenderDevice* ren, File* f) } if(header.PixelFormat.Flags & OVR_DDS_PF_FOURCC) { - if(header.PixelFormat.FourCC == OVR_DTX1_MAGIC_NUMBER) - { - format = Texture_DXT1; - } - else if(header.PixelFormat.FourCC == OVR_DTX5_MAGIC_NUMBER) - { - format = Texture_DXT5; - } - else - { - return NULL; - } + format = InterpretPixelFormatFourCC(header.PixelFormat.FourCC); + if (format == -1) { + return NULL; + } } int byteLen = f->BytesAvailable(); unsigned char* bytes = new unsigned char[byteLen]; f->Read(bytes, byteLen); Texture* out = ren->CreateTexture(format, (int)width, (int)height, bytes, mipCount); + if (!out) { + return NULL; + } + if(strstr(f->GetFilePath(), "_c.")) { out->SetSampleMode(Sample_Clamp); diff --git a/Samples/OculusWorldDemo/OptionMenu.cpp b/Samples/CommonSrc/Util/OptionMenu.cpp index 283136d..d9acc44 100644 --- a/Samples/OculusWorldDemo/OptionMenu.cpp +++ b/Samples/CommonSrc/Util/OptionMenu.cpp @@ -24,11 +24,11 @@ limitations under the License. #include "OptionMenu.h" // Embed the font. -#include "../CommonSrc/Render/Render_FontEmbed_DejaVu48.h" +#include "../Render/Render_FontEmbed_DejaVu48.h" //------------------------------------------------------------------------------------- -bool OptionShortcut::MatchKey(KeyCode key, bool shift) const +bool OptionShortcut::MatchKey(OVR::KeyCode key, bool shift) const { for (UInt32 i = 0; i < Keys.GetSize(); i++) { @@ -252,7 +252,7 @@ String OptionVar::HandleShortcutUpdate() return Label + " - " + GetValue(); } -String OptionVar::ProcessShortcutKey(KeyCode key, bool shift) +String OptionVar::ProcessShortcutKey(OVR::KeyCode key, bool shift) { if (ShortcutUp.MatchKey(key, shift) || ShortcutDown.MatchKey(key, shift)) { @@ -432,7 +432,7 @@ bool OptionSelectionMenu::OnGamepad(UInt32 buttonMask) return false; } -String OptionSelectionMenu::ProcessShortcutKey(KeyCode key, bool shift) +String OptionSelectionMenu::ProcessShortcutKey(OVR::KeyCode key, bool shift) { String s; @@ -702,10 +702,10 @@ void OptionSelectionMenu::Select() OptionSelectionMenu* OptionSelectionMenu::GetSubmenu() { - if (!SelectionActive) + if (!SelectionActive || !Items[SelectedIndex]->IsMenu()) return NULL; - OptionSelectionMenu* submenu = dynamic_cast<OptionSelectionMenu*>(Items[SelectedIndex]); + OptionSelectionMenu* submenu = static_cast<OptionSelectionMenu*>(Items[SelectedIndex]); return submenu; } @@ -714,9 +714,12 @@ OptionSelectionMenu* OptionSelectionMenu::GetOrCreateSubmenu(String submenuName) { for (UInt32 i = 0; i < Items.GetSize(); i++) { - OptionSelectionMenu* submenu = dynamic_cast<OptionSelectionMenu*>(Items[i]); + if (!Items[i]->IsMenu()) + continue; + + OptionSelectionMenu* submenu = static_cast<OptionSelectionMenu*>(Items[i]); - if (submenu != NULL && submenu->Label == submenuName) + if (submenu->Label == submenuName) { return submenu; } diff --git a/Samples/OculusWorldDemo/OptionMenu.h b/Samples/CommonSrc/Util/OptionMenu.h index ba90b08..d52ba5c 100644 --- a/Samples/OculusWorldDemo/OptionMenu.h +++ b/Samples/CommonSrc/Util/OptionMenu.h @@ -26,9 +26,9 @@ limitations under the License. #include "OVR.h" -#include "../CommonSrc/Platform/Platform_Default.h" -#include "../CommonSrc/Render/Render_Device.h" -#include "../CommonSrc/Platform/Gamepad.h" +#include "../Platform/Platform_Default.h" +#include "../Render/Render_Device.h" +#include "../Platform/Gamepad.h" #include "Util/Util_Render_Stereo.h" using namespace OVR::Util::Render; @@ -37,7 +37,6 @@ using namespace OVR::Util::Render; #include <Kernel/OVR_Log.h> #include <Kernel/OVR_Timer.h> -#include "Player.h" #include "OVR_DeviceConstants.h" @@ -97,10 +96,10 @@ struct ShortcutKey Shift_RequireOff }; - ShortcutKey(KeyCode key = Key_None, ShiftUsageType shiftUsage = Shift_RequireOff) + ShortcutKey(OVR::KeyCode key = Key_None, ShiftUsageType shiftUsage = Shift_RequireOff) : Key(key), ShiftUsage(shiftUsage) { } - KeyCode Key; + OVR::KeyCode Key; ShiftUsageType ShiftUsage; }; @@ -119,7 +118,7 @@ struct OptionShortcut void AddShortcut(ShortcutKey key) { Keys.PushBack(key); } void AddShortcut(UInt32 gamepadButton) { GamepadButtons.PushBack(gamepadButton); } - bool MatchKey(KeyCode key, bool shift) const; + bool MatchKey(OVR::KeyCode key, bool shift) const; bool MatchGamepadButton(UInt32 gamepadButtonMask) const; }; @@ -142,9 +141,11 @@ public: virtual String GetValue() { return ""; } // Returns empty string if shortcut not handled - virtual String ProcessShortcutKey(KeyCode key, bool shift) = 0; + virtual String ProcessShortcutKey(OVR::KeyCode key, bool shift) = 0; virtual String ProcessShortcutButton(UInt32 buttonMask) = 0; + virtual bool IsMenu() const { return false; } + protected: String Label; String PopNamespaceFrom(OptionMenuItem* menuItem); @@ -208,7 +209,7 @@ public: // Executes shortcut message and returns notification string. // Returns empty string for no action. String HandleShortcutUpdate(); - virtual String ProcessShortcutKey(KeyCode key, bool shift); + virtual String ProcessShortcutKey(OVR::KeyCode key, bool shift); virtual String ProcessShortcutButton(UInt32 buttonMask); OptionVar& AddEnumValue(const char* displayName, SInt32 value); @@ -227,7 +228,7 @@ public: OptionVar& AddShortcutUpKey(const ShortcutKey& shortcut) { ShortcutUp.AddShortcut(shortcut); return *this; } - OptionVar& AddShortcutUpKey(KeyCode key, + OptionVar& AddShortcutUpKey(OVR::KeyCode key, ShortcutKey::ShiftUsageType shiftUsage = ShortcutKey::Shift_Modify) { ShortcutUp.AddShortcut(ShortcutKey(key, shiftUsage)); return *this; } OptionVar& AddShortcutUpButton(UInt32 gamepadButton) @@ -235,7 +236,7 @@ public: OptionVar& AddShortcutDownKey(const ShortcutKey& shortcut) { ShortcutDown.AddShortcut(shortcut); return *this; } - OptionVar& AddShortcutDownKey(KeyCode key, + OptionVar& AddShortcutDownKey(OVR::KeyCode key, ShortcutKey::ShiftUsageType shiftUsage = ShortcutKey::Shift_Modify) { ShortcutDown.AddShortcut(ShortcutKey(key, shiftUsage)); return *this; } OptionVar& AddShortcutDownButton(UInt32 gamepadButton) @@ -243,7 +244,7 @@ public: OptionVar& AddShortcutKey(const ShortcutKey& shortcut) { return AddShortcutUpKey(shortcut); } - OptionVar& AddShortcutKey(KeyCode key, + OptionVar& AddShortcutKey(OVR::KeyCode key, ShortcutKey::ShiftUsageType shiftUsage = ShortcutKey::Shift_RequireOff) { return AddShortcutUpKey(key, shiftUsage); } OptionVar& AddShortcutButton(UInt32 gamepadButton) @@ -356,7 +357,7 @@ public: virtual void Select(); virtual String GetLabel() { return Label + " >"; } - virtual String ProcessShortcutKey(KeyCode key, bool shift); + virtual String ProcessShortcutKey(OVR::KeyCode key, bool shift); virtual String ProcessShortcutButton(UInt32 buttonMask); // Sets a message to display with a time-out. Default time-out is 4 seconds. @@ -366,6 +367,8 @@ public: // intended to be called right after SetPopupMessage. void SetPopupTimeout(double timeoutSeconds, bool border = false); + virtual bool IsMenu() const { return true; } + protected: void renderShortcutChangeMessage(RenderDevice* prender); diff --git a/Samples/OculusWorldDemo/RenderProfiler.cpp b/Samples/CommonSrc/Util/RenderProfiler.cpp index 00bbdd9..00bbdd9 100644 --- a/Samples/OculusWorldDemo/RenderProfiler.cpp +++ b/Samples/CommonSrc/Util/RenderProfiler.cpp diff --git a/Samples/OculusWorldDemo/RenderProfiler.h b/Samples/CommonSrc/Util/RenderProfiler.h index 96ec50a..96ec50a 100644 --- a/Samples/OculusWorldDemo/RenderProfiler.h +++ b/Samples/CommonSrc/Util/RenderProfiler.h diff --git a/Samples/LibOVR_Samples_VS2010.sln b/Samples/LibOVR_Samples_VS2010.sln deleted file mode 100644 index 182c95e..0000000 --- a/Samples/LibOVR_Samples_VS2010.sln +++ /dev/null @@ -1,35 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OculusRoomTiny", "OculusRoomTiny\Projects\Win\VS2010\OculusRoomTiny.vcxproj", "{6C6ECAC4-DB5C-4301-8371-9C7CC8C623C2}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OculusWorldDemo", "OculusWorldDemo\Projects\Win\VS2010\OculusWorldDemo.vcxproj", "{456DA1F5-7D65-4B77-8336-277F3921639B}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {6C6ECAC4-DB5C-4301-8371-9C7CC8C623C2}.Debug|Win32.ActiveCfg = Debug|Win32 - {6C6ECAC4-DB5C-4301-8371-9C7CC8C623C2}.Debug|Win32.Build.0 = Debug|Win32 - {6C6ECAC4-DB5C-4301-8371-9C7CC8C623C2}.Debug|x64.ActiveCfg = Debug|x64 - {6C6ECAC4-DB5C-4301-8371-9C7CC8C623C2}.Debug|x64.Build.0 = Debug|x64 - {6C6ECAC4-DB5C-4301-8371-9C7CC8C623C2}.Release|Win32.ActiveCfg = Release|Win32 - {6C6ECAC4-DB5C-4301-8371-9C7CC8C623C2}.Release|Win32.Build.0 = Release|Win32 - {6C6ECAC4-DB5C-4301-8371-9C7CC8C623C2}.Release|x64.ActiveCfg = Release|x64 - {6C6ECAC4-DB5C-4301-8371-9C7CC8C623C2}.Release|x64.Build.0 = Release|x64 - {456DA1F5-7D65-4B77-8336-277F3921639B}.Debug|Win32.ActiveCfg = Debug|Win32 - {456DA1F5-7D65-4B77-8336-277F3921639B}.Debug|Win32.Build.0 = Debug|Win32 - {456DA1F5-7D65-4B77-8336-277F3921639B}.Debug|x64.ActiveCfg = Debug|x64 - {456DA1F5-7D65-4B77-8336-277F3921639B}.Debug|x64.Build.0 = Debug|x64 - {456DA1F5-7D65-4B77-8336-277F3921639B}.Release|Win32.ActiveCfg = Release|Win32 - {456DA1F5-7D65-4B77-8336-277F3921639B}.Release|Win32.Build.0 = Release|Win32 - {456DA1F5-7D65-4B77-8336-277F3921639B}.Release|x64.ActiveCfg = Release|x64 - {456DA1F5-7D65-4B77-8336-277F3921639B}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/Samples/LibOVR_Samples_VS2012.sln b/Samples/LibOVR_Samples_VS2012.sln deleted file mode 100644 index 5e2247c..0000000 --- a/Samples/LibOVR_Samples_VS2012.sln +++ /dev/null @@ -1,43 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2012 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OculusWorldDemo", "OculusWorldDemo\Projects\Win\VS2012\OculusWorldDemo.vcxproj", "{4F8C2B89-7CF1-4763-8EEF-E969FB760E32}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OculusRoomTiny", "OculusRoomTiny\Projects\Win\VS2012\OculusRoomTiny.vcxproj", "{5736727A-FEB0-49C0-B63A-36BF0FEB4FF3}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {4F8C2B89-7CF1-4763-8EEF-E969FB760E32}.Debug|Win32.ActiveCfg = Debug|Win32 - {4F8C2B89-7CF1-4763-8EEF-E969FB760E32}.Debug|Win32.Build.0 = Debug|Win32 - {4F8C2B89-7CF1-4763-8EEF-E969FB760E32}.Debug|Win32.Deploy.0 = Debug|Win32 - {4F8C2B89-7CF1-4763-8EEF-E969FB760E32}.Debug|x64.ActiveCfg = Debug|x64 - {4F8C2B89-7CF1-4763-8EEF-E969FB760E32}.Debug|x64.Build.0 = Debug|x64 - {4F8C2B89-7CF1-4763-8EEF-E969FB760E32}.Debug|x64.Deploy.0 = Debug|x64 - {4F8C2B89-7CF1-4763-8EEF-E969FB760E32}.Release|Win32.ActiveCfg = Release|Win32 - {4F8C2B89-7CF1-4763-8EEF-E969FB760E32}.Release|Win32.Build.0 = Release|Win32 - {4F8C2B89-7CF1-4763-8EEF-E969FB760E32}.Release|Win32.Deploy.0 = Release|Win32 - {4F8C2B89-7CF1-4763-8EEF-E969FB760E32}.Release|x64.ActiveCfg = Release|x64 - {4F8C2B89-7CF1-4763-8EEF-E969FB760E32}.Release|x64.Build.0 = Release|x64 - {4F8C2B89-7CF1-4763-8EEF-E969FB760E32}.Release|x64.Deploy.0 = Release|x64 - {5736727A-FEB0-49C0-B63A-36BF0FEB4FF3}.Debug|Win32.ActiveCfg = Debug|Win32 - {5736727A-FEB0-49C0-B63A-36BF0FEB4FF3}.Debug|Win32.Build.0 = Debug|Win32 - {5736727A-FEB0-49C0-B63A-36BF0FEB4FF3}.Debug|Win32.Deploy.0 = Debug|Win32 - {5736727A-FEB0-49C0-B63A-36BF0FEB4FF3}.Debug|x64.ActiveCfg = Debug|x64 - {5736727A-FEB0-49C0-B63A-36BF0FEB4FF3}.Debug|x64.Build.0 = Debug|x64 - {5736727A-FEB0-49C0-B63A-36BF0FEB4FF3}.Debug|x64.Deploy.0 = Debug|x64 - {5736727A-FEB0-49C0-B63A-36BF0FEB4FF3}.Release|Win32.ActiveCfg = Release|Win32 - {5736727A-FEB0-49C0-B63A-36BF0FEB4FF3}.Release|Win32.Build.0 = Release|Win32 - {5736727A-FEB0-49C0-B63A-36BF0FEB4FF3}.Release|Win32.Deploy.0 = Release|Win32 - {5736727A-FEB0-49C0-B63A-36BF0FEB4FF3}.Release|x64.ActiveCfg = Release|x64 - {5736727A-FEB0-49C0-B63A-36BF0FEB4FF3}.Release|x64.Build.0 = Release|x64 - {5736727A-FEB0-49C0-B63A-36BF0FEB4FF3}.Release|x64.Deploy.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/Samples/LibOVR_Samples_VS2013.sln b/Samples/LibOVR_Samples_VS2013.sln deleted file mode 100644 index 42b9e07..0000000 --- a/Samples/LibOVR_Samples_VS2013.sln +++ /dev/null @@ -1,38 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.30110.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OculusRoomTiny", "OculusRoomTiny\Projects\Win\VS2013\OculusRoomTiny.vcxproj", "{394FF596-A90B-4C95-888B-B743834ED15B}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OculusWorldDemo", "OculusWorldDemo\Projects\Win\VS2013\OculusWorldDemo.vcxproj", "{CA4E4127-1BAD-447C-BFF9-5AF940EEC376}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {394FF596-A90B-4C95-888B-B743834ED15B}.Debug|Win32.ActiveCfg = Debug|Win32 - {394FF596-A90B-4C95-888B-B743834ED15B}.Debug|Win32.Build.0 = Debug|Win32 - {394FF596-A90B-4C95-888B-B743834ED15B}.Debug|x64.ActiveCfg = Debug|x64 - {394FF596-A90B-4C95-888B-B743834ED15B}.Debug|x64.Build.0 = Debug|x64 - {394FF596-A90B-4C95-888B-B743834ED15B}.Release|Win32.ActiveCfg = Release|Win32 - {394FF596-A90B-4C95-888B-B743834ED15B}.Release|Win32.Build.0 = Release|Win32 - {394FF596-A90B-4C95-888B-B743834ED15B}.Release|x64.ActiveCfg = Release|x64 - {394FF596-A90B-4C95-888B-B743834ED15B}.Release|x64.Build.0 = Release|x64 - {CA4E4127-1BAD-447C-BFF9-5AF940EEC376}.Debug|Win32.ActiveCfg = Debug|Win32 - {CA4E4127-1BAD-447C-BFF9-5AF940EEC376}.Debug|Win32.Build.0 = Debug|Win32 - {CA4E4127-1BAD-447C-BFF9-5AF940EEC376}.Debug|x64.ActiveCfg = Debug|x64 - {CA4E4127-1BAD-447C-BFF9-5AF940EEC376}.Debug|x64.Build.0 = Debug|x64 - {CA4E4127-1BAD-447C-BFF9-5AF940EEC376}.Release|Win32.ActiveCfg = Release|Win32 - {CA4E4127-1BAD-447C-BFF9-5AF940EEC376}.Release|Win32.Build.0 = Release|Win32 - {CA4E4127-1BAD-447C-BFF9-5AF940EEC376}.Release|x64.ActiveCfg = Release|x64 - {CA4E4127-1BAD-447C-BFF9-5AF940EEC376}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/Samples/LibOVR_With_Samples_VS2010.sln b/Samples/LibOVR_With_Samples_VS2010.sln index 36888ff..6b0b7aa 100644 --- a/Samples/LibOVR_With_Samples_VS2010.sln +++ b/Samples/LibOVR_With_Samples_VS2010.sln @@ -1,15 +1,15 @@ Microsoft Visual Studio Solution File, Format Version 11.00 # Visual Studio 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibOVR", "..\LibOVR\Projects\Win32\VS2010\LibOVR.vcxproj", "{720F6C5E-6DCF-495A-B25E-10540EA081A2}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibOVR", "..\LibOVR\Projects\Win32\VS2010\LibOVR.vcxproj", "{934B40C7-F40A-4E4C-97A7-B9659BE0A441}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OculusRoomTiny", "OculusRoomTiny\Projects\Win\VS2010\OculusRoomTiny.vcxproj", "{6C6ECAC4-DB5C-4301-8371-9C7CC8C623C2}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OculusRoomTiny", "OculusRoomTiny\Projects\Win\VS2010\OculusRoomTiny.vcxproj", "{80523489-2881-4F64-8C3B-FAF88B60ABCD}" ProjectSection(ProjectDependencies) = postProject - {720F6C5E-6DCF-495A-B25E-10540EA081A2} = {720F6C5E-6DCF-495A-B25E-10540EA081A2} + {934B40C7-F40A-4E4C-97A7-B9659BE0A441} = {934B40C7-F40A-4E4C-97A7-B9659BE0A441} EndProjectSection EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OculusWorldDemo", "OculusWorldDemo\Projects\Win\VS2010\OculusWorldDemo.vcxproj", "{456DA1F5-7D65-4B77-8336-277F3921639B}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OculusWorldDemo", "OculusWorldDemo\Projects\Win\VS2010\OculusWorldDemo.vcxproj", "{8051B877-2992-4F64-8C3B-FAF88B6D83AA}" ProjectSection(ProjectDependencies) = postProject - {720F6C5E-6DCF-495A-B25E-10540EA081A2} = {720F6C5E-6DCF-495A-B25E-10540EA081A2} + {934B40C7-F40A-4E4C-97A7-B9659BE0A441} = {934B40C7-F40A-4E4C-97A7-B9659BE0A441} EndProjectSection EndProject Global @@ -20,30 +20,30 @@ Global Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {720F6C5E-6DCF-495A-B25E-10540EA081A2}.Debug|Win32.ActiveCfg = Debug|Win32 - {720F6C5E-6DCF-495A-B25E-10540EA081A2}.Debug|Win32.Build.0 = Debug|Win32 - {720F6C5E-6DCF-495A-B25E-10540EA081A2}.Debug|x64.ActiveCfg = Debug|x64 - {720F6C5E-6DCF-495A-B25E-10540EA081A2}.Debug|x64.Build.0 = Debug|x64 - {720F6C5E-6DCF-495A-B25E-10540EA081A2}.Release|Win32.ActiveCfg = Release|Win32 - {720F6C5E-6DCF-495A-B25E-10540EA081A2}.Release|Win32.Build.0 = Release|Win32 - {720F6C5E-6DCF-495A-B25E-10540EA081A2}.Release|x64.ActiveCfg = Release|x64 - {720F6C5E-6DCF-495A-B25E-10540EA081A2}.Release|x64.Build.0 = Release|x64 - {6C6ECAC4-DB5C-4301-8371-9C7CC8C623C2}.Debug|Win32.ActiveCfg = Debug|Win32 - {6C6ECAC4-DB5C-4301-8371-9C7CC8C623C2}.Debug|Win32.Build.0 = Debug|Win32 - {6C6ECAC4-DB5C-4301-8371-9C7CC8C623C2}.Debug|x64.ActiveCfg = Debug|x64 - {6C6ECAC4-DB5C-4301-8371-9C7CC8C623C2}.Debug|x64.Build.0 = Debug|x64 - {6C6ECAC4-DB5C-4301-8371-9C7CC8C623C2}.Release|Win32.ActiveCfg = Release|Win32 - {6C6ECAC4-DB5C-4301-8371-9C7CC8C623C2}.Release|Win32.Build.0 = Release|Win32 - {6C6ECAC4-DB5C-4301-8371-9C7CC8C623C2}.Release|x64.ActiveCfg = Release|x64 - {6C6ECAC4-DB5C-4301-8371-9C7CC8C623C2}.Release|x64.Build.0 = Release|x64 - {456DA1F5-7D65-4B77-8336-277F3921639B}.Debug|Win32.ActiveCfg = Debug|Win32 - {456DA1F5-7D65-4B77-8336-277F3921639B}.Debug|Win32.Build.0 = Debug|Win32 - {456DA1F5-7D65-4B77-8336-277F3921639B}.Debug|x64.ActiveCfg = Debug|x64 - {456DA1F5-7D65-4B77-8336-277F3921639B}.Debug|x64.Build.0 = Debug|x64 - {456DA1F5-7D65-4B77-8336-277F3921639B}.Release|Win32.ActiveCfg = Release|Win32 - {456DA1F5-7D65-4B77-8336-277F3921639B}.Release|Win32.Build.0 = Release|Win32 - {456DA1F5-7D65-4B77-8336-277F3921639B}.Release|x64.ActiveCfg = Release|x64 - {456DA1F5-7D65-4B77-8336-277F3921639B}.Release|x64.Build.0 = Release|x64 + {934B40C7-F40A-4E4C-97A7-B9659BE0A441}.Debug|Win32.ActiveCfg = Debug|Win32 + {934B40C7-F40A-4E4C-97A7-B9659BE0A441}.Debug|Win32.Build.0 = Debug|Win32 + {934B40C7-F40A-4E4C-97A7-B9659BE0A441}.Debug|x64.ActiveCfg = Debug|x64 + {934B40C7-F40A-4E4C-97A7-B9659BE0A441}.Debug|x64.Build.0 = Debug|x64 + {934B40C7-F40A-4E4C-97A7-B9659BE0A441}.Release|Win32.ActiveCfg = Release|Win32 + {934B40C7-F40A-4E4C-97A7-B9659BE0A441}.Release|Win32.Build.0 = Release|Win32 + {934B40C7-F40A-4E4C-97A7-B9659BE0A441}.Release|x64.ActiveCfg = Release|x64 + {934B40C7-F40A-4E4C-97A7-B9659BE0A441}.Release|x64.Build.0 = Release|x64 + {80523489-2881-4F64-8C3B-FAF88B60ABCD}.Debug|Win32.ActiveCfg = Debug|Win32 + {80523489-2881-4F64-8C3B-FAF88B60ABCD}.Debug|Win32.Build.0 = Debug|Win32 + {80523489-2881-4F64-8C3B-FAF88B60ABCD}.Debug|x64.ActiveCfg = Debug|x64 + {80523489-2881-4F64-8C3B-FAF88B60ABCD}.Debug|x64.Build.0 = Debug|x64 + {80523489-2881-4F64-8C3B-FAF88B60ABCD}.Release|Win32.ActiveCfg = Release|Win32 + {80523489-2881-4F64-8C3B-FAF88B60ABCD}.Release|Win32.Build.0 = Release|Win32 + {80523489-2881-4F64-8C3B-FAF88B60ABCD}.Release|x64.ActiveCfg = Release|x64 + {80523489-2881-4F64-8C3B-FAF88B60ABCD}.Release|x64.Build.0 = Release|x64 + {8051B877-2992-4F64-8C3B-FAF88B6D83AA}.Debug|Win32.ActiveCfg = Debug|Win32 + {8051B877-2992-4F64-8C3B-FAF88B6D83AA}.Debug|Win32.Build.0 = Debug|Win32 + {8051B877-2992-4F64-8C3B-FAF88B6D83AA}.Debug|x64.ActiveCfg = Debug|x64 + {8051B877-2992-4F64-8C3B-FAF88B6D83AA}.Debug|x64.Build.0 = Debug|x64 + {8051B877-2992-4F64-8C3B-FAF88B6D83AA}.Release|Win32.ActiveCfg = Release|Win32 + {8051B877-2992-4F64-8C3B-FAF88B6D83AA}.Release|Win32.Build.0 = Release|Win32 + {8051B877-2992-4F64-8C3B-FAF88B6D83AA}.Release|x64.ActiveCfg = Release|x64 + {8051B877-2992-4F64-8C3B-FAF88B6D83AA}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Samples/OculusRoomTiny/OculusRoomModel.cpp b/Samples/OculusRoomTiny/OculusRoomModel.cpp index f425be0..a7776a0 100644 --- a/Samples/OculusRoomTiny/OculusRoomModel.cpp +++ b/Samples/OculusRoomTiny/OculusRoomModel.cpp @@ -60,6 +60,7 @@ Slab FloorSlabs[] = SlabModel Floor = {sizeof(FloorSlabs)/sizeof(Slab), FloorSlabs, Tex_Checker}; + Slab CeilingSlabs[] = { { -10.0f, 4.0f, -20.0f, 10.0f, 4.1f, 20.1f, Color(128,128,128) } @@ -254,3 +255,49 @@ void PopulateRoomScene(Scene* scene, RenderDevice* render) scene->AddLight(Vector3f(-4,3,25), Vector4f(3,6,3,1)); } + +// Render a debug marker static in rift (special request for eye-tracking) +void renderSphere(RenderDevice* render, Vector3f ViewAdjust, float metresLeft, float metresUp, float metresAway, float metresRadius, + unsigned char red,unsigned char green,unsigned char blue) +{ + //Get textures, if haven't already + static FillCollection * pfills; + static bool firstTime = true; + if (firstTime) + { + firstTime=false; + pfills = new FillCollection(render); + } + + //Create object + Scene* scene = new Scene; + Slab CubeSlabs[] = + { + #if 0 //Simple cube + { metresLeft-metresRadius, metresUp-metresRadius, metresAway-metresRadius, + metresLeft+metresRadius, metresUp+metresRadius, metresAway+metresRadius, Color(red,green,blue) } + #else //Blob + { metresLeft-0.33f*metresRadius, metresUp-metresRadius, metresAway-0.33f*metresRadius, + metresLeft+0.33f*metresRadius, metresUp+metresRadius, metresAway+0.33f*metresRadius, Color(red,green,blue) }, + { metresLeft-metresRadius, metresUp-0.33f*metresRadius, metresAway-0.33f*metresRadius, + metresLeft+metresRadius, metresUp+0.33f*metresRadius, metresAway+0.33f*metresRadius, Color(red,green,blue) }, + { metresLeft-0.33f*metresRadius, metresUp-0.33f*metresRadius, metresAway-metresRadius, + metresLeft+0.33f*metresRadius, metresUp+0.33f*metresRadius, metresAway+metresRadius, Color(red,green,blue) }, + { metresLeft-0.71f*metresRadius, metresUp-0.71f*metresRadius, metresAway-0.71f*metresRadius, + metresLeft+0.71f*metresRadius, metresUp+0.71f*metresRadius, metresAway+0.71f*metresRadius, Color(red,green,blue) }, + + #endif + + }; + SlabModel Cube = {sizeof(CubeSlabs)/sizeof(Slab), CubeSlabs, Tex_None}; + scene->World.Add(Ptr<Model>(*CreateModel(Vector3f(0,0,0), &Cube, *pfills))); + scene->SetAmbient(Vector4f(1.0f,1.0f,1.0f,1)); + + //Render object + Matrix4f view = Matrix4f::LookAtRH(Vector3f(0,0,0), Vector3f(0,0,0) + Vector3f(0,0,1), Vector3f(0,1,0)); + scene->Render(render, Matrix4f::Translation(ViewAdjust) * view); + + //Delete object + delete scene; +} + diff --git a/Samples/OculusRoomTiny/Projects/Win/VS2010/OculusRoomTiny.vcxproj b/Samples/OculusRoomTiny/Projects/Win/VS2010/OculusRoomTiny.vcxproj index d6bb3e7..846c501 100644 --- a/Samples/OculusRoomTiny/Projects/Win/VS2010/OculusRoomTiny.vcxproj +++ b/Samples/OculusRoomTiny/Projects/Win/VS2010/OculusRoomTiny.vcxproj @@ -19,7 +19,7 @@ </ProjectConfiguration> </ItemGroup> <PropertyGroup Label="Globals"> - <ProjectGuid>{6C6ECAC4-DB5C-4301-8371-9C7CC8C623C2}</ProjectGuid> + <ProjectGuid>{80523489-2881-4F64-8C3B-FAF88B60ABCD}</ProjectGuid> <Keyword>Win32Proj</Keyword> <RootNamespace>OculusRoomTiny</RootNamespace> <ProjectName>OculusRoomTiny</ProjectName> diff --git a/Samples/OculusRoomTiny/Projects/Win/VS2012/OculusRoomTiny.vcxproj b/Samples/OculusRoomTiny/Projects/Win/VS2012/OculusRoomTiny.vcxproj index b547f70..12413ba 100644 --- a/Samples/OculusRoomTiny/Projects/Win/VS2012/OculusRoomTiny.vcxproj +++ b/Samples/OculusRoomTiny/Projects/Win/VS2012/OculusRoomTiny.vcxproj @@ -107,7 +107,7 @@ <Link> <SubSystem>Windows</SubSystem> <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>opengl32.lib;libovrd.lib;dxgi.lib;dxguid.lib;d3d10.lib;d3d11.lib;d3dcompiler.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> + <AdditionalDependencies>libovrd.lib;dxgi.lib;dxguid.lib;d3d10.lib;d3d11.lib;d3dcompiler.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/$(PlatformName)/VS2012/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> </Link> </ItemDefinitionGroup> @@ -127,7 +127,7 @@ <Link> <SubSystem>Windows</SubSystem> <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>opengl32.lib;libovr64d.lib;dxgi.lib;dxguid.lib;d3d10.lib;d3d11.lib;d3dcompiler.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> + <AdditionalDependencies>libovr64d.lib;dxgi.lib;dxguid.lib;d3d10.lib;d3d11.lib;d3dcompiler.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/$(PlatformName)/VS2012/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> </Link> </ItemDefinitionGroup> @@ -153,7 +153,7 @@ <EnableCOMDATFolding>true</EnableCOMDATFolding> <OptimizeReferences>true</OptimizeReferences> <AdditionalLibraryDirectories>../../../../../LibOVR/Lib/$(PlatformName)/VS2012/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> - <AdditionalDependencies>opengl32.lib;libovr.lib;dxguid.lib;dxgi.lib;d3d10.lib;d3d11.lib;d3dcompiler.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> + <AdditionalDependencies>libovr.lib;dxguid.lib;dxgi.lib;d3d10.lib;d3d11.lib;d3dcompiler.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> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> @@ -178,7 +178,7 @@ <EnableCOMDATFolding>true</EnableCOMDATFolding> <OptimizeReferences>true</OptimizeReferences> <AdditionalLibraryDirectories>../../../../../LibOVR/Lib/$(PlatformName)/VS2012/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> - <AdditionalDependencies>opengl32.lib;libovr64.lib;dxgi.lib;dxguid.lib;d3d10.lib;d3d11.lib;d3dcompiler.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> + <AdditionalDependencies>libovr64.lib;dxgi.lib;dxguid.lib;d3d10.lib;d3d11.lib;d3dcompiler.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> </Link> </ItemDefinitionGroup> <ItemGroup> diff --git a/Samples/OculusRoomTiny/Projects/Win/VS2013/OculusRoomTiny.vcxproj b/Samples/OculusRoomTiny/Projects/Win/VS2013/OculusRoomTiny.vcxproj index e09a883..7fb717c 100644 --- a/Samples/OculusRoomTiny/Projects/Win/VS2013/OculusRoomTiny.vcxproj +++ b/Samples/OculusRoomTiny/Projects/Win/VS2013/OculusRoomTiny.vcxproj @@ -115,7 +115,7 @@ <Link> <SubSystem>Windows</SubSystem> <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>opengl32.lib;libovrd.lib;dxgi.lib;dxguid.lib;d3d10.lib;d3d11.lib;d3dcompiler.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> + <AdditionalDependencies>libovrd.lib;dxgi.lib;dxguid.lib;d3d10.lib;d3d11.lib;d3dcompiler.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/VS2013/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> </Link> </ItemDefinitionGroup> @@ -135,7 +135,7 @@ <Link> <SubSystem>Windows</SubSystem> <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>opengl32.lib;libovr64d.lib;dxgi.lib;dxguid.lib;d3d10.lib;d3d11.lib;d3dcompiler.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> + <AdditionalDependencies>libovr64d.lib;dxgi.lib;dxguid.lib;d3d10.lib;d3d11.lib;d3dcompiler.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/VS2013/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> </Link> </ItemDefinitionGroup> @@ -161,7 +161,7 @@ <EnableCOMDATFolding>true</EnableCOMDATFolding> <OptimizeReferences>true</OptimizeReferences> <AdditionalLibraryDirectories>../../../../../LibOVR/Lib/Win32/VS2013/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> - <AdditionalDependencies>opengl32.lib;libovr.lib;dxguid.lib;dxgi.lib;d3d10.lib;d3d11.lib;d3dcompiler.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> + <AdditionalDependencies>libovr.lib;dxguid.lib;dxgi.lib;d3d10.lib;d3d11.lib;d3dcompiler.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> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> @@ -186,7 +186,7 @@ <EnableCOMDATFolding>true</EnableCOMDATFolding> <OptimizeReferences>true</OptimizeReferences> <AdditionalLibraryDirectories>../../../../../LibOVR/Lib/x64/VS2013/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> - <AdditionalDependencies>opengl32.lib;libovr64.lib;dxguid.lib;dxgi.lib;d3d10.lib;d3d11.lib;d3dcompiler.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> + <AdditionalDependencies>libovr64.lib;dxguid.lib;dxgi.lib;d3d10.lib;d3d11.lib;d3dcompiler.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> </Link> </ItemDefinitionGroup> <ItemGroup> diff --git a/Samples/OculusRoomTiny/RenderTiny_D3D11_Device.h b/Samples/OculusRoomTiny/RenderTiny_D3D11_Device.h index f4ec71a..e16aa73 100644 --- a/Samples/OculusRoomTiny/RenderTiny_D3D11_Device.h +++ b/Samples/OculusRoomTiny/RenderTiny_D3D11_Device.h @@ -777,7 +777,7 @@ public: virtual void SetRenderTarget(Texture* color, Texture* depth = NULL, Texture* stencil = NULL); - + void SetDefaultRenderTarget() { SetRenderTarget(NULL, NULL); } virtual void SetDepthMode(bool enable, bool write, CompareFunc func = Compare_Less); virtual void SetProjection(const Matrix4f& proj); virtual void SetWorldUniforms(const Matrix4f& proj); diff --git a/Samples/OculusRoomTiny/Win32_DistortionMesh.cpp b/Samples/OculusRoomTiny/Win32_DistortionMesh.cpp index 3356467..cacfc04 100644 --- a/Samples/OculusRoomTiny/Win32_DistortionMesh.cpp +++ b/Samples/OculusRoomTiny/Win32_DistortionMesh.cpp @@ -61,16 +61,22 @@ static D3D11_INPUT_ELEMENT_DESC DistortionMeshVertexDesc[] = void DistortionMeshInit(unsigned distortionCaps, ovrHmd HMD, - ovrEyeRenderDesc eyeRenderDesc[2], RenderDevice* pRender) + ovrEyeRenderDesc eyeRenderDesc[2], + ovrSizei textureSize, ovrRecti viewports[2], + RenderDevice* pRender) { //Generate distortion mesh for each eye for ( int eyeNum = 0; eyeNum < 2; eyeNum++ ) { // Allocate & generate distortion mesh vertices. ovrDistortionMesh meshData; - ovrHmd_CreateDistortionMesh(HMD, eyeRenderDesc[eyeNum].Desc, distortionCaps, - (ovrVector2f* ) DistortionData.UVScaleOffset[eyeNum], - &meshData); + ovrHmd_CreateDistortionMesh(HMD, + eyeRenderDesc[eyeNum].Eye, eyeRenderDesc[eyeNum].Fov, + distortionCaps, &meshData); + + ovrHmd_GetRenderScaleAndOffset(eyeRenderDesc[eyeNum].Fov, + textureSize, viewports[eyeNum], + (ovrVector2f*) DistortionData.UVScaleOffset[eyeNum]); // Now parse the vertex data and create a render ready vertex buffer from it DistortionVertex * pVBVerts = (DistortionVertex*)OVR_ALLOC( @@ -119,7 +125,7 @@ void DistortionMeshInit(unsigned distortionCaps, ovrHmd HMD, // Choose the vertex shader, according to if you have timewarp enabled - if (distortionCaps & ovrDistortion_TimeWarp) + if (distortionCaps & ovrDistortionCap_TimeWarp) { // TIMEWARP //-------------------------------------------------------------------------------------------- const char* vertexShader = @@ -188,14 +194,14 @@ void DistortionMeshRender(unsigned distortionCaps, ovrHmd HMD, double timwarpTimePoint, ovrPosef eyeRenderPoses[2], RenderDevice* pRender, Texture* pRendertargetTexture) { - if (distortionCaps & ovrDistortion_TimeWarp) + if (distortionCaps & ovrDistortionCap_TimeWarp) { // TIMEWARP // Wait till time-warp to reduce latency. ovr_WaitTillTime(timwarpTimePoint); } // Clear screen - pRender->SetRenderTarget(NULL); + pRender->SetDefaultRenderTarget(); pRender->SetFullViewport(); pRender->Clear(0.0f, 0.0f, 0.0f, 0.0f); @@ -212,10 +218,11 @@ void DistortionMeshRender(unsigned distortionCaps, ovrHmd HMD, DistortionData.Shaders->SetUniform2f("EyeToSourceUVOffset", DistortionData.UVScaleOffset[eyeNum][1].x, DistortionData.UVScaleOffset[eyeNum][1].y); - if (distortionCaps & ovrDistortion_TimeWarp) + if (distortionCaps & ovrDistortionCap_TimeWarp) { // TIMEWARP - Additional shader constants required ovrMatrix4f timeWarpMatrices[2]; ovrHmd_GetEyeTimewarpMatrices(HMD, (ovrEyeType)eyeNum, eyeRenderPoses[eyeNum], timeWarpMatrices); + //WARNING!!! These matrices are transposed in SetUniform4x4f, before being used by the shader. DistortionData.Shaders->SetUniform4x4f("EyeRotationStart", Matrix4f(timeWarpMatrices[0])); DistortionData.Shaders->SetUniform4x4f("EyeRotationEnd", Matrix4f(timeWarpMatrices[1])); } @@ -224,7 +231,7 @@ void DistortionMeshRender(unsigned distortionCaps, ovrHmd HMD, DistortionData.MeshVBs[eyeNum], DistortionData.MeshIBs[eyeNum]); } - pRender->SetRenderTarget(NULL); + pRender->SetDefaultRenderTarget(); } diff --git a/Samples/OculusRoomTiny/Win32_OculusRoomTiny.cpp b/Samples/OculusRoomTiny/Win32_OculusRoomTiny.cpp index 5300537..8caf3d5 100644 --- a/Samples/OculusRoomTiny/Win32_OculusRoomTiny.cpp +++ b/Samples/OculusRoomTiny/Win32_OculusRoomTiny.cpp @@ -33,9 +33,9 @@ limitations under the License. // ***** Choices and settings // Whether the SDK performs rendering/distortion, or the app. -//#define SDK_RENDER 1 - -const unsigned DistortionCaps = ovrDistortion_Chromatic | ovrDistortion_TimeWarp; +#define SDK_RENDER 1 + +const unsigned DistortionCaps = ovrDistortionCap_Chromatic | ovrDistortionCap_TimeWarp; const bool VSyncEnabled = true; const bool FullScreen = true; @@ -52,9 +52,10 @@ void PopulateRoomScene (Scene* scene, RenderDevice* rend ovrHmd HMD; ovrHmdDesc HMDDesc; ovrEyeRenderDesc EyeRenderDesc[2]; -RenderDevice* pRender; -Texture* pRendertargetTexture; -Scene* pRoomScene; +ovrRecti EyeRenderViewport[2]; +RenderDevice* pRender = 0; +Texture* pRendertargetTexture = 0; +Scene* pRoomScene = 0; // Specifics for whether the SDK or the app is doing the distortion. #if SDK_RENDER @@ -63,7 +64,9 @@ Scene* pRoomScene; ovrD3D11Texture EyeTexture[2]; #else void DistortionMeshInit (unsigned distortionCaps, ovrHmd HMD, - ovrEyeRenderDesc eyeRenderDesc[2], RenderDevice * pRender); + ovrEyeRenderDesc eyeRenderDesc[2], + ovrSizei textureSize, ovrRecti viewports[2], + RenderDevice * pRender); void DistortionMeshRender(unsigned distortionCaps, ovrHmd HMD, double timwarpTimePoint, ovrPosef eyeRenderPoses[2], RenderDevice * pRender, Texture* pRendertargetTexture); @@ -110,30 +113,25 @@ int Init() // 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]; - eyes[0].TextureSize = RenderTargetSize; - eyes[1].TextureSize = RenderTargetSize; - eyes[0].RenderViewport.Pos = Vector2i(0,0); - eyes[0].RenderViewport.Size = Sizei(RenderTargetSize.w / 2, RenderTargetSize.h); - eyes[1].RenderViewport.Pos = Vector2i((RenderTargetSize.w + 1) / 2, 0); - eyes[1].RenderViewport.Size = eyes[0].RenderViewport.Size; + ovrFovPort eyeFov[2] = { HMDDesc.DefaultEyeFov[0], HMDDesc.DefaultEyeFov[1] } ; + + EyeRenderViewport[0].Pos = Vector2i(0,0); + EyeRenderViewport[0].Size = Sizei(RenderTargetSize.w / 2, RenderTargetSize.h); + EyeRenderViewport[1].Pos = Vector2i((RenderTargetSize.w + 1) / 2, 0); + EyeRenderViewport[1].Size = EyeRenderViewport[0].Size; #if SDK_RENDER // Query D3D texture data. Texture* rtt = (Texture*)pRendertargetTexture; EyeTexture[0].D3D11.Header.API = ovrRenderAPI_D3D11; EyeTexture[0].D3D11.Header.TextureSize = RenderTargetSize; - EyeTexture[0].D3D11.Header.RenderViewport = eyes[0].RenderViewport; + EyeTexture[0].D3D11.Header.RenderViewport = EyeRenderViewport[0]; EyeTexture[0].D3D11.pTexture = rtt->Tex.GetPtr(); EyeTexture[0].D3D11.pSRView = rtt->TexSv.GetPtr(); // Right eye uses the same texture, but different rendering viewport. EyeTexture[1] = EyeTexture[0]; - EyeTexture[1].D3D11.Header.RenderViewport = eyes[1].RenderViewport; + EyeTexture[1].D3D11.Header.RenderViewport = EyeRenderViewport[1]; // Configure d3d11. RenderDevice* render = (RenderDevice*)pRender; @@ -147,22 +145,24 @@ int Init() d3d11cfg.D3D11.pSwapChain = render->SwapChain; if (!ovrHmd_ConfigureRendering(HMD, &d3d11cfg.Config, - (VSyncEnabled ? 0 : ovrHmdCap_NoVSync), DistortionCaps, - eyes, EyeRenderDesc)) return(1); + DistortionCaps, + eyeFov, EyeRenderDesc)) return(1); #else // !SDK_RENDER - EyeRenderDesc[0] = ovrHmd_GetRenderDesc(HMD, eyes[0]); - EyeRenderDesc[1] = ovrHmd_GetRenderDesc(HMD, eyes[1]); + EyeRenderDesc[0] = ovrHmd_GetRenderDesc(HMD, ovrEye_Left, eyeFov[0]); + EyeRenderDesc[1] = ovrHmd_GetRenderDesc(HMD, ovrEye_Right, eyeFov[1]); // Create our own distortion mesh and shaders - DistortionMeshInit(DistortionCaps, HMD, EyeRenderDesc, pRender); + DistortionMeshInit(DistortionCaps, HMD, EyeRenderDesc, + RenderTargetSize, EyeRenderViewport, pRender); #endif + ovrHmd_SetEnabledCaps(HMD, ovrHmdCap_LowPersistence | + ovrHmdCap_LatencyTest); + // Start the sensor which informs of the Rift's pose and motion - ovrHmd_StartSensor(HMD, ovrHmdCap_Orientation | - ovrHmdCap_YawCorrection | - ovrHmdCap_Position | - ovrHmdCap_LowPersistence | - ovrHmdCap_LatencyTest, 0); + ovrHmd_StartSensor(HMD, ovrSensorCap_Orientation | + ovrSensorCap_YawCorrection | + ovrSensorCap_Position, 0); // This creates lights and models. pRoomScene = new Scene; @@ -185,12 +185,12 @@ void ProcessAndRender() static Vector3f EyePos(0.0f, 1.6f, -5.0f); static float EyeYaw(3.141592f); - Posef movePose = ovrHmd_GetSensorState(HMD, frameTiming.ScanoutMidpointSeconds).Predicted.Pose; - ovrPosef eyeRenderPose[2]; + Transformf movePose = ovrHmd_GetSensorState(HMD, frameTiming.ScanoutMidpointSeconds).Predicted.Pose; + static ovrPosef eyeRenderPose[2]; EyePos.y = ovrHmd_GetFloat(HMD, OVR_KEY_EYE_HEIGHT, EyePos.y); bool freezeEyeRender = Util_RespondToControls(EyeYaw, EyePos, - frameTiming.DeltaSeconds, movePose.Orientation); + frameTiming.DeltaSeconds, movePose.Rotation); pRender->BeginScene(); @@ -220,12 +220,9 @@ void ProcessAndRender() Matrix4f view = Matrix4f::LookAtRH(shiftedEyePos, shiftedEyePos + finalForward, finalUp); - Matrix4f proj = ovrMatrix4f_Projection(EyeRenderDesc[eye].Desc.Fov, 0.01f, 10000.0f, true); + Matrix4f proj = ovrMatrix4f_Projection(EyeRenderDesc[eye].Fov, 0.01f, 10000.0f, true); - pRender->SetViewport(EyeRenderDesc[eye].Desc.RenderViewport.Pos.x, - EyeRenderDesc[eye].Desc.RenderViewport.Pos.y, - EyeRenderDesc[eye].Desc.RenderViewport.Size.w, - EyeRenderDesc[eye].Desc.RenderViewport.Size.h); + pRender->SetViewport(Recti(EyeRenderViewport[eye])); pRender->SetProjection(proj); pRender->SetDepthMode(true, true); pRoomScene->Render(pRender, Matrix4f::Translation(EyeRenderDesc[eye].ViewAdjust) * view); @@ -274,8 +271,10 @@ ovrHmd_EndFrame(hmd); //------------------------------------------------------------------------------------- void Release(void) { - pRendertargetTexture->Release(); - pRendertargetTexture = 0; + if (pRendertargetTexture) { + pRendertargetTexture->Release(); + pRendertargetTexture = 0; + } ovrHmd_Destroy(HMD); Util_ReleaseWindowAndGraphics(pRender); pRender = 0; diff --git a/Samples/OculusWorldDemo/Assets/Tuscany/Tuscany.xml b/Samples/OculusWorldDemo/Assets/Tuscany/Tuscany.xml index f6be29b..3ce2edf 100644 --- a/Samples/OculusWorldDemo/Assets/Tuscany/Tuscany.xml +++ b/Samples/OculusWorldDemo/Assets/Tuscany/Tuscany.xml @@ -36,7 +36,7 @@ <texture fileName="tree_A02LightingMap.dds"/> <texture fileName="tree_A03LightingMap.dds"/> <texture fileName="Vase.dds"/> - <texture fileName="vaseLightingMap.dds"/> + <texture fileName="VaseLightingMap.dds"/> <texture fileName="Rocks.dds"/> <texture fileName="Props_ExteriorLightingMap.dds"/> <texture fileName="Bench.dds"/> @@ -48,12 +48,12 @@ <texture fileName="Chair1.dds"/> <texture fileName="Picture2.dds"/> <texture fileName="Picture3.dds"/> - <texture fileName="hutch.dds"/> + <texture fileName="Hutch.dds"/> <texture fileName="Book.dds"/> <texture fileName="Iron.dds"/> <texture fileName="Table2.dds"/> <texture fileName="Picture1.dds"/> - <texture fileName="fireWood.dds"/> + <texture fileName="FireWood.dds"/> <texture fileName="Floor.dds"/> <texture fileName="House_InteriorLightingMap.dds"/> <texture fileName="IntertiorFront.dds"/> @@ -64,7 +64,7 @@ <texture fileName="ChimneyBrick.dds"/> <texture fileName="Concrete1.dds"/> <texture fileName="Concrete2.dds"/> - <texture fileName="House_ExteriorLightingMap.dds"/> + <texture fileName="house_exteriorLightingMap.dds"/> <texture fileName="HouseFront.dds"/> <texture fileName="HouseLeft.dds"/> <texture fileName="HouseRight.dds"/> @@ -2291,4 +2291,4 @@ </groundCollisionModels> <lights count="0"> </lights> -</scene>
\ No newline at end of file +</scene> diff --git a/Samples/OculusWorldDemo/OculusWorldDemo.cpp b/Samples/OculusWorldDemo/OculusWorldDemo.cpp index e89403f..9c62d59 100644 --- a/Samples/OculusWorldDemo/OculusWorldDemo.cpp +++ b/Samples/OculusWorldDemo/OculusWorldDemo.cpp @@ -59,7 +59,7 @@ OculusWorldDemoApp::OculusWorldDemoApp() CenterPupilDepthMeters(0.05f), ForceZeroHeadMovement(false), VsyncEnabled(true), - MultisampleEnabled(true), + MultisampleEnabled(false), IsLowPersistence(true), DynamicPrediction(true), PositionTrackingEnabled(true), @@ -78,6 +78,8 @@ OculusWorldDemoApp::OculusWorldDemoApp() FrameCounter = 0; LastFpsUpdate = 0; + EyeRenderSize[0] = EyeRenderSize[1] = Sizei(0); + DistortionClearBlue = false; } @@ -138,7 +140,7 @@ int OculusWorldDemoApp::OnStartup(int argc, const char** argv) FovSideTanLimit = FovPort::Max(HmdDesc.MaxEyeFov[0], HmdDesc.MaxEyeFov[1]).GetMaxSideTan(); FovSideTanMax = FovPort::Max(HmdDesc.DefaultEyeFov[0], HmdDesc.DefaultEyeFov[1]).GetMaxSideTan(); - PositionTrackingEnabled = (HmdDesc.Caps & ovrHmdCap_Position) ? true : false; + PositionTrackingEnabled = (HmdDesc.SensorCaps & ovrSensorCap_Position) ? true : false; // *** Configure HMD Stereo settings. @@ -189,7 +191,11 @@ bool OculusWorldDemoApp::SetupWindowAndRendering(int argc, const char** argv) // *** Initialize Rendering +#if defined(OVR_OS_WIN32) const char* graphics = "d3d11"; +#else + const char* graphics = "GL"; +#endif // Select renderer based on command line arguments. for(int i = 1; i < argc; i++) @@ -322,11 +328,11 @@ void OculusWorldDemoApp::PopulateOptionMenu() 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 (HmdDesc.SensorCaps & ovrSensorCap_Position) { - Menu.AddBool("Low Persistence 'P'", &IsLowPersistence). + Menu.AddBool("Low Persistence 'P'", &IsLowPersistence). AddShortcutKey(Key_P).SetNotify(this, &OWD::HmdSettingChange); - Menu.AddBool("Dynamic Prediction", &DynamicPrediction). + Menu.AddBool("Dynamic Prediction", &DynamicPrediction). SetNotify(this, &OWD::HmdSettingChange); Menu.AddBool("Positional Tracking 'X'", &PositionTrackingEnabled). AddShortcutKey(Key_X).SetNotify(this, &OWD::HmdSettingChange); @@ -338,16 +344,14 @@ 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]; + ovrFovPort eyeFov[2]; + eyeFov[0] = HmdDesc.DefaultEyeFov[0]; + eyeFov[1] = 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)); + eyeFov[0] = FovPort::Min(eyeFov[0], FovPort(FovSideTanMax)); + eyeFov[1] = FovPort::Min(eyeFov[1], FovPort(FovSideTanMax)); if (ForceZeroIpd) @@ -357,28 +361,30 @@ void OculusWorldDemoApp::CalculateHmdValues() // 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; + eyeFov[0] = FovPort::Max(eyeFov[0], eyeFov[1]); + eyeFov[1] = eyeFov[0]; Sizei recommenedTexSize = ovrHmd_GetFovTextureSize(Hmd, ovrEye_Left, - eyes[0].Fov, DesiredPixelDensity); + eyeFov[0], 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; + Sizei textureSize = EnsureRendertargetAtLeastThisBig(Rendertarget_Left, recommenedTexSize); + + EyeRenderSize[0] = Sizei::Min(textureSize, recommenedTexSize); + EyeRenderSize[1] = EyeRenderSize[0]; // Store texture pointers that will be passed for rendering. - EyeTexture[0] = RenderTargets[Rendertarget_Left].Tex; - EyeTexture[1] = RenderTargets[Rendertarget_Left].Tex; + EyeTexture[0] = RenderTargets[Rendertarget_Left].Tex; + EyeTexture[0].Header.TextureSize = textureSize; + EyeTexture[0].Header.RenderViewport = Recti(EyeRenderSize[0]); + // Right eye is the same. + EyeTexture[1] = EyeTexture[0]; } else { // 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); + Sizei recommenedTex0Size = ovrHmd_GetFovTextureSize(Hmd, ovrEye_Left, eyeFov[0], DesiredPixelDensity); + Sizei recommenedTex1Size = ovrHmd_GetFovTextureSize(Hmd, ovrEye_Right, eyeFov[1], DesiredPixelDensity); if (RendertargetIsSharedByBothEyes) { @@ -390,46 +396,55 @@ void OculusWorldDemoApp::CalculateHmdValues() // 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); + EyeRenderSize[0] = Sizei::Min(Sizei(rtSize.w/2, rtSize.h), recommenedTex0Size); + EyeRenderSize[1] = Sizei::Min(Sizei(rtSize.w/2, rtSize.h), recommenedTex1Size); // 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; + EyeTexture[0] = RenderTargets[Rendertarget_BothEyes].Tex; + EyeTexture[0].Header.TextureSize = rtSize; + EyeTexture[0].Header.RenderViewport = Recti(Vector2i(0), EyeRenderSize[0]); + EyeTexture[1] = RenderTargets[Rendertarget_BothEyes].Tex; + EyeTexture[1].Header.TextureSize = rtSize; + EyeTexture[1].Header.RenderViewport = Recti(Vector2i((rtSize.w+1)/2, 0), EyeRenderSize[1]); } 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; + Sizei tex0Size = EnsureRendertargetAtLeastThisBig(Rendertarget_Left, recommenedTex0Size); + Sizei tex1Size = EnsureRendertargetAtLeastThisBig(Rendertarget_Right, recommenedTex1Size); + + EyeRenderSize[0] = Sizei::Min(tex0Size, recommenedTex0Size); + EyeRenderSize[1] = Sizei::Min(tex1Size, recommenedTex1Size); + + // Store texture pointers and viewports that will be passed for rendering. + EyeTexture[0] = RenderTargets[Rendertarget_Left].Tex; + EyeTexture[0].Header.TextureSize = tex0Size; + EyeTexture[0].Header.RenderViewport = Recti(EyeRenderSize[0]); + EyeTexture[1] = RenderTargets[Rendertarget_Right].Tex; + EyeTexture[1].Header.TextureSize = tex1Size; + EyeTexture[1].Header.RenderViewport = Recti(EyeRenderSize[1]); } } + // Hmd caps. + unsigned hmdCaps = (VsyncEnabled ? 0 : ovrHmdCap_NoVSync) | + ovrHmdCap_LatencyTest; + if (IsLowPersistence) + hmdCaps |= ovrHmdCap_LowPersistence; + if (DynamicPrediction) + hmdCaps |= ovrHmdCap_DynamicPrediction; - unsigned hmdCaps = ovrHmdCap_Orientation | (VsyncEnabled ? 0 : ovrHmdCap_NoVSync); - unsigned distortionCaps = ovrDistortion_Chromatic; + ovrHmd_SetEnabledCaps(Hmd, hmdCaps); - ovrRenderAPIConfig config = pRender->Get_ovrRenderAPIConfig(); + ovrRenderAPIConfig config = pRender->Get_ovrRenderAPIConfig(); + unsigned distortionCaps = ovrDistortionCap_Chromatic; if (TimewarpEnabled) - distortionCaps |= ovrDistortion_TimeWarp; + distortionCaps |= ovrDistortionCap_TimeWarp; - if (!ovrHmd_ConfigureRendering( Hmd, &config, hmdCaps, distortionCaps, - eyes, EyeRenderDesc )) + if (!ovrHmd_ConfigureRendering( Hmd, &config, distortionCaps, + eyeFov, EyeRenderDesc )) { // Fail exit? TBD return; @@ -443,14 +458,10 @@ void OculusWorldDemoApp::CalculateHmdValues() } // ovrHmdCap_LatencyTest - enables internal latency feedback - unsigned sensorCaps = ovrHmdCap_Orientation|ovrHmdCap_YawCorrection|ovrHmdCap_LatencyTest; + unsigned sensorCaps = ovrSensorCap_Orientation|ovrSensorCap_YawCorrection; if (PositionTrackingEnabled) - sensorCaps |= ovrHmdCap_Position; - if (IsLowPersistence) - sensorCaps |= ovrHmdCap_LowPersistence; - if (DynamicPrediction) - sensorCaps |= ovrHmdCap_DynamicPrediction; - + sensorCaps |= ovrSensorCap_Position; + if (StartSensorCaps != sensorCaps) { ovrHmd_StartSensor(Hmd, sensorCaps, 0); @@ -458,8 +469,8 @@ void OculusWorldDemoApp::CalculateHmdValues() } // 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); + Projection[0] = ovrMatrix4f_Projection(EyeRenderDesc[0].Fov, 0.01f, 10000.0f, true); + Projection[1] = ovrMatrix4f_Projection(EyeRenderDesc[1].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); @@ -530,7 +541,7 @@ Sizei OculusWorldDemoApp::EnsureRendertargetAtLeastThisBig(int rtNum, Sizei requ void OculusWorldDemoApp::OnResize(int width, int height) { WindowSize = Sizei(width, height); - // Re-calculate? + HmdSettingsChanged = true; } void OculusWorldDemoApp::OnMouseMove(int x, int y, int modifiers) @@ -570,13 +581,9 @@ void OculusWorldDemoApp::OnKey(OVR::KeyCode key, int chr, bool down, int modifie break; case Key_F9: -#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 // F11 is reserved on Mac, F10 doesn't work on Windows @@ -652,13 +659,13 @@ void OculusWorldDemoApp::OnKey(OVR::KeyCode key, int chr, bool down, int modifie //----------------------------------------------------------------------------- -Matrix4f OculusWorldDemoApp::CalculateViewFromPose(const Posef& pose) +Matrix4f OculusWorldDemoApp::CalculateViewFromPose(const Transformf& pose) { - Posef worldPose = ThePlayer.VirtualWorldPoseFromRealPose(pose); + Transformf worldPose = ThePlayer.VirtualWorldTransformfromRealPose(pose); // Rotate and position View Camera - Vector3f up = worldPose.Orientation.Rotate(UpVector); - Vector3f forward = worldPose.Orientation.Rotate(ForwardVector); + Vector3f up = worldPose.Rotation.Rotate(UpVector); + Vector3f forward = worldPose.Rotation.Rotate(ForwardVector); // 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. @@ -667,7 +674,7 @@ Matrix4f OculusWorldDemoApp::CalculateViewFromPose(const Posef& pose) // 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; + Vector3f viewPos = ForceZeroHeadMovement ? ThePlayer.BodyPos : worldPose.Translation; Matrix4f view = Matrix4f::LookAtRH(viewPos, viewPos + forward, up); return view; @@ -726,14 +733,14 @@ void OculusWorldDemoApp::OnIdle() // Update pose based on frame! - ThePlayer.HeadPose = ss.Predicted.Transform; + ThePlayer.HeadPose = ss.Predicted.Pose; // Movement/rotation with the gamepad. ThePlayer.BodyYaw -= ThePlayer.GamepadRotate.x * dt; ThePlayer.HandleMovement(dt, &CollisionModels, &GroundCollisionModels, ShiftDown); // Record after processing time. - Profiler.RecordSample(RenderProfiler::Sample_AfterGameProcessing); + Profiler.RecordSample(RenderProfiler::Sample_AfterGameProcessing); // Determine if we are rendering this frame. Frame rendering may be @@ -774,7 +781,7 @@ void OculusWorldDemoApp::OnIdle() for (int eyeIndex = 0; eyeIndex < ovrEye_Count; eyeIndex++) { ovrEyeType eye = HmdDesc.EyeRenderOrder[eyeIndex]; - ovrPosef eyeRenderPose = ovrHmd_BeginEyeRender(Hmd, eye); + ovrPosef eyeRenderPose = ovrHmd_BeginEyeRender(Hmd, eye); View = CalculateViewFromPose(eyeRenderPose); RenderEyeView(eye); @@ -800,9 +807,16 @@ void OculusWorldDemoApp::OnIdle() } } - pRender->SetRenderTarget(0); + pRender->SetDefaultRenderTarget(); pRender->FinishScene(); } + + /* + double t= ovr_GetTimeInSeconds(); + while (ovr_GetTimeInSeconds() < (t + 0.017)) + { + + } */ Profiler.RecordSample(RenderProfiler::Sample_AfterEyeRender); @@ -864,8 +878,8 @@ void OculusWorldDemoApp::ApplyDynamicResolutionScaling() if (!DynamicRezScalingEnabled) { // 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; + EyeTexture[0].Header.RenderViewport.Size = EyeRenderSize[0]; + EyeTexture[1].Header.RenderViewport.Size = EyeRenderSize[1]; return; } @@ -901,14 +915,14 @@ void OculusWorldDemoApp::ApplyDynamicResolutionScaling() dynamicRezScale = dynamicRezScale * 0.5f + 0.5f; } - Sizei sizeLeft = EyeRenderDesc[0].Desc.RenderViewport.Size; - Sizei sizeRight = EyeRenderDesc[1].Desc.RenderViewport.Size; + Sizei sizeLeft = EyeRenderSize[0]; + Sizei sizeRight = EyeRenderSize[1]; // 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)); + int(sizeLeft.h * dynamicRezScale)); EyeTexture[1].Header.RenderViewport.Size = Sizei(int(sizeRight.w * dynamicRezScale), - int(sizeRight.h * dynamicRezScale)); + int(sizeRight.h * dynamicRezScale)); } @@ -1042,13 +1056,13 @@ void OculusWorldDemoApp::RenderTextInfoHud(float textHeight) char buf[512], gpustat[256]; // Average FOVs. - FovPort leftFov = EyeRenderDesc[0].Desc.Fov; - FovPort rightFov = EyeRenderDesc[1].Desc.Fov; + FovPort leftFov = EyeRenderDesc[0].Fov; + FovPort rightFov = EyeRenderDesc[1].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); + EyeTexture[1].Header.RenderViewport.Size.w : 0); int pixelSizeHeight = ( EyeTexture[0].Header.RenderViewport.Size.h + EyeTexture[1].Header.RenderViewport.Size.h ) / 2; @@ -1074,7 +1088,7 @@ void OculusWorldDemoApp::RenderTextInfoHud(float textHeight) } } - ThePlayer.HeadPose.Orientation.GetEulerAngles<Axis_Y, Axis_X, Axis_Z>(&hmdYaw, &hmdPitch, &hmdRoll); + ThePlayer.HeadPose.Rotation.GetEulerAngles<Axis_Y, Axis_X, Axis_Z>(&hmdYaw, &hmdPitch, &hmdRoll); OVR_sprintf(buf, sizeof(buf), " HMD YPR:%4.0f %4.0f %4.0f Player Yaw: %4.0f\n" " FPS: %.1f ms/frame: %.1f Frame: %d\n" diff --git a/Samples/OculusWorldDemo/OculusWorldDemo.h b/Samples/OculusWorldDemo/OculusWorldDemo.h index 54f0e9d..049ac94 100644 --- a/Samples/OculusWorldDemo/OculusWorldDemo.h +++ b/Samples/OculusWorldDemo/OculusWorldDemo.h @@ -31,6 +31,8 @@ limitations under the License. #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; @@ -42,9 +44,6 @@ using namespace OVR::Util::Render; #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" @@ -133,7 +132,7 @@ public: void RenderAnimatedBlocks(ovrEyeType eye, double appTime); void RenderGrid(ovrEyeType eye); - Matrix4f CalculateViewFromPose(const Posef& pose); + Matrix4f CalculateViewFromPose(const Transformf& pose); // Determine whether this frame needs rendering based on timewarp timing and flags. bool FrameNeedsRendering(double curtime); @@ -191,9 +190,10 @@ protected: ovrHmd Hmd; ovrHmdDesc HmdDesc; ovrEyeRenderDesc EyeRenderDesc[2]; - Matrix4f Projection[2]; // Projection matrix for eye. - Matrix4f OrthoProjection[2]; // Projection for 2D. + Matrix4f Projection[2]; // Projection matrix for eye. + Matrix4f OrthoProjection[2]; // Projection for 2D. ovrTexture EyeTexture[2]; + Sizei EyeRenderSize[2]; // Saved render eye sizes; base for dynamic sizing. // Sensor caps applied. unsigned StartSensorCaps; bool UsingDebugHmd; diff --git a/Samples/OculusWorldDemo/OculusWorldDemo_Scene.cpp b/Samples/OculusWorldDemo/OculusWorldDemo_Scene.cpp index 5dfe2d2..68cee1b 100644 --- a/Samples/OculusWorldDemo/OculusWorldDemo_Scene.cpp +++ b/Samples/OculusWorldDemo/OculusWorldDemo_Scene.cpp @@ -332,7 +332,7 @@ void OculusWorldDemoApp::RenderGrid(ovrEyeType eye) case Grid_Lens: { lineStep = 48; - Vector2f rendertargetNDC = FovPort(EyeRenderDesc[eye].Desc.Fov).TanAngleToRendertargetNDC(Vector2f(0.0f)); + Vector2f rendertargetNDC = FovPort(EyeRenderDesc[eye].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 ); diff --git a/Samples/OculusWorldDemo/Player.cpp b/Samples/OculusWorldDemo/Player.cpp index b2bf00e..c9f0997 100644 --- a/Samples/OculusWorldDemo/Player.cpp +++ b/Samples/OculusWorldDemo/Player.cpp @@ -39,21 +39,21 @@ Player::~Player() Vector3f Player::GetPosition() { - return BodyPos + Quatf(Vector3f(0,1,0), BodyYaw.Get()).Rotate(HeadPose.Position); + return BodyPos + Quatf(Vector3f(0,1,0), BodyYaw.Get()).Rotate(HeadPose.Translation); } Quatf Player::GetOrientation(bool baseOnly) { Quatf baseQ = Quatf(Vector3f(0,1,0), BodyYaw.Get()); - return baseOnly ? baseQ : baseQ * HeadPose.Orientation; + return baseOnly ? baseQ : baseQ * HeadPose.Rotation; } -Posef Player::VirtualWorldPoseFromRealPose(const Posef &sensorHeadPose) +Transformf Player::VirtualWorldTransformfromRealPose(const Transformf &sensorHeadPose) { Quatf baseQ = Quatf(Vector3f(0,1,0), BodyYaw.Get()); - return Posef(baseQ * sensorHeadPose.Orientation, - BodyPos + baseQ.Rotate(sensorHeadPose.Position)); + return Transformf(baseQ * sensorHeadPose.Rotation, + BodyPos + baseQ.Rotate(sensorHeadPose.Translation)); } @@ -187,8 +187,8 @@ bool Player::HandleMoveKey(OVR::KeyCode key, bool down) 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; + default: return false; } - return false; } diff --git a/Samples/OculusWorldDemo/Player.h b/Samples/OculusWorldDemo/Player.h index f8d29d5..7b45d7d 100644 --- a/Samples/OculusWorldDemo/Player.h +++ b/Samples/OculusWorldDemo/Player.h @@ -61,7 +61,7 @@ public: Anglef BodyYaw; // Where the player head is positioned and oriented in the real world - Posef HeadPose; + Transformf HeadPose; // Where the avatar head is positioned and oriented in the virtual world Vector3f GetPosition(); @@ -69,7 +69,7 @@ public: // Returns virtual world position based on a real world head pose. // Allows predicting eyes separately based on scanout time. - Posef VirtualWorldPoseFromRealPose(const Posef &sensorHeadPose); + Transformf VirtualWorldTransformfromRealPose(const Transformf &sensorHeadPose); // Handle directional movement. Returns 'true' if movement was processed. bool HandleMoveKey(OVR::KeyCode key, bool down); diff --git a/Samples/OculusWorldDemo/Projects/Win/VS2010/OculusWorldDemo.vcxproj b/Samples/OculusWorldDemo/Projects/Win/VS2010/OculusWorldDemo.vcxproj index 2167237..b113a51 100644 --- a/Samples/OculusWorldDemo/Projects/Win/VS2010/OculusWorldDemo.vcxproj +++ b/Samples/OculusWorldDemo/Projects/Win/VS2010/OculusWorldDemo.vcxproj @@ -19,7 +19,7 @@ </ProjectConfiguration> </ItemGroup> <PropertyGroup Label="Globals"> - <ProjectGuid>{456DA1F5-7D65-4B77-8336-277F3921639B}</ProjectGuid> + <ProjectGuid>{8051B877-2992-4F64-8C3B-FAF88B6D83AA}</ProjectGuid> <Keyword>Win32Proj</Keyword> <RootNamespace>OculusWorldDemo</RootNamespace> <ProjectName>OculusWorldDemo</ProjectName> @@ -192,11 +192,11 @@ </ClCompile> <ClCompile Include="..\..\..\..\..\3rdParty\TinyXml\tinyxml2.cpp" /> <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_XmlSceneLoader.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Util\OptionMenu.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Util\RenderProfiler.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" /> @@ -211,12 +211,12 @@ <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="..\..\..\..\CommonSrc\Util\OptionMenu.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Util\RenderProfiler.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" /> diff --git a/Samples/OculusWorldDemo/Projects/Win/VS2010/OculusWorldDemo.vcxproj.filters b/Samples/OculusWorldDemo/Projects/Win/VS2010/OculusWorldDemo.vcxproj.filters index 67678ea..6e568ee 100644 --- a/Samples/OculusWorldDemo/Projects/Win/VS2010/OculusWorldDemo.vcxproj.filters +++ b/Samples/OculusWorldDemo/Projects/Win/VS2010/OculusWorldDemo.vcxproj.filters @@ -10,6 +10,9 @@ <Filter Include="CommonSrc\Render"> <UniqueIdentifier>{1b6d51ae-a405-4f3d-be93-41a50db4f328}</UniqueIdentifier> </Filter> + <Filter Include="CommonSrc\Util"> + <UniqueIdentifier>{604daee3-bd81-41a5-ac3f-181bbbe9416a}</UniqueIdentifier> + </Filter> </ItemGroup> <ItemGroup> <ClCompile Include="..\..\..\..\CommonSrc\Platform\Platform.cpp"> @@ -45,8 +48,6 @@ <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> @@ -54,6 +55,12 @@ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_GL_Win32_Device.cpp"> <Filter>CommonSrc\Render</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\CommonSrc\Util\OptionMenu.cpp"> + <Filter>CommonSrc\Util</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\CommonSrc\Util\RenderProfiler.cpp"> + <Filter>CommonSrc\Util</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\..\..\CommonSrc\Platform\Win32_Platform.h"> @@ -91,15 +98,19 @@ <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> + <ClInclude Include="..\..\..\..\CommonSrc\Util\OptionMenu.h"> + <Filter>CommonSrc\Util</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\CommonSrc\Util\RenderProfiler.h"> + <Filter>CommonSrc\Util</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <ResourceCompile Include="..\..\..\OculusWorldDemo.rc" /> diff --git a/Samples/OculusWorldDemo/Projects/Win/VS2012/OculusWorldDemo.vcxproj b/Samples/OculusWorldDemo/Projects/Win/VS2012/OculusWorldDemo.vcxproj index 1dae2b3..4748329 100644 --- a/Samples/OculusWorldDemo/Projects/Win/VS2012/OculusWorldDemo.vcxproj +++ b/Samples/OculusWorldDemo/Projects/Win/VS2012/OculusWorldDemo.vcxproj @@ -198,11 +198,11 @@ </ClCompile> <ClCompile Include="..\..\..\..\..\3rdParty\TinyXml\tinyxml2.cpp" /> <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_XmlSceneLoader.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Util\OptionMenu.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Util\RenderProfiler.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" /> @@ -217,11 +217,12 @@ <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="..\..\..\..\CommonSrc\Util\OptionMenu.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Util\RenderProfiler.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" /> diff --git a/Samples/OculusWorldDemo/Projects/Win/VS2012/OculusWorldDemo.vcxproj.filters b/Samples/OculusWorldDemo/Projects/Win/VS2012/OculusWorldDemo.vcxproj.filters index 7246205..29b9844 100644 --- a/Samples/OculusWorldDemo/Projects/Win/VS2012/OculusWorldDemo.vcxproj.filters +++ b/Samples/OculusWorldDemo/Projects/Win/VS2012/OculusWorldDemo.vcxproj.filters @@ -10,6 +10,9 @@ <Filter Include="CommonSrc\Render"> <UniqueIdentifier>{1b6d51ae-a405-4f3d-be93-41a50db4f328}</UniqueIdentifier> </Filter> + <Filter Include="CommonSrc\Util"> + <UniqueIdentifier>{57bdf278-35e5-4f2f-ad41-dc9614a112fa}</UniqueIdentifier> + </Filter> </ItemGroup> <ItemGroup> <ClCompile Include="..\..\..\..\CommonSrc\Platform\Platform.cpp"> @@ -45,8 +48,6 @@ <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> @@ -54,6 +55,12 @@ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_GL_Device.cpp"> <Filter>CommonSrc\Render</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\CommonSrc\Util\OptionMenu.cpp"> + <Filter>CommonSrc\Util</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\CommonSrc\Util\RenderProfiler.cpp"> + <Filter>CommonSrc\Util</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\..\..\CommonSrc\Platform\Win32_Platform.h"> @@ -91,7 +98,6 @@ <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> @@ -99,6 +105,12 @@ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_GL_Win32_Device.h"> <Filter>CommonSrc\Render</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\CommonSrc\Util\OptionMenu.h"> + <Filter>CommonSrc\Util</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\CommonSrc\Util\RenderProfiler.h"> + <Filter>CommonSrc\Util</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <ResourceCompile Include="..\..\..\OculusWorldDemo.rc" /> diff --git a/Samples/OculusWorldDemo/Projects/Win/VS2013/OculusWorldDemo.vcxproj b/Samples/OculusWorldDemo/Projects/Win/VS2013/OculusWorldDemo.vcxproj index b894075..660cb60 100644 --- a/Samples/OculusWorldDemo/Projects/Win/VS2013/OculusWorldDemo.vcxproj +++ b/Samples/OculusWorldDemo/Projects/Win/VS2013/OculusWorldDemo.vcxproj @@ -198,11 +198,11 @@ </ClCompile> <ClCompile Include="..\..\..\..\..\3rdParty\TinyXml\tinyxml2.cpp" /> <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_XmlSceneLoader.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Util\OptionMenu.cpp" /> + <ClCompile Include="..\..\..\..\CommonSrc\Util\RenderProfiler.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" /> @@ -217,11 +217,12 @@ <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="..\..\..\..\CommonSrc\Util\OptionMenu.h" /> + <ClInclude Include="..\..\..\..\CommonSrc\Util\RenderProfiler.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" /> diff --git a/Samples/OculusWorldDemo/Projects/Win/VS2013/OculusWorldDemo.vcxproj.filters b/Samples/OculusWorldDemo/Projects/Win/VS2013/OculusWorldDemo.vcxproj.filters index 93fff72..bd553f1 100644 --- a/Samples/OculusWorldDemo/Projects/Win/VS2013/OculusWorldDemo.vcxproj.filters +++ b/Samples/OculusWorldDemo/Projects/Win/VS2013/OculusWorldDemo.vcxproj.filters @@ -10,6 +10,9 @@ <Filter Include="CommonSrc\Render"> <UniqueIdentifier>{1b6d51ae-a405-4f3d-be93-41a50db4f328}</UniqueIdentifier> </Filter> + <Filter Include="CommonSrc\Util"> + <UniqueIdentifier>{7fda3cf5-3371-45bc-b3b6-3b0424b46d93}</UniqueIdentifier> + </Filter> </ItemGroup> <ItemGroup> <ClCompile Include="..\..\..\..\CommonSrc\Platform\Platform.cpp"> @@ -45,8 +48,6 @@ <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> @@ -54,6 +55,12 @@ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_GL_Device.cpp"> <Filter>CommonSrc\Render</Filter> </ClCompile> + <ClCompile Include="..\..\..\..\CommonSrc\Util\OptionMenu.cpp"> + <Filter>CommonSrc\Util</Filter> + </ClCompile> + <ClCompile Include="..\..\..\..\CommonSrc\Util\RenderProfiler.cpp"> + <Filter>CommonSrc\Util</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\..\..\CommonSrc\Platform\Win32_Platform.h"> @@ -91,7 +98,6 @@ <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> @@ -99,6 +105,12 @@ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_GL_Device.h"> <Filter>CommonSrc\Render</Filter> </ClInclude> + <ClInclude Include="..\..\..\..\CommonSrc\Util\RenderProfiler.h"> + <Filter>CommonSrc\Util</Filter> + </ClInclude> + <ClInclude Include="..\..\..\..\CommonSrc\Util\OptionMenu.h"> + <Filter>CommonSrc\Util</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <ResourceCompile Include="..\..\..\OculusWorldDemo.rc" /> |