summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--LibOVR/Include/OVRVersion.h4
-rw-r--r--LibOVR/Projects/Win32/VS2010/LibOVR.vcxproj13
-rw-r--r--LibOVR/Projects/Win32/VS2010/LibOVR.vcxproj.filters5
-rw-r--r--LibOVR/Projects/Win32/VS2012/LibOVR.vcxproj3
-rw-r--r--LibOVR/Projects/Win32/VS2012/LibOVR.vcxproj.filters5
-rw-r--r--LibOVR/Projects/Win32/VS2013/LibOVR.vcxproj3
-rw-r--r--LibOVR/Projects/Win32/VS2013/LibOVR.vcxproj.filters5
-rw-r--r--LibOVR/Src/CAPI/CAPI_DistortionRenderer.cpp10
-rw-r--r--LibOVR/Src/CAPI/CAPI_DistortionRenderer.h22
-rw-r--r--LibOVR/Src/CAPI/CAPI_FrameTimeManager.cpp9
-rw-r--r--LibOVR/Src/CAPI/CAPI_FrameTimeManager.h4
-rw-r--r--LibOVR/Src/CAPI/CAPI_HMDRenderState.cpp38
-rw-r--r--LibOVR/Src/CAPI/CAPI_HMDRenderState.h8
-rw-r--r--LibOVR/Src/CAPI/CAPI_HMDState.cpp268
-rw-r--r--LibOVR/Src/CAPI/CAPI_HMDState.h29
-rw-r--r--LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.cpp113
-rw-r--r--LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.h19
-rw-r--r--LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.h2
-rw-r--r--LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.cpp182
-rw-r--r--LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.h53
-rw-r--r--LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_Util.cpp93
-rw-r--r--LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.cpp868
-rw-r--r--LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.h73
-rw-r--r--LibOVR/Src/CAPI/GL/CAPI_GL_DistortionShaders.h326
-rw-r--r--LibOVR/Src/CAPI/GL/CAPI_GL_Util.cpp210
-rw-r--r--LibOVR/Src/CAPI/GL/CAPI_GL_Util.h65
-rw-r--r--LibOVR/Src/CAPI/Shaders/DistortionChroma_ps.h84
-rw-r--r--LibOVR/Src/CAPI/Shaders/DistortionChroma_ps.psh6
-rw-r--r--LibOVR/Src/CAPI/Shaders/DistortionChroma_ps_refl.h1
-rw-r--r--LibOVR/Src/CAPI/Shaders/DistortionChroma_vs.h106
-rw-r--r--LibOVR/Src/CAPI/Shaders/DistortionChroma_vs_refl.h9
-rw-r--r--LibOVR/Src/CAPI/Shaders/DistortionTimewarpChroma_vs.h219
-rw-r--r--LibOVR/Src/CAPI/Shaders/DistortionTimewarpChroma_vs_refl.h11
-rw-r--r--LibOVR/Src/CAPI/Shaders/DistortionTimewarp_vs.h169
-rw-r--r--LibOVR/Src/CAPI/Shaders/DistortionTimewarp_vs_refl.h11
-rw-r--r--LibOVR/Src/CAPI/Shaders/Distortion_ps.h66
-rw-r--r--LibOVR/Src/CAPI/Shaders/Distortion_ps.psh2
-rw-r--r--LibOVR/Src/CAPI/Shaders/Distortion_ps_refl.h1
-rw-r--r--LibOVR/Src/CAPI/Shaders/Distortion_vs.h84
-rw-r--r--LibOVR/Src/CAPI/Shaders/Distortion_vs_refl.h9
-rw-r--r--LibOVR/Src/CAPI/Shaders/SimpleQuad_ps.h51
-rw-r--r--LibOVR/Src/CAPI/Shaders/SimpleQuad_ps_refl.h8
-rw-r--r--LibOVR/Src/CAPI/Shaders/SimpleQuad_vs.h64
-rw-r--r--LibOVR/Src/CAPI/Shaders/SimpleQuad_vs_refl.h9
-rw-r--r--LibOVR/Src/Kernel/OVR_Alg.h18
-rw-r--r--LibOVR/Src/Kernel/OVR_Deque.h30
-rw-r--r--LibOVR/Src/Kernel/OVR_FileFILE.cpp2
-rw-r--r--LibOVR/Src/Kernel/OVR_Math.h107
-rw-r--r--LibOVR/Src/Kernel/OVR_String.cpp11
-rw-r--r--LibOVR/Src/Kernel/OVR_String.h1
-rw-r--r--LibOVR/Src/Kernel/OVR_SysFile.cpp2
-rw-r--r--LibOVR/Src/Kernel/OVR_SysFile.h2
-rw-r--r--LibOVR/Src/Kernel/OVR_Threads.h2
-rw-r--r--LibOVR/Src/Kernel/OVR_Types.h2
-rw-r--r--LibOVR/Src/OVR_CAPI.cpp102
-rw-r--r--LibOVR/Src/OVR_CAPI.h144
-rw-r--r--LibOVR/Src/OVR_CAPI_D3D.h11
-rw-r--r--LibOVR/Src/OVR_CAPI_GL.h22
-rw-r--r--LibOVR/Src/OVR_Common_HMDDevice.cpp1
-rw-r--r--LibOVR/Src/OVR_Device.h96
-rw-r--r--LibOVR/Src/OVR_DeviceImpl.h1
-rw-r--r--LibOVR/Src/OVR_DeviceMessages.h15
-rw-r--r--LibOVR/Src/OVR_HIDDevice.h2
-rw-r--r--LibOVR/Src/OVR_JSON.cpp67
-rw-r--r--LibOVR/Src/OVR_JSON.h9
-rw-r--r--LibOVR/Src/OVR_LatencyTestImpl.cpp6
-rw-r--r--LibOVR/Src/OVR_LatencyTestImpl.h4
-rw-r--r--LibOVR/Src/OVR_Profile.cpp8
-rw-r--r--LibOVR/Src/OVR_Recording.cpp38
-rw-r--r--LibOVR/Src/OVR_Recording.h83
-rw-r--r--LibOVR/Src/OVR_Sensor2Impl.cpp96
-rw-r--r--LibOVR/Src/OVR_Sensor2Impl.h8
-rw-r--r--LibOVR/Src/OVR_Sensor2ImplUtil.h4
-rw-r--r--LibOVR/Src/OVR_SensorCalibration.cpp112
-rw-r--r--LibOVR/Src/OVR_SensorCalibration.h7
-rw-r--r--LibOVR/Src/OVR_SensorFilter.h2
-rw-r--r--LibOVR/Src/OVR_SensorFusion.cpp644
-rw-r--r--LibOVR/Src/OVR_SensorFusion.h220
-rw-r--r--LibOVR/Src/OVR_SensorFusionDebug.h82
-rw-r--r--LibOVR/Src/OVR_SensorImpl.cpp61
-rw-r--r--LibOVR/Src/OVR_SensorImpl.h11
-rw-r--r--LibOVR/Src/OVR_SensorImpl_Common.cpp14
-rw-r--r--LibOVR/Src/OVR_SensorImpl_Common.h4
-rw-r--r--LibOVR/Src/OVR_Stereo.cpp17
-rw-r--r--LibOVR/Src/OVR_Stereo.h4
-rw-r--r--LibOVR/Src/OVR_ThreadCommandQueue.cpp3
-rw-r--r--LibOVR/Src/OVR_Win32_DeviceManager.cpp6
-rw-r--r--LibOVR/Src/OVR_Win32_HIDDevice.cpp26
-rw-r--r--LibOVR/Src/OVR_Win32_HMDDevice.cpp6
-rw-r--r--LibOVR/Src/OVR_Win32_HMDDevice.h2
-rw-r--r--LibOVR/Src/OVR_Win32_SensorDevice.cpp6
-rw-r--r--LibOVR/Src/Recording/Recorder.h273
-rw-r--r--LibOVR/Src/Util/Util_ImageWindow.cpp290
-rw-r--r--LibOVR/Src/Util/Util_ImageWindow.h112
-rw-r--r--LibOVR/Src/Util/Util_LatencyTest2.cpp3
-rw-r--r--LibOVR/Src/Util/Util_LatencyTest2.h2
-rw-r--r--LibOVR/Src/Util/Util_Render_Stereo.cpp236
-rw-r--r--LibOVR/Src/Util/Util_Render_Stereo.h46
-rw-r--r--Samples/CommonSrc/Platform/Win32_Platform.h7
-rw-r--r--Samples/CommonSrc/Render/Render_D3D1X_Device.cpp344
-rw-r--r--Samples/CommonSrc/Render/Render_D3D1X_Device.h3
-rw-r--r--Samples/CommonSrc/Render/Render_Device.cpp535
-rw-r--r--Samples/CommonSrc/Render/Render_Device.h67
-rw-r--r--Samples/CommonSrc/Render/Render_FontEmbed_DejaVu48.h2
-rw-r--r--Samples/CommonSrc/Render/Render_GL_Device.cpp593
-rw-r--r--Samples/CommonSrc/Render/Render_GL_Device.h72
-rw-r--r--Samples/CommonSrc/Render/Render_GL_Win32_Device.cpp143
-rw-r--r--Samples/CommonSrc/Render/Render_GL_Win32_Device.h3
-rw-r--r--Samples/CommonSrc/Render/Render_LoadTextureDDS.cpp41
-rw-r--r--Samples/CommonSrc/Util/OptionMenu.cpp (renamed from Samples/OculusWorldDemo/OptionMenu.cpp)19
-rw-r--r--Samples/CommonSrc/Util/OptionMenu.h (renamed from Samples/OculusWorldDemo/OptionMenu.h)29
-rw-r--r--Samples/CommonSrc/Util/RenderProfiler.cpp (renamed from Samples/OculusWorldDemo/RenderProfiler.cpp)0
-rw-r--r--Samples/CommonSrc/Util/RenderProfiler.h (renamed from Samples/OculusWorldDemo/RenderProfiler.h)0
-rw-r--r--Samples/LibOVR_Samples_VS2010.sln35
-rw-r--r--Samples/LibOVR_Samples_VS2012.sln43
-rw-r--r--Samples/LibOVR_Samples_VS2013.sln38
-rw-r--r--Samples/LibOVR_With_Samples_VS2010.sln58
-rw-r--r--Samples/OculusRoomTiny/OculusRoomModel.cpp47
-rw-r--r--Samples/OculusRoomTiny/Projects/Win/VS2010/OculusRoomTiny.vcxproj2
-rw-r--r--Samples/OculusRoomTiny/Projects/Win/VS2012/OculusRoomTiny.vcxproj8
-rw-r--r--Samples/OculusRoomTiny/Projects/Win/VS2013/OculusRoomTiny.vcxproj8
-rw-r--r--Samples/OculusRoomTiny/RenderTiny_D3D11_Device.h2
-rw-r--r--Samples/OculusRoomTiny/Win32_DistortionMesh.cpp25
-rw-r--r--Samples/OculusRoomTiny/Win32_OculusRoomTiny.cpp79
-rw-r--r--Samples/OculusWorldDemo/Assets/Tuscany/Tuscany.xml10
-rw-r--r--Samples/OculusWorldDemo/OculusWorldDemo.cpp178
-rw-r--r--Samples/OculusWorldDemo/OculusWorldDemo.h12
-rw-r--r--Samples/OculusWorldDemo/OculusWorldDemo_Scene.cpp2
-rw-r--r--Samples/OculusWorldDemo/Player.cpp12
-rw-r--r--Samples/OculusWorldDemo/Player.h4
-rw-r--r--Samples/OculusWorldDemo/Projects/Win/VS2010/OculusWorldDemo.vcxproj10
-rw-r--r--Samples/OculusWorldDemo/Projects/Win/VS2010/OculusWorldDemo.vcxproj.filters19
-rw-r--r--Samples/OculusWorldDemo/Projects/Win/VS2012/OculusWorldDemo.vcxproj7
-rw-r--r--Samples/OculusWorldDemo/Projects/Win/VS2012/OculusWorldDemo.vcxproj.filters18
-rw-r--r--Samples/OculusWorldDemo/Projects/Win/VS2013/OculusWorldDemo.vcxproj7
-rw-r--r--Samples/OculusWorldDemo/Projects/Win/VS2013/OculusWorldDemo.vcxproj.filters18
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, &currentSwapInterval);
+ 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, &currentSwapInterval);
+ 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" />